Напоминалки: тесты гейта часового пояса, конвертации и паузы
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -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 # невалидный ввод не поменял значение
|
||||||
|
|||||||
Reference in New Issue
Block a user