From bb9f291623ca2c0db9d300c4a8c107eef8c44216 Mon Sep 17 00:00:00 2001 From: deadzilla Date: Tue, 14 Jul 2026 22:20:45 +0500 Subject: [PATCH] =?UTF-8?q?Scheduler.=5F=5Finit=5F=5F=20=D0=B1=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D1=88=D0=B5=20=D0=BD=D0=B5=20=D1=81=D0=BE=D0=B7=D0=B4?= =?UTF-8?q?=D0=B0=D1=91=D1=82=20task=20=D1=81=D0=B8=D0=BD=D1=85=D1=80?= =?UTF-8?q?=D0=BE=D0=BD=D0=BD=D0=BE;=20start()=20=D1=81=D1=82=D0=B0=D0=BB?= =?UTF-8?q?=20async-=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=BE=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bot.py | 1 + tests/test_morning_runner.py | 25 ++++++++++++++----------- utils/morning_runner.py | 3 +-- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/bot.py b/bot.py index 8815741..fb0dbd7 100644 --- a/bot.py +++ b/bot.py @@ -143,6 +143,7 @@ class BotRunner: morning_time = os.getenv("MORNING_TIME", "07:00") self.scheduler = Scheduler(self.bot, morning_time) self.bot._scheduler = self.scheduler + await self.scheduler.start() logger.info( "Планировщик запущен (время: %s, сервер: %s)", morning_time, guild.name ) diff --git a/tests/test_morning_runner.py b/tests/test_morning_runner.py index 0969681..10bc3b6 100644 --- a/tests/test_morning_runner.py +++ b/tests/test_morning_runner.py @@ -25,12 +25,12 @@ class TestSchedulerInit: scheduler = Scheduler(bot) assert scheduler.morning_time == "07:00" - def test_init_creates_task(self) -> None: - """Инициализация должна вызывать _start_scheduler.""" + def test_init_does_not_start_scheduler(self) -> None: + """Инициализация не должна запускать планировщик (start() вызывается отдельно).""" bot = AsyncMock() with patch.object(Scheduler, "_start_scheduler") as mock_start: Scheduler(bot) - mock_start.assert_called_once() + mock_start.assert_not_called() class TestSchedulerCalculateNextRun: @@ -67,14 +67,14 @@ class TestSchedulerCalculateNextRun: class TestSchedulerStartStop: """Тесты запуска/остановки планировщика.""" - def test_start_starts_task(self) -> None: - """start() должен вызывать _start_scheduler (1 в __init__ + 1 в start, но реальный task один).""" + @pytest.mark.asyncio + async def test_start_starts_task(self) -> None: + """start() должен вызывать _start_scheduler один раз.""" bot = AsyncMock() with patch.object(Scheduler, "_start_scheduler") as mock_start: scheduler = Scheduler(bot) - scheduler.start() - # __init__ вызывает _start_scheduler, start() тоже вызывает - assert mock_start.call_count == 2 + await scheduler.start() + mock_start.assert_called_once() def test_stop_stops_task(self) -> None: """stop() должен остановить task.""" @@ -88,12 +88,15 @@ class TestSchedulerStartStop: scheduler.stop() assert scheduler._running is False - def test_double_start_no_duplicate(self) -> None: - """Повторный start должен вызывать _start_scheduler дважды (реальный task не дублируется благодаря флагам).""" + @pytest.mark.asyncio + async def test_double_start_no_duplicate(self) -> None: + """Повторный start() не должен дублировать task (благодаря флагам).""" bot = AsyncMock() with patch.object(Scheduler, "_start_scheduler") as mock_start: scheduler = Scheduler(bot) - scheduler.start() # второй вызов + await scheduler.start() + await scheduler.start() # повторный вызов + # _start_scheduler вызывается 2 раза, но реальный task один (флаг _running защищает) assert mock_start.call_count == 2 diff --git a/utils/morning_runner.py b/utils/morning_runner.py index 255d3e4..256ef7f 100644 --- a/utils/morning_runner.py +++ b/utils/morning_runner.py @@ -151,7 +151,6 @@ class Scheduler: ) self._task: asyncio.Task | None = None self._running = False - self._start_scheduler() def _start_scheduler(self): if self._running: @@ -276,7 +275,7 @@ class Scheduler: if not sent: logger.error("Не удалось найти канал для отправки morning-дайджеста") - def start(self) -> None: + async def start(self) -> None: self._start_scheduler() def stop(self) -> None: