WIP: Temporary commit for branch move
This commit is contained in:
339
tests/test_error_handling.py
Normal file
339
tests/test_error_handling.py
Normal file
@@ -0,0 +1,339 @@
|
||||
# Импортируем моки в самом начале
|
||||
import tests.mocks
|
||||
|
||||
import pytest
|
||||
from unittest.mock import Mock, AsyncMock, patch
|
||||
from aiogram.types import Message, User, Chat
|
||||
|
||||
from helper_bot.handlers.private.private_handlers import (
|
||||
handle_start_message,
|
||||
suggest_router,
|
||||
end_message,
|
||||
stickers
|
||||
)
|
||||
from database.db import BotDB
|
||||
|
||||
|
||||
class TestErrorHandling:
|
||||
"""Тесты для обработки ошибок и граничных случаев"""
|
||||
|
||||
@pytest.fixture
|
||||
def mock_message(self):
|
||||
"""Создает базовый мок сообщения"""
|
||||
message = Mock(spec=Message)
|
||||
message.from_user = Mock(spec=User)
|
||||
message.from_user.id = 123456
|
||||
message.from_user.full_name = "Test User"
|
||||
message.from_user.username = "testuser"
|
||||
message.from_user.first_name = "Test"
|
||||
message.from_user.is_bot = False
|
||||
message.from_user.language_code = "ru"
|
||||
message.chat = Mock(spec=Chat)
|
||||
message.chat.id = 123456
|
||||
message.chat.type = "private"
|
||||
message.message_id = 1
|
||||
message.forward = AsyncMock()
|
||||
message.answer = AsyncMock()
|
||||
message.answer_sticker = AsyncMock()
|
||||
message.bot.send_message = AsyncMock()
|
||||
return message
|
||||
|
||||
@pytest.fixture
|
||||
def mock_state(self):
|
||||
"""Создает мок состояния"""
|
||||
state = Mock()
|
||||
state.set_state = AsyncMock()
|
||||
state.get_state = AsyncMock(return_value="START")
|
||||
return state
|
||||
|
||||
@pytest.fixture
|
||||
def mock_db(self):
|
||||
"""Создает мок базы данных"""
|
||||
db = Mock(spec=BotDB)
|
||||
db.user_exists = Mock(return_value=False)
|
||||
db.add_new_user_in_db = Mock()
|
||||
db.update_date_for_user = Mock()
|
||||
db.update_username_and_full_name = Mock()
|
||||
db.add_post_in_db = Mock()
|
||||
db.update_info_about_stickers = Mock()
|
||||
return db
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_start_message_user_without_username(self, mock_message, mock_state, mock_db):
|
||||
"""Тест обработки пользователя без username"""
|
||||
with patch('helper_bot.handlers.private.private_handlers.BotDB', mock_db):
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_reply_keyboard') as mock_keyboard:
|
||||
with patch('helper_bot.handlers.private.private_handlers.messages.get_message') as mock_messages:
|
||||
with patch('helper_bot.handlers.private.private_handlers.Path') as mock_path:
|
||||
with patch('helper_bot.handlers.private.private_handlers.FSInputFile') as mock_fs:
|
||||
with patch('helper_bot.handlers.private.private_handlers.sleep'):
|
||||
# Настройка моков
|
||||
mock_message.from_user.username = None
|
||||
mock_keyboard.return_value = Mock()
|
||||
mock_messages.return_value = "Привет!"
|
||||
mock_path.return_value.rglob.return_value = ["sticker1.tgs"]
|
||||
mock_fs.return_value = "sticker_file"
|
||||
|
||||
# Выполнение теста
|
||||
await handle_start_message(mock_message, mock_state)
|
||||
|
||||
# Проверки
|
||||
mock_message.bot.send_message.assert_called()
|
||||
# Проверяем, что отправлено сообщение о пользователе без username
|
||||
call_args = mock_message.bot.send_message.call_args_list
|
||||
username_log_call = next(
|
||||
(call for call in call_args if 'без username' in call[1]['text']),
|
||||
None
|
||||
)
|
||||
assert username_log_call is not None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_start_message_sticker_error(self, mock_message, mock_state, mock_db):
|
||||
"""Тест обработки ошибки при получении стикера"""
|
||||
with patch('helper_bot.handlers.private.private_handlers.BotDB', mock_db):
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_reply_keyboard') as mock_keyboard:
|
||||
with patch('helper_bot.handlers.private.private_handlers.messages.get_message') as mock_messages:
|
||||
with patch('helper_bot.handlers.private.private_handlers.Path') as mock_path:
|
||||
with patch('helper_bot.handlers.private.private_handlers.sleep'):
|
||||
# Настройка моков с ошибкой
|
||||
mock_path.return_value.rglob.side_effect = Exception("Sticker error")
|
||||
mock_keyboard.return_value = Mock()
|
||||
mock_messages.return_value = "Привет!"
|
||||
|
||||
# Выполнение теста
|
||||
await handle_start_message(mock_message, mock_state)
|
||||
|
||||
# Проверки
|
||||
mock_message.bot.send_message.assert_called()
|
||||
# Проверяем, что отправлено сообщение об ошибке
|
||||
call_args = mock_message.bot.send_message.call_args_list
|
||||
error_call = next(
|
||||
(call for call in call_args if 'ошибка при получении стикеров' in call[1]['text']),
|
||||
None
|
||||
)
|
||||
assert error_call is not None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_start_message_message_error(self, mock_message, mock_state, mock_db):
|
||||
"""Тест обработки ошибки при отправке приветственного сообщения"""
|
||||
with patch('helper_bot.handlers.private.private_handlers.BotDB', mock_db):
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_reply_keyboard') as mock_keyboard:
|
||||
with patch('helper_bot.handlers.private.private_handlers.messages.get_message') as mock_messages:
|
||||
with patch('helper_bot.handlers.private.private_handlers.Path') as mock_path:
|
||||
with patch('helper_bot.handlers.private.private_handlers.FSInputFile') as mock_fs:
|
||||
with patch('helper_bot.handlers.private.private_handlers.sleep'):
|
||||
# Настройка моков
|
||||
mock_keyboard.return_value = Mock()
|
||||
mock_messages.side_effect = Exception("Message error")
|
||||
mock_path.return_value.rglob.return_value = ["sticker1.tgs"]
|
||||
mock_fs.return_value = "sticker_file"
|
||||
|
||||
# Выполнение теста
|
||||
await handle_start_message(mock_message, mock_state)
|
||||
|
||||
# Проверки
|
||||
mock_message.bot.send_message.assert_called()
|
||||
# Проверяем, что отправлено сообщение об ошибке
|
||||
call_args = mock_message.bot.send_message.call_args_list
|
||||
# Проверяем, что было отправлено хотя бы одно сообщение
|
||||
assert len(call_args) > 0
|
||||
# Проверяем, что в одном из сообщений есть текст об ошибке
|
||||
error_found = False
|
||||
for call in call_args:
|
||||
text = call.kwargs.get('text', '') or (call[0][1] if len(call[0]) > 1 else '')
|
||||
if 'Произошла ошибка' in text:
|
||||
error_found = True
|
||||
break
|
||||
assert error_found
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_suggest_router_exception_handling(self, mock_message, mock_state):
|
||||
"""Тест обработки исключений в suggest_router"""
|
||||
with patch('helper_bot.handlers.private.private_handlers.BotDB') as mock_db:
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_text_message') as mock_get_text:
|
||||
# Настройка моков с ошибкой
|
||||
mock_message.content_type = 'text'
|
||||
mock_message.text = 'Тестовый пост'
|
||||
mock_message.media_group_id = None
|
||||
mock_get_text.side_effect = Exception("Processing error")
|
||||
|
||||
# Выполнение теста
|
||||
await suggest_router(mock_message, mock_state)
|
||||
|
||||
# Проверки
|
||||
mock_message.bot.send_message.assert_called_once()
|
||||
call_args = mock_message.bot.send_message.call_args
|
||||
assert 'Произошла ошибка' in call_args[1]['text']
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_end_message_sticker_error(self, mock_message, mock_state):
|
||||
"""Тест обработки ошибки при получении стикера в end_message"""
|
||||
with patch('helper_bot.handlers.private.private_handlers.Path') as mock_path:
|
||||
with patch('helper_bot.handlers.private.private_handlers.messages.get_message') as mock_messages:
|
||||
with patch('helper_bot.handlers.private.private_handlers.sleep'):
|
||||
# Настройка моков с ошибкой
|
||||
mock_message.text = '👋🏼Сказать пока!'
|
||||
mock_path.return_value.rglob.side_effect = Exception("Sticker error")
|
||||
mock_messages.return_value = "До свидания!"
|
||||
|
||||
# Выполнение теста
|
||||
await end_message(mock_message, mock_state)
|
||||
|
||||
# Проверки
|
||||
mock_message.bot.send_message.assert_called()
|
||||
call_args = mock_message.bot.send_message.call_args_list
|
||||
# Проверяем, что в одном из сообщений есть текст об ошибке
|
||||
error_found = False
|
||||
for call in call_args:
|
||||
text = call.kwargs.get('text', '') or (call[0][1] if len(call[0]) > 1 else '')
|
||||
if 'Произошла ошибка' in text:
|
||||
error_found = True
|
||||
break
|
||||
assert error_found
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_end_message_message_error(self, mock_message, mock_state):
|
||||
"""Тест обработки ошибки при отправке сообщения в end_message"""
|
||||
with patch('helper_bot.handlers.private.private_handlers.Path') as mock_path:
|
||||
with patch('helper_bot.handlers.private.private_handlers.FSInputFile') as mock_fs:
|
||||
with patch('helper_bot.handlers.private.private_handlers.messages.get_message') as mock_messages:
|
||||
with patch('helper_bot.handlers.private.private_handlers.sleep'):
|
||||
# Настройка моков
|
||||
mock_message.text = '👋🏼Сказать пока!'
|
||||
mock_path.return_value.rglob.return_value = ["sticker1.tgs"]
|
||||
mock_fs.return_value = "sticker_file"
|
||||
mock_messages.side_effect = Exception("Message error")
|
||||
|
||||
# Выполнение теста
|
||||
await end_message(mock_message, mock_state)
|
||||
|
||||
# Проверки
|
||||
mock_message.bot.send_message.assert_called()
|
||||
call_args = mock_message.bot.send_message.call_args_list
|
||||
# Проверяем, что в одном из сообщений есть текст об ошибке
|
||||
error_found = False
|
||||
for call in call_args:
|
||||
text = call.kwargs.get('text', '') or (call[0][1] if len(call[0]) > 1 else '')
|
||||
if 'Произошла ошибка' in text:
|
||||
error_found = True
|
||||
break
|
||||
assert error_found
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_stickers_exception_handling(self, mock_message, mock_state, mock_db):
|
||||
"""Тест обработки исключений в stickers"""
|
||||
with patch('helper_bot.handlers.private.private_handlers.BotDB', mock_db):
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_reply_keyboard') as mock_keyboard:
|
||||
# Настройка моков с ошибкой
|
||||
mock_message.text = '🤪Хочу стикеры'
|
||||
mock_db.update_info_about_stickers.side_effect = Exception("Database error")
|
||||
mock_keyboard.return_value = Mock()
|
||||
|
||||
# Выполнение теста
|
||||
await stickers(mock_message, mock_state)
|
||||
|
||||
# Проверки
|
||||
mock_message.bot.send_message.assert_called_once()
|
||||
call_args = mock_message.bot.send_message.call_args
|
||||
assert 'Произошла ошибка' in call_args[1]['text']
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_suggest_router_empty_text(self, mock_message, mock_state, mock_db):
|
||||
"""Тест обработки пустого текста"""
|
||||
with patch('helper_bot.handlers.private.private_handlers.BotDB', mock_db):
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_text_message') as mock_get_text:
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_reply_keyboard_for_post') as mock_keyboard_post:
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_reply_keyboard') as mock_keyboard:
|
||||
with patch('helper_bot.handlers.private.private_handlers.send_text_message') as mock_send:
|
||||
with patch('helper_bot.handlers.private.private_handlers.messages.get_message') as mock_messages:
|
||||
with patch('helper_bot.handlers.private.private_handlers.sleep'):
|
||||
# Настройка моков
|
||||
mock_message.content_type = 'text'
|
||||
mock_message.text = ''
|
||||
mock_message.media_group_id = None
|
||||
mock_get_text.return_value = ''
|
||||
mock_keyboard_post.return_value = Mock()
|
||||
mock_keyboard.return_value = Mock()
|
||||
mock_send.return_value = 123
|
||||
mock_messages.return_value = "Пост отправлен!"
|
||||
|
||||
# Выполнение теста
|
||||
await suggest_router(mock_message, mock_state)
|
||||
|
||||
# Проверки - даже пустой текст должен обрабатываться
|
||||
mock_message.forward.assert_called_once()
|
||||
mock_send.assert_called()
|
||||
mock_db.add_post_in_db.assert_called_once()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_suggest_router_photo_without_caption(self, mock_message, mock_state, mock_db):
|
||||
"""Тест обработки фото без подписи"""
|
||||
with patch('helper_bot.handlers.private.private_handlers.BotDB', mock_db):
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_reply_keyboard_for_post') as mock_keyboard_post:
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_reply_keyboard') as mock_keyboard:
|
||||
with patch('helper_bot.handlers.private.private_handlers.send_photo_message') as mock_send_photo:
|
||||
with patch('helper_bot.handlers.private.private_handlers.add_in_db_media') as mock_add_media:
|
||||
with patch('helper_bot.handlers.private.private_handlers.messages.get_message') as mock_messages:
|
||||
with patch('helper_bot.handlers.private.private_handlers.sleep'):
|
||||
# Настройка моков для фото без подписи
|
||||
mock_message.content_type = 'photo'
|
||||
mock_message.caption = None
|
||||
mock_message.media_group_id = None
|
||||
mock_message.photo = [Mock()]
|
||||
mock_message.photo[-1].file_id = 'photo_file_id'
|
||||
|
||||
mock_keyboard_post.return_value = Mock()
|
||||
mock_keyboard.return_value = Mock()
|
||||
mock_send_photo.return_value = Mock()
|
||||
mock_send_photo.return_value.message_id = 123
|
||||
mock_send_photo.return_value.caption = ''
|
||||
mock_messages.return_value = "Фото отправлено!"
|
||||
|
||||
# Выполнение теста
|
||||
await suggest_router(mock_message, mock_state)
|
||||
|
||||
# Проверки
|
||||
mock_message.forward.assert_called_once()
|
||||
mock_send_photo.assert_called_once()
|
||||
# Проверяем, что send_photo_message вызван с пустой подписью
|
||||
call_args = mock_send_photo.call_args
|
||||
assert call_args.kwargs.get('caption', '') == ''
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_suggest_router_media_group_without_caption(self, mock_message, mock_state, mock_db):
|
||||
"""Тест обработки медиагруппы без подписи"""
|
||||
with patch('helper_bot.handlers.private.private_handlers.BotDB', mock_db):
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_reply_keyboard_for_post') as mock_keyboard_post:
|
||||
with patch('helper_bot.handlers.private.private_handlers.get_reply_keyboard') as mock_keyboard:
|
||||
with patch('helper_bot.handlers.private.private_handlers.prepare_media_group_from_middlewares') as mock_prepare:
|
||||
with patch('helper_bot.handlers.private.private_handlers.send_media_group_message_to_private_chat') as mock_send_group:
|
||||
with patch('helper_bot.handlers.private.private_handlers.send_text_message') as mock_send_text:
|
||||
with patch('helper_bot.handlers.private.private_handlers.messages.get_message') as mock_messages:
|
||||
with patch('helper_bot.handlers.private.private_handlers.sleep'):
|
||||
# Настройка моков для медиагруппы без подписи
|
||||
mock_message.media_group_id = 'group_123'
|
||||
mock_message.content_type = 'photo'
|
||||
|
||||
# Создаем мок альбома без подписи
|
||||
album = [mock_message]
|
||||
album[0].caption = None
|
||||
|
||||
mock_keyboard_post.return_value = Mock()
|
||||
mock_keyboard.return_value = Mock()
|
||||
mock_prepare.return_value = ['media1', 'media2']
|
||||
mock_send_group.return_value = 123
|
||||
mock_send_text.return_value = 456
|
||||
mock_messages.return_value = "Медиагруппа отправлена!"
|
||||
|
||||
# Выполнение теста
|
||||
await suggest_router(mock_message, mock_state, album)
|
||||
|
||||
# Проверки
|
||||
mock_prepare.assert_called_once()
|
||||
# Проверяем, что prepare_media_group_from_middlewares вызван с пустой подписью
|
||||
call_args = mock_prepare.call_args
|
||||
assert call_args.kwargs.get('post_caption', '') == ''
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
pytest.main([__file__, '-v'])
|
||||
Reference in New Issue
Block a user