package configuration import ( "context" "errors" "reflect" "testing" "go.maximumdirect.net/configkit" "go.maximumdirect.net/promptkit/internal/domain" ) func TestLoadedListsSortedEffectiveIdentities(t *testing.T) { state, err := Load(mapping("identities", map[string]any{ "backends": []any{map[string]any{"id": "local", "endpoint": "http://localhost:8080/v1"}}, "collections": map[string]any{ "z": map[string]any{"profiles": []any{map[string]any{"id": "profile", "backend": "local", "model": "z-model"}}, "prompts": []any{listingPromptDefinition("prompt")}}, "partial": map[string]any{"profiles": []any{map[string]any{"id": "profile", "backend": "local"}}}, "a": map[string]any{"profiles": []any{map[string]any{"id": "profile", "backend": "local", "model": "a-model"}}, "prompts": []any{listingPromptDefinition("prompt")}}, " z": map[string]any{"profiles": []any{map[string]any{"id": "profile ", "backend": "local", "model": "spaced-model"}}, "prompts": []any{listingPromptDefinition("prompt ")}}, }, }), nil) if err != nil { t.Fatal(err) } backends, err := state.ListBackends(context.Background(), IdentityFilter{All: true}) if err != nil { t.Fatal(err) } wantBackends := []string{"local"} if !reflect.DeepEqual(backends, wantBackends) { t.Fatalf("backend IDs = %#v, want %#v", backends, wantBackends) } profiles, err := state.ListProfiles(context.Background(), IdentityFilter{All: true}) if err != nil { t.Fatal(err) } wantProfiles := []string{" z/profile ", "a/profile", "partial/profile", "z/profile"} if !reflect.DeepEqual(profiles, wantProfiles) { t.Fatalf("profile IDs = %#v, want %#v", profiles, wantProfiles) } prompts, err := state.ListPrompts(context.Background(), IdentityFilter{All: true}) if err != nil { t.Fatal(err) } wantPrompts := []domain.PromptIdentity{ {ID: " z/prompt "}, {ID: "a/prompt"}, {ID: "z/prompt"}, } if !reflect.DeepEqual(prompts, wantPrompts) { t.Fatalf("prompt identities = %#v, want %#v", prompts, wantPrompts) } } func TestLoadedListsAreIndependent(t *testing.T) { state, err := Load(mapping("identities", map[string]any{ "backends": []any{map[string]any{"id": "backend", "endpoint": "https://example.test/v1"}}, "profiles": []any{map[string]any{"id": "profile"}}, "prompts": []any{listingPromptDefinition("example")}, }), nil) if err != nil { t.Fatal(err) } profiles, err := state.ListProfiles(context.Background(), IdentityFilter{All: true}) if err != nil { t.Fatal(err) } profiles = append(profiles, "caller profile") profiles[0] = "changed profile" backends, err := state.ListBackends(context.Background(), IdentityFilter{All: true}) if err != nil { t.Fatal(err) } backends[0] = "changed backend" prompts, err := state.ListPrompts(context.Background(), IdentityFilter{All: true}) if err != nil { t.Fatal(err) } prompts[0].ID = "changed prompt" profiles, err = state.ListProfiles(context.Background(), IdentityFilter{All: true}) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(profiles, []string{"profile"}) { t.Fatalf("caller mutation changed profile inventory: %#v", profiles) } backends, err = state.ListBackends(context.Background(), IdentityFilter{All: true}) if err != nil || !reflect.DeepEqual(backends, []string{"backend"}) { t.Fatalf("caller mutation changed backend inventory: %#v, %v", backends, err) } prompts, err = state.ListPrompts(context.Background(), IdentityFilter{All: true}) if err != nil { t.Fatal(err) } wantPrompts := []domain.PromptIdentity{{ID: "example"}} if !reflect.DeepEqual(prompts, wantPrompts) { t.Fatalf("caller mutation changed prompt inventory: %#v", prompts) } } func TestLoadedListsSelectNamespaces(t *testing.T) { ids := []string{"a", "a-b/one", "a/one", "a/two", "b", "z/one"} state := &loaded{profileIDs: append([]string(nil), ids...), backendIDs: append([]string(nil), ids...)} for _, id := range ids { state.promptIDs = append(state.promptIDs, domain.PromptIdentity{ID: id}) } cases := []struct { name string filter IdentityFilter want []string }{ {"all", IdentityFilter{All: true}, ids}, {"unqualified", IdentityFilter{}, []string{"a", "b"}}, {"namespace", IdentityFilter{Namespace: "a"}, []string{"a/one", "a/two"}}, {"prefix sharing", IdentityFilter{Namespace: "a-b"}, []string{"a-b/one"}}, {"missing", IdentityFilter{Namespace: "absent"}, nil}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { profiles, err := state.ListProfiles(context.Background(), tc.filter) if err != nil || !reflect.DeepEqual(profiles, tc.want) { t.Fatalf("profiles = %v, %v; want %v", profiles, err, tc.want) } backends, err := state.ListBackends(context.Background(), tc.filter) if err != nil || !reflect.DeepEqual(backends, tc.want) { t.Fatalf("backends = %v, %v; want %v", backends, err, tc.want) } prompts, err := state.ListPrompts(context.Background(), tc.filter) if err != nil || len(prompts) != len(tc.want) { t.Fatalf("prompts = %v, %v; want %v", prompts, err, tc.want) } for i := range prompts { if prompts[i].ID != tc.want[i] { t.Fatalf("prompt ID = %q; want %q", prompts[i].ID, tc.want[i]) } } if len(profiles) > 0 { profiles[0], backends[0], prompts[0].ID = "changed", "changed", "changed" } }) } if !reflect.DeepEqual(state.profileIDs, ids) || !reflect.DeepEqual(state.backendIDs, ids) || state.promptIDs[0].ID != ids[0] { t.Fatal("caller mutation changed captured identities") } } func TestLoadedListsEmptyInventory(t *testing.T) { state, err := Load(configkit.Input{Source: configkit.NoSource()}, nil) if err != nil { t.Fatal(err) } profiles, err := state.ListProfiles(context.Background(), IdentityFilter{All: true}) if err != nil || len(profiles) != 0 { t.Fatalf("empty profile listing = %#v, %v", profiles, err) } backends, err := state.ListBackends(context.Background(), IdentityFilter{All: true}) if err != nil || len(backends) != 0 { t.Fatalf("empty backend listing = %#v, %v", backends, err) } prompts, err := state.ListPrompts(context.Background(), IdentityFilter{All: true}) if err != nil || len(prompts) != 0 { t.Fatalf("empty prompt listing = %#v, %v", prompts, err) } } func TestLoadedListsHonorCanceledContext(t *testing.T) { state, err := Load(mapping("identities", map[string]any{ "profiles": []any{map[string]any{"id": "partial"}}, "prompts": []any{listingPromptDefinition("example")}, }), nil) if err != nil { t.Fatal(err) } ctx, cancel := context.WithCancel(context.Background()) cancel() for _, filter := range []IdentityFilter{{All: true}, {}, {Namespace: "example"}} { profiles, err := state.ListProfiles(ctx, filter) if !errors.Is(err, context.Canceled) || len(profiles) != 0 { t.Fatalf("canceled profile listing = %#v, %v", profiles, err) } backends, err := state.ListBackends(ctx, filter) if !errors.Is(err, context.Canceled) || len(backends) != 0 { t.Fatalf("canceled backend listing = %#v, %v", backends, err) } prompts, err := state.ListPrompts(ctx, filter) if !errors.Is(err, context.Canceled) || len(prompts) != 0 { t.Fatalf("canceled prompt listing = %#v, %v", prompts, err) } } } func listingPromptDefinition(id string) map[string]any { return map[string]any{ "id": id, "messages": []any{map[string]any{"role": "user", "content": "Hello."}}, "output": map[string]any{"format": "text", "validation_mode": "basic"}, } }