package protosocket import ( "context" "testing" ) func TestEnvelopeStructRoundTrip(t *testing.T) { original := Envelope{ ProtocolVersion: ProtocolVersion, ID: "msg-123", CorrelationID: "corr-456", Type: "request", Channel: "tasks", Action: "create", Actor: map[string]any{"id": "user-1"}, Auth: map[string]any{"token": "secret"}, Payload: map[string]any{"title": "hello"}, Meta: map[string]any{"source": "client"}, Error: &EnvelopeError{ Code: "SOME_ERROR", Message: "An error occurred", Retryable: true, Details: map[string]any{"retry": true}, }, } s, err := original.ToStruct() if err != nil { t.Fatalf("failed to convert Envelope to Struct: %v", err) } roundtrip, err := EnvelopeFromStruct(s) if err != nil { t.Fatalf("failed to convert Struct back to Envelope: %v", err) } if roundtrip.ProtocolVersion != original.ProtocolVersion { t.Errorf("ProtocolVersion mismatch: got %q, want %q", roundtrip.ProtocolVersion, original.ProtocolVersion) } if roundtrip.ID != original.ID { t.Errorf("ID mismatch: got %q, want %q", roundtrip.ID, original.ID) } if roundtrip.CorrelationID != original.CorrelationID { t.Errorf("CorrelationID mismatch: got %q, want %q", roundtrip.CorrelationID, original.CorrelationID) } if roundtrip.Type != original.Type { t.Errorf("Type mismatch: got %q, want %q", roundtrip.Type, original.Type) } if roundtrip.Channel != original.Channel { t.Errorf("Channel mismatch: got %q, want %q", roundtrip.Channel, original.Channel) } if roundtrip.Action != original.Action { t.Errorf("Action mismatch: got %q, want %q", roundtrip.Action, original.Action) } if roundtrip.Actor["id"] != "user-1" { t.Errorf("Actor mismatch: got %v", roundtrip.Actor) } if roundtrip.Auth["token"] != "secret" { t.Errorf("Auth mismatch: got %v", roundtrip.Auth) } if roundtrip.Payload["title"] != "hello" { t.Errorf("Payload mismatch: got %v", roundtrip.Payload) } if roundtrip.Meta["source"] != "client" { t.Errorf("Meta mismatch: got %v", roundtrip.Meta) } if roundtrip.Error == nil { t.Fatal("Error should not be nil") } if roundtrip.Error.Code != "SOME_ERROR" { t.Errorf("Error.Code mismatch: got %q, want %q", roundtrip.Error.Code, "SOME_ERROR") } if roundtrip.Error.Message != "An error occurred" { t.Errorf("Error.Message mismatch: got %q, want %q", roundtrip.Error.Message, "An error occurred") } if !roundtrip.Error.Retryable { t.Errorf("Error.Retryable mismatch: got false, want true") } if roundtrip.Error.Details["retry"] != true { t.Errorf("Error.Details mismatch: got %v", roundtrip.Error.Details) } } func TestDispatcherReturnsUnsupportedActionErrorEnvelope(t *testing.T) { dispatcher := NewDispatcher() ctx := context.Background() request := Envelope{ ProtocolVersion: ProtocolVersion, ID: "req-1", Type: "request", Channel: "tasks", Action: "unknown-action", } response := dispatcher.Dispatch(ctx, request) if response.Type != "error" { t.Errorf("expected response type 'error', got %q", response.Type) } if response.CorrelationID != "req-1" { t.Errorf("expected CorrelationID 'req-1', got %q", response.CorrelationID) } if response.Error == nil { t.Fatal("expected non-nil Error in response") } if response.Error.Code != "UNSUPPORTED_ACTION" { t.Errorf("expected error code 'UNSUPPORTED_ACTION', got %q", response.Error.Code) } if response.Error.Retryable { t.Error("expected Retryable to be false for UNSUPPORTED_ACTION") } }