fix: align traffic top-up flows and unlimited overrides

This commit is contained in:
3252a8
2026-05-31 23:05:29 +03:00
parent df8f2636d2
commit 1578a9da36
13 changed files with 139 additions and 47 deletions
+53
View File
@@ -133,6 +133,59 @@ class AdminGrantTopupTests(unittest.IsolatedAsyncioTestCase):
self.assertIsNone(await service.admin_grant_topup(AsyncMock(), 1, 0))
self.assertIsNone(await service.admin_grant_topup(AsyncMock(), 1, -10))
async def test_regular_unlimited_override_syncs_zero_panel_limit(self):
with tempfile.TemporaryDirectory() as tmpdir:
settings = _make_settings(_tariffs_config_payload(), tmpdir)
panel_service = AsyncMock(spec=PanelApiService)
panel_service.update_user_details_on_panel = AsyncMock(return_value={"response": {}})
service = SubscriptionService(settings, panel_service)
db_user = SimpleNamespace(
user_id=42,
first_name="Tester",
last_name=None,
username="tester",
language_code="ru",
panel_user_uuid="panel-uuid",
email=None,
telegram_id=42,
)
sub = SimpleNamespace(
subscription_id=7,
user_id=42,
panel_user_uuid="panel-uuid",
end_date=datetime.now(timezone.utc) + timedelta(days=10),
tariff_key="standard",
tier_baseline_bytes=100 * (1024**3),
topup_balance_bytes=0,
traffic_limit_bytes=105 * (1024**3),
traffic_used_bytes=2 * (1024**5),
regular_bonus_bytes=0,
regular_unlimited_override=True,
is_throttled=True,
hwid_device_limit=3,
extra_hwid_devices=0,
premium_is_limited=False,
)
with (
patch(
"bot.services.subscription_service.user_dal.get_user_by_id",
new=AsyncMock(return_value=db_user),
),
patch(
"bot.services.subscription_service.subscription_dal.get_active_subscription_by_user_id",
new=AsyncMock(return_value=sub),
),
):
await service.sync_main_traffic_limit_to_panel(AsyncMock(), 42)
self.assertEqual(sub.traffic_limit_bytes, 0)
self.assertFalse(sub.is_throttled)
panel_service.update_user_details_on_panel.assert_awaited_once()
panel_payload = panel_service.update_user_details_on_panel.await_args.args[1]
self.assertEqual(panel_payload["trafficLimitBytes"], 0)
async def test_premium_grant_clears_limited_state_when_balance_covers_overuse(self):
with tempfile.TemporaryDirectory() as tmpdir:
settings = _make_settings(_tariffs_config_payload(premium=True), tmpdir)
+17
View File
@@ -46,6 +46,23 @@ class MiniAppUrlTests(unittest.TestCase):
subscription_mini_app_topup_url(s, "regular"),
"https://app.example.com/webapp?topup=regular",
)
self.assertEqual(
subscription_mini_app_topup_url(s, "premium"),
"https://app.example.com/webapp?topup=premium",
)
def test_subscription_mini_app_topup_url_preserves_existing_query(self):
s = Settings(
_env_file=None,
BOT_TOKEN="x",
POSTGRES_USER="u",
POSTGRES_PASSWORD="p",
SUBSCRIPTION_MINI_APP_URL="https://app.example.com/webapp?lang=ru",
)
self.assertEqual(
subscription_mini_app_topup_url(s, "premium"),
"https://app.example.com/webapp?lang=ru&topup=premium",
)
def test_subscription_mini_app_path_url(self):
s = Settings(
+2 -2
View File
@@ -96,7 +96,7 @@ class SubscriptionServiceCalculationTests(unittest.TestCase):
["fallback-a", "fallback-b"],
)
def test_main_traffic_limit_includes_topup_bonus_and_unlimited_floor(self):
def test_main_traffic_limit_includes_topup_bonus_and_unlimited_zero(self):
with tempfile.TemporaryDirectory() as tmpdir:
settings = _make_settings(_tariffs_config_payload(), tmpdir)
service = _make_service(settings)
@@ -117,7 +117,7 @@ class SubscriptionServiceCalculationTests(unittest.TestCase):
regular_unlimited_override=True,
traffic_used_bytes=2 * (1024**5),
)
self.assertEqual(unlimited_limit, 2 * (1024**5) + 512 * GIB)
self.assertEqual(unlimited_limit, 0)
def test_premium_effective_limit_ignores_negative_balances(self):
self.assertEqual(
+1 -1
View File
@@ -41,7 +41,7 @@ def test_support_ticket_closed_email_uses_user_language():
assert '<html lang="ru"' in content.html
assert "Ticket #7 was closed" not in content.text
assert "Тема: Проблема с подключением" in content.text
assert "Открыть в Mini App" in content.html
assert "Открыть обращение" in content.html
def test_support_admin_email_localizes_snapshot_rows_for_recipient():
+25
View File
@@ -34,6 +34,31 @@ def _tariffs_config_payload() -> dict:
class TariffWorkerTests(unittest.IsolatedAsyncioTestCase):
def test_topup_webapp_button_labels_do_not_mention_mini_app(self):
class I18n:
def gettext(self, _lang, key, **_kwargs):
return {
"traffic_warn_btn_topup_webapp_regular": "Top up traffic",
"traffic_warn_btn_topup_webapp_premium": "Top up premium traffic",
}.get(key, key)
worker = TariffTrafficWorker(
settings=SimpleNamespace(SUBSCRIPTION_MINI_APP_URL="https://app.example.com"),
session_factory=SimpleNamespace(),
panel_service=SimpleNamespace(),
subscription_service=SimpleNamespace(),
bot=SimpleNamespace(),
i18n=I18n(),
)
regular = worker._traffic_topup_markup("en", "regular").inline_keyboard[0][0]
premium = worker._traffic_topup_markup("en", "premium").inline_keyboard[0][0]
self.assertEqual(regular.text, "Top up traffic")
self.assertEqual(regular.web_app.url, "https://app.example.com?topup=regular")
self.assertEqual(premium.text, "Top up premium traffic")
self.assertEqual(premium.web_app.url, "https://app.example.com?topup=premium")
async def test_db_tick_retries_deadlock_once(self):
class FakeSession:
def __init__(self):