package consumers_test import ( "bytes" "errors" "fmt" "os" "strings" "testing" configkit "gitea.maximumdirect.net/eric/ConfigKit" "gitea.maximumdirect.net/eric/ConfigKit/examples/consumers" ) func Example_sequenceCatalog() { const oldSecret = "CONFIGKIT_SEQUENCE_CATALOG_OLD_SECRET" const newSecret = "CONFIGKIT_SEQUENCE_CATALOG_NEW_SECRET" restoreOld, restoreNew := preserveEnvironment(oldSecret), preserveEnvironment(newSecret) defer restoreOld() defer restoreNew() _ = os.Setenv(oldSecret, "disposable-old-example-credential") _ = os.Setenv(newSecret, "disposable-new-example-credential") result, err := consumers.LoadSequenceCatalog(fixture("sequence-catalog", "config.yml"), "upsert", "preview") if err != nil { fmt.Println(err) return } ids := make([]string, 0, len(result.Config.Prompts)) for _, prompt := range result.Config.Prompts { ids = append(ids, prompt.ID) } shared := configkit.Keys("prompts").Index(1).Key("name") info, _ := result.Metadata().Lookup(shared) resource, resourceErr := consumers.ReadSequenceCatalogResource(result, "concise") fmt.Println(ids, result.Config.ResolvedLabel, info.Explicit, len(result.Metadata().History(shared)), resource, resourceErr == nil, err) // Output: [foundation shared welcome concise extra] for:preview true 2 Foundation resource text. // true } func TestSequenceCatalogSelectedOverlayOperations(t *testing.T) { const oldSecret = "CONFIGKIT_SEQUENCE_CATALOG_OLD_SECRET" const newSecret = "CONFIGKIT_SEQUENCE_CATALOG_NEW_SECRET" t.Setenv(oldSecret, "sequence-catalog-old-canary") t.Setenv(newSecret, "sequence-catalog-new-canary") tests := []struct { name string wantIDs []string shared *consumers.SequenceCatalogEntry }{ {name: "append", wantIDs: []string{"foundation", "shared", "welcome", "concise", "extra"}}, {name: "upsert", wantIDs: []string{"foundation", "shared", "welcome", "concise", "extra"}, shared: &consumers.SequenceCatalogEntry{ID: "shared", Name: "Shared replacement", Messages: []string{"Replacement message"}, Credential: configkit.SecretEnv(newSecret)}}, {name: "replace", wantIDs: []string{"replacement", "last"}}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { result, err := consumers.LoadSequenceCatalog(fixture("sequence-catalog", "config.yml"), test.name, "test") if err != nil { var loadError *configkit.LoadError if errors.As(err, &loadError) { t.Fatalf("load selected overlay: %v (%#v)", err, loadError.Diagnostics()) } t.Fatal(err) } gotIDs := make([]string, 0, len(result.Config.Prompts)) for _, prompt := range result.Config.Prompts { gotIDs = append(gotIDs, prompt.ID) } if strings.Join(gotIDs, ",") != strings.Join(test.wantIDs, ",") { t.Fatalf("prompt order = %v, want %v", gotIDs, test.wantIDs) } if test.shared == nil { return } shared := result.Config.Prompts[1] if shared.ID != test.shared.ID || shared.Name != test.shared.Name || len(shared.Messages) != 1 || shared.Messages[0] != test.shared.Messages[0] || shared.Description != "" || shared.Resource != "" || shared.Credential.EnvName() != newSecret { t.Fatalf("upsert did not replace the complete matched record: %#v", shared) } }) } } func TestSequenceCatalogInspectionTracksResourcesAndSecretHistory(t *testing.T) { const oldSecret = "CONFIGKIT_SEQUENCE_CATALOG_OLD_SECRET" const newSecret = "CONFIGKIT_SEQUENCE_CATALOG_NEW_SECRET" const oldCanary = "sequence-catalog-old-canary" const newCanary = "sequence-catalog-new-canary" t.Setenv(oldSecret, oldCanary) t.Setenv(newSecret, newCanary) result, err := consumers.LoadSequenceCatalog(fixture("sequence-catalog", "config.yml"), "upsert", "history") if err != nil { var loadError *configkit.LoadError if errors.As(err, &loadError) { t.Fatalf("load sequence catalog: %v (%#v)", err, loadError.Diagnostics()) } t.Fatal(err) } resourcePath := configkit.Keys("prompts").Index(3).Key("resource") resourceInfo, found := result.Metadata().Lookup(resourcePath) if !found || len(resourceInfo.Origin.Locations) != 1 || len(resourceInfo.Origin.Inheritance) != 1 { t.Fatalf("inherited resource inspection = %#v, %v", resourceInfo, found) } resource, err := consumers.ReadSequenceCatalogResource(result, "concise") if err != nil || resource != "Foundation resource text.\n" { t.Fatalf("resource from inherited source context = %q, %v", resource, err) } if len(result.Metadata().History(configkit.Keys("resolved_label"))) == 0 { t.Fatal("recorded CLI-driven resolution was absent from final inspection") } credentialPath := configkit.Keys("prompts").Index(1).Key("credential") credentialHistory := result.Metadata().History(credentialPath) if len(credentialHistory) == 0 { t.Fatal("upsert did not retain the replaced secret reference in history") } var explanation bytes.Buffer if err := result.WriteExplanation(&explanation, credentialPath); err != nil { t.Fatal(err) } if strings.Contains(explanation.String(), oldCanary) || strings.Contains(explanation.String(), newCanary) { t.Fatalf("secret explanation exposed a credential value: %s", explanation.String()) } } func TestNamespacedTypedMapIdentityScopesAreIndependent(t *testing.T) { source := configkit.Bytes("namespaced maps", []byte(` prompts: - id: shared text: root prompt collections: team: prompts: - id: shared text: team prompt operations: prompts: - id: shared text: operations prompt `)) result, err := consumers.LoadNamespacedMapCatalog(source) if err != nil { t.Fatal(err) } if result.Config.Prompts[0]["text"] != "root prompt" || result.Config.Collections["team"]["prompts"].([]any)[0].(map[string]any)["text"] != "team prompt" || result.Config.Collections["operations"]["prompts"].([]any)[0].(map[string]any)["text"] != "operations prompt" { t.Fatalf("typed map collections = %#v", result.Config) } } func TestNamespacedTypedMapIdentityFindsCollectionsIntroducedByInheritance(t *testing.T) { result, err := consumers.LoadNamespacedMapCatalog(configkit.Bytes("inherited namespace", []byte(` collections: source: prompts: - id: shared text: inherited prompt copied: extends: source `))) if err != nil { t.Fatal(err) } copied := result.Config.Collections["copied"]["prompts"].([]any) if len(copied) != 1 || copied[0].(map[string]any)["text"] != "inherited prompt" { t.Fatalf("inherited typed-map collection = %#v", result.Config.Collections["copied"]) } } func Example_yamlDeclaredIdentityOnly() { result, err := configkit.Load(configkit.Bytes("YAML identity only", []byte(` configkit: sequences: - destination: [prompts] key: id prompts: - id: initial `)), configkit.Options[map[string]any]{ Overrides: []configkit.Override{{ Path: configkit.Keys("prompts"), Value: []any{ map[string]any{"id": "same"}, map[string]any{"id": "same"}, }, Flag: "--prompts", }}, }) fmt.Println(len(result.Config["prompts"].([]any)), err) // Output: 2 } func TestYAMLDeclaredIdentityDoesNotRegisterFinalTypedConstraint(t *testing.T) { result, err := configkit.Load(configkit.Bytes("YAML identity only", []byte(` configkit: sequences: - destination: [prompts] key: id prompts: - id: initial `)), configkit.Options[map[string]any]{ Overrides: []configkit.Override{{ Path: configkit.Keys("prompts"), Value: []any{ map[string]any{"id": "same"}, map[string]any{"id": "same"}, }, Flag: "--prompts", }}, }) if err != nil { t.Fatalf("YAML-only identity incorrectly became an application constraint: %v", err) } prompts := result.Config["prompts"].([]any) if len(prompts) != 2 || prompts[0].(map[string]any)["id"] != prompts[1].(map[string]any)["id"] { t.Fatalf("CLI result = %#v", result.Config) } } func TestNamespacedTypedMapRejectsDuplicatesWithinOneCollection(t *testing.T) { _, err := consumers.LoadNamespacedMapCatalog(configkit.Bytes("duplicate namespace", []byte(` collections: team: prompts: - id: duplicate - id: duplicate `))) var loadError *configkit.LoadError if !errors.As(err, &loadError) || len(loadError.Diagnostics()) != 1 || loadError.Diagnostics()[0].Code != configkit.CodeComposeConflict || loadError.Diagnostics()[0].Path.String() != "/collections/team/prompts" { diagnostics := []configkit.Diagnostic(nil) if loadError != nil { diagnostics = loadError.Diagnostics() } t.Fatalf("duplicate namespaced identity error = %v (%#v)", err, diagnostics) } }