Project version protections through item placement

This commit is contained in:
2026-10-16 19:11:08 +00:00
parent 190431740a
commit c19825620c
10 changed files with 276 additions and 50 deletions

View File

@@ -193,6 +193,43 @@ func TestLayeredMountedVersionProtectionCoversInheritanceAndUpperTiers(t *testin
})
}
func TestLayeredItemVersionProtectionTracksAssignedPeerIndexes(t *testing.T) {
t.Parallel()
definition := Definition[map[string]any]{
Version: &VersionRule{Path: Keys("schema", "version"), Check: func(Version, *Validation) error { return nil }},
sequenceRegistrations: []sequenceRegistration{{path: Keys("catalog", "entries"), identityField: "id"}},
}
item := func(label string, value map[string]any) Input {
return Input{Source: Mapping(label, value), Destination: Keys("catalog", "entries"), placementMode: placementModeSequenceItem}
}
options := func(inputs ...Input) LayeredOptions[map[string]any] {
return LayeredOptions[map[string]any]{Definition: definition, SourceVersionMode: sourceVersionModeIfPresent, Underlays: []Underlay{{Inputs: inputs}}}
}
main := item("main", map[string]any{"id": "main", "schema": map[string]any{"version": "v1"}})
t.Run("same assigned main path is protected", func(t *testing.T) {
_, err := LoadLayered(main, testSecretBinding(), options(item("underlay", map[string]any{"id": "underlay", "schema": nil})))
if got := groupedErrorCode(t, err); got != CodeUnderlayVersion {
t.Fatalf("protected item claim code = %s, want %s", got, CodeUnderlayVersion)
}
})
t.Run("appended peer does not claim main path", func(t *testing.T) {
loaded, err := LoadLayered(main, testSecretBinding(), options(
item("first", map[string]any{"id": "first", "schema": map[string]any{"other": "value"}}),
item("peer", map[string]any{"id": "peer", "schema": nil}),
))
if err != nil {
t.Fatalf("unrelated appended peer rejected: %v", err)
}
entries := layeredMapValue(t, testLoaded(loaded).Config, "catalog", "entries").([]any)
if len(entries) != 1 || entries[0].(map[string]any)["id"] != "main" {
t.Fatalf("main item projection = %#v", entries)
}
})
}
type destinationDecodeProbe string
var destinationDecodeProbeValues []string