"""Tests für tools/ingest_sources.py: KV-HTML-Konverter, RIS-Intake, LAW_MAP.""" import sys from pathlib import Path import pytest ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) from tools import ingest_sources as ing # noqa: E402 from tools.kb_common import LAW_MAP # noqa: E402 WKO_HTML = """
Räumlicher Geltungsbereich:
Österreichweit
Geltungsdauer:
ab 1.4.2026

Lohnabkommen für Testgewerbe

Inhalt

§ 1 Geltungsbereich

§ 1 Geltungsbereich

Für alle Betriebe
des Testgewerbes.

§ 2 Mindestlöhne

GruppeBetrag
A1€ 2.020,00
B1 | C1€ 2.100,00

Text nach Tabelle.

""" @pytest.fixture() def converted(): soup = ing.prep_soup(WKO_HTML) main = soup.find("main", class_="col-lg-8") meta = ing.parse_kv_meta(main) return meta, ing.blocks_to_md(main) def test_kv_meta_and_geltungsdauer(converted): meta, _ = converted assert meta == [ ("Räumlicher Geltungsbereich", "Österreichweit"), ("Geltungsdauer", "ab 1.4.2026"), ] title = "Lohnordnung Testgewerbe, gültig ab 1.4.2026" stand, tags = ing.derive_stand(title, meta, "test.html") assert stand == "2026-04" and tags == [] def test_kv_stand_fallbacks(): stand, tags = ing.derive_stand("Lohnordnung X 2025", [], "x.html") assert (stand, tags) == ("2025-01", ["stand-jahr"]) stand, tags = ing.derive_stand("Generalkollektivvertrag", [], "undatiert.html") assert (stand, tags) == (ing.CRAWL_STAND, ["stand-geschaetzt"]) stand, _ = ing.derive_stand("KV X", [], "lohnordnung-x-2023.html") assert stand == "2023-01" def test_kv_blocks_heading_toc_table(converted): _, lines = converted md = "\n".join(lines) assert "## Lohnabkommen für Testgewerbe" in md assert "## § 1 Geltungsbereich" in md assert "Für alle Betriebe\ndes Testgewerbes." in md # TOC übersprungen assert "§ 1 Geltungsbereich" not in md assert "Content start" not in md # Tabelle als Markdown, Pipe escaped assert "| Gruppe | Betrag |" in md assert "| --- | --- |" in md assert "| A1 | € 2.020,00 |" in md assert "| B1 \\| C1 | € 2.100,00 |" in md assert "Text nach Tabelle." in md def test_kv_entry_writes_frontmatter(tmp_path, monkeypatch): catalog = {"source": "kv", "updated": None, "next_seq": 1, "entries": {}} stats = {"kv_written": 0, "no_og": [], "no_main": []} p = tmp_path / "lohnordnung-testgewerbe-2026.html" p.write_text(WKO_HTML, encoding="utf-8") slug, md = ing.kv_entry(p, catalog, stats) assert slug.startswith("kv_") assert "id: kv-kvt-001" in md assert "topic: kollektivvertraege" in md assert "stand: 2026-04" in md assert "chapter: \"Lohnordnung\"" in md assert "jahr-2026" in md assert catalog["next_seq"] == 2 def test_doctype_classification(): assert ing.classify_doctype("Zusatz-KV Wachorgane 2026") == "Zusatz-KV" assert ing.classify_doctype("Rahmenkollektivvertrag Textil 2026") == "Rahmen-KV" assert ing.classify_doctype("Gehaltsordnung Information und Consulting") == "Gehaltsordnung" assert ing.classify_doctype("Lohnordnung Friseur/in") == "Lohnordnung" assert ing.classify_doctype("Empfehlung Lohntafeln Handel") == "Empfehlung" assert ing.classify_doctype("Fragen und Antworten KV IT 2026") == "Fragen & Antworten" assert ing.classify_doctype("Kollektivvertrag Handel Angestellte 2026") == "Kollektivvertrag" assert ing.classify_doctype("Dienst- und Besoldungsordnung Privatbahnen") == "Dienst- und Besoldungsordnung" def test_law_map_covers_all_ris_files(): ris_files = {p.stem for p in ing.RIS_DIR.glob("*.md")} assert ris_files == set(LAW_MAP.keys()), "LAW_MAP und .ris/*.md müssen 1:1 passen" def test_ris_entry(tmp_path, monkeypatch): catalog = {"source": "ris", "updated": None, "next_seq": 1, "entries": {}} stats = {"ris_written": 0, "ris_unmapped": []} p = tmp_path / "TestG.md" p.write_text( "# Testgesetz (TestG)\n\n" "Quelle: RIS (https://www.ris.bka.gv.at/), Gesetzesnummer 12345678, " "Stand: 2026-09-13. Es sind nur die zitierten Paragraphen enthalten.\n\n" "## § 1. Geltungsbereich\n\n(1) Dieses Gesetz gilt für alle.\n\n" "## § 2. Anspruch\n\nEs besteht ein Anspruch.\n", encoding="utf-8", ) # LAW_MAP hat kein TestG — Mapping über Monkeypatch injizieren monkeypatch.setitem(ing.LAW_MAP, "TestG", ("normen-sonstige", "Testrecht", 6)) slug, md = ing.ris_entry(p, catalog, stats) assert slug == "ris_testg" assert "id: ris-nso-06" in md assert "stand: 2026-09" in md assert 'legal_bases: ["TestG"]' in md assert "## § 1. Geltungsbereich" in md assert "(1) Dieses Gesetz gilt für alle." in md assert "ris-nso-06" in md # ID-Zeile im Body