package configkit_test import ( "bytes" "strings" "testing" configkit "go.maximumdirect.net/configkit" ) func TestFinalDynamicTagRedactsEqualValuedResolution(t *testing.T) { t.Parallel() type classified struct { Token string `yaml:"token" configkit:"secret"` } type configuration struct { Value any `yaml:"value"` } const canary = "DYNAMIC-TAG-CANARY" result, err := configkit.Load(configkit.Bytes("input", []byte("value: {token: "+canary+"}\n")), configkit.Options[configuration]{ Definition: configkit.Definition[configuration]{ Resolve: func(c *configuration, _ *configkit.Resolution) error { // No canonical value changes, so no normalization record is needed. c.Value = classified{Token: canary} return nil }, }, }) if err != nil { t.Fatal(err) } var effective bytes.Buffer if err := result.WriteEffective(&effective); err != nil { t.Fatal(err) } if strings.Contains(effective.String(), canary) || !strings.Contains(effective.String(), "[REDACTED]") { t.Fatal("effective rendering did not preserve the final dynamic tag") } explanation, found := result.Explain(configkit.Keys("value", "token")) if !found || !explanation.Effective.Redacted || strings.Contains(explanation.Effective.YAML, canary) { t.Fatal("effective explanation did not preserve the final dynamic tag") } if len(explanation.History) == 0 { t.Fatal("source history is absent") } for _, change := range explanation.History { for _, value := range []configkit.ValueSnapshot{change.Before, change.After} { if value.Present && (!value.Redacted || strings.Contains(value.YAML, canary)) { t.Fatal("historical explanation did not preserve the final dynamic tag") } } } }