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") } }