generated from unai/python_boilerplate
feat: add include_text and exclude_text filters to settings and playlist tests
This commit is contained in:
@@ -243,6 +243,8 @@ class TestPlaylistManager:
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = []
|
||||
mock_settings.exclude_text = []
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
@@ -277,6 +279,8 @@ class TestPlaylistManager:
|
||||
mock_settings.username = "user"
|
||||
mock_settings.password = "pass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = []
|
||||
mock_settings.exclude_text = []
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
@@ -306,6 +310,8 @@ class TestPlaylistManager:
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = []
|
||||
mock_settings.exclude_text = []
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
@@ -459,3 +465,368 @@ class TestPlaylistManager:
|
||||
manager.loop()
|
||||
|
||||
assert iterations == 3
|
||||
|
||||
# ========================================
|
||||
# Tests para filtros include_text y exclude_text
|
||||
# Complejidad Alta - Múltiples paths de filtrado
|
||||
# ========================================
|
||||
|
||||
def test_write_m3u_include_text_filters_by_prefix(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: include_text filtra canales que EMPIEZAN con el texto."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = ["ESPN"]
|
||||
mock_settings.exclude_text = []
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# "ESPN Sports" empieza con "ESPN" - DEBE incluirse
|
||||
assert "ESPN Sports" in content
|
||||
# "Sports Center ESPN" NO empieza con "ESPN" - NO debe incluirse
|
||||
assert "Sports Center ESPN" not in content
|
||||
# Otros canales no deben estar
|
||||
assert "HBO Movies" not in content
|
||||
assert "CNN News" not in content
|
||||
|
||||
def test_write_m3u_include_text_case_insensitive(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: include_text es case-insensitive."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = ["espn"] # minúsculas
|
||||
mock_settings.exclude_text = []
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# "ESPN Sports" debe incluirse aunque el filtro está en minúsculas
|
||||
assert "ESPN Sports" in content
|
||||
|
||||
def test_write_m3u_include_text_multiple_prefixes(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: include_text acepta múltiples prefijos (OR logic)."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = ["ESPN", "CNN", "BBC"]
|
||||
mock_settings.exclude_text = []
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# Canales que empiezan con ESPN, CNN o BBC
|
||||
assert "ESPN Sports" in content
|
||||
assert "CNN News" in content
|
||||
assert "BBC World" in content
|
||||
# Canales que no empiezan con ninguno
|
||||
assert "HBO Movies" not in content
|
||||
assert "FOX News" not in content
|
||||
|
||||
def test_write_m3u_include_text_empty_includes_all(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: include_text vacío incluye todos los canales."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = []
|
||||
mock_settings.exclude_text = []
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# Todos los canales deben estar incluidos
|
||||
for channel in channels_for_filtering:
|
||||
assert channel["name"] in content
|
||||
|
||||
def test_write_m3u_exclude_text_filters_by_contains(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: exclude_text filtra canales que CONTIENEN el texto."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = []
|
||||
mock_settings.exclude_text = ["Adult"]
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# "Adult Content" contiene "Adult" - NO debe incluirse
|
||||
assert "Adult Content" not in content
|
||||
# Otros canales deben estar
|
||||
assert "ESPN Sports" in content
|
||||
assert "HBO Movies" in content
|
||||
|
||||
def test_write_m3u_exclude_text_matches_anywhere_in_name(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: exclude_text busca en cualquier parte del nombre."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = []
|
||||
mock_settings.exclude_text = ["News"] # Está en medio/final
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# "CNN News" y "FOX News" contienen "News" - NO deben incluirse
|
||||
assert "CNN News" not in content
|
||||
assert "FOX News" not in content
|
||||
# Otros canales deben estar
|
||||
assert "ESPN Sports" in content
|
||||
assert "HBO Movies" in content
|
||||
|
||||
def test_write_m3u_exclude_text_case_insensitive(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: exclude_text es case-insensitive."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = []
|
||||
mock_settings.exclude_text = ["adult"] # minúsculas
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# "Adult Content" debe excluirse aunque el filtro está en minúsculas
|
||||
assert "Adult Content" not in content
|
||||
|
||||
def test_write_m3u_exclude_text_multiple_patterns(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: exclude_text acepta múltiples patrones (OR logic)."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = []
|
||||
mock_settings.exclude_text = ["Adult", "News"]
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# Canales que contienen "Adult" o "News" no deben incluirse
|
||||
assert "Adult Content" not in content
|
||||
assert "CNN News" not in content
|
||||
assert "FOX News" not in content
|
||||
# Otros canales deben estar
|
||||
assert "ESPN Sports" in content
|
||||
assert "HBO Movies" in content
|
||||
assert "BBC World" in content
|
||||
|
||||
def test_write_m3u_include_and_exclude_combined(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: include_text y exclude_text funcionan juntos."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
# Solo canales que empiezan con "ESPN" o "Sports"
|
||||
mock_settings.include_text = ["ESPN", "Sports"]
|
||||
# Pero excluir los que contienen "Center"
|
||||
mock_settings.exclude_text = ["Center"]
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# "ESPN Sports" empieza con "ESPN" y no contiene "Center" - INCLUIR
|
||||
assert "ESPN Sports" in content
|
||||
# "Sports Center ESPN" empieza con "Sports" pero contiene "Center" - EXCLUIR
|
||||
assert "Sports Center ESPN" not in content
|
||||
|
||||
def test_write_m3u_include_filters_before_exclude(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: include se aplica antes que exclude."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = ["CNN"]
|
||||
mock_settings.exclude_text = ["News"]
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# "CNN News" empieza con "CNN" pero contiene "News" - EXCLUIR
|
||||
assert "CNN News" not in content
|
||||
# Solo debe quedar el header
|
||||
assert content.strip() == "#EXTM3U"
|
||||
|
||||
def test_write_m3u_no_match_for_include_results_in_empty(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: si ningún canal coincide con include, resultado vacío."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = ["NONEXISTENT"]
|
||||
mock_settings.exclude_text = []
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# Solo header, sin canales
|
||||
assert content == "#EXTM3U\n"
|
||||
|
||||
def test_write_m3u_exclude_all_results_in_empty(
|
||||
self, temp_dir, channels_for_filtering
|
||||
):
|
||||
"""Test: si todos los canales son excluidos, resultado vacío."""
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = []
|
||||
# Excluir texto común a todos
|
||||
mock_settings.exclude_text = ["a", "e", "i", "o", "u"]
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels_for_filtering)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# Solo header, sin canales (todos tienen vocales)
|
||||
assert content == "#EXTM3U\n"
|
||||
|
||||
def test_write_m3u_include_startswith_not_contains(self, temp_dir):
|
||||
"""Test: include usa startswith, NO contains - verificación explícita."""
|
||||
channels = [
|
||||
{"name": "ABC News", "stream_id": 1, "stream_icon": "", "category_id": "1"},
|
||||
{
|
||||
"name": "News ABC",
|
||||
"stream_id": 2,
|
||||
"stream_icon": "",
|
||||
"category_id": "1",
|
||||
}, # Contiene ABC pero no empieza
|
||||
{
|
||||
"name": "ZABC Channel",
|
||||
"stream_id": 3,
|
||||
"stream_icon": "",
|
||||
"category_id": "1",
|
||||
}, # Contiene ABC pero no empieza
|
||||
]
|
||||
|
||||
with patch("m3u_list_builder.playlist.PUBLIC_DIR", temp_dir):
|
||||
with patch("m3u_list_builder.playlist.settings") as mock_settings:
|
||||
mock_settings.host = "http://test-iptv.com"
|
||||
mock_settings.username = "testuser"
|
||||
mock_settings.password = "testpass"
|
||||
mock_settings.output_file = "playlist.m3u"
|
||||
mock_settings.include_text = ["ABC"]
|
||||
mock_settings.exclude_text = []
|
||||
|
||||
from m3u_list_builder.playlist import PlaylistManager
|
||||
|
||||
manager = PlaylistManager()
|
||||
manager._write_m3u(channels)
|
||||
|
||||
output_file = temp_dir / "playlist.m3u"
|
||||
content = output_file.read_text()
|
||||
|
||||
# Solo "ABC News" debe estar - empieza con ABC
|
||||
assert "ABC News" in content
|
||||
# "News ABC" y "ZABC Channel" NO deben estar
|
||||
assert "News ABC" not in content
|
||||
assert "ZABC Channel" not in content
|
||||
|
||||
Reference in New Issue
Block a user