RemnaWave-bot Update

This commit is contained in:
2026-05-06 15:41:56 +03:00
parent ce7a1f70b2
commit 2cc2f12a21
22 changed files with 3087 additions and 129 deletions

View File

@@ -1,11 +1,20 @@
from __future__ import annotations
from datetime import datetime
from datetime import datetime, timedelta
from sqlalchemy import select
from app.config import Settings
from app.db.models import ReferralCode, ReferralInvite, RemnawaveUser, TelegramUser
from app.db.base import utcnow
from app.db.models import (
PromoCode,
PromoCodeApplication,
ReferralCode,
ReferralInvite,
RemnawaveUser,
TelegramUser,
)
from app.schemas.remnawave import PaginatedUsers
from app.services.sync_service import SyncService
from tests.helpers import make_remote_user
@@ -17,6 +26,10 @@ class _StubRemnawaveClient:
async def get_users_by_telegram_id(self, telegram_id: int):
return list(self.users)
async def get_all_users(self, *, start: int = 0, size: int = 100):
items = list(self.users)[start : start + size]
return PaginatedUsers(users=items, total=len(self.users))
async def test_refresh_cached_users_clears_stale_links_and_keeps_profile(
session_factory,
@@ -206,3 +219,103 @@ async def test_get_admin_telegram_user_profile_returns_referral_and_access_data(
assert profile.recent_invited_names == ["Child User"]
assert len(profile.accesses) == 1
assert profile.accesses[0].record.username == "oreol-profile"
async def test_promo_code_can_be_applied_through_referral_input(session_factory) -> None:
service = SyncService(
settings=Settings.model_construct(
bot_admin_ids_raw="",
sync_subscription_history=False,
),
session_factory=session_factory,
remnawave_client=_StubRemnawaveClient([]),
)
promo = await service.create_promo_code(
code="white50",
plan_code="white",
discount_percent=50,
expires_at=utcnow() + timedelta(days=7),
created_by_telegram_id=1001,
)
applied_code = await service.apply_referral_code(
telegram_id=2001,
username="buyer",
first_name="Buyer",
last_name=None,
language_code="ru",
referral_code="white50",
)
summary = await service.get_referral_summary(2001)
active_promo = await service.get_active_promo_for_user(2001)
assert promo.code == "WHITE50"
assert applied_code == "WHITE50"
assert summary.applied_referral_code == ""
assert summary.applied_promo_code == "WHITE50"
assert summary.applied_promo_discount_percent == 50
assert summary.applied_promo_plan_code == "white"
assert active_promo is not None
assert active_promo.code == "WHITE50"
async with session_factory() as session:
promo_record = await session.scalar(
select(PromoCode).where(PromoCode.code == "WHITE50")
)
application = await session.scalar(
select(PromoCodeApplication).where(PromoCodeApplication.telegram_id == 2001)
)
assert promo_record is not None
assert application is not None
assert application.promo_code_id == promo_record.id
async def test_sync_all_users_does_not_autoflush_half_built_user(
session_factory,
) -> None:
remote_user = make_remote_user(
user_uuid="77777777-7777-7777-7777-777777777777",
user_id=7,
short_uuid="sync-all-user",
username="oreol-sync-all",
telegram_id=4001,
)
service = SyncService(
settings=Settings.model_construct(
bot_admin_ids_raw="",
sync_subscription_history=False,
),
session_factory=session_factory,
remnawave_client=_StubRemnawaveClient([remote_user]),
)
async with session_factory() as session:
session.add(
TelegramUser(
telegram_id=4001,
username="owner",
first_name="Sync",
last_name="Owner",
language_code="ru",
)
)
await session.commit()
total = await service.sync_all_users(batch_size=50)
assert total == 1
async with session_factory() as session:
owner = await session.scalar(
select(TelegramUser).where(TelegramUser.telegram_id == 4001)
)
cached_user = await session.scalar(
select(RemnawaveUser).where(RemnawaveUser.rw_uuid == str(remote_user.uuid))
)
assert owner is not None
assert cached_user is not None
assert cached_user.rw_id == 7
assert cached_user.owner_telegram_user_id == owner.id
assert cached_user.username == "oreol-sync-all"