mirror of
https://github.com/BEDOLAGA-DEV/remnawave-bedolaga-telegram-bot.git
synced 2026-02-26 14:21:25 +00:00
- Add pyproject.toml with uv and ruff configuration - Pin Python version to 3.13 via .python-version - Add Makefile commands: lint, format, fix - Apply ruff formatting to entire codebase - Remove unused imports (base64 in yookassa/simple_subscription) - Update .gitignore for new config files
140 lines
4.6 KiB
Python
140 lines
4.6 KiB
Python
"""Тесты для MenuLayoutService."""
|
||
|
||
from unittest.mock import MagicMock, patch
|
||
|
||
import pytest
|
||
from aiogram.types import InlineKeyboardButton
|
||
|
||
from app.services.menu_layout.context import MenuContext
|
||
from app.services.menu_layout.service import MenuLayoutService
|
||
|
||
|
||
@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'
|