Напоминалки: тесты гейта часового пояса, конвертации и паузы

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Kenik
2026-09-05 14:51:35 +03:00
parent b766d445b4
commit c814eca596
+89
View File
@@ -1,4 +1,6 @@
import bot import bot
import reminders
from datetime import datetime, timedelta
def _state(uid): def _state(uid):
@@ -356,6 +358,7 @@ def test_stats_runs(app):
def test_admin_reminder_wizard_creates_reminder(app, monkeypatch): def test_admin_reminder_wizard_creates_reminder(app, monkeypatch):
admin = 80001 admin = 80001
monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin]) monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin])
bot.db.set_admin_tz_offset(admin, 3) # пояс уже задан — гейт не должен мешать
app.handle_message(admin, "Админка ⚙️") app.handle_message(admin, "Админка ⚙️")
app.handle_message(admin, "⏰ Напоминалки") app.handle_message(admin, "⏰ Напоминалки")
@@ -387,6 +390,7 @@ def test_admin_reminder_wizard_creates_reminder(app, monkeypatch):
def test_admin_reminder_wizard_specific_recipients(app, monkeypatch): def test_admin_reminder_wizard_specific_recipients(app, monkeypatch):
admin, other = 80003, 80004 admin, other = 80003, 80004
monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin, other]) monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin, other])
bot.db.set_admin_tz_offset(admin, 0)
app.handle_message(admin, "⏰ Напоминалки") app.handle_message(admin, "⏰ Напоминалки")
app.handle_message(admin, " Добавить") app.handle_message(admin, " Добавить")
@@ -406,6 +410,7 @@ def test_admin_reminder_wizard_specific_recipients(app, monkeypatch):
def test_admin_reminder_delete(app, monkeypatch): def test_admin_reminder_delete(app, monkeypatch):
admin = 80002 admin = 80002
monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin]) monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin])
bot.db.set_admin_tz_offset(admin, 0)
rid = bot.db.add_reminder("Тест", "2099-01-01 09:00:00", "once", [admin], created_by=admin) rid = bot.db.add_reminder("Тест", "2099-01-01 09:00:00", "once", [admin], created_by=admin)
app.handle_message(admin, f"напоминалка удалить {rid}") app.handle_message(admin, f"напоминалка удалить {rid}")
@@ -423,6 +428,7 @@ def test_admin_reminder_delete_via_picker_button(app, monkeypatch):
"""Удаление через кнопку «🗑 Удалить напоминание» + выбор из списка (без ввода id вручную).""" """Удаление через кнопку «🗑 Удалить напоминание» + выбор из списка (без ввода id вручную)."""
admin = 80005 admin = 80005
monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin]) monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin])
bot.db.set_admin_tz_offset(admin, 0)
rid = bot.db.add_reminder("Продлить хостинг", "2099-01-01 09:00:00", "once", [admin], created_by=admin) rid = bot.db.add_reminder("Продлить хостинг", "2099-01-01 09:00:00", "once", [admin], created_by=admin)
app.handle_message(admin, "⏰ Напоминалки") app.handle_message(admin, "⏰ Напоминалки")
@@ -432,3 +438,86 @@ def test_admin_reminder_delete_via_picker_button(app, monkeypatch):
app.handle_message(admin, f"{rid}. Продлить хостинг") # клик по кнопке пикера app.handle_message(admin, f"{rid}. Продлить хостинг") # клик по кнопке пикера
assert _state(admin) == "FREE_CHAT" assert _state(admin) == "FREE_CHAT"
assert not bot.db.get_active_reminders() assert not bot.db.get_active_reminders()
def test_reminder_tz_gate_before_list(app, monkeypatch):
"""Без заданного часового пояса раздел не открывается — сначала гейт."""
admin = 80006
monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin])
app.handle_message(admin, "⏰ Напоминалки")
assert _state(admin) == "ADMIN_REMINDER_TZ_SETUP"
app.handle_message(admin, "не число") # невалидный формат — остаёмся на шаге
assert _state(admin) == "ADMIN_REMINDER_TZ_SETUP"
app.handle_message(admin, "+3")
assert _state(admin) == "FREE_CHAT"
assert bot.db.get_admin_tz_offset(admin) == 3
# повторный вход — пояс уже задан, гейт больше не срабатывает
app.handle_message(admin, "⏰ Напоминалки")
assert _state(admin) == "FREE_CHAT"
def test_reminder_creation_converts_author_local_time_to_server(app, monkeypatch):
admin = 80007
monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin])
bot.db.set_admin_tz_offset(admin, 3) # пояс уже задан — гейт не мешает
app.handle_message(admin, "⏰ Напоминалки")
app.handle_message(admin, " Добавить")
app.handle_message(admin, "01.06.2099 09:00") # 09:00 по времени автора (UTC+3)
app.handle_message(admin, "Тест конвертации")
app.handle_message(admin, "0")
app.handle_message(admin, "Разово")
rows = bot.db.get_active_reminders()
stored = datetime.strptime(rows[0]["remind_at"], "%Y-%m-%d %H:%M:%S")
server_offset = reminders.server_utc_offset_hours()
expected = datetime(2099, 6, 1, 9, 0) + timedelta(hours=(server_offset - 3))
assert stored == expected
def test_reminder_pause_and_resume_via_picker(app, monkeypatch):
admin = 80008
monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin])
bot.db.set_admin_tz_offset(admin, 0)
rid = bot.db.add_reminder("Продлить хостинг", "2020-01-01 09:00:00", "once", [admin], created_by=admin)
app.handle_message(admin, "⏰ Напоминалки")
app.handle_message(admin, "⏸/▶ Пауза")
assert _state(admin) == "ADMIN_REMINDER_PAUSE_PICK"
app.handle_message(admin, f"{rid}. Продлить хостинг")
assert _state(admin) == "FREE_CHAT"
row = next(r for r in bot.db.get_active_reminders() if r["id"] == rid)
assert row["paused"] == 1
# напоминание давно просрочено, но на паузе — планировщик не должен его отправить
app._sent.clear()
app._check_due_reminders()
assert not app._sent
assert bot.db.get_active_reminders() # всё ещё активно (не деактивировалось)
# возобновляем через тот же пикер
app.handle_message(admin, "⏸/▶ Пауза")
app.handle_message(admin, f"{rid}. Продлить хостинг")
row = next(r for r in bot.db.get_active_reminders() if r["id"] == rid)
assert row["paused"] == 0
# теперь просроченное разовое напоминание должно уйти при следующей проверке
app._check_due_reminders()
assert app._sent
assert not bot.db.get_active_reminders() # once — деактивировалось после отправки
def test_timezone_change_command(app, monkeypatch):
admin = 80009
monkeypatch.setattr(bot.config, "ADMIN_IDS", [admin])
bot.db.set_admin_tz_offset(admin, 3)
app.handle_message(admin, "часовой пояс -5")
assert bot.db.get_admin_tz_offset(admin) == -5
app.handle_message(admin, "часовой пояс много")
assert bot.db.get_admin_tz_offset(admin) == -5 # невалидный ввод не поменял значение