from copy import deepcopy from jsonschema import Draft202012Validator import yaml from info_tech_canon.service import DEFAULT_INFOSPACE_ROOT SCHEMA_PATH = DEFAULT_INFOSPACE_ROOT / "schemas" / "emission-cadence.schema.yaml" EXAMPLE_PATH = ( DEFAULT_INFOSPACE_ROOT / "standards" / "emission-cadence" / "examples" / "qonto-assistant.yaml" ) def _load_yaml(path): return yaml.safe_load(path.read_text(encoding="utf-8")) def _validator() -> Draft202012Validator: schema = _load_yaml(SCHEMA_PATH) Draft202012Validator.check_schema(schema) return Draft202012Validator(schema) def test_worked_example_validates() -> None: assert list(_validator().iter_errors(_load_yaml(EXAMPLE_PATH))) == [] def test_expected_rate_requires_one_window_representation() -> None: payload = deepcopy(_load_yaml(EXAMPLE_PATH)) rate = payload["sources"][0] rate.pop("window") assert list(_validator().iter_errors(payload)) rate["window"] = "PT24H" rate["window_seconds"] = 86400 assert list(_validator().iter_errors(payload)) def test_heartbeat_form_accepts_either_mechanism_but_not_neither() -> None: payload = deepcopy(_load_yaml(EXAMPLE_PATH)) intermittent = payload["sources"][1] intermittent.pop("heartbeat") assert list(_validator().iter_errors(payload)) == [] intermittent.pop("reconciliation") assert list(_validator().iter_errors(payload)) def test_profile_fields_must_be_namespaced_extensions() -> None: payload = deepcopy(_load_yaml(EXAMPLE_PATH)) payload["sources"][1]["evidence_class"] = "load-bearing" assert list(_validator().iter_errors(payload))