Files
telegram-helper-bot/tests/test_voice_services.py
Andrey c8c7d50cbb Refactor metrics handling and improve logging
- Removed the MetricsManager initialization from `run_helper.py` to avoid duplication, as metrics are now handled in `main.py`.
- Updated logging levels in `server_prometheus.py` and `metrics_middleware.py` to use debug instead of info for less critical messages.
- Added metrics configuration to `BaseDependencyFactory` for better management of metrics settings.
- Deleted the obsolete `metrics_exporter.py` file to streamline the codebase.
- Updated various tests to reflect changes in the metrics handling and ensure proper functionality.
2025-09-03 00:33:20 +03:00

243 lines
11 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 pytest
from unittest.mock import Mock, AsyncMock, patch, MagicMock
from pathlib import Path
from datetime import datetime
from helper_bot.handlers.voice.services import VoiceBotService
from helper_bot.handlers.voice.exceptions import VoiceMessageError, AudioProcessingError
class TestVoiceBotService:
"""Тесты для VoiceBotService"""
@pytest.fixture
def mock_bot_db(self):
"""Мок для базы данных"""
mock_db = Mock()
mock_db.settings = {
'Settings': {'logs': True},
'Telegram': {'important_logs': 'test_chat_id'}
}
return mock_db
@pytest.fixture
def mock_settings(self):
"""Мок для настроек"""
return {
'Settings': {'logs': True},
'Telegram': {'preview_link': True}
}
@pytest.fixture
def voice_service(self, mock_bot_db, mock_settings):
"""Экземпляр VoiceBotService для тестов"""
return VoiceBotService(mock_bot_db, mock_settings)
@pytest.mark.asyncio
async def test_get_welcome_sticker_success(self, voice_service, mock_settings):
"""Тест успешного получения стикера"""
with patch('pathlib.Path.rglob') as mock_rglob:
mock_rglob.return_value = ['/path/to/sticker1.tgs', '/path/to/sticker2.tgs']
sticker = await voice_service.get_welcome_sticker()
assert sticker is not None
mock_rglob.assert_called_once()
@pytest.mark.asyncio
async def test_get_welcome_sticker_no_stickers(self, voice_service, mock_settings):
"""Тест получения стикера когда их нет"""
with patch('pathlib.Path.rglob') as mock_rglob:
mock_rglob.return_value = []
sticker = await voice_service.get_welcome_sticker()
assert sticker is None
@pytest.mark.asyncio
async def test_get_welcome_sticker_only_webp_files(self, voice_service, mock_settings):
"""Тест получения стикера когда есть только webp файлы"""
with patch('pathlib.Path.rglob') as mock_rglob:
mock_rglob.return_value = ['/path/to/sticker1.webp', '/path/to/sticker2.webp']
sticker = await voice_service.get_welcome_sticker()
# Проверяем, что стикер не None (метод ищет файлы по паттерну Hello_*)
assert sticker is not None
@pytest.mark.asyncio
async def test_get_welcome_sticker_mixed_files(self, voice_service, mock_settings):
"""Тест получения стикера когда есть смешанные файлы"""
with patch('pathlib.Path.rglob') as mock_rglob:
mock_rglob.return_value = [
'/path/to/sticker1.webp',
'/path/to/sticker2.tgs',
'/path/to/sticker3.webp'
]
sticker = await voice_service.get_welcome_sticker()
assert sticker is not None
# Проверяем, что стикер не None (метод возвращает FSInputFile объект)
@pytest.mark.asyncio
async def test_get_random_audio_success(self, voice_service, mock_bot_db):
"""Тест успешного получения случайного аудио"""
mock_bot_db.check_listen_audio = AsyncMock(return_value=['audio1', 'audio2'])
mock_bot_db.get_user_id_by_file_name = AsyncMock(return_value=123)
mock_bot_db.get_date_by_file_name = AsyncMock(return_value='2025-01-01 12:00:00')
mock_bot_db.get_user_emoji = AsyncMock(return_value='😊')
result = await voice_service.get_random_audio(456)
assert result is not None
assert len(result) == 3
# Проверяем, что результат содержит ожидаемые данные, но не проверяем точное значение audio
assert result[0] in ['audio1', 'audio2']
assert result[1] == '2025-01-01 12:00:00'
assert result[2] == '😊'
@pytest.mark.asyncio
async def test_get_random_audio_no_audio(self, voice_service, mock_bot_db):
"""Тест получения аудио когда их нет"""
mock_bot_db.check_listen_audio = AsyncMock(return_value=[])
result = await voice_service.get_random_audio(456)
assert result is None
@pytest.mark.asyncio
async def test_get_random_audio_single_audio(self, voice_service, mock_bot_db):
"""Тест получения аудио когда есть только одно"""
mock_bot_db.check_listen_audio = AsyncMock(return_value=['audio1'])
mock_bot_db.get_user_id_by_file_name = AsyncMock(return_value=123)
mock_bot_db.get_date_by_file_name = AsyncMock(return_value='2025-01-01 12:00:00')
mock_bot_db.get_user_emoji = AsyncMock(return_value='😊')
result = await voice_service.get_random_audio(456)
assert result is not None
assert len(result) == 3
assert result[0] == 'audio1'
@pytest.mark.asyncio
async def test_mark_audio_as_listened_success(self, voice_service, mock_bot_db):
"""Тест успешной пометки аудио как прослушанного"""
mock_bot_db.mark_listened_audio = AsyncMock()
await voice_service.mark_audio_as_listened('test_audio', 123)
mock_bot_db.mark_listened_audio.assert_called_once_with('test_audio', user_id=123)
@pytest.mark.asyncio
async def test_clear_user_listenings_success(self, voice_service, mock_bot_db):
"""Тест успешной очистки прослушиваний"""
mock_bot_db.delete_listen_count_for_user = AsyncMock()
await voice_service.clear_user_listenings(123)
mock_bot_db.delete_listen_count_for_user.assert_called_once_with(123)
@pytest.mark.asyncio
async def test_get_remaining_audio_count_success(self, voice_service, mock_bot_db):
"""Тест получения количества оставшихся аудио"""
mock_bot_db.check_listen_audio = AsyncMock(return_value=['audio1', 'audio2', 'audio3'])
result = await voice_service.get_remaining_audio_count(123)
assert result == 3
mock_bot_db.check_listen_audio.assert_called_once_with(user_id=123)
@pytest.mark.asyncio
async def test_get_remaining_audio_count_zero(self, voice_service, mock_bot_db):
"""Тест получения количества оставшихся аудио когда их нет"""
mock_bot_db.check_listen_audio = AsyncMock(return_value=[])
result = await voice_service.get_remaining_audio_count(123)
assert result == 0
mock_bot_db.check_listen_audio.assert_called_once_with(user_id=123)
@pytest.mark.asyncio
async def test_send_welcome_messages_success(self, voice_service, mock_bot_db, mock_settings):
"""Тест успешной отправки приветственных сообщений"""
mock_message = Mock()
mock_message.from_user.id = 123
mock_message.answer = AsyncMock()
mock_message.answer.return_value = Mock()
mock_message.answer_sticker = AsyncMock()
with patch.object(voice_service, 'get_welcome_sticker') as mock_sticker:
mock_sticker.return_value = 'test_sticker.tgs'
await voice_service.send_welcome_messages(mock_message, '😊')
# Проверяем, что сообщения отправлены
assert mock_message.answer.call_count >= 1
@pytest.mark.asyncio
async def test_send_welcome_messages_no_sticker(self, voice_service, mock_bot_db, mock_settings):
"""Тест отправки приветственных сообщений без стикера"""
mock_message = Mock()
mock_message.from_user.id = 123
mock_message.answer = AsyncMock()
mock_message.answer.return_value = Mock()
with patch.object(voice_service, 'get_welcome_sticker') as mock_sticker:
mock_sticker.return_value = None
await voice_service.send_welcome_messages(mock_message, '😊')
# Проверяем, что сообщения отправлены
assert mock_message.answer.call_count >= 1
@pytest.mark.asyncio
async def test_send_welcome_messages_with_sticker(self, voice_service, mock_bot_db, mock_settings):
"""Тест отправки приветственных сообщений со стикером"""
mock_message = Mock()
mock_message.from_user.id = 123
mock_message.answer = AsyncMock()
mock_message.answer.return_value = Mock()
mock_message.answer_sticker = AsyncMock()
with patch.object(voice_service, 'get_welcome_sticker') as mock_sticker:
mock_sticker.return_value = 'test_sticker.tgs'
await voice_service.send_welcome_messages(mock_message, '😊')
# Проверяем, что сообщения отправлены
assert mock_message.answer.call_count >= 1
@pytest.mark.asyncio
async def test_get_welcome_sticker_with_tgs_files(self, voice_service, mock_settings):
"""Тест получения стикера когда есть .tgs файлы"""
with patch('pathlib.Path.rglob') as mock_rglob:
mock_rglob.return_value = ['/path/to/sticker1.tgs', '/path/to/sticker2.tgs']
sticker = await voice_service.get_welcome_sticker()
assert sticker is not None
# Проверяем, что стикер не None (метод возвращает FSInputFile объект)
def test_service_initialization(self, mock_bot_db, mock_settings):
"""Тест инициализации сервиса"""
service = VoiceBotService(mock_bot_db, mock_settings)
assert service.bot_db == mock_bot_db
assert service.settings == mock_settings
def test_service_attributes(self, voice_service):
"""Тест атрибутов сервиса"""
assert hasattr(voice_service, 'bot_db')
assert hasattr(voice_service, 'settings')
assert hasattr(voice_service, 'get_welcome_sticker')
assert hasattr(voice_service, 'get_random_audio')
assert hasattr(voice_service, 'mark_audio_as_listened')
assert hasattr(voice_service, 'clear_user_listenings')
assert hasattr(voice_service, 'get_remaining_audio_count')
assert hasattr(voice_service, 'send_welcome_messages')
if __name__ == '__main__':
pytest.main([__file__])