mirror of
http://100.103.83.12:3003/fegger/odoo-at-payroll.git
synced 2026-09-17 16:56:42 +00:00
76 lines
2.9 KiB
Python
76 lines
2.9 KiB
Python
"""Tests für die KV-Varianten-Map (Odoo library_variant_id ↔ KB kv-kvt-IDs)."""
|
|
import json
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
|
|
|
|
def load_map() -> dict:
|
|
return json.loads(
|
|
(ROOT / "tools" / "catalogs" / "kv_variant_map.json").read_text(encoding="utf-8")
|
|
)
|
|
|
|
|
|
def load_kb_catalog() -> dict:
|
|
return json.loads(
|
|
(ROOT / "tools" / "catalogs" / "kv_catalog.json").read_text(encoding="utf-8")
|
|
)
|
|
|
|
|
|
def test_map_structure_and_kb_id_integrity():
|
|
kb = load_kb_catalog()
|
|
kb_ids = {e["id"] for e in kb["entries"].values()}
|
|
variant_map = load_map()
|
|
|
|
variants = variant_map["variants"]
|
|
assert variants, "Mapping muss Varianten enthalten"
|
|
referenced = set()
|
|
for vid, variant in variants.items():
|
|
assert variant["variant_id"] == vid
|
|
assert variant["docs"], f"leere Variante: {vid}"
|
|
assert variant["confidence"] in ("matched", "low")
|
|
for doc in variant["docs"]:
|
|
assert {"kv_kvt_id", "slug", "doctype"} <= set(doc)
|
|
referenced.add(doc["kv_kvt_id"])
|
|
assert referenced <= kb_ids, "Mapping darf nur existierende KB-IDs führen"
|
|
|
|
# Unmatched-Einträge sind ebenfalls echte KB-IDs und decken den Rest ab
|
|
unmatched = variant_map["unmatched_kb_entries"]
|
|
assert set(unmatched) <= kb_ids
|
|
stats = variant_map["stats"]
|
|
assert stats["n_kb_entries_covered"] + stats["n_kb_entries_unmatched"] == (
|
|
stats["n_kb_entries_total"]
|
|
)
|
|
assert stats["n_variants"] == len(variants)
|
|
|
|
|
|
def test_odoo_seed_variants_are_covered():
|
|
"""Odoo-Seed-KVs (kv_seed.xml): SI-2203 Handwerk und Gewerbe,
|
|
SI-2748 Metallgewerbe müssen KV- und Tabellendokumente führen."""
|
|
variants = load_map()["variants"]
|
|
seeds = {vid: variants.get(vid) for vid in ("SI-2203_de", "SI-2748_de")}
|
|
assert seeds["SI-2203_de"] and seeds["SI-2203_de"]["confidence"] == "matched"
|
|
assert seeds["SI-2748_de"] and seeds["SI-2748_de"]["confidence"] == "matched"
|
|
|
|
slugs_2203 = {d["slug"] for d in seeds["SI-2203_de"]["docs"]}
|
|
slugs_2748 = {d["slug"] for d in seeds["SI-2748_de"]["docs"]}
|
|
assert "kollektivvertrag-gewerbe-handwerk-und-dienstleistung-2026" in slugs_2203
|
|
assert "gehaltsordnung-gewerbe-handwerk-dienstleistung-2026" in slugs_2203
|
|
assert "kollektivvertrag-abschluss-angestellte-metallgewerbe-2026" in slugs_2748
|
|
assert "lohnordnung-metallgewerbe-arbeiter-2026" in slugs_2748
|
|
|
|
|
|
def test_doc_pairs_keep_slug_and_id_correspondence():
|
|
kb = load_kb_catalog()
|
|
by_id = {e["id"]: e for e in kb["entries"].values()}
|
|
variant_map = load_map()
|
|
checked = 0
|
|
for variant in variant_map["variants"].values():
|
|
for doc in variant["docs"]:
|
|
entry = by_id[doc["kv_kvt_id"]]
|
|
url_slug = entry["url"].rstrip("/").rsplit("/", 1)[-1]
|
|
assert url_slug == doc["slug"], (
|
|
f"{doc['kv_kvt_id']}: {url_slug} != {doc['slug']}"
|
|
)
|
|
checked += 1
|
|
assert checked >= 400 |