Files
telegram-helper-bot/tests/test_improved_media_processing.py
2026-02-02 00:46:44 +03:00

332 lines
12 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 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__])