package engine import ( "reflect" "testing" ) func TestSecretPathCollectionKeepsParsedContributions(t *testing.T) { for _, pointer := range []string{"", "/", "/records/0", "/records/a~1b~0/01"} { t.Run(pointer, func(t *testing.T) { paths := make(map[string]Path) for repeat := 0; repeat < 3; repeat++ { addSecretPath(paths, pointer) path, found := paths[pointer] if !found || !path.valid() || path.String() != pointer { t.Fatalf("collected path = %#v, found %v; want %q", path, found, pointer) } for _, segment := range path.segments { if segment.kind != pathSegmentParsed { t.Fatalf("collected path %q retained a typed segment: %#v", pointer, segment) } } } }) } } func TestSecretClassificationParsesTypedHistoryAfterNumericShapeChanges(t *testing.T) { tests := []struct { name string earlier string final string historical Path }{ {"mapping to sequence", "items: {'0': old}", "items: [new]", Keys("items", "0")}, {"sequence to mapping", "items: [old]", "items: {'0': new}", Keys("items").Index(0)}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { earlier := parseCompositionDocument(t, "earlier", test.earlier) final := parseCompositionDocument(t, "final", test.final) pointer := test.historical.String() metadata := Metadata{history: map[string][]Change{pointer: {{Path: test.historical}}}} seen := false classified := classifySecretPaths(nil, func(path Path) bool { if path.String() != pointer { return false } seen = true for _, segment := range path.segments { if segment.kind != pathSegmentParsed { t.Fatalf("predicate received typed history after final projection: %#v", path) } } return true }, metadata, final, []historyApplication{{value: earlier}}, earlier) if !seen || !classified[pointer] { t.Fatalf("historical/final numeric path was not classified: %#v", classified) } }) } } func TestSecretPredicateReceivesDetachedHistoricalPath(t *testing.T) { path := Keys("records").Key("1") metadata := Metadata{history: map[string][]Change{ path.String(): {{Path: path}}, }} seen := false classified := classifySecretPaths(nil, func(candidate Path) bool { if candidate.String() != path.String() { return false } seen = true candidate.segments[0].key = "changed" return true }, metadata, nil, nil) if !seen || !classified[path.String()] || classified["/changed/1"] { t.Fatalf("classification after predicate mutation = %#v, predicate called: %v", classified, seen) } } func TestSourceVersionEvidenceSensitivityUsesOriginalMountedPaths(t *testing.T) { const canary = "PRIVATE-VERSION-CANARY" type credential struct { Value string `yaml:"credential" configkit:"secret"` Public string `yaml:"public"` } type account struct { Token string `yaml:"token"` } type tenant struct { Groups map[string][]credential `yaml:"groups"` Account account `yaml:"account" configkit:"secret"` Settings map[string]string `yaml:"settings"` Labels map[string]string `yaml:"labels"` } type configuration struct { Tenant tenant `yaml:"tenant"` } schema, issue := buildSchema(reflect.TypeFor[configuration](), testSecretBinding()) if issue != nil { t.Fatal(issue) } destination := Keys("tenant") sequencePath := Keys("groups").Key("blue").Index(2).Key("credential") accountPath := Keys("account", "token") predicatePath := Keys("settings", "private") nullPath := Keys("settings", "nullable") absentPath := Keys("settings", "missing") publicPath := Keys("labels", "public") evidence := []*sourceVersionEvidence{ { path: sequencePath.clone(), resolvedPath: sequencePath.clone(), destination: destination.clone(), version: Version{Present: true, Text: canary}, ancestors: []sourceVersionAncestor{{}, {path: Keys("groups")}, {path: Keys("groups").Key("blue")}, {path: Keys("groups").Key("blue").Index(2)}, {path: sequencePath.clone()}}, }, { path: accountPath.clone(), resolvedPath: accountPath.clone(), destination: destination.clone(), version: Version{Present: true, Text: canary}, ancestors: []sourceVersionAncestor{{}, {path: Keys("account")}, {path: accountPath.clone()}}, }, {path: predicatePath.clone(), resolvedPath: predicatePath.clone(), destination: destination.clone(), version: Version{Present: true, Text: canary}}, {path: nullPath.clone(), resolvedPath: nullPath.clone(), destination: destination.clone(), version: Version{Present: true, Null: true}}, {path: absentPath.clone(), resolvedPath: absentPath.clone(), destination: destination.clone()}, {path: publicPath.clone(), resolvedPath: publicPath.clone(), destination: destination.clone(), version: Version{Present: true, Text: canary}}, } final := parseCompositionDocument(t, "final", "tenant:\n groups:\n blue:\n - public: shifted-neighbor\n labels:\n public: visible\n") var sawOriginalSequencePath, sawAncestorPredicate bool classified := classifySecretPathsWithEvidence(schema, func(path Path) bool { if path.String() == appendDestination(destination, predicatePath).String() { return true } if path.String() == appendDestination(destination, nullPath).String() { return true } if path.String() == appendDestination(destination, absentPath).String() { return true } if path.String() == appendDestination(destination, Keys("account")).String() { sawAncestorPredicate = true return true } if path.String() == appendDestination(destination, sequencePath).String() { sawOriginalSequencePath = len(path.segments) == 5 && path.segments[3].kind == pathSegmentIndex && path.segments[3].index == 2 } return false }, Metadata{}, final, []historyApplication{{path: destination, value: final}}, evidence) for _, path := range []Path{ appendDestination(destination, sequencePath), appendDestination(destination, Keys("account")), appendDestination(destination, predicatePath), appendDestination(destination, nullPath), appendDestination(destination, absentPath), } { if !classified[path.String()] { t.Errorf("evidence path %s was not classified: %#v", path, classified) } } shiftedNeighbor := appendDestination(destination, Keys("groups").Key("blue").Index(0).Key("public")) if classified[shiftedNeighbor.String()] { t.Fatalf("shifted neighboring payload was classified from declaration evidence: %#v", classified) } if classified[appendDestination(destination, publicPath).String()] || !sawOriginalSequencePath || !sawAncestorPredicate { t.Fatalf("unclassified or semantic evidence candidates = %#v; original path seen %v, ancestor predicate seen %v", classified, sawOriginalSequencePath, sawAncestorPredicate) } }