| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- # -*- coding: utf-8 -*-
- """
- Tests fuer den ChannelMapper und die CHANNELS-Definitionen.
- Testet Alias-Aufloesung, XMLTV-Mapping, Sender-Filterung und
- benutzerdefinierte Aliase.
- """
- from __future__ import annotations
- import pytest
- from plugins.tv_program.epg.channels import CHANNELS, ChannelMapper
- # ============================================================================
- # CHANNELS-Dict Struktur
- # ============================================================================
- class TestChannelsDictStruktur:
- """Tests fuer die CHANNELS-Konstantendefinition."""
- def test_channels_enthaelt_ard(self) -> None:
- """ARD muss im CHANNELS-Dict vorhanden sein."""
- assert "ard" in CHANNELS
- def test_channels_enthaelt_zdf(self) -> None:
- """ZDF muss im CHANNELS-Dict vorhanden sein."""
- assert "zdf" in CHANNELS
- def test_channels_enthaelt_rtl(self) -> None:
- """RTL muss im CHANNELS-Dict vorhanden sein."""
- assert "rtl" in CHANNELS
- def test_channels_enthaelt_sat1(self) -> None:
- """SAT.1 muss im CHANNELS-Dict vorhanden sein."""
- assert "sat1" in CHANNELS
- def test_channels_enthaelt_pro7(self) -> None:
- """ProSieben muss im CHANNELS-Dict vorhanden sein."""
- assert "pro7" in CHANNELS
- def test_channels_enthaelt_mindestens_35_sender(self) -> None:
- """Das CHANNELS-Dict muss mindestens 35 Sender enthalten."""
- assert len(CHANNELS) >= 35
- def test_channels_eintraege_haben_pflichtfelder(self) -> None:
- """Jeder Sender muss name, aliases, group und xmltv_ids haben."""
- for channel_id, info in CHANNELS.items():
- assert "name" in info, f"'{channel_id}' fehlt 'name'"
- assert "aliases" in info, f"'{channel_id}' fehlt 'aliases'"
- assert "group" in info, f"'{channel_id}' fehlt 'group'"
- assert "xmltv_ids" in info, f"'{channel_id}' fehlt 'xmltv_ids'"
- def test_channels_aliase_sind_listen(self) -> None:
- """Alle Alias-Felder muessen Listen sein."""
- for channel_id, info in CHANNELS.items():
- assert isinstance(info["aliases"], list), (
- f"'{channel_id}' aliases ist keine Liste"
- )
- def test_channels_xmltv_ids_sind_listen(self) -> None:
- """Alle xmltv_ids-Felder muessen Listen sein."""
- for channel_id, info in CHANNELS.items():
- assert isinstance(info["xmltv_ids"], list), (
- f"'{channel_id}' xmltv_ids ist keine Liste"
- )
- # ============================================================================
- # ChannelMapper - resolve()
- # ============================================================================
- class TestChannelMapperResolve:
- """Tests fuer die Namensaufloesung ueber resolve()."""
- @pytest.fixture
- def mapper(self) -> ChannelMapper:
- """Standard-Mapper ohne Filter oder benutzerdefinierte Aliase."""
- return ChannelMapper()
- def test_resolve_exakt_rtl2(self, mapper: ChannelMapper) -> None:
- """Exakter Match: 'RTL2' wird auf 'rtl2' aufgeloest."""
- assert mapper.resolve("RTL2") == "rtl2"
- def test_resolve_exakt_prosieben(self, mapper: ChannelMapper) -> None:
- """Exakter Match: 'ProSieben' wird auf 'pro7' aufgeloest."""
- assert mapper.resolve("ProSieben") == "pro7"
- def test_resolve_exakt_ard(self, mapper: ChannelMapper) -> None:
- """Exakter Match: 'ARD' wird auf 'ard' aufgeloest."""
- assert mapper.resolve("ARD") == "ard"
- def test_resolve_gross_kleinschreibung_rtl2(self, mapper: ChannelMapper) -> None:
- """Gross-/Kleinschreibung wird ignoriert: 'rtl2' -> 'rtl2'."""
- assert mapper.resolve("rtl2") == "rtl2"
- def test_resolve_gross_kleinschreibung_prosieben(self, mapper: ChannelMapper) -> None:
- """Gross-/Kleinschreibung wird ignoriert: 'PROSIEBEN' -> 'pro7'."""
- assert mapper.resolve("PROSIEBEN") == "pro7"
- def test_resolve_gross_kleinschreibung_zdf(self, mapper: ChannelMapper) -> None:
- """Gross-/Kleinschreibung wird ignoriert: 'zdf' -> 'zdf'."""
- assert mapper.resolve("zdf") == "zdf"
- def test_resolve_alias_pro7(self, mapper: ChannelMapper) -> None:
- """Alias-Match: 'Pro 7' wird auf 'pro7' aufgeloest."""
- assert mapper.resolve("Pro 7") == "pro7"
- def test_resolve_alias_sat_eins(self, mapper: ChannelMapper) -> None:
- """Alias-Match: 'Sat eins' wird auf 'sat1' aufgeloest."""
- assert mapper.resolve("Sat eins") == "sat1"
- def test_resolve_alias_rtl_zwei(self, mapper: ChannelMapper) -> None:
- """Alias-Match: 'RTL Zwei' wird auf 'rtl2' aufgeloest."""
- assert mapper.resolve("RTL Zwei") == "rtl2"
- def test_resolve_alias_rtl_ii(self, mapper: ChannelMapper) -> None:
- """Alias-Match: 'RTL II' wird auf 'rtl2' aufgeloest."""
- assert mapper.resolve("RTL II") == "rtl2"
- def test_resolve_teilstring_pro7_maxx(self, mapper: ChannelMapper) -> None:
- """Teilstring-Match: 'Pro7 Maxx' wird auf 'pro7_maxx' aufgeloest."""
- assert mapper.resolve("Pro7 Maxx") == "pro7_maxx"
- def test_resolve_unbekannter_sender_none(self, mapper: ChannelMapper) -> None:
- """Unbekannter Sendername gibt None zurueck."""
- assert mapper.resolve("Unbekannter Sender XYZ") is None
- def test_resolve_leerer_string_none(self, mapper: ChannelMapper) -> None:
- """Leerer String gibt None zurueck."""
- assert mapper.resolve("") is None
- def test_resolve_whitespace_wird_gestrippt(self, mapper: ChannelMapper) -> None:
- """Fuehrende und abschliessende Leerzeichen werden entfernt."""
- assert mapper.resolve(" RTL ") == "rtl"
- def test_resolve_channel_id_direkt(self, mapper: ChannelMapper) -> None:
- """Die Sender-ID selbst wird als Alias erkannt."""
- assert mapper.resolve("ard") == "ard"
- def test_resolve_display_name(self, mapper: ChannelMapper) -> None:
- """Der Display-Name wird als Alias erkannt."""
- assert mapper.resolve("Das Erste") == "ard"
- # ============================================================================
- # ChannelMapper - resolve_xmltv_id()
- # ============================================================================
- class TestChannelMapperResolveXmltvId:
- """Tests fuer die XMLTV-ID-Aufloesung."""
- @pytest.fixture
- def mapper(self) -> ChannelMapper:
- return ChannelMapper()
- def test_resolve_xmltv_id_das_erste(self, mapper: ChannelMapper) -> None:
- """XMLTV-ID 'DasErste.de' wird auf 'ard' aufgeloest."""
- assert mapper.resolve_xmltv_id("DasErste.de") == "ard"
- def test_resolve_xmltv_id_prosieben(self, mapper: ChannelMapper) -> None:
- """XMLTV-ID 'ProSieben.de' wird auf 'pro7' aufgeloest."""
- assert mapper.resolve_xmltv_id("ProSieben.de") == "pro7"
- def test_resolve_xmltv_id_zdf(self, mapper: ChannelMapper) -> None:
- """XMLTV-ID 'ZDF.de' wird auf 'zdf' aufgeloest."""
- assert mapper.resolve_xmltv_id("ZDF.de") == "zdf"
- def test_resolve_xmltv_id_unbekannt_none(self, mapper: ChannelMapper) -> None:
- """Unbekannte XMLTV-ID gibt None zurueck."""
- assert mapper.resolve_xmltv_id("UnbekannterSender.de") is None
- def test_resolve_xmltv_id_alternative_id(self, mapper: ChannelMapper) -> None:
- """Alternative XMLTV-ID 'ARD.de' wird ebenfalls auf 'ard' aufgeloest."""
- assert mapper.resolve_xmltv_id("ARD.de") == "ard"
- # ============================================================================
- # ChannelMapper - get_display_name()
- # ============================================================================
- class TestChannelMapperGetDisplayName:
- """Tests fuer die Display-Name-Abfrage."""
- @pytest.fixture
- def mapper(self) -> ChannelMapper:
- return ChannelMapper()
- def test_display_name_rtl2(self, mapper: ChannelMapper) -> None:
- """Display-Name fuer 'rtl2' ist 'RTLZWEI'."""
- assert mapper.get_display_name("rtl2") == "RTLZWEI"
- def test_display_name_ard(self, mapper: ChannelMapper) -> None:
- """Display-Name fuer 'ard' ist 'Das Erste'."""
- assert mapper.get_display_name("ard") == "Das Erste"
- def test_display_name_unbekannt_fallback(self, mapper: ChannelMapper) -> None:
- """Unbekannte Sender-ID gibt die ID selbst als Fallback zurueck."""
- assert mapper.get_display_name("unbekannt_123") == "unbekannt_123"
- # ============================================================================
- # ChannelMapper - get_all_channel_ids()
- # ============================================================================
- class TestChannelMapperGetAllChannelIds:
- """Tests fuer die Abfrage aller aktiven Sender-IDs."""
- def test_alle_sender_ohne_filter(self) -> None:
- """Ohne Filter werden alle Sender zurueckgegeben."""
- mapper = ChannelMapper()
- ids = mapper.get_all_channel_ids()
- assert len(ids) == len(CHANNELS)
- def test_alle_sender_ist_liste(self) -> None:
- """Die Rueckgabe ist eine Liste."""
- mapper = ChannelMapper()
- ids = mapper.get_all_channel_ids()
- assert isinstance(ids, list)
- def test_alle_sender_enthaelt_ard(self) -> None:
- """Die Liste enthaelt 'ard'."""
- mapper = ChannelMapper()
- ids = mapper.get_all_channel_ids()
- assert "ard" in ids
- # ============================================================================
- # ChannelMapper - channel_filter
- # ============================================================================
- class TestChannelMapperFilter:
- """Tests fuer die Sender-Filterung."""
- def test_filter_nur_ard_zdf(self) -> None:
- """Mit Filter ['ard', 'zdf'] werden nur 2 Sender aktiv."""
- mapper = ChannelMapper(channel_filter=["ard", "zdf"])
- ids = mapper.get_all_channel_ids()
- assert set(ids) == {"ard", "zdf"}
- def test_filter_resolve_aktiver_sender(self) -> None:
- """Aktive Sender koennen ueber resolve() gefunden werden."""
- mapper = ChannelMapper(channel_filter=["rtl"])
- assert mapper.resolve("RTL") == "rtl"
- def test_filter_resolve_inaktiver_sender_none(self) -> None:
- """Inaktive (gefilterte) Sender geben None zurueck."""
- mapper = ChannelMapper(channel_filter=["rtl"])
- assert mapper.resolve("ARD") is None
- def test_filter_xmltv_nur_aktive(self) -> None:
- """XMLTV-IDs gefilterter Sender sind nicht verfuegbar."""
- mapper = ChannelMapper(channel_filter=["rtl"])
- assert mapper.resolve_xmltv_id("DasErste.de") is None
- assert mapper.resolve_xmltv_id("RTL.de") == "rtl"
- # ============================================================================
- # ChannelMapper - custom_aliases
- # ============================================================================
- class TestChannelMapperCustomAliases:
- """Tests fuer benutzerdefinierte Aliase."""
- def test_custom_alias_ueberschreibt(self) -> None:
- """Benutzerdefinierter Alias wird korrekt aufgeloest."""
- mapper = ChannelMapper(custom_aliases={"Mein Sender": "rtl2"})
- assert mapper.resolve("Mein Sender") == "rtl2"
- def test_custom_alias_aktiviert_sender(self) -> None:
- """Benutzerdefinierter Alias aktiviert einen gefilterten Sender."""
- mapper = ChannelMapper(
- channel_filter=["ard"],
- custom_aliases={"Lieblingssender": "rtl"},
- )
- ids = mapper.get_all_channel_ids()
- assert "rtl" in ids
- def test_custom_alias_ungueltiger_sender_ignoriert(self) -> None:
- """Alias auf nicht existierenden Sender wird ignoriert."""
- mapper = ChannelMapper(custom_aliases={"Test": "existiert_nicht"})
- assert mapper.resolve("Test") is None
- class TestChannelMapperBlacklist:
- """Tests fuer die Blacklist-Funktion."""
- def test_blacklist_schliesst_sender_aus(self) -> None:
- """Sender auf der Blacklist werden nicht aufgenommen."""
- mapper = ChannelMapper(blacklist=["rtl", "rtl2"])
- ids = mapper.get_all_channel_ids()
- assert "rtl" not in ids
- assert "rtl2" not in ids
- assert "ard" in ids
- def test_blacklist_resolve_gibt_none(self) -> None:
- """Geblacklister Sender kann nicht aufgeloest werden."""
- mapper = ChannelMapper(blacklist=["vox"])
- assert mapper.resolve("VOX") is None
- assert mapper.resolve("Vox") is None
- def test_blacklist_case_insensitive(self) -> None:
- """Blacklist-Vergleich ist case-insensitive."""
- mapper = ChannelMapper(blacklist=["PRO7", "RTL2"])
- ids = mapper.get_all_channel_ids()
- assert "pro7" not in ids
- assert "rtl2" not in ids
- def test_blacklist_andere_sender_bleiben(self) -> None:
- """Nicht geblackliste Sender bleiben verfuegbar."""
- mapper = ChannelMapper(blacklist=["vox"])
- ids = mapper.get_all_channel_ids()
- assert "vox" not in ids
- assert len(ids) == len(CHANNELS) - 1
- def test_whitelist_hat_vorrang_vor_blacklist(self) -> None:
- """Wenn Whitelist gesetzt, wird Blacklist ignoriert."""
- mapper = ChannelMapper(
- channel_filter=["ard", "zdf", "rtl"],
- blacklist=["rtl"],
- )
- ids = mapper.get_all_channel_ids()
- # RTL ist auf Whitelist → Blacklist wird ignoriert
- assert "rtl" in ids
- assert len(ids) == 3
- def test_leere_blacklist_aendert_nichts(self) -> None:
- """Leere Blacklist hat keine Auswirkung."""
- mapper_normal = ChannelMapper()
- mapper_empty = ChannelMapper(blacklist=[])
- assert len(mapper_normal.get_all_channel_ids()) == len(mapper_empty.get_all_channel_ids())
- def test_blacklist_xmltv_ids_auch_ausgeschlossen(self) -> None:
- """XMLTV-IDs von geblacklisteten Sendern werden nicht aufgeloest."""
- mapper = ChannelMapper(blacklist=["rtl"])
- assert mapper.resolve_xmltv_id("RTL.de") is None
|