fix: always close the operation status so the draft stops hanging
Драфт исчезает только когда бот отправляет реальное сообщение. Ряд путей завершения операции не закрывал статус, из-за чего последняя показанная фраза висела в чате до конца TTL драфта и выглядела неактуальной. - OperationStatus: флаг _closed, finish() принимает None (только снять статус), finish_if_open() — идемпотентное закрытие, _finished_draft_id сохраняется до обнуления draft_id - finish_status(status, text) — хелпер, терпит None: закрывает статус на любом пути выхода без повторения `if status:` - закрыты пути без finish: _rebuild_account_profile при переданном статусе, _process_voice -> _classify_and_respond, успешные выходы _handle_image_message и transcribe_voice через else-ветку, ранние возвраты /help и проверки подписки Проверено: 176 тестов OK (4 новых на закрытие статуса). VERSION: 0.1.0+49 -> 0.1.0+50
This commit is contained in:
1 parent
87e421ae73
commit
635b78cb86
5 files changed
+155
-17
No files matched your search
@@ -150,6 +150,41 @@ class GroupStatusTests(unittest.IsolatedAsyncioTestCase):
|
||||
status = await bot.OperationStatus.start(message, "⏳ Старт", kind="generation")
|
||||
self.assertIsNone(status._rotation_task)
|
||||
|
||||
async def test_finish_without_text_only_stops_rotation(self):
|
||||
message = make_message("private")
|
||||
status = await bot.OperationStatus.start(message, "⏳ Старт", kind="generation")
|
||||
await status.finish()
|
||||
|
||||
# Никакого сообщения, но ротация остановлена и статус закрыт.
|
||||
message.answer.assert_not_awaited()
|
||||
self.assertTrue(status._closed)
|
||||
self.assertIsNone(status._rotation_task)
|
||||
|
||||
async def test_finish_is_idempotent(self):
|
||||
message = make_message("private")
|
||||
status = await bot.OperationStatus.start(message, "⏳ Старт", kind="generation")
|
||||
await status.finish("✅ Готово")
|
||||
await status.finish_if_open("✅ Ещё раз")
|
||||
await status.finish_if_open("✅ И ещё")
|
||||
|
||||
# Повторные вызовы не должны слать дубли.
|
||||
self.assertEqual(message.answer.await_count, 1)
|
||||
message.answer.assert_awaited_once_with("✅ Готово")
|
||||
|
||||
async def test_finish_status_helper_tolerates_none(self):
|
||||
await bot.finish_status(None, "✅ Готово") # не должно падать
|
||||
|
||||
async def test_image_and_voice_paths_close_the_status(self):
|
||||
"""Успешный выход без явного finish не оставляет драфт висеть."""
|
||||
for kind in ("images", "voice"):
|
||||
message = make_message("private")
|
||||
status = await bot.OperationStatus.start(message, "⏳ Старт", kind=kind)
|
||||
await bot.finish_status(status, "✅ Готово")
|
||||
self.assertTrue(status._closed)
|
||||
self.assertIsNone(status._rotation_task)
|
||||
self.assertIsNone(status.draft_id)
|
||||
message.answer.assert_awaited_once_with("✅ Готово")
|
||||
|
||||
async def test_draft_failure_falls_back_to_real_message(self):
|
||||
message = make_message("private")
|
||||
message.bot.send_message_draft = AsyncMock(side_effect=RuntimeError("draft unsupported"))
|
||||
|
||||
Reference in new issue
Block a user