Переписал почти все тесты
feat: улучшено логирование и обработка скорингов в PostService и RagApiClient - Добавлены отладочные сообщения для передачи скорингов в функции обработки постов. - Обновлено логирование успешного получения скорингов из RAG API с дополнительной информацией. - Оптимизирована обработка скорингов в функции get_text_message для улучшения отладки. - Обновлены тесты для проверки новых функциональных возможностей и обработки ошибок.
This commit is contained in:
@@ -4,7 +4,13 @@ from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from helper_bot.handlers.callback.callback_handlers import (
|
||||
delete_voice_message, save_voice_message)
|
||||
change_page,
|
||||
delete_voice_message,
|
||||
process_ban_user,
|
||||
process_unlock_user,
|
||||
return_to_main_menu,
|
||||
save_voice_message,
|
||||
)
|
||||
from helper_bot.handlers.voice.constants import CALLBACK_DELETE, CALLBACK_SAVE
|
||||
|
||||
|
||||
@@ -291,5 +297,244 @@ class TestCallbackHandlersEdgeCases:
|
||||
mock_bot_db.delete_audio_moderate_record.assert_called_once_with(99999)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.asyncio
|
||||
class TestReturnToMainMenu:
|
||||
"""Тесты для return_to_main_menu."""
|
||||
|
||||
@pytest.fixture
|
||||
def mock_call(self):
|
||||
call = Mock()
|
||||
call.message = Mock()
|
||||
call.message.message_id = 1
|
||||
call.message.from_user = Mock()
|
||||
call.message.from_user.id = 123
|
||||
call.message.delete = AsyncMock()
|
||||
call.message.answer = AsyncMock()
|
||||
return call
|
||||
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.get_reply_keyboard_admin")
|
||||
async def test_return_to_main_menu_deletes_and_answers(self, mock_keyboard, mock_call):
|
||||
"""return_to_main_menu удаляет сообщение и отправляет приветствие."""
|
||||
mock_keyboard.return_value = MagicMock()
|
||||
|
||||
await return_to_main_menu(mock_call)
|
||||
|
||||
mock_call.message.delete.assert_called_once()
|
||||
mock_call.message.answer.assert_called_once()
|
||||
assert "админк" in mock_call.message.answer.call_args[0][0].lower() or "добро" in mock_call.message.answer.call_args[0][0].lower()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.asyncio
|
||||
class TestChangePage:
|
||||
"""Тесты для change_page."""
|
||||
|
||||
@pytest.fixture
|
||||
def mock_bot_db_for_page(self):
|
||||
"""Мок БД для change_page."""
|
||||
db = Mock()
|
||||
db.get_last_users = AsyncMock(return_value=[("U1", 1), ("U2", 2)])
|
||||
return db
|
||||
|
||||
@pytest.fixture
|
||||
def mock_call_list_users(self):
|
||||
call = Mock()
|
||||
call.data = "page_2"
|
||||
call.message = Mock()
|
||||
call.message.text = "Список пользователей которые последними обращались к боту"
|
||||
call.message.chat = Mock()
|
||||
call.message.chat.id = 1
|
||||
call.message.message_id = 10
|
||||
call.bot = Mock()
|
||||
call.bot.edit_message_reply_markup = AsyncMock()
|
||||
call.answer = AsyncMock()
|
||||
return call
|
||||
|
||||
@pytest.fixture
|
||||
def mock_bot_db(self):
|
||||
db = Mock()
|
||||
db.get_last_users = AsyncMock(return_value=[("U1", 1), ("U2", 2)])
|
||||
return db
|
||||
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.create_keyboard_with_pagination")
|
||||
async def test_change_page_list_users_edits_markup(
|
||||
self, mock_keyboard, mock_call_list_users, mock_bot_db_for_page
|
||||
):
|
||||
"""change_page для списка пользователей редактирует reply_markup."""
|
||||
mock_keyboard.return_value = MagicMock()
|
||||
|
||||
await change_page(mock_call_list_users, bot_db=mock_bot_db_for_page)
|
||||
|
||||
mock_bot_db_for_page.get_last_users.assert_awaited_once_with(30)
|
||||
mock_call_list_users.bot.edit_message_reply_markup.assert_awaited_once()
|
||||
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.get_banned_users_buttons", new_callable=AsyncMock)
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.get_banned_users_list", new_callable=AsyncMock)
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.create_keyboard_with_pagination")
|
||||
async def test_change_page_banned_list_edits_text_and_markup(
|
||||
self, mock_keyboard, mock_get_list, mock_get_buttons, mock_bot_db_for_page
|
||||
):
|
||||
"""change_page для списка забаненных редактирует текст и клавиатуру."""
|
||||
mock_get_list.return_value = "Текст страницы"
|
||||
mock_get_buttons.return_value = []
|
||||
call = Mock()
|
||||
call.data = "page_1"
|
||||
call.message = Mock()
|
||||
call.message.text = "Заблокированные пользователи"
|
||||
call.message.chat = Mock()
|
||||
call.message.chat.id = 1
|
||||
call.message.message_id = 10
|
||||
call.bot = Mock()
|
||||
call.bot.edit_message_text = AsyncMock()
|
||||
call.bot.edit_message_reply_markup = AsyncMock()
|
||||
call.answer = AsyncMock()
|
||||
mock_keyboard.return_value = MagicMock()
|
||||
|
||||
await change_page(call, bot_db=mock_bot_db_for_page)
|
||||
|
||||
mock_get_list.assert_awaited_once()
|
||||
mock_get_buttons.assert_awaited_once()
|
||||
call.bot.edit_message_text.assert_awaited_once()
|
||||
call.bot.edit_message_reply_markup.assert_awaited_once()
|
||||
|
||||
async def test_change_page_invalid_page_number_answers_error(self, mock_bot_db_for_page):
|
||||
"""change_page при некорректном номере страницы отвечает ошибкой."""
|
||||
call = Mock()
|
||||
call.data = "page_abc"
|
||||
call.answer = AsyncMock()
|
||||
|
||||
await change_page(call, bot_db=mock_bot_db_for_page)
|
||||
|
||||
call.answer.assert_awaited_once_with(
|
||||
text="Ошибка: некорректный номер страницы", show_alert=True, cache_time=3
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.asyncio
|
||||
class TestProcessBanUser:
|
||||
"""Тесты для process_ban_user."""
|
||||
|
||||
@pytest.fixture
|
||||
def mock_bot_db_ban(self):
|
||||
"""Мок БД для process_ban_user."""
|
||||
db = Mock()
|
||||
db.get_full_name_by_id = AsyncMock(return_value="Full Name")
|
||||
return db
|
||||
|
||||
@pytest.fixture
|
||||
def mock_call(self):
|
||||
call = Mock()
|
||||
call.data = "ban_123456"
|
||||
call.from_user = Mock()
|
||||
call.message = Mock()
|
||||
call.message.answer = AsyncMock()
|
||||
call.answer = AsyncMock()
|
||||
return call
|
||||
|
||||
@pytest.fixture
|
||||
def mock_state(self):
|
||||
state = Mock()
|
||||
state.update_data = AsyncMock()
|
||||
state.set_state = AsyncMock()
|
||||
return state
|
||||
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.create_keyboard_for_ban_reason")
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.format_user_info")
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.get_ban_service")
|
||||
async def test_process_ban_user_success_sets_state_await_details(
|
||||
self, mock_get_ban, mock_format, mock_keyboard, mock_call, mock_state, mock_bot_db_ban
|
||||
):
|
||||
"""process_ban_user при успехе переводит в AWAIT_BAN_DETAILS."""
|
||||
mock_ban = Mock()
|
||||
mock_ban.ban_user = AsyncMock(return_value="username")
|
||||
mock_get_ban.return_value = mock_ban
|
||||
mock_format.return_value = "User info"
|
||||
mock_keyboard.return_value = MagicMock()
|
||||
|
||||
await process_ban_user(mock_call, mock_state, bot_db=mock_bot_db_ban)
|
||||
|
||||
mock_state.update_data.assert_awaited_once()
|
||||
mock_state.set_state.assert_awaited_once_with("AWAIT_BAN_DETAILS")
|
||||
mock_call.message.answer.assert_awaited_once()
|
||||
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.get_reply_keyboard_admin")
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.get_ban_service")
|
||||
async def test_process_ban_user_not_found_returns_to_admin(
|
||||
self, mock_get_ban, mock_keyboard, mock_call, mock_state, mock_bot_db_ban
|
||||
):
|
||||
"""process_ban_user при UserNotFoundError возвращает в админ-меню."""
|
||||
from helper_bot.handlers.callback.exceptions import UserNotFoundError
|
||||
mock_ban = Mock()
|
||||
mock_ban.ban_user = AsyncMock(side_effect=UserNotFoundError("not found"))
|
||||
mock_get_ban.return_value = mock_ban
|
||||
mock_keyboard.return_value = MagicMock()
|
||||
|
||||
await process_ban_user(mock_call, mock_state, bot_db=mock_bot_db_ban)
|
||||
|
||||
mock_call.message.answer.assert_awaited_once()
|
||||
mock_state.set_state.assert_awaited_once_with("ADMIN")
|
||||
|
||||
async def test_process_ban_user_invalid_user_id_answers_error(self, mock_call, mock_state, mock_bot_db_ban):
|
||||
"""process_ban_user при некорректном user_id отвечает ошибкой."""
|
||||
mock_call.data = "ban_abc"
|
||||
|
||||
await process_ban_user(mock_call, mock_state, bot_db=mock_bot_db_ban)
|
||||
|
||||
mock_call.answer.assert_awaited_once_with(
|
||||
text="Ошибка: некорректный ID пользователя", show_alert=True, cache_time=3
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
@pytest.mark.asyncio
|
||||
class TestProcessUnlockUser:
|
||||
"""Тесты для process_unlock_user."""
|
||||
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.get_ban_service")
|
||||
async def test_process_unlock_user_success_answers_unlocked(self, mock_get_ban):
|
||||
"""process_unlock_user при успехе отвечает сообщением о разблокировке."""
|
||||
call = Mock()
|
||||
call.data = "unlock_123"
|
||||
call.answer = AsyncMock()
|
||||
mock_ban = Mock()
|
||||
mock_ban.unlock_user = AsyncMock(return_value="username")
|
||||
mock_get_ban.return_value = mock_ban
|
||||
|
||||
await process_unlock_user(call)
|
||||
|
||||
mock_ban.unlock_user.assert_awaited_once_with("123")
|
||||
call.answer.assert_awaited_once()
|
||||
assert "username" in call.answer.call_args[0][0] or "разблокирован" in call.answer.call_args[0][0].lower()
|
||||
|
||||
@patch("helper_bot.handlers.callback.callback_handlers.get_ban_service")
|
||||
async def test_process_unlock_user_not_found_answers_error(self, mock_get_ban):
|
||||
"""process_unlock_user при UserNotFoundError отвечает что пользователь не найден."""
|
||||
from helper_bot.handlers.callback.exceptions import UserNotFoundError
|
||||
call = Mock()
|
||||
call.data = "unlock_999"
|
||||
call.answer = AsyncMock()
|
||||
mock_ban = Mock()
|
||||
mock_ban.unlock_user = AsyncMock(side_effect=UserNotFoundError("not found"))
|
||||
mock_get_ban.return_value = mock_ban
|
||||
|
||||
await process_unlock_user(call)
|
||||
|
||||
call.answer.assert_awaited_once_with(text="Пользователь не найден в базе", show_alert=True, cache_time=3)
|
||||
|
||||
async def test_process_unlock_user_invalid_user_id_answers_error(self):
|
||||
"""process_unlock_user при некорректном user_id отвечает ошибкой."""
|
||||
call = Mock()
|
||||
call.data = "unlock_abc"
|
||||
call.answer = AsyncMock()
|
||||
|
||||
await process_unlock_user(call)
|
||||
|
||||
call.answer.assert_awaited_once_with(
|
||||
text="Ошибка: некорректный ID пользователя", show_alert=True, cache_time=3
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__])
|
||||
|
||||
Reference in New Issue
Block a user