unai 128432f679
Some checks failed
CI/CD Pipeline / test-and-lint (push) Failing after 32s
CI/CD Pipeline / publish-container (push) Has been skipped
Add unit tests for all modules including config, main, playlist, and server
2026-02-01 18:47:32 +00:00

178 lines
6.1 KiB
Python

"""Tests unitarios para el módulo config."""
import os
import pytest
from pydantic import ValidationError
@pytest.fixture(autouse=True)
def clean_env(monkeypatch):
"""Limpia todas las variables de entorno relevantes antes de cada test."""
env_vars = [
"HOST",
"USERNAME",
"PASSWORD",
"PORT",
"UPDATE_INTERVAL",
"OUTPUT_FILE",
]
for var in env_vars:
monkeypatch.delenv(var, raising=False)
yield
class TestSettings:
"""Tests para la clase Settings."""
def test_settings_with_required_fields(self, monkeypatch):
"""Test: Settings se crea correctamente con campos obligatorios."""
monkeypatch.setenv("HOST", "http://test.com")
monkeypatch.setenv("USERNAME", "user")
monkeypatch.setenv("PASSWORD", "pass")
from m3u_list_builder.config import Settings
# _env_file=None evita leer el archivo .env
settings = Settings(_env_file=None)
assert settings.host == "http://test.com"
assert settings.username == "user"
assert settings.password == "pass"
def test_settings_default_values(self, monkeypatch):
"""Test: Settings usa valores por defecto correctos."""
monkeypatch.setenv("HOST", "http://test.com")
monkeypatch.setenv("USERNAME", "user")
monkeypatch.setenv("PASSWORD", "pass")
from m3u_list_builder.config import Settings
settings = Settings(_env_file=None)
assert settings.port == 8080
assert settings.update_interval == 3600
assert settings.output_file == "playlist.m3u"
def test_settings_custom_values(self, monkeypatch):
"""Test: Settings acepta valores personalizados."""
monkeypatch.setenv("HOST", "http://custom.com")
monkeypatch.setenv("USERNAME", "custom_user")
monkeypatch.setenv("PASSWORD", "custom_pass")
monkeypatch.setenv("PORT", "9090")
monkeypatch.setenv("UPDATE_INTERVAL", "7200")
monkeypatch.setenv("OUTPUT_FILE", "custom.m3u")
from m3u_list_builder.config import Settings
settings = Settings(_env_file=None)
assert settings.host == "http://custom.com"
assert settings.username == "custom_user"
assert settings.password == "custom_pass"
assert settings.port == 9090
assert settings.update_interval == 7200
assert settings.output_file == "custom.m3u"
def test_settings_missing_required_host(self, monkeypatch):
"""Test: Settings falla sin HOST."""
monkeypatch.setenv("USERNAME", "user")
monkeypatch.setenv("PASSWORD", "pass")
from m3u_list_builder.config import Settings
with pytest.raises(ValidationError) as exc_info:
Settings(_env_file=None)
assert "host" in str(exc_info.value).lower()
def test_settings_missing_required_username(self, monkeypatch):
"""Test: Settings falla sin USERNAME."""
monkeypatch.setenv("HOST", "http://test.com")
monkeypatch.setenv("PASSWORD", "pass")
from m3u_list_builder.config import Settings
with pytest.raises(ValidationError) as exc_info:
Settings(_env_file=None)
assert "username" in str(exc_info.value).lower()
def test_settings_missing_required_password(self, monkeypatch):
"""Test: Settings falla sin PASSWORD."""
monkeypatch.setenv("HOST", "http://test.com")
monkeypatch.setenv("USERNAME", "user")
from m3u_list_builder.config import Settings
with pytest.raises(ValidationError) as exc_info:
Settings(_env_file=None)
assert "password" in str(exc_info.value).lower()
def test_settings_invalid_port_type(self, monkeypatch):
"""Test: Settings falla con PORT inválido."""
monkeypatch.setenv("HOST", "http://test.com")
monkeypatch.setenv("USERNAME", "user")
monkeypatch.setenv("PASSWORD", "pass")
monkeypatch.setenv("PORT", "invalid")
from m3u_list_builder.config import Settings
with pytest.raises(ValidationError):
Settings(_env_file=None)
def test_settings_extra_fields_ignored(self, monkeypatch):
"""Test: Settings ignora campos extra (extra='ignore')."""
monkeypatch.setenv("HOST", "http://test.com")
monkeypatch.setenv("USERNAME", "user")
monkeypatch.setenv("PASSWORD", "pass")
monkeypatch.setenv("UNKNOWN_FIELD", "should_be_ignored")
from m3u_list_builder.config import Settings
# No debe lanzar excepción
settings = Settings(_env_file=None)
assert not hasattr(settings, "unknown_field")
def test_settings_reads_env_file(self, tmp_path, monkeypatch):
"""Test: Settings puede leer desde archivo .env."""
# Crear archivo .env temporal
env_file = tmp_path / ".env"
env_file.write_text(
"HOST=http://from-env-file.com\nUSERNAME=envuser\nPASSWORD=envpass\n"
)
from m3u_list_builder.config import Settings
settings = Settings(_env_file=str(env_file))
assert settings.host == "http://from-env-file.com"
assert settings.username == "envuser"
assert settings.password == "envpass"
def test_settings_invalid_port_type(self, monkeypatch):
"""Test: Settings falla con PORT inválido."""
monkeypatch.setenv("HOST", "http://test.com")
monkeypatch.setenv("USERNAME", "user")
monkeypatch.setenv("PASSWORD", "pass")
monkeypatch.setenv("PORT", "invalid")
from m3u_list_builder.config import Settings
with pytest.raises(ValidationError):
Settings()
def test_settings_extra_fields_ignored(self, monkeypatch):
"""Test: Settings ignora campos extra (extra='ignore')."""
monkeypatch.setenv("HOST", "http://test.com")
monkeypatch.setenv("USERNAME", "user")
monkeypatch.setenv("PASSWORD", "pass")
monkeypatch.setenv("UNKNOWN_FIELD", "should_be_ignored")
from m3u_list_builder.config import Settings
# No debe lanzar excepción
settings = Settings()
assert not hasattr(settings, "unknown_field")