A served value or a contribution's may be the operator's: ${setting:…} fills there too, refused by name when unset

Issue 173's rule needs it: a mail provider serves its domain and an identity provider its issuer,
and neither is the definition's to state. Declared as ${setting:<key>}, filled from the layers after
the overrides; a key so asked for is not stray.
This commit is contained in:
2026-09-30 22:34:43 +02:00
parent 05d977666a
commit 29be985c23
3 changed files with 73 additions and 5 deletions
+21
View File
@@ -213,3 +213,24 @@ func TestContentThatIsNotJSONIsRefusedWhereSomebodyIsLooking(t *testing.T) {
t.Fatal("a module claiming to merge as JSON shipped something else and was accepted")
}
}
func TestAServedValueMayBeTheOperators(t *testing.T) {
// A mail provider serves its domain and an identity provider its issuer; neither is the
// definition's to state (ADR 0155). Filled from the layers, refused by name when unset.
served, err := Settle(map[string]any{"port": 587, "domain": "${setting:domain}"},
[]Layer{{From: "the mesh", Values: map[string]any{"domain": "example.tld"}}})
if err != nil {
t.Fatal(err)
}
if served["domain"] != "example.tld" {
t.Errorf("the operator's value did not fill the served key: %v", served)
}
_, err = Settle(map[string]any{"domain": "${setting:domain}"}, nil)
if err == nil || !strings.Contains(err.Error(), `"domain"`) {
t.Errorf("a served value nothing sets must be refused by name; got %v", err)
}
m := Manifest{Module: "mail", Serves: map[string]map[string]any{"smtp": {"domain": "${setting:domain}"}}}
if unused := UnusedSettings(m, []Layer{{From: "the mesh", Values: map[string]any{"domain": "x"}}}); len(unused) != 0 {
t.Errorf("a setting a served fact asks for is not stray: %v", unused)
}
}