207 lines
5.3 KiB
Go
207 lines
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")
|
||
|
|
}
|
||
|
|
}
|