mirror of
https://github.com/FerraSoft/bottohelp.git
synced 2026-08-06 21:55:03 +00:00
Подготовка к релизу
This commit is contained in:
@@ -0,0 +1,648 @@
|
||||
"""
|
||||
Комплексные интеграционные тесты полного пользовательского сценария.
|
||||
Тестирование полной цепочки взаимодействия пользователя с ботом:
|
||||
от /start -> игры -> модерация -> донаты -> достижения.
|
||||
Проверяет взаимодействие всех слоев архитектуры в реальном сценарии использования.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import tempfile
|
||||
import os
|
||||
from unittest.mock import Mock, AsyncMock, patch
|
||||
from datetime import datetime
|
||||
|
||||
# Добавляем корневую директорию в путь
|
||||
import sys
|
||||
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
from core.config import Config
|
||||
from services.user_service import UserService
|
||||
from services.game_service import GameService
|
||||
from services.moderation_service import ModerationService
|
||||
from services.donation_service import DonationService
|
||||
from handlers.user_handlers import UserHandlers
|
||||
from handlers.game_handlers import GameHandlers
|
||||
from handlers.moderation_handlers import ModerationHandlers
|
||||
from database import UserRepository, ScoreRepository, PaymentRepository
|
||||
|
||||
|
||||
class TestFullUserScenarioIntegration:
|
||||
"""Комплексные интеграционные тесты полного сценария использования бота"""
|
||||
|
||||
@pytest.fixture
|
||||
def temp_config(self):
|
||||
"""Временный файл конфигурации для интеграционных тестов"""
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:
|
||||
f.write("""
|
||||
BOT_TOKEN = "123456789:integration_test_token"
|
||||
ADMIN_IDS = [123456789, 987654321]
|
||||
MODERATOR_IDS = [555666777]
|
||||
OPENWEATHER_API_KEY = "test_key"
|
||||
NEWS_API_KEY = "test_key"
|
||||
OPENAI_API_KEY = "test_key"
|
||||
STRIPE_SECRET_KEY = "sk_test_123456789"
|
||||
YOOKASSA_SHOP_ID = "123456"
|
||||
YOOKASSA_SECRET_KEY = "test_secret_key"
|
||||
""")
|
||||
config_path = f.name
|
||||
|
||||
yield config_path
|
||||
|
||||
# Очистка
|
||||
if os.path.exists(config_path):
|
||||
os.unlink(config_path)
|
||||
|
||||
@pytest.fixture
|
||||
def temp_db(self):
|
||||
"""Временная база данных для тестов с полной инициализацией"""
|
||||
from database.models import DatabaseSchema
|
||||
|
||||
with tempfile.NamedTemporaryFile(suffix='.db', delete=False) as f:
|
||||
db_path = f.name
|
||||
|
||||
# Инициализируем базу данных
|
||||
repo = UserRepository(db_path)
|
||||
try:
|
||||
# Создаем все таблицы
|
||||
for table_sql in DatabaseSchema.get_create_tables_sql():
|
||||
repo._execute_query(table_sql)
|
||||
|
||||
# Создаем стандартные достижения
|
||||
repo.initialize_achievements()
|
||||
|
||||
finally:
|
||||
repo.close()
|
||||
|
||||
yield db_path
|
||||
|
||||
# Очистка
|
||||
if os.path.exists(db_path):
|
||||
os.unlink(db_path)
|
||||
|
||||
@pytest.fixture
|
||||
def mock_update(self):
|
||||
"""Мокированный объект Update для команд"""
|
||||
update = Mock()
|
||||
|
||||
# Мокаем пользователя
|
||||
user = Mock()
|
||||
user.id = 123456789
|
||||
user.username = "test_user"
|
||||
user.first_name = "Test"
|
||||
user.last_name = "User"
|
||||
update.effective_user = user
|
||||
|
||||
# Мокаем сообщение
|
||||
message = Mock()
|
||||
message.message_id = 1
|
||||
message.reply_text = AsyncMock()
|
||||
message.edit_text = AsyncMock()
|
||||
update.message = message
|
||||
|
||||
# Мокаем чат
|
||||
chat = Mock()
|
||||
chat.id = -1001234567890
|
||||
update.effective_chat = chat
|
||||
|
||||
# Мокаем callback_query
|
||||
callback_query = Mock()
|
||||
callback_query.id = "test_callback_id"
|
||||
callback_query.data = "test_data"
|
||||
callback_query.message = message
|
||||
callback_query.answer = AsyncMock()
|
||||
update.callback_query = callback_query
|
||||
|
||||
return update
|
||||
|
||||
@pytest.fixture
|
||||
def mock_context(self):
|
||||
"""Мокированный контекст бота"""
|
||||
context = Mock()
|
||||
context.args = []
|
||||
|
||||
# Мокаем приложение
|
||||
app = Mock()
|
||||
app._date_time = datetime.now()
|
||||
context._application = app
|
||||
|
||||
# Мокаем бота
|
||||
bot = AsyncMock()
|
||||
context.bot = bot
|
||||
|
||||
context.user_data = {}
|
||||
|
||||
return context
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_complete_new_user_journey(self, temp_config, temp_db, mock_update, mock_context):
|
||||
"""Тест полного пути нового пользователя: от первого контакта до активного использования"""
|
||||
config = Config(temp_config)
|
||||
user_repo = UserRepository(temp_db)
|
||||
score_repo = ScoreRepository(temp_db)
|
||||
payment_repo = PaymentRepository(temp_db)
|
||||
|
||||
# Инициализируем все сервисы
|
||||
user_service = UserService(user_repo, score_repo)
|
||||
game_service = GameService(user_repo, score_repo)
|
||||
moderation_service = ModerationService(user_repo, score_repo)
|
||||
donation_service = DonationService(payment_repo, config.api_keys)
|
||||
|
||||
# Инициализируем все хендлеры
|
||||
user_handlers = UserHandlers(config, user_service)
|
||||
game_handlers = GameHandlers(config, config, game_service, config)
|
||||
moderation_handlers = ModerationHandlers(config, config, user_service, moderation_service)
|
||||
|
||||
try:
|
||||
# === ЭТАП 1: Первый контакт - /start ===
|
||||
print("Этап 1: Регистрация нового пользователя")
|
||||
await user_handlers.handle_start(mock_update, mock_context)
|
||||
|
||||
# Проверяем создание пользователя
|
||||
profile = await user_service.get_or_create_user(
|
||||
mock_update.effective_user.id,
|
||||
mock_update.effective_user.username,
|
||||
mock_update.effective_user.first_name,
|
||||
mock_update.effective_user.last_name
|
||||
)
|
||||
assert profile.user_id == mock_update.effective_user.id
|
||||
assert profile.rank == "Новичок"
|
||||
assert profile.reputation == 0
|
||||
|
||||
# === ЭТАП 2: Изучение команд - /help ===
|
||||
print("Этап 2: Изучение команд")
|
||||
mock_update.message.reply_text.reset_mock()
|
||||
await user_handlers.handle_help(mock_update, mock_context)
|
||||
|
||||
help_response = mock_update.message.reply_text.call_args[0][0]
|
||||
assert "Помощь по командам" in help_response or "📋" in help_response
|
||||
|
||||
# === ЭТАП 3: Проверка ранга - /rank ===
|
||||
print("Этап 3: Проверка ранга")
|
||||
mock_update.message.reply_text.reset_mock()
|
||||
await user_handlers.handle_rank(mock_update, mock_context)
|
||||
|
||||
rank_response = mock_update.message.reply_text.call_args[0][0]
|
||||
assert "🏆" in rank_response or "Ранг" in rank_response
|
||||
|
||||
# === ЭТАП 4: Игра - камень-ножницы-бумага ===
|
||||
print("Этап 4: Первая игра")
|
||||
mock_update.message.reply_text.reset_mock()
|
||||
await game_handlers._handle_play_game(mock_update, mock_context)
|
||||
|
||||
# Выбираем камень
|
||||
mock_context.args = ['rock']
|
||||
await game_handlers.handle_rps_choice(mock_update, mock_context)
|
||||
|
||||
# Проверяем начисление очков за игру
|
||||
game_profile = await user_service.get_or_create_user(
|
||||
mock_update.effective_user.id,
|
||||
mock_update.effective_user.username,
|
||||
mock_update.effective_user.first_name,
|
||||
mock_update.effective_user.last_name
|
||||
)
|
||||
assert game_profile.reputation >= 0 # Очки могли начислиться
|
||||
|
||||
# === ЭТАП 5: Крестики-нолики ===
|
||||
print("Этап 5: Крестики-нолики")
|
||||
mock_update.message.reply_text.reset_mock()
|
||||
await game_handlers._handle_tic_tac_toe(mock_update, mock_context)
|
||||
|
||||
# Делаем ход
|
||||
mock_context.args = ['4']
|
||||
await game_handlers.handle_tictactoe_move(mock_update, mock_context)
|
||||
|
||||
# === ЭТАП 6: Викторина ===
|
||||
print("Этап 6: Викторина")
|
||||
mock_update.message.reply_text.reset_mock()
|
||||
await game_handlers._handle_quiz(mock_update, mock_context)
|
||||
|
||||
# Отвечаем на вопрос
|
||||
mock_context.args = ['0']
|
||||
await game_handlers.handle_quiz_answer(mock_update, mock_context)
|
||||
|
||||
# === ЭТАП 7: Первый донат ===
|
||||
print("Этап 7: Первый донат")
|
||||
donation_amount = 500.0
|
||||
success = await user_service.add_donation(mock_update.effective_user.id, donation_amount)
|
||||
assert success
|
||||
|
||||
# Проверяем достижения
|
||||
achievements = await user_service.get_user_achievements(mock_update.effective_user.id)
|
||||
achievement_names = []
|
||||
for ach_id, unlocked_at in achievements:
|
||||
ach_data = user_repo.get_all_achievements()
|
||||
for ach in ach_data:
|
||||
if ach['id'] == ach_id:
|
||||
achievement_names.append(ach['name'])
|
||||
break
|
||||
|
||||
assert "Первый донат" in achievement_names
|
||||
|
||||
# Проверяем повышение ранга
|
||||
donator_profile = await user_service.get_or_create_user(
|
||||
mock_update.effective_user.id,
|
||||
mock_update.effective_user.username,
|
||||
mock_update.effective_user.first_name,
|
||||
mock_update.effective_user.last_name
|
||||
)
|
||||
assert donator_profile.reputation >= 5 # Минимум 5 очков от доната
|
||||
|
||||
# === ЭТАП 8: Проверка лидерборда ===
|
||||
print("Этап 8: Лидерборд")
|
||||
mock_update.message.reply_text.reset_mock()
|
||||
await user_handlers.handle_leaderboard(mock_update, mock_context)
|
||||
|
||||
leaderboard_response = mock_update.message.reply_text.call_args[0][0]
|
||||
assert "🥇" in leaderboard_response or "Топ" in leaderboard_response
|
||||
|
||||
# === ЭТАП 9: Финальная проверка профиля ===
|
||||
print("Этап 9: Финальный профиль")
|
||||
final_profile = await user_service.get_or_create_user(
|
||||
mock_update.effective_user.id,
|
||||
mock_update.effective_user.username,
|
||||
mock_update.effective_user.first_name,
|
||||
mock_update.effective_user.last_name
|
||||
)
|
||||
|
||||
# Проверяем прогресс пользователя
|
||||
assert final_profile.reputation > 0
|
||||
assert final_profile.user_id == mock_update.effective_user.id
|
||||
assert final_profile.username == mock_update.effective_user.username
|
||||
|
||||
print(f"✅ Пользователь прошел полный путь: {final_profile.reputation} очков, ранг: {final_profile.rank}")
|
||||
|
||||
finally:
|
||||
user_repo.close()
|
||||
score_repo.close()
|
||||
payment_repo.close()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_progression_scenario(self, temp_config, temp_db, mock_update, mock_context):
|
||||
"""Тест сценария прогрессии пользователя: от новичка до опытного игрока"""
|
||||
config = Config(temp_config)
|
||||
user_repo = UserRepository(temp_db)
|
||||
score_repo = ScoreRepository(temp_db)
|
||||
payment_repo = PaymentRepository(temp_db)
|
||||
|
||||
user_service = UserService(user_repo, score_repo)
|
||||
game_service = GameService(user_repo, score_repo)
|
||||
donation_service = DonationService(payment_repo, config.api_keys)
|
||||
|
||||
try:
|
||||
# === ФАЗА 1: Новичок ===
|
||||
print("Фаза 1: Новичок")
|
||||
profile = await user_service.get_or_create_user(
|
||||
mock_update.effective_user.id,
|
||||
mock_update.effective_user.username,
|
||||
mock_update.effective_user.first_name,
|
||||
mock_update.effective_user.last_name
|
||||
)
|
||||
assert profile.rank == "Новичок"
|
||||
initial_score = profile.reputation
|
||||
|
||||
# Несколько игр для накопления очков
|
||||
for _ in range(5):
|
||||
await score_repo.update_score(mock_update.effective_user.id, 2) # +2 за каждую игру
|
||||
|
||||
# === ФАЗА 2: Первый донат ===
|
||||
print("Фаза 2: Первый донат")
|
||||
await user_service.add_donation(mock_update.effective_user.id, 300.0) # +3 очка
|
||||
|
||||
# Проверяем достижения
|
||||
achievements = await user_service.get_user_achievements(mock_update.effective_user.id)
|
||||
achievement_names = [user_repo.get_all_achievements()[i]['name']
|
||||
for i, _ in achievements if i < len(user_repo.get_all_achievements())]
|
||||
|
||||
# === ФАЗА 3: Активный игрок ===
|
||||
print("Фаза 3: Активный игрок")
|
||||
# Еще игры и донаты
|
||||
for _ in range(10):
|
||||
await score_repo.update_score(mock_update.effective_user.id, 1)
|
||||
|
||||
await user_service.add_donation(mock_update.effective_user.id, 1000.0) # +10 очков
|
||||
|
||||
# === ФАЗА 4: Опытный пользователь ===
|
||||
print("Фаза 4: Опытный пользователь")
|
||||
final_profile = await user_service.get_or_create_user(
|
||||
mock_update.effective_user.id,
|
||||
mock_update.effective_user.username,
|
||||
mock_update.effective_user.first_name,
|
||||
mock_update.effective_user.last_name
|
||||
)
|
||||
|
||||
# Проверяем значительный прогресс
|
||||
total_score = final_profile.reputation
|
||||
assert total_score > initial_score + 20 # Минимум 20+ очков прогресса
|
||||
|
||||
# Проверяем достижения
|
||||
final_achievements = await user_service.get_user_achievements(mock_update.effective_user.id)
|
||||
assert len(final_achievements) >= 2 # Минимум 2 достижения
|
||||
|
||||
print(f"✅ Прогрессия завершена: {total_score} очков, {len(final_achievements)} достижений")
|
||||
|
||||
finally:
|
||||
user_repo.close()
|
||||
score_repo.close()
|
||||
payment_repo.close()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_interaction_with_moderation(self, temp_config, temp_db, mock_update, mock_context):
|
||||
"""Тест сценария взаимодействия с системой модерации"""
|
||||
config = Config(temp_config)
|
||||
user_repo = UserRepository(temp_db)
|
||||
score_repo = ScoreRepository(temp_db)
|
||||
|
||||
user_service = UserService(user_repo, score_repo)
|
||||
moderation_service = ModerationService(user_repo, score_repo)
|
||||
user_handlers = UserHandlers(config, user_service)
|
||||
moderation_handlers = ModerationHandlers(config, config, user_service, moderation_service)
|
||||
|
||||
try:
|
||||
# Создаем обычного пользователя
|
||||
regular_user_id = 999999999
|
||||
await user_service.get_or_create_user(regular_user_id, "regular", "Regular", "User")
|
||||
|
||||
# Имитируем нарушение (предупреждение)
|
||||
mock_context.args = [str(regular_user_id), "Тестовое нарушение"]
|
||||
await moderation_handlers._handle_warn(mock_update, mock_context, mock_context.args)
|
||||
|
||||
# Проверяем, что предупреждение записано
|
||||
user_history = await moderation_service.get_user_moderation_history(regular_user_id)
|
||||
assert len(user_history) >= 1
|
||||
|
||||
# Пользователь должен иметь предупреждения
|
||||
regular_profile = await user_service.get_or_create_user(regular_user_id, "regular", "Regular", "User")
|
||||
assert regular_profile.warnings >= 1
|
||||
|
||||
# При повторных нарушениях - мут
|
||||
await moderation_service.warn_user(regular_user_id, "Повторное нарушение", mock_update.effective_user.id)
|
||||
await moderation_service.warn_user(regular_user_id, "Еще одно нарушение", mock_update.effective_user.id)
|
||||
|
||||
# Проверяем эскалацию
|
||||
is_muted = moderation_service.is_user_muted(regular_user_id)
|
||||
# Логика эскалации может быть разной, но система должна реагировать
|
||||
|
||||
print("✅ Система модерации отработала корректно")
|
||||
|
||||
finally:
|
||||
user_repo.close()
|
||||
score_repo.close()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_community_interaction_scenario(self, temp_config, temp_db, mock_update, mock_context):
|
||||
"""Тест сценария взаимодействия в сообществе"""
|
||||
config = Config(temp_config)
|
||||
user_repo = UserRepository(temp_db)
|
||||
score_repo = ScoreRepository(temp_db)
|
||||
payment_repo = PaymentRepository(temp_db)
|
||||
|
||||
user_service = UserService(user_repo, score_repo)
|
||||
donation_service = DonationService(payment_repo, config.api_keys)
|
||||
user_handlers = UserHandlers(config, user_service)
|
||||
|
||||
try:
|
||||
# Создаем несколько пользователей сообщества
|
||||
users_data = [
|
||||
(111111111, "alice", "Alice", "Smith"),
|
||||
(222222222, "bob", "Bob", "Johnson"),
|
||||
(333333333, "charlie", "Charlie", "Brown"),
|
||||
(mock_update.effective_user.id, mock_update.effective_user.username,
|
||||
mock_update.effective_user.first_name, mock_update.effective_user.last_name)
|
||||
]
|
||||
|
||||
# Регистрируем всех пользователей
|
||||
for user_id, username, first_name, last_name in users_data:
|
||||
await user_service.get_or_create_user(user_id, username, first_name, last_name)
|
||||
|
||||
# Каждый делает донат
|
||||
await user_service.add_donation(user_id, 200.0) # +2 очка каждому
|
||||
|
||||
# Каждый играет в игры
|
||||
await score_repo.update_score(user_id, 5) # +5 очков каждому
|
||||
|
||||
# Проверяем лидерборд
|
||||
mock_update.message.reply_text.reset_mock()
|
||||
await user_handlers.handle_leaderboard(mock_update, mock_context)
|
||||
|
||||
leaderboard_response = mock_update.message.reply_text.call_args[0][0]
|
||||
|
||||
# Проверяем, что все пользователи в лидерборде
|
||||
top_users = await user_service.get_top_users(10)
|
||||
assert len(top_users) >= 4
|
||||
|
||||
# Проверяем разнообразие рангов
|
||||
ranks = set()
|
||||
for user_id, username, first_name, score in top_users:
|
||||
profile = await user_service.get_or_create_user(user_id, username, first_name, "Test")
|
||||
ranks.add(profile.rank)
|
||||
|
||||
assert len(ranks) >= 1 # Минимум один ранг
|
||||
|
||||
# Проверяем достижения в сообществе
|
||||
total_achievements = 0
|
||||
for user_id, _, _, _ in top_users[:3]: # Проверяем топ-3
|
||||
user_achievements = await user_service.get_user_achievements(user_id)
|
||||
total_achievements += len(user_achievements)
|
||||
|
||||
assert total_achievements >= 3 # Минимум достижения в сообществе
|
||||
|
||||
print(f"✅ Сообщество активно: {len(top_users)} участников, {total_achievements} достижений")
|
||||
|
||||
finally:
|
||||
user_repo.close()
|
||||
score_repo.close()
|
||||
payment_repo.close()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_user_retention_scenario(self, temp_config, temp_db, mock_update, mock_context):
|
||||
"""Тест сценария удержания пользователя: регулярная активность"""
|
||||
config = Config(temp_config)
|
||||
user_repo = UserRepository(temp_db)
|
||||
score_repo = ScoreRepository(temp_db)
|
||||
payment_repo = PaymentRepository(temp_db)
|
||||
|
||||
user_service = UserService(user_repo, score_repo)
|
||||
game_service = GameService(user_repo, score_repo)
|
||||
donation_service = DonationService(payment_repo, config.api_keys)
|
||||
user_handlers = UserHandlers(config, user_service)
|
||||
|
||||
try:
|
||||
# === НЕДЕЛЯ 1: Начало ===
|
||||
print("Неделя 1: Регистрация и первые взаимодействия")
|
||||
await user_handlers.handle_start(mock_update, mock_context)
|
||||
|
||||
# Ежедневные игры
|
||||
for day in range(7):
|
||||
await score_repo.update_score(mock_update.effective_user.id, 3) # 3 игры в день
|
||||
|
||||
week1_score = score_repo.get_total_score(mock_update.effective_user.id)
|
||||
|
||||
# === НЕДЕЛЯ 2: Активность ===
|
||||
print("Неделя 2: Рост активности")
|
||||
# Донат
|
||||
await user_service.add_donation(mock_update.effective_user.id, 300.0)
|
||||
|
||||
# Больше игр
|
||||
for day in range(7):
|
||||
await score_repo.update_score(mock_update.effective_user.id, 5) # 5 игр в день
|
||||
|
||||
week2_score = score_repo.get_total_score(mock_update.effective_user.id)
|
||||
|
||||
# === НЕДЕЛЯ 3: Пик активности ===
|
||||
print("Неделя 3: Пик активности")
|
||||
# Еще один донат
|
||||
await user_service.add_donation(mock_update.effective_user.id, 500.0)
|
||||
|
||||
# Максимальная активность
|
||||
for day in range(7):
|
||||
await score_repo.update_score(mock_update.effective_user.id, 8) # 8 игр в день
|
||||
|
||||
week3_score = score_repo.get_total_score(mock_update.effective_user.id)
|
||||
|
||||
# === ПРОВЕРКИ ===
|
||||
# Прогресс должен расти
|
||||
assert week2_score > week1_score
|
||||
assert week3_score > week2_score
|
||||
|
||||
# Финальный профиль
|
||||
final_profile = await user_service.get_or_create_user(
|
||||
mock_update.effective_user.id,
|
||||
mock_update.effective_user.username,
|
||||
mock_update.effective_user.first_name,
|
||||
mock_update.effective_user.last_name
|
||||
)
|
||||
|
||||
# Проверяем достижения
|
||||
achievements = await user_service.get_user_achievements(mock_update.effective_user.id)
|
||||
assert len(achievements) >= 2 # Минимум 2 достижения за 3 недели
|
||||
|
||||
# Проверяем ранг
|
||||
assert final_profile.reputation >= 50 # Минимум 50 очков
|
||||
|
||||
# Проверяем статистику донатов
|
||||
total_donations = await user_service.get_total_donations(mock_update.effective_user.id, 2025)
|
||||
assert total_donations >= 800.0
|
||||
|
||||
print(f"✅ Удержание пользователя успешно: {final_profile.reputation} очков, ранг {final_profile.rank}")
|
||||
|
||||
finally:
|
||||
user_repo.close()
|
||||
score_repo.close()
|
||||
payment_repo.close()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_error_recovery_scenario(self, temp_config, temp_db, mock_update, mock_context):
|
||||
"""Тест сценария восстановления после ошибок"""
|
||||
config = Config(temp_config)
|
||||
user_repo = UserRepository(temp_db)
|
||||
score_repo = ScoreRepository(temp_db)
|
||||
|
||||
user_service = UserService(user_repo, score_repo)
|
||||
user_handlers = UserHandlers(config, user_service)
|
||||
|
||||
try:
|
||||
# Создаем пользователя
|
||||
await user_handlers.handle_start(mock_update, mock_context)
|
||||
|
||||
# Имитируем ошибку в сервисе
|
||||
original_get_or_create = user_service.get_or_create_user
|
||||
user_service.get_or_create_user = AsyncMock(side_effect=Exception("Temporary service error"))
|
||||
|
||||
# Пытаемся выполнить команду (должна обработать ошибку)
|
||||
await user_handlers.handle_rank(mock_update, mock_context)
|
||||
|
||||
# Восстанавливаем сервис
|
||||
user_service.get_or_create_user = original_get_or_create
|
||||
|
||||
# Повторяем команду (теперь должна работать)
|
||||
mock_update.message.reply_text.reset_mock()
|
||||
await user_handlers.handle_rank(mock_update, mock_context)
|
||||
|
||||
# Проверяем, что команда выполнилась успешно после восстановления
|
||||
assert mock_update.message.reply_text.called
|
||||
rank_response = mock_update.message.reply_text.call_args[0][0]
|
||||
assert "Ранг" in rank_response or "🏆" in rank_response
|
||||
|
||||
print("✅ Система корректно восстановилась после ошибки")
|
||||
|
||||
finally:
|
||||
user_repo.close()
|
||||
score_repo.close()
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_cross_feature_integration_scenario(self, temp_config, temp_db, mock_update, mock_context):
|
||||
"""Тест сценария интеграции всех функций"""
|
||||
config = Config(temp_config)
|
||||
user_repo = UserRepository(temp_db)
|
||||
score_repo = ScoreRepository(temp_db)
|
||||
payment_repo = PaymentRepository(temp_db)
|
||||
|
||||
# Инициализируем все компоненты
|
||||
user_service = UserService(user_repo, score_repo)
|
||||
game_service = GameService(user_repo, score_repo)
|
||||
moderation_service = ModerationService(user_repo, score_repo)
|
||||
donation_service = DonationService(payment_repo, config.api_keys)
|
||||
|
||||
user_handlers = UserHandlers(config, user_service)
|
||||
game_handlers = GameHandlers(config, config, game_service, config)
|
||||
moderation_handlers = ModerationHandlers(config, config, user_service, moderation_service)
|
||||
|
||||
try:
|
||||
# === КОМПЛЕКСНЫЙ СЦЕНАРИЙ ===
|
||||
print("Запуск комплексного сценария интеграции всех функций")
|
||||
|
||||
# 1. Регистрация
|
||||
await user_handlers.handle_start(mock_update, mock_context)
|
||||
|
||||
# 2. Игры
|
||||
await game_handlers._handle_play_game(mock_update, mock_context)
|
||||
mock_context.args = ['rock']
|
||||
await game_handlers.handle_rps_choice(mock_update, mock_context)
|
||||
|
||||
# 3. Донаты
|
||||
await user_service.add_donation(mock_update.effective_user.id, 1000.0)
|
||||
|
||||
# 4. Статистика модерации (создаем другого пользователя для теста)
|
||||
target_user_id = 777777777
|
||||
await user_service.get_or_create_user(target_user_id, "target", "Target", "User")
|
||||
|
||||
mock_context.args = [str(target_user_id), "Тест модерации"]
|
||||
await moderation_handlers._handle_warn(mock_update, mock_context, mock_context.args)
|
||||
|
||||
# === ПРОВЕРКИ ИНТЕГРАЦИИ ===
|
||||
|
||||
# Проверяем, что все данные сохранены корректно
|
||||
final_profile = await user_service.get_or_create_user(
|
||||
mock_update.effective_user.id,
|
||||
mock_update.effective_user.username,
|
||||
mock_update.effective_user.first_name,
|
||||
mock_update.effective_user.last_name
|
||||
)
|
||||
|
||||
# Проверяем комплексные данные
|
||||
assert final_profile.reputation >= 10 # Минимум от доната
|
||||
assert final_profile.user_id == mock_update.effective_user.id
|
||||
|
||||
# Проверяем достижения
|
||||
achievements = await user_service.get_user_achievements(mock_update.effective_user.id)
|
||||
assert len(achievements) >= 1
|
||||
|
||||
# Проверяем игры
|
||||
game_stats = game_service.get_game_statistics(mock_update.effective_user.id)
|
||||
assert isinstance(game_stats, dict)
|
||||
|
||||
# Проверяем модерацию
|
||||
moderation_stats = await moderation_service.get_moderation_stats()
|
||||
assert isinstance(moderation_stats, dict)
|
||||
assert moderation_stats['total_warnings'] >= 1
|
||||
|
||||
# Проверяем платежи
|
||||
total_donations = await user_service.get_total_donations(mock_update.effective_user.id, 2025)
|
||||
assert total_donations >= 1000.0
|
||||
|
||||
print("✅ Все компоненты успешно интегрированы и работают вместе")
|
||||
|
||||
finally:
|
||||
user_repo.close()
|
||||
score_repo.close()
|
||||
payment_repo.close()
|
||||
Reference in New Issue
Block a user