package serviceadapter import ( "strings" "testing" ) func TestRegistryAdd(t *testing.T) { logger := &MockLogger{} reg := NewRegistry(logger) adapter := &ServiceAdapter{ Namespace: "api", ServiceName: "test-service", Spec: Spec{ ServiceName: "test-service", Upstream: Upstream{ URL: "http://example.com", TimeoutSeconds: 30, }, Auth: Auth{ Required: false, }, Resources: []Resource{ { Name: "default", Methods: []Method{ { Verb: "POST", UpstreamPath: "/api", }, }, }, }, }, } err := reg.Add(adapter) if err != nil { t.Fatalf("Add failed: %v", err) } retrieved := reg.Get("test-service") if retrieved == nil { t.Errorf("expected adapter to be retrievable") } if retrieved.ServiceName != "test-service" { t.Errorf("expected service name test-service, got %s", retrieved.ServiceName) } } func TestRegistryDelete(t *testing.T) { logger := &MockLogger{} reg := NewRegistry(logger) adapter := &ServiceAdapter{ Namespace: "api", ServiceName: "to-delete", Spec: Spec{ ServiceName: "to-delete", Upstream: Upstream{ URL: "http://example.com", TimeoutSeconds: 30, }, Auth: Auth{Required: false}, Resources: []Resource{ { Name: "default", Methods: []Method{ {Verb: "GET", UpstreamPath: "/"}, }, }, }, }, } reg.Add(adapter) if reg.Count() != 1 { t.Errorf("expected count 1 after add, got %d", reg.Count()) } reg.Delete("to-delete") if reg.Count() != 0 { t.Errorf("expected count 0 after delete, got %d", reg.Count()) } if reg.Get("to-delete") != nil { t.Errorf("expected deleted adapter to be nil") } } func TestRegistryMalformedSchema(t *testing.T) { logger := &MockLogger{} reg := NewRegistry(logger) adapter := &ServiceAdapter{ Namespace: "api", ServiceName: "bad-schema", Spec: Spec{ ServiceName: "bad-schema", Upstream: Upstream{ URL: "http://example.com", TimeoutSeconds: 30, }, Auth: Auth{Required: false}, Resources: []Resource{ { Name: "default", Methods: []Method{ { Verb: "POST", UpstreamPath: "/", RequestSchema: "{{ unclosed", // malformed }, }, }, }, }, } // Should not crash, should log error err := reg.Add(adapter) if err != nil { t.Fatalf("Add should not return error (should skip malformed), got: %v", err) } // Adapter should be skipped (not added) if reg.Get("bad-schema") != nil { t.Errorf("expected malformed adapter to be skipped") } // Should have logged an error entries := logger.Entries() errorLogged := false for _, entry := range entries { if strings.Contains(entry, "invalid schema") { errorLogged = true break } } if !errorLogged { t.Errorf("expected error to be logged for malformed schema") } } func TestRegistryList(t *testing.T) { logger := &MockLogger{} reg := NewRegistry(logger) for i := 0; i < 3; i++ { adapter := &ServiceAdapter{ Namespace: "api", ServiceName: "service-" + string(rune('1'+i)), Spec: Spec{ ServiceName: "service-" + string(rune('1'+i)), Upstream: Upstream{ URL: "http://example.com", TimeoutSeconds: 30, }, Auth: Auth{Required: false}, Resources: []Resource{}, }, } reg.Add(adapter) } list := reg.List() if len(list) != 3 { t.Errorf("expected 3 adapters, got %d", len(list)) } } func TestRegistryThreadSafety(t *testing.T) { logger := &MockLogger{} reg := NewRegistry(logger) done := make(chan bool, 2) // Writer goroutine go func() { for i := 0; i < 10; i++ { adapter := &ServiceAdapter{ Namespace: "api", ServiceName: "writer-service", Spec: Spec{ ServiceName: "writer-service", Upstream: Upstream{ URL: "http://example.com", TimeoutSeconds: 30, }, Auth: Auth{Required: false}, Resources: []Resource{}, }, } reg.Add(adapter) } done <- true }() // Reader goroutine go func() { for i := 0; i < 10; i++ { _ = reg.Get("writer-service") _ = reg.List() _ = reg.Count() } done <- true }() <-done <-done if reg.Count() != 1 { t.Errorf("expected 1 adapter after concurrent access, got %d", reg.Count()) } } func TestBasicSchemaCheck(t *testing.T) { tests := []struct { name string schema string valid bool }{ {"empty", "", true}, {"valid", "key1: string, key2: int", true}, {"unclosed braces", "{{ unclosed", false}, {"mismatched parens", "func(arg", false}, {"balanced parens", "func(arg)", true}, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { err := basicSchemaCheck(tc.schema) if tc.valid && err != nil { t.Errorf("expected valid schema to pass, got: %v", err) } if !tc.valid && err == nil { t.Errorf("expected invalid schema to fail") } }) } }