Files
RemnaWaveBOT/tests/test_panel_ui.py
2026-05-06 15:41:56 +03:00

474 lines
14 KiB
Python
Raw Permalink 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.
from datetime import datetime, timedelta
from types import SimpleNamespace
from app.bot.ui.panel import (
PANEL_SECTION_ADMIN,
PANEL_SECTION_HOME,
PANEL_SECTION_REFERRAL,
PANEL_SECTION_SUBSCRIPTION,
PANEL_SECTION_SUPPORT,
PANEL_SECTION_TERMS,
PanelContext,
build_panel_keyboard,
render_panel_caption,
)
from app.services.sync_service import CachedUserView
def _button_texts(markup) -> list[str]:
return [button.text for row in markup.inline_keyboard for button in row]
def _cached_user_view(*, telegram_id: int = 123456789) -> CachedUserView:
return CachedUserView(
record=SimpleNamespace(
username="oreol-renew",
status="ACTIVE",
expire_at=datetime.now() + timedelta(days=10),
used_traffic_bytes=0,
traffic_limit_bytes=0,
short_uuid="renew999",
subscription_url="https://example.com/sub/renew999",
telegram_id=telegram_id,
),
internal_squads=["VPN"],
)
def test_home_panel_caption_without_subscription() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
api_error=None,
)
caption = render_panel_caption(
section=PANEL_SECTION_HOME,
context=context,
brand_name="OREOL VPN",
)
assert "Добро пожаловать в <b>OREOL VPN</b>" in caption
assert "<b>Профиль</b>" not in caption
assert "<b>Подписка</b>" in caption
assert "Статус: <b>Не активна</b>" in caption
assert "Срок: <b>—</b>" in caption
assert "Трафик: <b>—</b>" in caption
def test_home_panel_keyboard_has_expected_buttons() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
api_error=None,
)
markup = build_panel_keyboard(section=PANEL_SECTION_HOME, context=context)
button_texts = _button_texts(markup)
assert "Профиль" not in button_texts
assert "💳 Подписка" in button_texts
assert "🆘 Поддержка" in button_texts
assert "👥 Реферальная система" in button_texts
assert "📜 Условия использования" in button_texts
assert len(markup.inline_keyboard[0]) == 1
assert markup.inline_keyboard[0][0].text == "💳 Подписка"
assert markup.inline_keyboard[0][0].callback_data == "payment:menu"
def test_admin_home_panel_keyboard_has_admin_button() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=True,
users=[],
api_error=None,
)
markup = build_panel_keyboard(section=PANEL_SECTION_HOME, context=context)
button_texts = _button_texts(markup)
assert "🛠 Админ-панель" in button_texts
assert len(markup.inline_keyboard[1]) == 1
assert markup.inline_keyboard[1][0].text == "🛠 Админ-панель"
assert markup.inline_keyboard[1][0].callback_data == "panel:admin"
def test_admin_panel_caption_contains_dashboard_stats() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=True,
users=[],
admin_total_telegram_users=120,
admin_total_cached_users=80,
admin_active_cached_users=67,
admin_pending_orders=9,
admin_review_orders=4,
admin_open_tickets=3,
admin_pending_referral_bonuses=2,
api_error=None,
)
caption = render_panel_caption(
section=PANEL_SECTION_ADMIN,
context=context,
brand_name="OREOL VPN",
)
assert "<b>🛠 Админ-панель OREOL VPN</b>" in caption
assert "Пользователей в боте: <b>120</b>" in caption
assert "Чеков на проверке: <b>4</b>" in caption
assert "Открытых тикетов: <b>3</b>" in caption
assert "Бонусов в ожидании: <b>2</b>" in caption
def test_admin_panel_keyboard_has_expected_buttons() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=True,
users=[],
api_error=None,
)
markup = build_panel_keyboard(
section=PANEL_SECTION_ADMIN,
context=context,
payment_review_url="https://t.me/c/123/56/57",
support_ticket_url="https://t.me/c/123/2/3",
)
button_texts = _button_texts(markup)
assert "🔍 Найти пользователя" in button_texts
assert "👤 Пользователи" in button_texts
assert "🔄 Полная синхронизация" in button_texts
assert "💸 Очередь оплат" in button_texts
assert "🗂 История тикетов" in button_texts
assert "🎫 Чат тикетов" in button_texts
assert "↻ Обновить" in button_texts
assert "🏠 Главное меню" in button_texts
def test_subscription_caption_without_subscription_but_with_payment() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
payment_enabled=True,
payment_plan_title="OREOL VPN на 30 дней",
payment_plan_description="Доступ к VPN на 30 дней",
payment_plan_price_stars=250,
payment_plan_duration_days=30,
payment_plan_traffic_limit_bytes=0,
api_error=None,
)
caption = render_panel_caption(
section=PANEL_SECTION_SUBSCRIPTION,
context=context,
brand_name="OREOL VPN",
)
assert "У вас пока нет активного доступа." in caption
assert "OREOL VPN на 30 дней" in caption
assert "Цена: <b>250 ₽</b>" in caption
assert "После выбора тарифа бот покажет реквизиты" in caption
def test_subscription_caption_without_payment_uses_ui_instructions() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
payment_enabled=False,
api_error=None,
)
caption = render_panel_caption(
section=PANEL_SECTION_SUBSCRIPTION,
context=context,
brand_name="OREOL VPN",
)
assert "откройте поддержку" in caption
assert "short UUID" in caption
assert "/link" not in caption
def test_subscription_keyboard_has_buy_button() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
payment_enabled=True,
api_error=None,
)
markup = build_panel_keyboard(section=PANEL_SECTION_SUBSCRIPTION, context=context)
button_texts = _button_texts(markup)
assert "💳 Купить подписку" in button_texts
assert "🏠 Главное меню" in button_texts
def test_subscription_keyboard_has_renew_button_when_access_exists() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[_cached_user_view()],
payment_enabled=True,
api_error=None,
)
markup = build_panel_keyboard(section=PANEL_SECTION_SUBSCRIPTION, context=context)
button_texts = _button_texts(markup)
assert "💳 Продлить подписку" in button_texts
assert "💳 Купить подписку" not in button_texts
def test_subscription_caption_with_existing_access_mentions_renewal() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[_cached_user_view()],
payment_enabled=True,
api_error=None,
)
caption = render_panel_caption(
section=PANEL_SECTION_SUBSCRIPTION,
context=context,
brand_name="OREOL VPN",
)
assert "Продлить подписку" in caption
assert "автоматически добавит выбранный срок" in caption
def test_terms_panel_caption() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
api_error=None,
)
caption = render_panel_caption(
section=PANEL_SECTION_TERMS,
context=context,
brand_name="OREOL VPN",
)
assert "<b>📜 Правила VPN</b>" in caption
assert "использовать VPN только в законных целях" in caption
assert "не гарантирует полной анонимности" in caption
def test_support_panel_has_create_ticket_button() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
api_error=None,
)
markup = build_panel_keyboard(section=PANEL_SECTION_SUPPORT, context=context)
button_texts = _button_texts(markup)
assert "🎫 Создать тикет" in button_texts
assert "🏠 Главное меню" in button_texts
def test_support_panel_has_support_url_button() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
api_error=None,
)
markup = build_panel_keyboard(
section=PANEL_SECTION_SUPPORT,
context=context,
support_url="https://t.me/support_account",
)
button_texts = _button_texts(markup)
assert "Написать в поддержку" in button_texts
def test_support_panel_caption() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
api_error=None,
)
caption = render_panel_caption(
section=PANEL_SECTION_SUPPORT,
context=context,
brand_name="OREOL VPN",
)
assert "<b>🆘 Помощь и сопровождение</b>" in caption
assert "откройте тикет через кнопку ниже" in caption
def test_referral_panel_caption_with_link() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
referral_code="ABCD1234",
referral_count=3,
referral_link="https://t.me/oreol_vpn_bot?start=ref_ABCD1234",
referral_share_url="https://t.me/share/url?url=test",
referral_recent_names=["Alex", "Maria"],
referral_discount_percent=12,
referral_bonus_days=7,
api_error=None,
)
caption = render_panel_caption(
section=PANEL_SECTION_REFERRAL,
context=context,
brand_name="OREOL VPN",
)
assert "<b>👥 Реферальная система</b>" in caption
assert "Ваш реферальный код: <code>ABCD1234</code>" in caption
assert "Приглашено пользователей: <b>3</b>" in caption
assert "+7 дней" in caption
assert "Чтобы получить скидку 12%" in caption
assert "https://t.me/oreol_vpn_bot?start=ref_ABCD1234" in caption
assert "Alex" in caption
assert "Maria" in caption
def test_referral_caption_uses_runtime_discount_for_applied_code() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
referral_code="ABCD1234",
referral_count=1,
applied_referral_code="PROMO777",
referral_discount_percent=17,
api_error=None,
)
caption = render_panel_caption(
section=PANEL_SECTION_REFERRAL,
context=context,
brand_name="OREOL VPN",
)
assert "Код: <code>PROMO777</code>" in caption
assert "Скидка перед оплатой: <b>17%</b>" in caption
def test_admin_panel_keyboard_has_settings_button() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=True,
users=[],
api_error=None,
)
markup = build_panel_keyboard(section=PANEL_SECTION_ADMIN, context=context)
button_texts = _button_texts(markup)
assert any("Настрой" in text for text in button_texts)
def test_home_panel_hides_referral_when_disabled() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
referral_enabled=False,
api_error=None,
)
markup = build_panel_keyboard(section=PANEL_SECTION_HOME, context=context)
button_texts = _button_texts(markup)
assert all("Реферал" not in text for text in button_texts)
def test_referral_panel_caption_when_disabled() -> None:
context = PanelContext(
telegram_id=123456789,
display_name="Evgeniy Spirin",
username="evgeniy",
language_code="ru",
is_admin=False,
users=[],
referral_enabled=False,
api_error=None,
)
caption = render_panel_caption(
section=PANEL_SECTION_REFERRAL,
context=context,
brand_name="OREOL VPN",
)
assert "отключена" in caption