mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-01-20 11:50:27 +00:00
140 lines
4.7 KiB
Python
140 lines
4.7 KiB
Python
"""Тесты для MenuLayoutService."""
|
||
|
||
import pytest
|
||
from unittest.mock import AsyncMock, MagicMock, patch
|
||
from aiogram.types import InlineKeyboardButton
|
||
|
||
from app.services.menu_layout.service import MenuLayoutService
|
||
from app.services.menu_layout.context import MenuContext
|
||
|
||
|
||
@pytest.mark.anyio
|
||
async def test_build_button_connect_direct_mode_with_url():
|
||
"""Тест: кнопка connect с open_mode=direct и валидным URL должна создавать WebAppInfo."""
|
||
button_config = {
|
||
"type": "builtin",
|
||
"builtin_id": "connect",
|
||
"text": {"ru": "🔗 Подключиться"},
|
||
"action": "subscription_connect",
|
||
"open_mode": "direct",
|
||
"webapp_url": "https://example.com/miniapp",
|
||
}
|
||
|
||
context = MenuContext(
|
||
language="ru",
|
||
has_active_subscription=True,
|
||
subscription_is_active=True,
|
||
)
|
||
|
||
texts = MagicMock()
|
||
texts.t = lambda key, default: default
|
||
|
||
button = MenuLayoutService._build_button(button_config, context, texts)
|
||
|
||
assert button is not None
|
||
assert isinstance(button, InlineKeyboardButton)
|
||
assert button.web_app is not None
|
||
assert button.web_app.url == "https://example.com/miniapp"
|
||
assert button.callback_data is None
|
||
|
||
|
||
@pytest.mark.anyio
|
||
async def test_build_button_connect_direct_mode_with_subscription_url():
|
||
"""Тест: кнопка connect с open_mode=direct должна получать URL из подписки."""
|
||
button_config = {
|
||
"type": "builtin",
|
||
"builtin_id": "connect",
|
||
"text": {"ru": "🔗 Подключиться"},
|
||
"action": "subscription_connect",
|
||
"open_mode": "direct",
|
||
"webapp_url": None,
|
||
}
|
||
|
||
# Мокаем подписку с URL
|
||
mock_subscription = MagicMock()
|
||
mock_subscription.subscription_url = "https://subscription.example.com/link"
|
||
mock_subscription.subscription_crypto_link = None
|
||
|
||
context = MenuContext(
|
||
language="ru",
|
||
has_active_subscription=True,
|
||
subscription_is_active=True,
|
||
subscription=mock_subscription,
|
||
)
|
||
|
||
texts = MagicMock()
|
||
texts.t = lambda key, default: default
|
||
|
||
with patch('app.utils.subscription_utils.get_display_subscription_link') as mock_get_link:
|
||
mock_get_link.return_value = "https://subscription.example.com/link"
|
||
|
||
button = MenuLayoutService._build_button(button_config, context, texts)
|
||
|
||
assert button is not None
|
||
assert isinstance(button, InlineKeyboardButton)
|
||
assert button.web_app is not None
|
||
assert button.web_app.url == "https://subscription.example.com/link"
|
||
|
||
|
||
@pytest.mark.anyio
|
||
async def test_build_button_connect_callback_mode():
|
||
"""Тест: кнопка connect с open_mode=callback должна создавать callback кнопку."""
|
||
button_config = {
|
||
"type": "builtin",
|
||
"builtin_id": "connect",
|
||
"text": {"ru": "🔗 Подключиться"},
|
||
"action": "subscription_connect",
|
||
"open_mode": "callback",
|
||
"webapp_url": None,
|
||
}
|
||
|
||
context = MenuContext(
|
||
language="ru",
|
||
has_active_subscription=True,
|
||
subscription_is_active=True,
|
||
)
|
||
|
||
texts = MagicMock()
|
||
texts.t = lambda key, default: default
|
||
|
||
button = MenuLayoutService._build_button(button_config, context, texts)
|
||
|
||
assert button is not None
|
||
assert isinstance(button, InlineKeyboardButton)
|
||
assert button.callback_data == "subscription_connect"
|
||
assert button.web_app is None
|
||
|
||
|
||
@pytest.mark.anyio
|
||
async def test_build_button_connect_direct_mode_fallback_to_callback():
|
||
"""Тест: кнопка connect с open_mode=direct без URL должна fallback на callback."""
|
||
button_config = {
|
||
"type": "builtin",
|
||
"builtin_id": "connect",
|
||
"text": {"ru": "🔗 Подключиться"},
|
||
"action": "subscription_connect",
|
||
"open_mode": "direct",
|
||
"webapp_url": None,
|
||
}
|
||
|
||
context = MenuContext(
|
||
language="ru",
|
||
has_active_subscription=True,
|
||
subscription_is_active=True,
|
||
subscription=None, # Нет подписки
|
||
)
|
||
|
||
texts = MagicMock()
|
||
texts.t = lambda key, default: default
|
||
|
||
with patch('app.services.menu_layout.service.settings') as mock_settings:
|
||
mock_settings.MINIAPP_CUSTOM_URL = None
|
||
|
||
button = MenuLayoutService._build_button(button_config, context, texts)
|
||
|
||
assert button is not None
|
||
assert isinstance(button, InlineKeyboardButton)
|
||
# Должен fallback на callback_data, так как URL не найден
|
||
assert button.callback_data == "subscription_connect"
|
||
|