test(#134): wahlprogramm_fetch Coverage 42.8% → 54.4%
8 zusaetzliche Tests: - TestLockFileRobustness: kaputtes JSON, fehlende Datei, _save_lock-Roundtrip - TestLoadLinks: missing yaml + empty yaml (gestubbed) - TestGetMissingProgrammes: leere/gefuellte Eintraege, Bundesland-Filter yaml ist im Unit-Setup gestubbed; Tests patchen _load_links direkt statt echte YAML-Parsing zu erzwingen — die echte Datei-Validierung gehoert in die integration-Suite gegen die produktive links.yaml.
This commit is contained in:
parent
8f3a811a83
commit
722b073bbd
@ -300,6 +300,88 @@ class TestShaLock:
|
||||
assert lock["spd-mv.pdf"] == _sha(content)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Test 5: Lock-File und YAML-Robustheit (#134 Coverage-Backfill)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestLockFileRobustness:
|
||||
def test_corrupt_lock_file_returns_empty_dict(self, tmp_path):
|
||||
"""Kaputtes JSON darf den Caller nicht crashen — leeren Lock liefern."""
|
||||
from app.wahlprogramm_fetch import _load_lock
|
||||
bad = tmp_path / "broken-lock.json"
|
||||
bad.write_text("{ this is not json ;)")
|
||||
with patch("app.wahlprogramm_fetch._LOCK_FILE", bad):
|
||||
result = _load_lock()
|
||||
assert result == {}
|
||||
|
||||
def test_missing_lock_file_returns_empty_dict(self, tmp_path):
|
||||
from app.wahlprogramm_fetch import _load_lock
|
||||
missing = tmp_path / "no-such-file.json"
|
||||
with patch("app.wahlprogramm_fetch._LOCK_FILE", missing):
|
||||
assert _load_lock() == {}
|
||||
|
||||
def test_save_lock_writes_valid_json(self, tmp_path):
|
||||
from app.wahlprogramm_fetch import _save_lock
|
||||
target = tmp_path / "lock.json"
|
||||
with patch("app.wahlprogramm_fetch._LOCK_FILE", target):
|
||||
_save_lock({"x.pdf": "abc123", "y.pdf": "def456"})
|
||||
import json
|
||||
loaded = json.loads(target.read_text())
|
||||
assert loaded == {"x.pdf": "abc123", "y.pdf": "def456"}
|
||||
|
||||
|
||||
class TestLoadLinks:
|
||||
def test_missing_yaml_returns_empty(self, tmp_path):
|
||||
from app.wahlprogramm_fetch import _load_links
|
||||
with patch("app.wahlprogramm_fetch._LINKS_FILE", tmp_path / "missing.yaml"):
|
||||
assert _load_links() == {}
|
||||
|
||||
def test_empty_yaml_returns_empty(self, tmp_path):
|
||||
from app.wahlprogramm_fetch import _load_links
|
||||
target = tmp_path / "empty.yaml"
|
||||
target.write_text("")
|
||||
with patch("app.wahlprogramm_fetch._LINKS_FILE", target):
|
||||
assert _load_links() == {}
|
||||
|
||||
# Hinweis: yaml ist im Unit-Setup gestubbed (siehe Top-of-File), deshalb
|
||||
# testen wir _load_links nur mit existing-vs-missing-File. Die echte
|
||||
# YAML-Parsing-Logik wird in der integration-Suite gegen die echte
|
||||
# links.yaml validiert.
|
||||
|
||||
|
||||
class TestGetMissingProgrammes:
|
||||
"""Tests fuer get_missing_programmes — listet BL/Partei-Kombinationen mit
|
||||
Kandidaten-URL aber fehlender lokaler Datei. yaml ist gestubbed; Tests
|
||||
patchen daher _load_links direkt."""
|
||||
|
||||
def test_no_yaml_returns_empty(self):
|
||||
from app.wahlprogramm_fetch import get_missing_programmes
|
||||
with patch("app.wahlprogramm_fetch._load_links", return_value={}):
|
||||
assert get_missing_programmes() == []
|
||||
|
||||
def test_lists_entries_when_file_missing(self, tmp_path):
|
||||
"""Eintrag in YAML, registriertes WAHLPROGRAMME-File fehlt → listed."""
|
||||
from app.wahlprogramm_fetch import get_missing_programmes
|
||||
fake_links = {"BX": {"XYZ": [{"url": "https://example.com/x.pdf"}]}}
|
||||
with patch("app.wahlprogramm_fetch._load_links", return_value=fake_links):
|
||||
with patch("app.wahlprogramm_fetch._REFERENZEN_DIR", tmp_path / "ref"):
|
||||
missing = get_missing_programmes()
|
||||
codes = [m["bl"] for m in missing]
|
||||
assert "BX" in codes
|
||||
|
||||
def test_bundesland_filter(self, tmp_path):
|
||||
from app.wahlprogramm_fetch import get_missing_programmes
|
||||
fake_links = {
|
||||
"BX": {"XYZ": [{"url": "https://example.com/x.pdf"}]},
|
||||
"BY": {"ABC": [{"url": "https://example.com/y.pdf"}]},
|
||||
}
|
||||
with patch("app.wahlprogramm_fetch._load_links", return_value=fake_links):
|
||||
with patch("app.wahlprogramm_fetch._REFERENZEN_DIR", tmp_path / "ref"):
|
||||
missing = get_missing_programmes(bundesland="BX")
|
||||
codes = {m["bl"] for m in missing}
|
||||
assert codes == {"BX"}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Test 4: og_card — cache_key Determinismus und Cache-Miss/Hit
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Loading…
Reference in New Issue
Block a user