""" Тесты для улучшенных методов обработки медиа """ import os import tempfile from unittest.mock import AsyncMock, MagicMock, Mock, patch import pytest from aiogram import types from helper_bot.utils.helper_func import ( add_in_db_media, add_in_db_media_mediagroup, download_file, send_media_group_message_to_private_chat) class TestDownloadFile: """Тесты для функции download_file""" @pytest.mark.asyncio async def test_download_file_success_photo(self): """Тест успешного скачивания фото""" # Создаем временную директорию with tempfile.TemporaryDirectory() as temp_dir: with ( patch("helper_bot.utils.helper_func.os.makedirs"), patch("helper_bot.utils.helper_func.os.path.exists", return_value=True), patch( "helper_bot.utils.helper_func.os.path.getsize", return_value=1024 ), patch( "helper_bot.utils.helper_func.os.path.basename", return_value="photo.jpg", ), patch( "helper_bot.utils.helper_func.os.path.splitext", return_value=("photo", ".jpg"), ), ): # Мокаем сообщение и бота mock_message = Mock() mock_message.bot = Mock() mock_file = Mock() mock_file.file_path = "photos/photo.jpg" mock_message.bot.get_file = AsyncMock(return_value=mock_file) mock_message.bot.download_file = AsyncMock() # Вызываем функцию result = await download_file(mock_message, "test_file_id", "photo") # Проверяем результат assert result is not None assert "files/photos/test_file_id.jpg" in result mock_message.bot.get_file.assert_called_once_with("test_file_id") mock_message.bot.download_file.assert_called_once() @pytest.mark.asyncio async def test_download_file_invalid_parameters(self): """Тест с неверными параметрами""" result = await download_file(None, "test_file_id", "photo") assert result is None mock_message = Mock() mock_message.bot = None result = await download_file(mock_message, "test_file_id", "photo") assert result is None @pytest.mark.asyncio async def test_download_file_error(self): """Тест обработки ошибки при скачивании""" mock_message = Mock() mock_message.bot = Mock() mock_message.bot.get_file = AsyncMock(side_effect=Exception("Network error")) result = await download_file(mock_message, "test_file_id", "photo") assert result is None class TestAddInDbMedia: """Тесты для функции add_in_db_media""" @pytest.mark.asyncio async def test_add_in_db_media_success_photo(self): """Тест успешного добавления фото в БД""" # Мокаем сообщение mock_message = Mock() mock_message.message_id = 123 mock_message.photo = [Mock()] mock_message.photo[-1].file_id = "photo_123" mock_message.video = None mock_message.voice = None mock_message.audio = None mock_message.video_note = None # Мокаем БД mock_db = AsyncMock() mock_db.add_post_content = AsyncMock(return_value=True) with patch( "helper_bot.utils.helper_func.download_file", return_value="files/photos/photo_123.jpg", ): result = await add_in_db_media(mock_message, mock_db) assert result is True mock_db.add_post_content.assert_called_once_with( 123, 123, "files/photos/photo_123.jpg", "photo" ) @pytest.mark.asyncio async def test_add_in_db_media_download_fails(self): """Тест когда скачивание файла не удается""" mock_message = Mock() mock_message.message_id = 123 mock_message.photo = [Mock()] mock_message.photo[-1].file_id = "photo_123" mock_message.video = None mock_message.voice = None mock_message.audio = None mock_message.video_note = None mock_db = AsyncMock() with patch("helper_bot.utils.helper_func.download_file", return_value=None): result = await add_in_db_media(mock_message, mock_db) assert result is False mock_db.add_post_content.assert_not_called() @pytest.mark.asyncio async def test_add_in_db_media_db_fails(self): """Тест когда добавление в БД не удается""" mock_message = Mock() mock_message.message_id = 123 mock_message.photo = [Mock()] mock_message.photo[-1].file_id = "photo_123" mock_message.video = None mock_message.voice = None mock_message.audio = None mock_message.video_note = None mock_db = AsyncMock() mock_db.add_post_content = AsyncMock(return_value=False) with ( patch( "helper_bot.utils.helper_func.download_file", return_value="files/photos/photo_123.jpg", ), patch("helper_bot.utils.helper_func.os.remove"), ): result = await add_in_db_media(mock_message, mock_db) assert result is False mock_db.add_post_content.assert_called_once() @pytest.mark.asyncio async def test_add_in_db_media_unsupported_content(self): """Тест с неподдерживаемым типом контента""" mock_message = Mock() mock_message.message_id = 123 mock_message.photo = None mock_message.video = None mock_message.voice = None mock_message.audio = None mock_message.video_note = None mock_db = AsyncMock() result = await add_in_db_media(mock_message, mock_db) assert result is False mock_db.add_post_content.assert_not_called() class TestAddInDbMediaMediagroup: """Тесты для функции add_in_db_media_mediagroup""" @pytest.mark.asyncio async def test_add_in_db_media_mediagroup_success(self): """Тест успешного добавления медиагруппы в БД""" # Создаем моки сообщений mock_message1 = Mock() mock_message1.message_id = 1 mock_message1.photo = [Mock()] mock_message1.photo[-1].file_id = "photo_1" mock_message1.video = None mock_message1.voice = None mock_message1.audio = None mock_message1.video_note = None mock_message2 = Mock() mock_message2.message_id = 2 mock_message2.photo = None mock_message2.video = Mock() mock_message2.video.file_id = "video_1" mock_message2.voice = None mock_message2.audio = None mock_message2.video_note = None sent_messages = [mock_message1, mock_message2] # Мокаем БД mock_db = AsyncMock() mock_db.add_post_content = AsyncMock(return_value=True) with patch( "helper_bot.utils.helper_func.download_file", return_value="files/test.jpg" ): result = await add_in_db_media_mediagroup( sent_messages, mock_db, main_post_id=100 ) assert result is True assert mock_db.add_post_content.call_count == 2 @pytest.mark.asyncio async def test_add_in_db_media_mediagroup_empty_list(self): """Тест с пустым списком сообщений""" mock_db = AsyncMock() result = await add_in_db_media_mediagroup([], mock_db) assert result is False mock_db.add_post_content.assert_not_called() @pytest.mark.asyncio async def test_add_in_db_media_mediagroup_partial_failure(self): """Тест когда часть сообщений обрабатывается успешно""" # Создаем моки сообщений mock_message1 = Mock() mock_message1.message_id = 1 mock_message1.photo = [Mock()] mock_message1.photo[-1].file_id = "photo_1" mock_message1.video = None mock_message1.voice = None mock_message1.audio = None mock_message1.video_note = None mock_message2 = Mock() mock_message2.message_id = 2 mock_message2.photo = None mock_message2.video = None mock_message2.voice = None mock_message2.audio = None mock_message2.video_note = None # Неподдерживаемый тип sent_messages = [mock_message1, mock_message2] # Мокаем БД mock_db = AsyncMock() mock_db.add_post_content = AsyncMock(return_value=True) with patch( "helper_bot.utils.helper_func.download_file", return_value="files/test.jpg" ): result = await add_in_db_media_mediagroup(sent_messages, mock_db) # Должен вернуть False, так как есть ошибки (второе сообщение не поддерживается) assert result is False assert mock_db.add_post_content.call_count == 1 class TestSendMediaGroupMessageToPrivateChat: """Тесты для функции send_media_group_message_to_private_chat""" @pytest.mark.asyncio async def test_send_media_group_message_success(self): """Тест успешной отправки медиагруппы""" # Мокаем сообщение mock_message = Mock() mock_message.from_user.id = 123 mock_message.bot = Mock() # Мокаем отправленное сообщение mock_sent_message = Mock() mock_sent_message.message_id = 456 mock_sent_message.caption = "Test caption" mock_message.bot.send_media_group = AsyncMock(return_value=[mock_sent_message]) # Мокаем БД mock_db = AsyncMock() with patch( "helper_bot.utils.helper_func.add_in_db_media_mediagroup", return_value=True ): with patch( "asyncio.create_task" ): # Мокаем create_task, чтобы фоновая задача не выполнялась result = await send_media_group_message_to_private_chat( 100, mock_message, [], mock_db, main_post_id=789 ) assert result == [456] # Функция возвращает список message_id mock_message.bot.send_media_group.assert_called_once() @pytest.mark.asyncio async def test_send_media_group_message_media_processing_fails(self): """Тест когда обработка медиа не удается""" # Мокаем сообщение mock_message = Mock() mock_message.from_user.id = 123 mock_message.bot = Mock() # Мокаем отправленное сообщение mock_sent_message = Mock() mock_sent_message.message_id = 456 mock_sent_message.caption = "Test caption" mock_message.bot.send_media_group = AsyncMock(return_value=[mock_sent_message]) # Мокаем БД mock_db = AsyncMock() with patch( "helper_bot.utils.helper_func.add_in_db_media_mediagroup", return_value=False, ): with patch( "asyncio.create_task" ): # Мокаем create_task, чтобы фоновая задача не выполнялась result = await send_media_group_message_to_private_chat( 100, mock_message, [], mock_db, main_post_id=789 ) assert result == [456] # Функция возвращает список message_id mock_message.bot.send_media_group.assert_called_once() if __name__ == "__main__": pytest.main([__file__])