Files
remnawave-bedolaga-telegram…/tests/services/test_menu_layout_service.py
c0mrade 9a2aea038a chore: add uv package manager and ruff linter configuration
- 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
2026-01-24 17:45:27 +03:00

140 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Тесты для 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'