"""Cross-language invariants for the Sense-to-Bell audit relay contract.""" from __future__ import annotations import json import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[1] CONTRACT = ROOT / "docs" / "contracts" / "sense-audit-relay-v1.openapi.json" class SenseAuditRelayContractTests(unittest.TestCase): @classmethod def setUpClass(cls) -> None: cls.document = json.loads(CONTRACT.read_text(encoding="utf-8")) def test_transport_and_response_are_frozen(self) -> None: operation = self.document["paths"]["/internal/v1/audit-events:batch"]["post"] self.assertEqual({"200", "400", "401", "409", "413", "503"}, set(operation["responses"])) headers = {item["name"] for item in operation["parameters"]} self.assertEqual( {"X-YoVision-Key-Id", "X-YoVision-Timestamp", "X-YoVision-Nonce", "X-YoVision-Signature"}, headers, ) def test_numeric_safety_bounds_match_task(self) -> None: events = self.document["components"]["schemas"]["BatchRequest"]["properties"]["events"] self.assertEqual((1, 100), (events["minItems"], events["maxItems"])) signature = self.document["x-yovision-signature"] delivery = self.document["x-yovision-delivery"] self.assertEqual(300, signature["clock_skew_seconds"]) self.assertEqual(600, signature["receipt_ttl_seconds"]) self.assertEqual((30, 1, 300), (delivery["lease_seconds"], delivery["initial_retry_seconds"], delivery["maximum_retry_seconds"])) def test_contract_and_implementations_share_literals(self) -> None: sense = (ROOT / "Sense" / "internal" / "auditrelay" / "client.go").read_text(encoding="utf-8") bell = (ROOT / "Bell" / "internal" / "audit" / "audit.go").read_text(encoding="utf-8") for marker in ( "/internal/v1/audit-events:batch", "X-YoVision-Key-Id", "X-YoVision-Timestamp", "X-YoVision-Nonce", "X-YoVision-Signature", ): self.assertIn(marker, sense) self.assertIn(marker, bell) self.assertIn("10 * time.Second", sense) self.assertIn("300*time.Second", (ROOT / "Sense" / "internal" / "auditrelay" / "worker.go").read_text(encoding="utf-8")) if __name__ == "__main__": unittest.main()