mail-address-semantics/tests/test_statute.py
tegwick eb10f54fd2 MAS-WP-0005-T08: v0.2 stand-ins and resource_id_case in policy; lint; gateway reports canonical form
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 252470@bnt-lap001
Assistant-Session: ad628c8f-4be2-4979-94c9-76c7ed6f8241
2026-10-18 22:24:28 +02:00

123 lines
4.8 KiB
Python

import pytest
from mas_conformance import statute_cases, statute_document
from mas_core.statute import (
ERROR,
WARNING,
InheritanceCycle,
StatuteInvalid,
build_statute,
lint,
resolve_inheritance,
)
CASES = statute_cases()
@pytest.mark.parametrize("case", CASES, ids=[c["id"] for c in CASES])
def test_statute_case(case):
doc = statute_document(case["file"])
findings = lint(doc, case["host"])
errors = [f for f in findings if f.severity == ERROR]
if case["expect"] == "valid":
assert not errors, errors
build_statute(doc, case["host"])
assert set(case.get("warnings", [])) <= {f.code for f in findings if f.severity == WARNING}
else:
assert errors and {f.layer for f in errors} == {case["expect"]}
assert set(case.get("codes", [])) <= {f.code for f in errors}
with pytest.raises(StatuteInvalid) as exc:
build_statute(doc, case["host"])
assert exc.value.layer == case["expect"]
def test_schema_valid_but_semantically_rejected():
doc = statute_document("semantic-p2-disabled-modes.json")
assert not [f for f in lint(doc) if f.layer == "schema"]
with pytest.raises(StatuteInvalid):
build_statute(doc)
def _doc(ns, inherits=None, **over):
d = {"mas_version": "0.1", "namespace": ns, "profiles": {"p1": True, "p2": True},
"equivalence": {"local_part_case": "exact", "dot_folding": False}}
if inherits:
d["inherits"] = inherits
d.update(over)
return d
def url(ns):
return f"https://{ns}/.well-known/mas"
def test_inheritance_defaults_only():
parent = build_statute(_doc("parent.example",
resource_types={"ticket": {"enabled": True}, "invoice": {"enabled": True}},
interaction_modes={"callback": {"enabled": True}},
addresses={"support": {"kind": "function"}}))
child = build_statute(_doc("child.example", url("parent.example"),
resource_types={"invoice": {"enabled": False}}))
merged = resolve_inheritance(child, url("child.example"), lambda u: parent)
assert merged.namespace == "child.example"
assert merged.resource_type_enabled("ticket") # inherited default
assert not merged.resource_type_enabled("invoice") # child overrides
assert merged.interaction_mode_enabled("callback")
assert "support" not in merged.addresses # registry never inherits
assert merged.inherited_from == (url("parent.example"),)
@pytest.mark.parametrize("length", [2, 3, 4])
def test_inheritance_cycles(length):
names = [f"n{i}.example" for i in range(length)]
docs = {url(n): build_statute(_doc(n, url(names[(i + 1) % length])))
for i, n in enumerate(names)}
with pytest.raises(InheritanceCycle) as exc:
resolve_inheritance(docs[url(names[0])], url(names[0]), docs.__getitem__)
assert exc.value.chain[0] == exc.value.chain[-1]
def _with_address(entry):
doc = statute_document("valid-great-service.json")
doc["addresses"]["intake"] = entry
return {f.code: f.severity for f in lint(doc, "great-service.example")}
def test_intake_for_lint():
assert "intake-unknown-type" not in _with_address({"kind": "function", "intake_for": "ticket"})
assert _with_address({"kind": "function", "intake_for": "invoice"})["intake-unknown-type"] == ERROR
assert _with_address({"kind": "group", "intake_for": "ticket"})["intake-not-function"] == ERROR
def _v02(**extra):
doc = statute_document("valid-great-service.json")
doc["mas_version"] = "0.2"
doc.update(extra)
return doc
def test_v02_statute_builds_with_new_fields():
doc = _v02(alternate_syntax={"resource": True, "interaction": True})
doc["equivalence"]["resource_id_case"] = "insensitive"
st = build_statute(doc, "great-service.example")
assert (st.mas_version, st.alt_resource, st.alt_interaction, st.resource_id_case) == \
("0.2", True, True, "insensitive")
plain = build_statute(_v02(), "great-service.example")
assert (plain.alt_resource, plain.alt_interaction, plain.resource_id_case) == (False, False, "exact")
def test_v01_statute_rejects_v02_fields():
doc = statute_document("valid-great-service.json")
doc["alternate_syntax"] = {"resource": True}
assert any(f.severity == ERROR and f.layer == "schema" for f in lint(doc, "great-service.example"))
def test_stand_in_lint():
doc = _v02(alternate_syntax={"resource": True, "interaction": True})
doc["addresses"]["ticket--legacy"] = {"kind": "function"}
doc["addresses"]["sales---callback"] = {"kind": "function"}
codes = [f.code for f in lint(doc, "great-service.example") if f.severity == ERROR]
assert codes.count("stand-in-collision") == 2
off = _v02()
off["addresses"]["ticket--legacy"] = {"kind": "function"}
assert "stand-in-collision" not in {f.code for f in lint(off, "great-service.example")}