import pytest from unittest.mock import Mock, AsyncMock, patch, MagicMock from aiogram import types from aiogram.fsm.context import FSMContext from helper_bot.handlers.voice.voice_handler import VoiceHandlers from helper_bot.handlers.voice.constants import STATE_START, STATE_STANDUP_WRITE class TestVoiceHandler: """Тесты для VoiceHandler""" @pytest.fixture def mock_db(self): """Мок для базы данных""" mock_db = Mock() mock_db.settings = { 'Telegram': { 'group_for_logs': 'test_logs_chat', 'group_for_posts': 'test_posts_chat', 'preview_link': True } } return mock_db @pytest.fixture def mock_settings(self): """Мок для настроек""" return { 'Telegram': { 'group_for_logs': 'test_logs_chat', 'group_for_posts': 'test_posts_chat', 'preview_link': True } } @pytest.fixture def mock_message(self): """Мок для сообщения""" message = Mock(spec=types.Message) message.from_user = Mock() message.from_user.id = 123 message.from_user.first_name = "Test" message.from_user.full_name = "Test User" message.chat = Mock() message.chat.id = 456 message.answer = AsyncMock() message.forward = AsyncMock() return message @pytest.fixture def mock_state(self): """Мок для состояния FSM""" state = Mock(spec=FSMContext) state.set_state = AsyncMock() return state @pytest.fixture def voice_handler(self, mock_db, mock_settings): """Экземпляр VoiceHandler для тестов""" return VoiceHandlers(mock_db, mock_settings) @pytest.mark.asyncio async def test_voice_bot_button_handler_welcome_received(self, voice_handler, mock_message, mock_state, mock_db, mock_settings): """Тест обработчика кнопки когда приветствие уже получено""" from unittest.mock import AsyncMock mock_db.check_voice_bot_welcome_received = AsyncMock(return_value=True) with patch.object(voice_handler, 'restart_function') as mock_restart: with patch('helper_bot.handlers.voice.voice_handler.update_user_info') as mock_update_user: mock_update_user.return_value = None await voice_handler.voice_bot_button_handler(mock_message, mock_state, mock_db, mock_settings) mock_db.check_voice_bot_welcome_received.assert_called_once_with(123) mock_restart.assert_called_once_with(mock_message, mock_state, mock_db, mock_settings) @pytest.mark.asyncio async def test_voice_bot_button_handler_welcome_not_received(self, voice_handler, mock_message, mock_state, mock_db, mock_settings): """Тест обработчика кнопки когда приветствие не получено""" from unittest.mock import AsyncMock mock_db.check_voice_bot_welcome_received = AsyncMock(return_value=False) with patch.object(voice_handler, 'start') as mock_start: await voice_handler.voice_bot_button_handler(mock_message, mock_state, mock_db, mock_settings) mock_db.check_voice_bot_welcome_received.assert_called_once_with(123) mock_start.assert_called_once_with(mock_message, mock_state, mock_db, mock_settings) @pytest.mark.asyncio async def test_voice_bot_button_handler_exception(self, voice_handler, mock_message, mock_state, mock_db, mock_settings): """Тест обработчика кнопки при исключении""" mock_db.check_voice_bot_welcome_received.side_effect = Exception("Test error") with patch.object(voice_handler, 'start') as mock_start: await voice_handler.voice_bot_button_handler(mock_message, mock_state, mock_db, mock_settings) mock_start.assert_called_once_with(mock_message, mock_state, mock_db, mock_settings) # Упрощенные тесты для основных функций @pytest.mark.asyncio async def test_standup_write(self, voice_handler, mock_message, mock_state, mock_db, mock_settings): """Тест функции standup_write""" with patch('helper_bot.handlers.voice.voice_handler.messages.get_message') as mock_get_message: mock_get_message.return_value = "Record voice message" await voice_handler.standup_write(mock_message, mock_state, mock_db, mock_settings) mock_state.set_state.assert_called_once_with(STATE_STANDUP_WRITE) mock_message.answer.assert_called_once_with( text="Record voice message", reply_markup=types.ReplyKeyboardRemove() ) def test_setup_handlers(self, voice_handler): """Тест настройки обработчиков""" # Проверяем, что роутер содержит обработчики assert len(voice_handler.router.message.handlers) > 0 if __name__ == '__main__': pytest.main([__file__])