arm-ka-docs/scripts/kfo_contract/test_ex_payload.py
Andrey Epifancev 013f7b673a ЕХ: схема ex-payload-v1, примеры, проверка в validate_contracts (#208)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 23:05:15 +04:00

64 lines
2.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Проверка схемы среза ЕХ ex-payload-v1 (docs #208): примеры проходят, типовые ошибки — нет.
Запуск: .venv/bin/python -I scripts/kfo_contract/test_ex_payload.py
"""
import copy
import json
import sys
from pathlib import Path
from jsonschema import Draft202012Validator
ROOT = Path(__file__).resolve().parents[2]
SCHEMA = ROOT / "contracts" / "ex-payload-v1.schema.json"
EXAMPLES = sorted((ROOT / "contracts" / "examples").glob("ex-payload-*.json"))
REQUIRED_TYPES = {"summary_osv", "vgo_pairs", "chess", "kfo_balance", "kfo_income", "goodwill", "corrections",
"version_card"}
def main():
schema = json.loads(SCHEMA.read_text(encoding="utf-8"))
Draft202012Validator.check_schema(schema)
v = Draft202012Validator(schema)
by_type = {}
for p in EXAMPLES:
doc = json.loads(p.read_text(encoding="utf-8"))
errs = list(v.iter_errors(doc))
assert not errs, f"{p.name}: {errs[0].message[:200]}"
by_type[doc["item_type"]] = doc
missing = REQUIRED_TYPES - set(by_type)
assert not missing, f"нет примеров: {sorted(missing)}"
def rejected(doc, why):
assert list(v.iter_errors(doc)), f"схема пропустила: {why}"
# 1. item_type конверта не совпадает с формой data
bad = copy.deepcopy(by_type["kfo_balance"])
bad["data"] = copy.deepcopy(by_type["goodwill"]["data"])
rejected(bad, "kfo_balance с данными гудвилла")
# 2. kfo_balance без сводки корректировок в реквизитах
bad = copy.deepcopy(by_type["kfo_balance"])
del bad["data"]["requisites"]["corrections_balance"]
rejected(bad, "нет requisites.corrections_balance")
# 4. деньги числом
bad = copy.deepcopy(by_type["kfo_balance"])
bad["data"]["balance"]["lines"][0]["bank_amount"] = 2500.0
rejected(bad, "деньги числом")
# конверт: лишнее поле и неизвестная единица
bad = copy.deepcopy(by_type["version_card"])
bad["extra"] = 1
rejected(bad, "лишнее поле конверта")
bad = copy.deepcopy(by_type["summary_osv"])
bad["units"] = "mln_rub"
rejected(bad, "неизвестная единица")
# единица не соответствует типу
bad = copy.deepcopy(by_type["summary_osv"])
bad["units"] = "thousand_rub"
rejected(bad, "summary_osv в тысячах")
print(f"OK: примеров {len(EXAMPLES)}, отрицательных случаев 6")
return 0
if __name__ == "__main__":
sys.exit(main())