from __future__ import annotations import json import unittest from pathlib import Path from jsonschema import Draft202012Validator ROOT = Path(__file__).resolve().parents[1] def read_json(path: Path) -> dict: try: return json.loads(path.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError) as exc: raise AssertionError(f"invalid JSON fixture: {path}") from exc class ContractTests(unittest.TestCase): def test_openapi_and_mq_contract_inventory(self) -> None: executor = (ROOT / "docs/contracts/executor.openapi.yaml").read_text( encoding="utf-8" ) saas = (ROOT / "docs/contracts/saas.openapi.yaml").read_text(encoding="utf-8") sip_management = ( ROOT / "docs/contracts/sip-management.openapi.yaml" ).read_text(encoding="utf-8") self.assertIn("openapi: 3.1.0", executor) self.assertIn("openapi: 3.1.0", saas) cell_agent = (ROOT / "docs/contracts/cell-agent.openapi.yaml").read_text( encoding="utf-8" ) self.assertIn("openapi: 3.1.0", sip_management) self.assertIn("openapi: 3.1.0", cell_agent) self.assertIn("CellManagementMtls", cell_agent) self.assertIn("/v1/sip/trunks/{trunk_id}/apply:", cell_agent) self.assertIn("SipAdminBearer", sip_management) self.assertIn("SaasTrunkReadBearer", sip_management) self.assertIn("/admin/v1/trunks/{trunk_id}/publish:", sip_management) self.assertIn("/readonly/v1/sip/trunks:", sip_management) self.assertNotIn("call.execute", executor) self.assertIn("/internal/v1/outbound/tasks/{task_id}/controls:", executor) self.assertIn( "/internal/v1/outbound/commands/{source_command_id}/replays:", executor ) self.assertIn("/internal/v1/outbound/recording-uploads:", saas) self.assertIn( "/internal/v1/outbound/recording-uploads/{upload_id}/complete:", saas ) def test_ai_config_contract_and_example(self) -> None: schema = read_json(ROOT / "docs/contracts/ai-config.schema.json") example = read_json(ROOT / "docs/contracts/examples/agent-version.json") self.assertEqual(list(Draft202012Validator(schema).iter_errors(example)), []) openapi = (ROOT / "docs/contracts/ai-config.openapi.yaml").read_text( encoding="utf-8" ) self.assertIn("openapi: 3.1.0", openapi) self.assertIn("ai.config.publish", openapi) self.assertIn("ai.config.read", openapi) self.assertIn("/internal/v1/ai/agent-versions:", openapi) self.assertNotIn("api_key", json.dumps(example, ensure_ascii=False)) def test_command_fixture_and_invalid_version(self) -> None: schema = read_json(ROOT / "docs/contracts/mq.schema.json") fixture = read_json(ROOT / "docs/contracts/examples/call.execute.json") validator = Draft202012Validator(schema) self.assertEqual(list(validator.iter_errors(fixture)), []) invalid = dict(fixture) invalid["schema_version"] = "2.0" self.assertTrue(list(validator.iter_errors(invalid))) def test_raw_unicode_tenant_key_and_user_selected_callee_are_preserved( self, ) -> None: fixture = read_json(ROOT / "docs/contracts/examples/call.execute.json") self.assertEqual(fixture["payload"]["callee"], "18601013734") fixture["tenant_key"] = "租户#原值" self.assertEqual(fixture["tenant_key"], "租户#原值") self.assertEqual( json.loads(json.dumps(fixture, ensure_ascii=False))["tenant_key"], "租户#原值", ) if __name__ == "__main__": unittest.main()