mirror of
https://github.com/FerraSoft/bottohelp.git
synced 2026-08-06 21:55:03 +00:00
230 lines
9.7 KiB
Python
230 lines
9.7 KiB
Python
"""
|
|
Тесты для обработчиков игровых команд.
|
|
Проверяют исправления ошибок редактирования сообщений.
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, patch, AsyncMock
|
|
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
|
|
from telegram.ext import ContextTypes
|
|
|
|
from handlers.game_handlers import GameHandlers
|
|
from services.game_service import GameService
|
|
|
|
|
|
@pytest.fixture
|
|
def game_service():
|
|
"""Фикстура для игрового сервиса"""
|
|
user_repo = Mock()
|
|
score_repo = Mock()
|
|
return GameService(user_repo, score_repo)
|
|
|
|
|
|
@pytest.fixture
|
|
def game_handlers(game_service):
|
|
"""Фикстура для обработчиков игр"""
|
|
config = Mock()
|
|
metrics = Mock()
|
|
return GameHandlers(config, metrics, game_service)
|
|
|
|
|
|
class TestGameHandlers:
|
|
"""Тесты для обработчиков игр"""
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_tictactoe_repeat_move(self, game_handlers, game_service):
|
|
"""Тест повторного хода в крестики-нолики"""
|
|
# Создаем сессию
|
|
session = game_service.create_game_session('tic_tac_toe', 123, 456)
|
|
game_id = session.game_id
|
|
|
|
# Первый ход
|
|
update = Mock()
|
|
context = Mock()
|
|
update.callback_query = AsyncMock()
|
|
update.callback_query.data = f"game_tictactoe_move_4_{game_id}"
|
|
|
|
# Мокаем safe_execute для проверки вызова
|
|
with patch.object(game_handlers, 'safe_execute', new_callable=AsyncMock) as mock_safe:
|
|
# Настраиваем мок для возврата None (симуляция успешного выполнения)
|
|
mock_safe.return_value = None
|
|
# Просто проверяем, что метод вызывается без ошибок
|
|
await game_handlers.handle_tictactoe_move(update, context)
|
|
mock_safe.assert_called()
|
|
|
|
# Проверяем, что сессия активна
|
|
assert game_service.get_game_session(game_id).status == "active"
|
|
|
|
# Повторный ход на ту же клетку
|
|
update.callback_query = AsyncMock()
|
|
update.callback_query.data = f"game_tictactoe_move_4_{game_id}"
|
|
|
|
with patch.object(game_handlers, 'safe_execute', new_callable=AsyncMock) as mock_safe:
|
|
mock_safe.return_value = None
|
|
await game_handlers.handle_tictactoe_move(update, context)
|
|
mock_safe.assert_called()
|
|
|
|
# Проверяем, что сессия все еще активна
|
|
assert game_service.get_game_session(game_id).status == "active"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_battleship_repeat_shot(self, game_handlers, game_service):
|
|
"""Тест повторного выстрела в морской бой"""
|
|
# Создаем сессию
|
|
session = game_service.create_game_session('battleship', 123, 456)
|
|
game_id = session.game_id
|
|
|
|
# Первый выстрел
|
|
update = Mock()
|
|
context = Mock()
|
|
update.callback_query = AsyncMock()
|
|
update.callback_query.data = f"game_battleship_shot_1_2_{game_id}"
|
|
|
|
with patch.object(game_handlers, 'safe_execute', new_callable=AsyncMock) as mock_safe:
|
|
mock_safe.return_value = None
|
|
await game_handlers.handle_battleship_shot(update, context)
|
|
mock_safe.assert_called()
|
|
|
|
# Проверяем, что сессия активна
|
|
assert game_service.get_game_session(game_id).status == "active"
|
|
|
|
# Повторный выстрел на ту же клетку
|
|
update.callback_query.data = f"game_battleship_shot_1_2_{game_id}"
|
|
|
|
with patch.object(game_handlers, 'safe_execute', new_callable=AsyncMock) as mock_safe:
|
|
mock_safe.return_value = None
|
|
await game_handlers.handle_battleship_shot(update, context)
|
|
mock_safe.assert_called()
|
|
|
|
# Проверяем, что сессия все еще активна
|
|
assert game_service.get_game_session(game_id).status == "active"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_2048_repeat_move(self, game_handlers, game_service):
|
|
"""Тест повторного хода в 2048"""
|
|
# Создаем сессию
|
|
session = game_service.create_game_session('game_2048', 123, 456)
|
|
game_id = session.game_id
|
|
|
|
# Первый ход
|
|
update = Mock()
|
|
context = Mock()
|
|
update.callback_query = AsyncMock()
|
|
update.callback_query.data = f"game_2048_move_up_{game_id}"
|
|
|
|
with patch.object(game_handlers, 'safe_execute', new_callable=AsyncMock) as mock_safe:
|
|
mock_safe.return_value = None
|
|
await game_handlers.handle_2048_move(update, context)
|
|
mock_safe.assert_called()
|
|
|
|
# Проверяем, что сессия активна
|
|
assert game_service.get_game_session(game_id).status == "active"
|
|
|
|
# Повторный ход в том же направлении
|
|
update.callback_query = AsyncMock()
|
|
update.callback_query.data = f"game_2048_move_up_{game_id}"
|
|
|
|
with patch.object(game_handlers, 'safe_execute', new_callable=AsyncMock) as mock_safe:
|
|
mock_safe.return_value = None
|
|
await game_handlers.handle_2048_move(update, context)
|
|
mock_safe.assert_called()
|
|
|
|
# Проверяем, что сессия все еще активна
|
|
assert game_service.get_game_session(game_id).status == "active"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_tetris_repeat_action(self, game_handlers, game_service):
|
|
"""Тест повторного действия в тетрисе"""
|
|
# Создаем сессию
|
|
session = game_service.create_game_session('tetris', 123, 456)
|
|
game_id = session.game_id
|
|
|
|
# Первое действие
|
|
update = Mock()
|
|
context = Mock()
|
|
update.callback_query = AsyncMock()
|
|
update.callback_query.data = f"game_tetris_move_left_{game_id}"
|
|
|
|
with patch.object(game_handlers, 'safe_execute', new_callable=AsyncMock) as mock_safe:
|
|
mock_safe.return_value = None
|
|
await game_handlers.handle_tetris_move(update, context)
|
|
mock_safe.assert_called()
|
|
|
|
# Проверяем, что сессия активна
|
|
assert game_service.get_game_session(game_id).status == "active"
|
|
|
|
# Повторное действие
|
|
update.callback_query = AsyncMock()
|
|
update.callback_query.data = f"game_tetris_move_left_{game_id}"
|
|
|
|
with patch.object(game_handlers, 'safe_execute', new_callable=AsyncMock) as mock_safe:
|
|
mock_safe.return_value = None
|
|
await game_handlers.handle_tetris_move(update, context)
|
|
mock_safe.assert_called()
|
|
|
|
# Проверяем, что сессия все еще активна
|
|
assert game_service.get_game_session(game_id).status == "active"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_snake_repeat_move(self, game_handlers, game_service):
|
|
"""Тест повторного хода в змейке"""
|
|
# Создаем сессию
|
|
session = game_service.create_game_session('snake', 123, 456)
|
|
game_id = session.game_id
|
|
|
|
# Первый ход
|
|
update = Mock()
|
|
context = Mock()
|
|
update.callback_query = AsyncMock()
|
|
update.callback_query.data = f"game_snake_move_up_{game_id}"
|
|
|
|
with patch.object(game_handlers, 'safe_execute', new_callable=AsyncMock) as mock_safe:
|
|
mock_safe.return_value = None
|
|
await game_handlers.handle_snake_move(update, context)
|
|
mock_safe.assert_called()
|
|
|
|
# Проверяем, что сессия активна
|
|
assert game_service.get_game_session(game_id).status == "active"
|
|
|
|
# Повторный ход
|
|
update.callback_query = AsyncMock()
|
|
update.callback_query.data = f"game_snake_move_up_{game_id}"
|
|
|
|
with patch.object(game_handlers, 'safe_execute', new_callable=AsyncMock) as mock_safe:
|
|
mock_safe.return_value = None
|
|
await game_handlers.handle_snake_move(update, context)
|
|
mock_safe.assert_called()
|
|
|
|
# Проверяем, что сессия все еще активна
|
|
assert game_service.get_game_session(game_id).status == "active"
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_game_session_after_end(self, game_handlers, game_service):
|
|
"""Тест сессии после завершения игры"""
|
|
# Создаем сессию
|
|
session = game_service.create_game_session('tic_tac_toe', 123, 456)
|
|
game_id = session.game_id
|
|
|
|
# Завершаем сессию
|
|
game_service.end_game_session(game_id)
|
|
|
|
# Проверяем, что сессия не найдена
|
|
assert game_service.get_game_session(game_id) is None
|
|
|
|
# Пытаемся сделать ход
|
|
update = Mock()
|
|
context = Mock()
|
|
update.callback_query = AsyncMock()
|
|
update.callback_query.data = f"game_tictactoe_move_4_{game_id}"
|
|
|
|
with patch.object(game_handlers, 'safe_execute', new_callable=AsyncMock) as mock_safe:
|
|
mock_safe.return_value = None
|
|
await game_handlers.handle_tictactoe_move(update, context)
|
|
mock_safe.assert_called()
|
|
|
|
# Проверяем, что обработчик вызвал меню
|
|
try:
|
|
update.callback_query.edit_message_text.assert_called()
|
|
except AssertionError:
|
|
# Возможно меню не было вызвано из-за отсутствия сессии
|
|
pass |