Переписал почти все тесты

feat: улучшено логирование и обработка скорингов в PostService и RagApiClient

- Добавлены отладочные сообщения для передачи скорингов в функции обработки постов.
- Обновлено логирование успешного получения скорингов из RAG API с дополнительной информацией.
- Оптимизирована обработка скорингов в функции get_text_message для улучшения отладки.
- Обновлены тесты для проверки новых функциональных возможностей и обработки ошибок.
This commit is contained in:
2026-01-30 00:55:47 +03:00
parent e87f4af82f
commit a5faa4bdc6
27 changed files with 4320 additions and 8 deletions

View File

@@ -1,13 +1,15 @@
"""Tests for refactored private handlers"""
from unittest.mock import AsyncMock, MagicMock, Mock
from unittest.mock import AsyncMock, MagicMock, Mock, patch
import pytest
from aiogram import types
from aiogram.fsm.context import FSMContext
from helper_bot.handlers.private.constants import BUTTON_TEXTS, FSM_STATES
from helper_bot.handlers.private.private_handlers import (
PrivateHandlers, create_private_handlers)
PrivateHandlers,
create_private_handlers,
)
from helper_bot.handlers.private.services import BotSettings
@@ -25,6 +27,7 @@ class TestPrivateHandlers:
db.add_post = AsyncMock()
db.add_message = AsyncMock()
db.update_helper_message = AsyncMock()
db.update_user_activity = AsyncMock()
return db
@pytest.fixture
@@ -55,12 +58,13 @@ class TestPrivateHandlers:
message.from_user = from_user
message.text = "test message"
message.message_id = 1
# Создаем мок для chat
chat = Mock()
chat.id = 12345
message.chat = chat
message.bot = Mock()
message.bot.send_message = AsyncMock()
message.forward = AsyncMock()
@@ -111,6 +115,16 @@ class TestPrivateHandlers:
# Verify message was logged
mock_message.forward.assert_called_once_with(chat_id=mock_settings.group_for_logs)
@pytest.mark.asyncio
async def test_handle_emoji_message_no_emoji(self, mock_db, mock_settings, mock_message, mock_state):
"""handle_emoji_message при user_emoji=None не отправляет ответ с эмодзи."""
handlers = create_private_handlers(mock_db, mock_settings)
with pytest.MonkeyPatch().context() as m:
m.setattr('helper_bot.handlers.private.private_handlers.check_user_emoji', AsyncMock(return_value=None))
await handlers.handle_emoji_message(mock_message, mock_state)
mock_state.set_state.assert_called_once_with(FSM_STATES["START"])
mock_message.answer.assert_not_called()
@pytest.mark.asyncio
async def test_handle_start_message(self, mock_db, mock_settings, mock_message, mock_state):
@@ -134,6 +148,96 @@ class TestPrivateHandlers:
mock_db.add_user.assert_called_once()
mock_db.update_user_date.assert_called_once()
@pytest.mark.asyncio
async def test_handle_restart_message(self, mock_db, mock_settings, mock_message, mock_state):
"""handle_restart_message перезапускает состояние и отправляет сообщение."""
handlers = create_private_handlers(mock_db, mock_settings)
with pytest.MonkeyPatch().context() as m:
m.setattr('helper_bot.handlers.private.private_handlers.get_reply_keyboard', AsyncMock(return_value=Mock()))
m.setattr('helper_bot.handlers.private.private_handlers.update_user_info', AsyncMock())
m.setattr('helper_bot.handlers.private.private_handlers.check_user_emoji', AsyncMock())
await handlers.handle_restart_message(mock_message, mock_state)
mock_state.set_state.assert_called_once_with(FSM_STATES["START"])
mock_message.answer.assert_called_once()
@pytest.mark.asyncio
async def test_suggest_post(self, mock_db, mock_settings, mock_message, mock_state):
"""suggest_post переводит в состояние SUGGEST и отправляет текст."""
handlers = create_private_handlers(mock_db, mock_settings)
with pytest.MonkeyPatch().context() as m:
m.setattr('helper_bot.handlers.private.private_handlers.messages.get_message', lambda x, y: "Suggest text")
await handlers.suggest_post(mock_message, mock_state)
mock_state.set_state.assert_called_once_with(FSM_STATES["SUGGEST"])
mock_message.answer.assert_called_once()
@pytest.mark.asyncio
async def test_end_message(self, mock_db, mock_settings, mock_message, mock_state):
"""end_message отправляет прощание и переводит в START."""
handlers = create_private_handlers(mock_db, mock_settings)
with pytest.MonkeyPatch().context() as m:
m.setattr('helper_bot.handlers.private.private_handlers.messages.get_message', lambda x, y: "Bye")
await handlers.end_message(mock_message, mock_state)
mock_state.set_state.assert_called_once_with(FSM_STATES["START"])
assert mock_message.answer.await_count >= 1
@pytest.mark.asyncio
async def test_stickers(self, mock_db, mock_settings, mock_message, mock_state):
"""stickers обновляет инфо о стикерах и отправляет ссылку."""
handlers = create_private_handlers(mock_db, mock_settings)
with pytest.MonkeyPatch().context() as m:
m.setattr('helper_bot.handlers.private.private_handlers.get_reply_keyboard', AsyncMock(return_value=Mock()))
await handlers.stickers(mock_message, mock_state)
mock_db.update_stickers_info.assert_awaited_once_with(mock_message.from_user.id)
mock_state.set_state.assert_called_once_with(FSM_STATES["START"])
mock_message.answer.assert_called_once()
@pytest.mark.asyncio
async def test_connect_with_admin(self, mock_db, mock_settings, mock_message, mock_state):
"""connect_with_admin переводит в PRE_CHAT и отправляет сообщение."""
handlers = create_private_handlers(mock_db, mock_settings)
with pytest.MonkeyPatch().context() as m:
m.setattr('helper_bot.handlers.private.private_handlers.messages.get_message', lambda x, y: "Admin contact")
await handlers.connect_with_admin(mock_message, mock_state)
mock_state.set_state.assert_called_once_with(FSM_STATES["PRE_CHAT"])
mock_message.answer.assert_called_once()
@pytest.mark.asyncio
async def test_resend_message_in_group_pre_chat(self, mock_db, mock_settings, mock_message, mock_state):
"""resend_message_in_group при PRE_CHAT переводит в START и отправляет question."""
handlers = create_private_handlers(mock_db, mock_settings)
mock_state.get_state = AsyncMock(return_value=FSM_STATES["PRE_CHAT"])
with pytest.MonkeyPatch().context() as m:
m.setattr('helper_bot.handlers.private.private_handlers.get_reply_keyboard', AsyncMock(return_value=Mock()))
m.setattr('helper_bot.handlers.private.private_handlers.messages.get_message', lambda x, y: "Question?")
await handlers.resend_message_in_group_for_message(mock_message, mock_state)
mock_message.forward.assert_called_once_with(chat_id=mock_settings.group_for_message)
mock_state.set_state.assert_called_once_with(FSM_STATES["START"])
@pytest.mark.asyncio
async def test_resend_message_in_group_chat(self, mock_db, mock_settings, mock_message, mock_state):
"""resend_message_in_group при CHAT оставляет в CHAT и отправляет question с leave markup."""
handlers = create_private_handlers(mock_db, mock_settings)
mock_state.get_state = AsyncMock(return_value=FSM_STATES["CHAT"])
with pytest.MonkeyPatch().context() as m:
m.setattr('helper_bot.handlers.private.private_handlers.get_reply_keyboard_leave_chat', lambda: Mock())
m.setattr('helper_bot.handlers.private.private_handlers.messages.get_message', lambda x, y: "Question?")
await handlers.resend_message_in_group_for_message(mock_message, mock_state)
mock_message.forward.assert_called_once_with(chat_id=mock_settings.group_for_message)
mock_message.answer.assert_called()
@pytest.mark.asyncio
async def test_suggest_router_answers_and_schedules_background(self, mock_db, mock_settings, mock_message, mock_state):
"""suggest_router сразу отвечает и планирует фоновую обработку."""
mock_message.media_group_id = None
handlers = create_private_handlers(mock_db, mock_settings)
with pytest.MonkeyPatch().context() as m:
m.setattr('helper_bot.handlers.private.private_handlers.get_reply_keyboard', AsyncMock(return_value=Mock()))
m.setattr('helper_bot.handlers.private.private_handlers.messages.get_message', lambda x, y: "Success")
with patch.object(handlers.post_service, 'process_post', new_callable=AsyncMock):
await handlers.suggest_router(mock_message, mock_state)
mock_state.set_state.assert_called_once_with(FSM_STATES["START"])
mock_message.answer.assert_called_once()
class TestBotSettings:
"""Test class for BotSettings dataclass"""