Moves the `domain` and `ports` packages from `internal/core` to `internal`. This refactoring simplifies the directory structure by elevating the core architectural concepts of domain and ports to the top level of the `internal` directory. The `core` directory is now removed as its only purpose was to house these two packages. All import paths across the project have been updated to reflect this change.
207 lines
No EOL
5.3 KiB
Go
207 lines
No EOL
5.3 KiB
Go
package domain
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
)
|
|
|
|
func TestDomainError_Creation(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
code ErrorCode
|
|
message string
|
|
expected string
|
|
}{
|
|
{
|
|
name: "simple error",
|
|
code: ErrResourceNotFound,
|
|
message: "test resource not found",
|
|
expected: "test resource not found",
|
|
},
|
|
{
|
|
name: "validation error",
|
|
code: ErrValidationFailed,
|
|
message: "invalid input",
|
|
expected: "invalid input",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := NewDomainError(tt.code, tt.message)
|
|
if err.Error() != tt.expected {
|
|
t.Errorf("Expected error message %q, got %q", tt.expected, err.Error())
|
|
}
|
|
if err.Code != tt.code {
|
|
t.Errorf("Expected error code %v, got %v", tt.code, err.Code)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDomainError_WithContext(t *testing.T) {
|
|
err := NewDomainError(ErrResourceNotFound, "test error")
|
|
err = err.WithContext("user_id", "123")
|
|
err = err.WithContext("operation", "create")
|
|
|
|
if len(err.Context) != 2 {
|
|
t.Errorf("Expected 2 context items, got %d", len(err.Context))
|
|
}
|
|
|
|
if err.Context["user_id"] != "123" {
|
|
t.Errorf("Expected user_id to be '123', got %v", err.Context["user_id"])
|
|
}
|
|
}
|
|
|
|
func TestDomainError_WithDetails(t *testing.T) {
|
|
err := NewDomainError(ErrValidationFailed, "validation failed")
|
|
err = err.WithDetails("name field is required")
|
|
|
|
expectedError := "validation failed: name field is required"
|
|
if err.Error() != expectedError {
|
|
t.Errorf("Expected error %q, got %q", expectedError, err.Error())
|
|
}
|
|
}
|
|
|
|
func TestDomainError_WithCause(t *testing.T) {
|
|
cause := errors.New("network timeout")
|
|
err := NewDomainErrorWithCause(ErrNetworkError, "operation failed", cause)
|
|
|
|
if err.Cause != cause {
|
|
t.Error("Expected cause to be preserved")
|
|
}
|
|
|
|
if !errors.Is(err, cause) {
|
|
t.Error("Expected error to wrap the cause")
|
|
}
|
|
}
|
|
|
|
func TestAppError_Creation(t *testing.T) {
|
|
appKey := AppKey{
|
|
Organization: "test-org",
|
|
Name: "test-app",
|
|
Version: "1.0.0",
|
|
}
|
|
|
|
err := NewAppError(ErrResourceNotFound, "ShowApp", appKey, "US", "not found")
|
|
|
|
expected := "operation ShowApp failed: resource app test-org/test-app version 1.0.0 in region US: not found"
|
|
if err.Error() != expected {
|
|
t.Errorf("Expected error %q, got %q", expected, err.Error())
|
|
}
|
|
|
|
if err.Resource.Type != "app" {
|
|
t.Errorf("Expected resource type 'app', got %q", err.Resource.Type)
|
|
}
|
|
}
|
|
|
|
func TestInstanceError_Creation(t *testing.T) {
|
|
instanceKey := AppInstanceKey{
|
|
Organization: "test-org",
|
|
Name: "test-instance",
|
|
CloudletKey: CloudletKey{
|
|
Organization: "cloudlet-org",
|
|
Name: "cloudlet-name",
|
|
},
|
|
}
|
|
|
|
err := NewInstanceError(ErrResourceNotFound, "ShowAppInstance", instanceKey, "US", "not found")
|
|
|
|
if err.Resource.Type != "app-instance" {
|
|
t.Errorf("Expected resource type 'app-instance', got %q", err.Resource.Type)
|
|
}
|
|
|
|
if err.Operation != "ShowAppInstance" {
|
|
t.Errorf("Expected operation 'ShowAppInstance', got %q", err.Operation)
|
|
}
|
|
}
|
|
|
|
func TestErrorChecking_Functions(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
err error
|
|
checkFn func(error) bool
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "IsNotFoundError with not found error",
|
|
err: NewDomainError(ErrResourceNotFound, "not found"),
|
|
checkFn: IsNotFoundError,
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "IsNotFoundError with validation error",
|
|
err: NewDomainError(ErrValidationFailed, "invalid"),
|
|
checkFn: IsNotFoundError,
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "IsValidationError with validation error",
|
|
err: NewDomainError(ErrValidationFailed, "invalid"),
|
|
checkFn: IsValidationError,
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "IsRetryableError with network error",
|
|
err: NewDomainError(ErrNetworkError, "connection failed"),
|
|
checkFn: IsRetryableError,
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "IsRetryableError with validation error",
|
|
err: NewDomainError(ErrValidationFailed, "invalid"),
|
|
checkFn: IsRetryableError,
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "IsAuthenticationError with auth error",
|
|
err: NewDomainError(ErrAuthenticationFailed, "unauthorized"),
|
|
checkFn: IsAuthenticationError,
|
|
expected: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := tt.checkFn(tt.err)
|
|
if result != tt.expected {
|
|
t.Errorf("Expected %v, got %v", tt.expected, result)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestErrorCode_String(t *testing.T) {
|
|
tests := []struct {
|
|
code ErrorCode
|
|
expected string
|
|
}{
|
|
{ErrResourceNotFound, "RESOURCE_NOT_FOUND"},
|
|
{ErrValidationFailed, "VALIDATION_FAILED"},
|
|
{ErrNetworkError, "NETWORK_ERROR"},
|
|
{ErrUnknownError, "UNKNOWN_ERROR"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.expected, func(t *testing.T) {
|
|
if tt.code.String() != tt.expected {
|
|
t.Errorf("Expected %q, got %q", tt.expected, tt.code.String())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPredefinedErrors(t *testing.T) {
|
|
// Test that predefined errors have correct codes
|
|
if ErrAppNotFound.Code != ErrResourceNotFound {
|
|
t.Error("ErrAppNotFound should have ErrResourceNotFound code")
|
|
}
|
|
|
|
if ErrInvalidAppKey.Code != ErrValidationFailed {
|
|
t.Error("ErrInvalidAppKey should have ErrValidationFailed code")
|
|
}
|
|
|
|
if ErrDeploymentFailed.Code != ErrOperationNotAllowed {
|
|
t.Error("ErrDeploymentFailed should have ErrOperationNotAllowed code")
|
|
}
|
|
} |