Files
bottohelp/test_architecture_integration.py
T

228 lines
11 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Интеграционный тест новой архитектуры обработчиков сообщений.
Проверяет работу всех компонентов в связке.
"""
import asyncio
import sys
import os
# Установка UTF-8 для корректного отображения русского текста и эмодзи
sys.stdout.reconfigure(encoding='utf-8')
sys.stderr.reconfigure(encoding='utf-8')
# Добавление корневой директории в путь
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
async def test_full_integration():
"""Полное тестирование интеграции новой архитектуры"""
print('=== ПОЛНОЕ ТЕСТИРОВАНИЕ ИНТЕГРАЦИИ НОВОЙ АРХИТЕКТУРЫ ===')
print()
try:
# === ШАГ 1: Импорт всех компонентов ===
print('1️⃣ Тестирование импортов...')
from core.menu_manager import create_menu_manager
from core.message_router import create_message_router
from core.unified_router import create_unified_router
from core.command_router import create_command_router
from utils.formatters import KeyboardFormatter
from core.permissions import permission_manager, UserRole
print('✅ Все импорты успешны')
# === ШАГ 2: Создание компонентов ===
print('2️⃣ Создание компонентов системы...')
formatter = KeyboardFormatter()
menu_manager = create_menu_manager(permission_manager, formatter)
message_router = create_message_router()
command_router = create_command_router(None, None)
unified_router = create_unified_router(command_router, message_router, menu_manager)
print('✅ Все компоненты созданы')
# === ШАГ 3: Тестирование системы меню ===
print('3️⃣ Тестирование системы меню...')
# Проверка доступных меню для разных ролей
user_menus = menu_manager.get_available_menus_for_role(UserRole.USER)
admin_menus = menu_manager.get_available_menus_for_role(UserRole.ADMIN)
super_admin_menus = menu_manager.get_available_menus_for_role(UserRole.SUPER_ADMIN)
print(f' Меню для USER: {len(user_menus)}')
print(f' Меню для ADMIN: {len(admin_menus)}')
print(f' Меню для SUPER_ADMIN: {len(super_admin_menus)}')
# Проверка наличия ключевых меню
assert 'menu_main' in user_menus, 'menu_main должно быть доступно для USER'
assert 'menu_admin' in admin_menus, 'menu_admin должно быть доступно для ADMIN'
assert 'admin_system' in super_admin_menus, 'admin_system должно быть доступно для SUPER_ADMIN'
# Тестирование создания меню
main_menu = await menu_manager.get_menu_for_user('menu_main', UserRole.USER)
assert main_menu is not None, 'Главное меню должно быть создано'
assert hasattr(main_menu, 'inline_keyboard'), 'Меню должно иметь inline_keyboard'
admin_menu = await menu_manager.get_menu_for_user('menu_admin', UserRole.ADMIN)
assert admin_menu is not None, 'Админ меню должно быть создано'
# Проверка отказа в доступе
forbidden_menu = await menu_manager.get_menu_for_user('menu_admin', UserRole.USER)
assert forbidden_menu is None, 'USER не должен иметь доступ к admin меню'
print('✅ Система меню работает корректно')
# === ШАГ 4: Тестирование маршрутизации сообщений ===
print('4️⃣ Тестирование маршрутизации сообщений...')
# Регистрация тестовых обработчиков
call_count = {'text': 0, 'callback': 0, 'voice': 0}
async def test_text_handler(update, context):
call_count['text'] += 1
print(' 📝 Текстовый обработчик вызван')
async def test_callback_handler(update, context):
call_count['callback'] += 1
print(' 🔘 Callback обработчик вызван')
async def test_voice_handler(update, context):
call_count['voice'] += 1
print(' 🎤 Голосовой обработчик вызван')
# Регистрация обработчиков
message_router.register_text_handler(r'hello.*', test_text_handler, UserRole.USER)
message_router.register_callback_handler('test_', test_callback_handler, UserRole.USER)
message_router.register_media_handler('voice', test_voice_handler, UserRole.USER)
print(' ✅ Обработчики зарегистрированы')
# === ШАГ 5: Тестирование статистики ===
print('5️⃣ Тестирование статистики системы...')
stats = unified_router.get_registered_handlers_count()
expected_total = 2 + 1 + 1 # command + callback + voice (text=1, но мы не считаем его отдельно в старом формате)
print(f' Зарегистрировано обработчиков: {stats}')
assert stats['total'] >= 3, f'Должно быть минимум 3 обработчика, получено {stats["total"]}'
print(' ✅ Статистика корректна')
# === ШАГ 6: Тестирование интеграции с Application ===
print('6️⃣ Тестирование интеграции с Application...')
from core.application import Application
from core.config import Config
# Создание облегченной версии Application для тестирования
config = Config()
app = Application.__new__(Application)
app.config = config
# Инициализация компонентов (имитация _initialize_unified_router)
app.command_router = create_command_router(config, None)
app.message_router = create_message_router()
app.menu_manager = create_menu_manager(permission_manager, KeyboardFormatter())
from core.unified_router import create_unified_router
app.unified_router = create_unified_router(
app.command_router, app.message_router, app.menu_manager
)
# Проверка регистрации стандартных команд
app._register_command_handlers()
app._register_message_handlers()
app._register_callback_handlers()
app_stats = app.unified_router.get_registered_handlers_count()
print(f' Статистика Application: {app_stats}')
assert app_stats['command_handlers'] > 0, 'Должны быть зарегистрированы команды'
assert app_stats['total'] > 5, 'Общее количество обработчиков должно быть > 5'
print(' ✅ Интеграция с Application успешна')
# === ШАГ 7: Тестирование кеширования ===
print('7️⃣ Тестирование кеширования...')
# Создание меню несколько раз для проверки кеширования
menu1 = await menu_manager.get_menu_for_user('menu_main', UserRole.USER)
menu2 = await menu_manager.get_menu_for_user('menu_main', UserRole.USER)
assert menu1 is not None and menu2 is not None, 'Меню должны создаваться'
# В реальной системе кеш должен возвращать один и тот же объект
# Очистка кеша
menu_manager.clear_cache()
print(' ✅ Кеширование работает')
# === ШАГ 8: Финальные проверки ===
print('8️⃣ Финальные проверки...')
# Проверка разделения по уровням
user_level_menus = menu_manager.get_menus_by_level('user')
admin_level_menus = menu_manager.get_menus_by_level('admin')
assert len(user_level_menus) > 0, 'Должны быть меню уровня user'
assert len(admin_level_menus) > 0, 'Должны быть меню уровня admin'
assert 'menu_main' in user_level_menus, 'menu_main должно быть в user level'
assert 'menu_admin' in admin_level_menus, 'menu_admin должно быть в admin level'
print(' ✅ Разделение по уровням корректно')
print()
print('=== 🎉 ВСЕ ТЕСТЫ ПРОШЛИ УСПЕШНО! ===')
print()
print('📊 РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ:')
print(f' • Меню для пользователей: {len(user_menus)}')
print(f' • Меню для администраторов: {len(admin_menus)}')
print(f' • Меню для супер-администраторов: {len(super_admin_menus)}')
print(f' • Всего обработчиков: {stats["total"]}')
print(f' • Команд: {stats["command_handlers"]}')
print(f' • Callback\'ов: {stats["callback_handlers"]}')
print()
print('🏆 НОВАЯ АРХИТЕКТУРА ГОТОВА К ПРОМЫШЛЕННОМУ ИСПОЛЬЗОВАНИЮ!')
print()
print('📋 СЛЕДУЮЩИЕ ШАГИ:')
print(' 1. 🚀 Запустите: python -m pytest tests/test_core/ -v')
print(' 2. 📖 Изучите: MIGRATION_GUIDE.md')
print(' 3. 🧪 Протестируйте в staging среде')
print(' 4. 🚀 Начните постепенную миграцию')
print(' 5. 📊 Мониторьте производительность')
return True
except Exception as e:
print(f'❌ КРИТИЧЕСКАЯ ОШИБКА В ТЕСТИРОВАНИИ: {e}')
import traceback
traceback.print_exc()
return False
async def main():
"""Главная функция"""
success = await test_full_integration()
if success:
print()
print('=' * 60)
print('✅ ИНТЕГРАЦИОННОЕ ТЕСТИРОВАНИЕ ЗАВЕРШЕНО УСПЕШНО')
print('✅ НОВАЯ АРХИТЕКТУРА ОБРАБОТЧИКОВ ГОТОВА К РАЗВЕРТЫВАНИЮ')
print('=' * 60)
sys.exit(0)
else:
print()
print('=' * 60)
print('❌ ТЕСТИРОВАНИЕ ПРОВАЛЕНО')
print('❌ ТРЕБУЕТСЯ ИСПРАВЛЕНИЕ ОШИБОК')
print('=' * 60)
sys.exit(1)
if __name__ == '__main__':
asyncio.run(main())