"""Тесты разбора формы расписаний (без HTTP и БД).""" from __future__ import annotations from admin.forms import format_weekdays, parse_schedule_fields def _parse(**overrides: object) -> tuple[dict | None, list[str]]: fields: dict[str, object] = { "template_key": "notify.blago", "hour": "17", "minute": "0", "weekdays": [], "timezone": "Europe/Moscow", "description": "Благо", "enabled": True, } fields.update(overrides) return parse_schedule_fields(**fields) # type: ignore[arg-type] def test_format_weekdays() -> None: assert format_weekdays([]) == "каждый день" assert format_weekdays((5, 1, 3, 3)) == "Пн, Ср, Пт" def test_parse_valid_daily_schedule() -> None: data, errors = _parse() assert errors == [] assert data == { "template_key": "notify.blago", "hour": 17, "minute": 0, "weekdays": [], "timezone": "Europe/Moscow", "enabled": True, "description": "Благо", } def test_parse_weekdays_are_sorted_and_deduplicated() -> None: data, errors = _parse(weekdays=["5", "1", "5"]) assert errors == [] assert data is not None assert data["weekdays"] == [1, 5] def test_parse_default_timezone() -> None: data, errors = _parse(timezone="") assert errors == [] assert data is not None assert data["timezone"] == "Europe/Moscow" def test_parse_rejects_bad_hour() -> None: data, errors = _parse(hour="25") assert data is None assert "Час должен быть от 0 до 23" in errors def test_parse_rejects_non_numeric_minute() -> None: data, errors = _parse(minute="abc") assert data is None assert "Минуты должны быть числом" in errors def test_parse_rejects_bad_weekday() -> None: data, errors = _parse(weekdays=["9"]) assert data is None assert any("День недели" in error for error in errors) def test_parse_rejects_unknown_timezone() -> None: data, errors = _parse(timezone="Mars/Olympus") assert data is None assert any("таймзона" in error for error in errors) def test_parse_rejects_empty_template() -> None: data, errors = _parse(template_key="") assert data is None assert "Выберите шаблон сообщения" in errors def test_parse_rejects_long_description() -> None: data, errors = _parse(description="x" * 201) assert data is None assert any("Описание длиннее" in error for error in errors)