Correct diff masking for historical descendants

This commit is contained in:
2026-10-09 13:22:40 +00:00
parent a4b5a6840a
commit 92025d65cb
5 changed files with 133 additions and 13 deletions

View File

@@ -21,6 +21,101 @@ type facadeDiffSecretConfig struct {
Secret configkit.Secret `yaml:"secret"`
}
func TestFacadeDiffKeepsPublicSequenceChangesWithHistoricalDescendants(t *testing.T) {
type configuration struct {
Items []any `yaml:"items"`
}
load := func(public string) *configkit.Result[configuration] {
t.Helper()
result, err := configkit.Load(configkit.Bytes("historical-sequence.yml", []byte("items: [{secret: disposable-canary}, "+public+"]\n")),
configkit.Options[configuration]{Definition: configkit.Definition[configuration]{
Secret: func(path configkit.Path) bool { return path.String() == "/items/0/secret" },
Resolve: func(current *configuration, resolution *configkit.Resolution) error {
current.Items[0] = "public scalar"
resolution.Record(configkit.Keys("items"), configkit.ChangeNormalization, "normalize first item")
return nil
},
}})
if err != nil {
t.Fatal(err)
}
return result
}
left, right := load("1"), load("2")
history, ok := left.Explain(configkit.Keys("items").Index(0).Key("secret"))
if !ok || history.Effective.Present || len(history.History) == 0 {
t.Fatalf("removed historical secret = %#v, known=%v", history, ok)
}
maskedHistory := false
for _, change := range history.History {
maskedHistory = maskedHistory || change.Before.Redacted || change.After.Redacted
}
if !maskedHistory {
t.Fatal("historical sensitivity was not retained")
}
differences, err := configkit.Diff(left, right)
if err != nil || len(differences) != 1 || differences[0].Path.String() != "/items" {
t.Fatalf("sequence difference = %#v, %v", differences, err)
}
difference := differences[0]
if !difference.Left.Present || !difference.Right.Present || difference.Left.Redacted || difference.Right.Redacted || difference.HiddenChanged {
t.Fatalf("public sequence change was concealed: %#v", difference)
}
if difference.Left.YAML != "- public scalar\n- 1\n" || difference.Right.YAML != "- public scalar\n- 2\n" {
t.Fatalf("public sequence snapshots = %#v", difference)
}
}
func TestFacadeDiffKeepsPublicScalarAcrossHistoricalAbsence(t *testing.T) {
type configuration struct {
Dynamic map[string]any `yaml:"dynamic"`
}
options := configkit.Options[configuration]{Definition: configkit.Definition[configuration]{
Secret: func(path configkit.Path) bool { return path.String() == "/dynamic/entry/token" },
Resolve: func(current *configuration, resolution *configkit.Resolution) error {
delete(current.Dynamic, "entry")
resolution.Record(configkit.Keys("dynamic", "entry"), configkit.ChangeNormalization, "remove entry")
return nil
},
}}
absent, err := configkit.Load(configkit.Bytes("removed-entry.yml", []byte("dynamic: {entry: {token: disposable-canary}}\n")), options)
if err != nil {
t.Fatal(err)
}
options.Definition.Resolve = nil
present, err := configkit.Load(configkit.Bytes("public-entry.yml", []byte("dynamic: {entry: public}\n")), options)
if err != nil {
t.Fatal(err)
}
for _, test := range []struct {
name string
left, right *configkit.Result[configuration]
leftPresent bool
}{
{name: "addition", left: absent, right: present},
{name: "removal", left: present, right: absent, leftPresent: true},
} {
t.Run(test.name, func(t *testing.T) {
differences, err := configkit.Diff(test.left, test.right)
if err != nil || len(differences) != 1 || differences[0].Path.String() != "/dynamic/entry" {
t.Fatalf("entry difference = %#v, %v", differences, err)
}
difference := differences[0]
if difference.Left.Present != test.leftPresent || difference.Right.Present == test.leftPresent ||
difference.Left.Redacted || difference.Right.Redacted || difference.HiddenChanged {
t.Fatalf("public presence change was concealed: %#v", difference)
}
wantLeft, wantRight := "", "public\n"
if test.leftPresent {
wantLeft, wantRight = wantRight, wantLeft
}
if difference.Left.YAML != wantLeft || difference.Right.YAML != wantRight {
t.Fatalf("entry snapshots = %#v", difference)
}
})
}
}
func TestFacadeDiffReturnsDetachedCanonicalRecords(t *testing.T) {
left, err := configkit.Load[facadeDiffConfig](configkit.Bytes("left.yml", []byte("value: before\ncount: 0\nitems: [one, two]\ndynamic: {}\n")))
if err != nil {