"""Unit tests for utils (dates, user, handover).""" from datetime import date import pytest from duty_teller.utils.dates import ( day_start_iso, day_end_iso, duty_to_iso, parse_iso_date, validate_date_range, ) from duty_teller.utils.user import build_full_name from duty_teller.utils.handover import parse_handover_time # --- dates --- def test_day_start_iso(): assert day_start_iso(date(2026, 2, 18)) == "2026-02-18T00:00:00Z" def test_day_end_iso(): assert day_end_iso(date(2026, 2, 18)) == "2026-02-18T23:59:59Z" def test_duty_to_iso(): assert duty_to_iso(date(2026, 2, 18), 6, 0) == "2026-02-18T06:00:00Z" def test_parse_iso_date_valid(): assert parse_iso_date("2026-02-18") == date(2026, 2, 18) assert parse_iso_date(" 2026-02-18 ") == date(2026, 2, 18) def test_parse_iso_date_invalid(): assert parse_iso_date("") is None assert parse_iso_date("2026-02-31") is None # invalid day assert parse_iso_date("18-02-2026") is None assert parse_iso_date("not-a-date") is None def test_validate_date_range_ok(): validate_date_range("2025-01-01", "2025-01-31") # no raise def test_validate_date_range_bad_format(): with pytest.raises(ValueError, match="формате YYYY-MM-DD"): validate_date_range("01-01-2025", "2025-01-31") with pytest.raises(ValueError, match="формате YYYY-MM-DD"): validate_date_range("2025-01-01", "invalid") def test_validate_date_range_from_after_to(): with pytest.raises(ValueError, match="from не должна быть позже"): validate_date_range("2025-02-01", "2025-01-01") # --- user --- def test_build_full_name_both(): assert build_full_name("John", "Doe") == "John Doe" def test_build_full_name_first_only(): assert build_full_name("John", None) == "John" def test_build_full_name_last_only(): assert build_full_name(None, "Doe") == "Doe" def test_build_full_name_empty(): assert build_full_name("", "") == "User" assert build_full_name(None, None) == "User" # --- handover --- def test_parse_handover_utc(): assert parse_handover_time("09:00") == (9, 0) assert parse_handover_time("09:00 UTC") == (9, 0) assert parse_handover_time(" 06:30 ") == (6, 30) def test_parse_handover_with_tz(): # Europe/Moscow UTC+3 in winter: 09:00 Moscow = 06:00 UTC assert parse_handover_time("09:00 Europe/Moscow") == (6, 0) def test_parse_handover_invalid(): assert parse_handover_time("") is None assert parse_handover_time("not a time") is None # 25:00 is normalized to 1:00 by hour % 24; use non-matching string assert parse_handover_time("12") is None