# Импортируем моки в самом начале import tests.mocks import pytest from unittest.mock import Mock, AsyncMock, patch from aiogram.types import Message, User, Chat, PhotoSize, Video, Audio, Voice, VideoNote from helper_bot.handlers.private.private_handlers import suggest_router from database.db import BotDB class TestMediaHandlers: """Тесты для обработки медиа-контента""" @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.chat = Mock(spec=Chat) message.chat.id = 123456 message.chat.type = "private" message.message_id = 1 message.forward = AsyncMock() message.answer = AsyncMock() message.bot.send_message = AsyncMock() return message @pytest.fixture def mock_state(self): """Создает мок состояния""" state = Mock() state.set_state = AsyncMock() return state @pytest.fixture def mock_db(self): """Создает мок базы данных""" db = Mock(spec=BotDB) db.add_post_in_db = Mock() return db @pytest.mark.asyncio async def test_suggest_router_photo(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_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 = 'Тестовое фото' mock_message.media_group_id = None mock_message.photo = [Mock(spec=PhotoSize)] mock_message.photo[-1].file_id = 'photo_file_id' mock_get_text.return_value = 'Обработанная подпись' 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() mock_db.add_post_in_db.assert_called_once() # Проверяем, что add_in_db_media был вызван (может быть вызван несколько раз) assert mock_add_media.call_count >= 1 mock_message.answer.assert_called_once() mock_state.set_state.assert_called_with("START") @pytest.mark.asyncio async def test_suggest_router_video(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_video_message') as mock_send_video: 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 = 'video' mock_message.caption = 'Тестовое видео' mock_message.media_group_id = None mock_message.video = Mock(spec=Video) mock_message.video.file_id = 'video_file_id' mock_get_text.return_value = 'Обработанная подпись' mock_keyboard_post.return_value = Mock() mock_keyboard.return_value = Mock() mock_send_video.return_value = Mock() mock_send_video.return_value.message_id = 123 mock_send_video.return_value.caption = 'Обработанная подпись' mock_messages.return_value = "Видео отправлено!" # Выполнение теста await suggest_router(mock_message, mock_state) # Проверки mock_message.forward.assert_called_once() mock_send_video.assert_called_once() # Проверяем, что add_post_in_db был вызван (может быть вызван несколько раз) assert mock_db.add_post_in_db.call_count >= 1 # Проверяем, что add_in_db_media был вызван (может быть вызван несколько раз) assert mock_add_media.call_count >= 1 mock_message.answer.assert_called_once() mock_state.set_state.assert_called_with("START") @pytest.mark.asyncio async def test_suggest_router_video_note(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_video_note_message') as mock_send_video_note: 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 = 'video_note' mock_message.media_group_id = None mock_message.video_note = Mock(spec=VideoNote) mock_message.video_note.file_id = 'video_note_file_id' mock_keyboard_post.return_value = Mock() mock_keyboard.return_value = Mock() mock_send_video_note.return_value = Mock() mock_send_video_note.return_value.message_id = 123 mock_messages.return_value = "Видеокружок отправлен!" # Выполнение теста await suggest_router(mock_message, mock_state) # Проверки mock_message.forward.assert_called_once() mock_send_video_note.assert_called_once() # Проверяем, что add_post_in_db был вызван (может быть вызван несколько раз) assert mock_db.add_post_in_db.call_count >= 1 # Проверяем, что add_in_db_media был вызван (может быть вызван несколько раз) assert mock_add_media.call_count >= 1 mock_message.answer.assert_called_once() mock_state.set_state.assert_called_with("START") @pytest.mark.asyncio async def test_suggest_router_audio(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_audio_message') as mock_send_audio: 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 = 'audio' mock_message.caption = 'Тестовое аудио' mock_message.media_group_id = None mock_message.audio = Mock(spec=Audio) mock_message.audio.file_id = 'audio_file_id' mock_get_text.return_value = 'Обработанная подпись' mock_keyboard_post.return_value = Mock() mock_keyboard.return_value = Mock() mock_send_audio.return_value = Mock() mock_send_audio.return_value.message_id = 123 mock_send_audio.return_value.caption = 'Обработанная подпись' mock_messages.return_value = "Аудио отправлено!" # Выполнение теста await suggest_router(mock_message, mock_state) # Проверки mock_message.forward.assert_called_once() mock_send_audio.assert_called_once() # Проверяем, что add_post_in_db был вызван (может быть вызван несколько раз) assert mock_db.add_post_in_db.call_count >= 1 # Проверяем, что add_in_db_media был вызван (может быть вызван несколько раз) assert mock_add_media.call_count >= 1 mock_message.answer.assert_called_once() mock_state.set_state.assert_called_with("START") @pytest.mark.asyncio async def test_suggest_router_voice(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_voice_message') as mock_send_voice: 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 = 'voice' mock_message.media_group_id = None mock_message.voice = Mock(spec=Voice) mock_message.voice.file_id = 'voice_file_id' mock_keyboard_post.return_value = Mock() mock_keyboard.return_value = Mock() mock_send_voice.return_value = Mock() mock_send_voice.return_value.message_id = 123 mock_messages.return_value = "Голосовое сообщение отправлено!" # Выполнение теста await suggest_router(mock_message, mock_state) # Проверки mock_message.forward.assert_called_once() mock_send_voice.assert_called_once() mock_db.add_post_in_db.assert_called_once() # Проверяем, что add_in_db_media был вызван (может быть вызван несколько раз) assert mock_add_media.call_count >= 1 mock_message.answer.assert_called_once() mock_state.set_state.assert_called_with("START") @pytest.mark.asyncio async def test_suggest_router_media_group(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.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 = 'Подпись к медиагруппе' mock_get_text.return_value = 'Обработанная подпись' 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_get_text.assert_called_once() mock_prepare.assert_called_once() mock_send_group.assert_called_once() # Проверяем, что send_text_message был вызван (может быть вызван несколько раз) assert mock_send_text.call_count >= 1 mock_db.update_helper_message_in_db.assert_called_once() mock_message.answer.assert_called_once() mock_state.set_state.assert_called_with("START") @pytest.mark.asyncio async def test_suggest_router_unsupported_content(self, mock_message, mock_state): """Тест обработки неподдерживаемого типа контента""" # Настройка моков для неподдерживаемого контента mock_message.content_type = 'document' mock_message.media_group_id = None # Выполнение теста await suggest_router(mock_message, mock_state) # Проверяем, что отправлено сообщение о неподдерживаемом типе mock_message.bot.send_message.assert_called_once() call_args = mock_message.bot.send_message.call_args # Проверяем текст сообщения (может быть в позиционных или именованных аргументах) text = call_args.kwargs.get('text', '') or (call_args[0][1] if len(call_args[0]) > 1 else '') assert 'не умею работать с таким сообщением' in text if __name__ == '__main__': pytest.main([__file__, '-v'])