"""Tests for bundeslaender.py — sanity over the parliament registry. Stand: 16 Bundesländer + Sondereintrag ``BUND`` für den Deutschen Bundestag (siehe #56). Der ``Bundesland``-Dataclass-Name ist historisch und wird inzwischen als generischer Parlament-Slot verwendet — eine Umbenennung ist als separates Refactoring-Item geplant. Includes the #48 classification regression: TH must be ParlDok, HB must be StarWeb, SN must be Eigensystem (not ParlDok). """ from app.bundeslaender import BUNDESLAENDER, get, aktive_bundeslaender, alle_bundeslaender class TestRegistryStructure: def test_sixteen_bundeslaender_plus_bund(self): # 16 echte Bundesländer + BUND-Sondereintrag (#56) assert len(BUNDESLAENDER) == 17 assert "BUND" in BUNDESLAENDER def test_codes_are_uppercase(self): for code in BUNDESLAENDER: assert code.isupper(), f"{code} is not uppercase" def test_each_entry_has_naechste_wahl_or_none(self): for code, bl in BUNDESLAENDER.items(): assert bl.naechste_wahl is None or len(bl.naechste_wahl) == 10 def test_wahlperiode_is_positive_integer(self): for bl in BUNDESLAENDER.values(): assert isinstance(bl.wahlperiode, int) and bl.wahlperiode > 0 class TestActiveBundeslaender: def test_active_bundeslaender_include_phase_1_set(self): """At least the original four (NRW, LSA, MV, BE) plus any Phase-1 additions (BW after #29) must be active. The test avoids hardcoding the exact count so adding a new active Bundesland in a follow-up doesn't break this case.""" active_codes = {bl.code for bl in aktive_bundeslaender()} original = {"NRW", "LSA", "MV", "BE"} assert original <= active_codes def test_alle_bundeslaender_returns_all(self): # 16 BL + BUND assert len(alle_bundeslaender()) == 17 def test_alle_bundeslaender_active_first(self): out = alle_bundeslaender() active_codes = {bl.code for bl in aktive_bundeslaender()} # The first len(active) entries must all be active for bl in out[: len(active_codes)]: assert bl.code in active_codes class TestGetHelper: def test_returns_bundesland_for_known_code(self): bl = get("NRW") assert bl is not None assert bl.name == "Nordrhein-Westfalen" def test_returns_none_for_unknown_code(self): assert get("XX") is None class TestClassificationFix48: """Regression: #48 corrected three doku_system entries that the follow-up adapter issues depend on.""" def test_th_is_parldok_not_starweb(self): assert BUNDESLAENDER["TH"].doku_system == "ParlDok" def test_hb_is_starweb_not_paris(self): """PARiS is just a StarWeb skin — must be classified as StarWeb.""" assert BUNDESLAENDER["HB"].doku_system == "StarWeb" def test_sn_is_eigensystem_not_parldok(self): """EDAS is ASP.NET-Webforms, NOT ParlDok-compatible with MV.""" assert BUNDESLAENDER["SN"].doku_system == "Eigensystem" class TestWahltermineSane: """All upcoming elections must be in chronological order and in the near future (sanity check that someone has not pasted a 1990 date).""" def test_no_election_before_2026(self): for bl in BUNDESLAENDER.values(): if bl.naechste_wahl: assert bl.naechste_wahl >= "2026-01-01" def test_no_election_after_2035(self): for bl in BUNDESLAENDER.values(): if bl.naechste_wahl: assert bl.naechste_wahl < "2035-01-01"