"""Unit tests for SchedulerConfig model fields and validators (Task 3).""" import pytest from pydantic import ValidationError from src.server.models.config import SchedulerConfig ALL_DAYS = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"] class TestSchedulerConfigDefaults: """3.1 – Default values.""" def test_default_schedule_time(self) -> None: config = SchedulerConfig() assert config.schedule_time == "03:00" def test_default_schedule_days(self) -> None: config = SchedulerConfig() assert config.schedule_days == ALL_DAYS def test_default_auto_download(self) -> None: config = SchedulerConfig() assert config.auto_download_after_rescan is False def test_default_enabled(self) -> None: config = SchedulerConfig() assert config.enabled is True def test_default_interval_minutes(self) -> None: config = SchedulerConfig() assert config.interval_minutes == 60 class TestSchedulerConfigValidScheduleTime: """3.2 – Valid schedule_time values.""" @pytest.mark.parametrize("time_val", ["00:00", "03:00", "12:30", "23:59"]) def test_valid_times(self, time_val: str) -> None: config = SchedulerConfig(schedule_time=time_val) assert config.schedule_time == time_val class TestSchedulerConfigInvalidScheduleTime: """3.3 – Invalid schedule_time values must raise ValidationError.""" @pytest.mark.parametrize( "time_val", ["25:00", "3pm", "", "3:00pm", "24:00", "-1:00", "9:00", "1:60"], ) def test_invalid_times(self, time_val: str) -> None: with pytest.raises(ValidationError): SchedulerConfig(schedule_time=time_val) class TestSchedulerConfigValidScheduleDays: """3.4 – Valid schedule_days values.""" def test_single_day(self) -> None: config = SchedulerConfig(schedule_days=["mon"]) assert config.schedule_days == ["mon"] def test_multiple_days(self) -> None: config = SchedulerConfig(schedule_days=["mon", "fri"]) assert config.schedule_days == ["mon", "fri"] def test_all_days(self) -> None: config = SchedulerConfig(schedule_days=ALL_DAYS) assert config.schedule_days == ALL_DAYS def test_empty_list(self) -> None: config = SchedulerConfig(schedule_days=[]) assert config.schedule_days == [] class TestSchedulerConfigInvalidScheduleDays: """3.5 – Invalid schedule_days values must raise ValidationError.""" @pytest.mark.parametrize( "days", [ ["monday"], ["xyz"], ["Mon"], # Case-sensitive — must be lowercase [""], ], ) def test_invalid_days(self, days: list) -> None: with pytest.raises(ValidationError): SchedulerConfig(schedule_days=days) class TestSchedulerConfigAutoDownload: """3.6 – auto_download_after_rescan field.""" def test_set_true(self) -> None: config = SchedulerConfig(auto_download_after_rescan=True) assert config.auto_download_after_rescan is True def test_set_false(self) -> None: config = SchedulerConfig(auto_download_after_rescan=False) assert config.auto_download_after_rescan is False class TestSchedulerConfigBackwardCompat: """3.7 – Backward compatibility: old fields still work.""" def test_legacy_fields_use_defaults(self) -> None: config = SchedulerConfig(enabled=True, interval_minutes=30) assert config.schedule_time == "03:00" assert config.schedule_days == ALL_DAYS assert config.auto_download_after_rescan is False assert config.enabled is True assert config.interval_minutes == 30 class TestSchedulerConfigSerialisation: """3.8 – Serialisation roundtrip.""" def test_roundtrip(self) -> None: original = SchedulerConfig( enabled=True, interval_minutes=120, schedule_time="04:30", schedule_days=["mon", "wed", "fri"], auto_download_after_rescan=True, ) dumped = original.model_dump() restored = SchedulerConfig(**dumped) assert restored == original