edge-connect-client/internal/domain/errors_test.go
Stephan Lo 1c13c93512 refactor(arch): Relocate domain and ports packages
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.
2025-10-09 01:16:31 +02:00

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