Files

73 lines
2.9 KiB
Python

from datetime import datetime
from reminders import parse_reminder_datetime, compute_next_occurrence, \
server_utc_offset_hours, convert_time
def test_parse_reminder_datetime_valid():
dt = parse_reminder_datetime("15.03.2027 09:00")
assert dt == datetime(2027, 3, 15, 9, 0)
def test_parse_reminder_datetime_invalid():
assert parse_reminder_datetime("не дата") is None
assert parse_reminder_datetime("2027-03-15 09:00") is None
assert parse_reminder_datetime("32.13.2027 09:00") is None
def test_compute_next_weekly():
anchor = datetime(2026, 9, 2, 9, 0)
nxt = compute_next_occurrence(anchor, "weekly", after=anchor)
assert nxt == datetime(2026, 9, 9, 9, 0)
def test_compute_next_monthly_end_of_month_clamp_no_drift():
"""31.01 -> 28.02 (2026 не високосный), а дальше 31.03 — не 28.03 (без дрейфа)."""
anchor = datetime(2026, 1, 31, 9, 0)
first = compute_next_occurrence(anchor, "monthly", after=anchor)
assert first == datetime(2026, 2, 28, 9, 0)
second = compute_next_occurrence(anchor, "monthly", after=first)
assert second == datetime(2026, 3, 31, 9, 0)
def test_compute_next_yearly_leap_day():
anchor = datetime(2024, 2, 29, 9, 0)
nxt = compute_next_occurrence(anchor, "yearly", after=anchor)
assert nxt == datetime(2025, 2, 28, 9, 0)
def test_compute_next_skips_missed_periods_during_downtime():
"""Бот стоял два месяца — пропущенные периоды пропускаются, берём ближайшее будущее."""
anchor = datetime(2026, 1, 1, 9, 0)
after = datetime(2026, 3, 15, 0, 0)
nxt = compute_next_occurrence(anchor, "monthly", after=after)
assert nxt == datetime(2026, 4, 1, 9, 0)
def test_compute_next_unknown_recurrence_raises():
import pytest
with pytest.raises(ValueError):
compute_next_occurrence(datetime(2026, 1, 1, 9, 0), "daily", after=datetime(2026, 1, 1, 9, 0))
def test_server_utc_offset_hours_in_sane_range():
"""Собственное смещение сервера от UTC — разумное число часов (реальные пояса Земли)."""
offset = server_utc_offset_hours()
assert -12 <= offset <= 14
def test_convert_time_to_utc():
dt = datetime(2027, 3, 15, 9, 0) # 09:00 по времени автора (UTC+3, Москва)
result = convert_time(dt, from_offset=3, to_offset=0) # переводим в UTC
assert result == datetime(2027, 3, 15, 6, 0)
def test_convert_time_crosses_midnight_backwards():
dt = datetime(2027, 3, 15, 1, 0) # 01:00 по времени автора (UTC+5, Екатеринбург)
result = convert_time(dt, from_offset=5, to_offset=-2)
assert result == datetime(2027, 3, 14, 18, 0) # переходит на предыдущие сутки
def test_convert_time_same_offset_is_noop():
dt = datetime(2027, 1, 1, 12, 0)
assert convert_time(dt, from_offset=3, to_offset=3) == dt