Files
telegram-helper-bot/tests/test_media_handlers.py

293 lines
22 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Импортируем моки в самом начале
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'])