feature: Add local subscription notification worker
This commit is contained in:
@@ -271,3 +271,14 @@ class SettingsTests(unittest.TestCase):
|
||||
)
|
||||
|
||||
self.assertEqual(settings.tariff_traffic_warning_levels, [85, 90, 95])
|
||||
|
||||
def test_subscription_hour_notification_default_is_available(self):
|
||||
settings = Settings(
|
||||
_env_file=None,
|
||||
BOT_TOKEN="token",
|
||||
POSTGRES_USER="app_user",
|
||||
POSTGRES_PASSWORD="app_password",
|
||||
)
|
||||
|
||||
self.assertEqual(settings.SUBSCRIPTION_NOTIFY_HOURS_BEFORE, 3)
|
||||
self.assertEqual(settings.SUBSCRIPTION_NOTIFICATION_WORKER_TICK_SECONDS, 300)
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from types import SimpleNamespace
|
||||
|
||||
from bot.services.subscription_notification_worker import SubscriptionNotificationWorker
|
||||
|
||||
|
||||
def _worker(**overrides):
|
||||
settings = SimpleNamespace(
|
||||
SUBSCRIPTION_NOTIFY_DAYS_BEFORE=3,
|
||||
SUBSCRIPTION_NOTIFY_HOURS_BEFORE=3,
|
||||
SUBSCRIPTION_NOTIFY_ON_EXPIRE=True,
|
||||
SUBSCRIPTION_NOTIFY_AFTER_EXPIRE=True,
|
||||
SUBSCRIPTION_NOTIFICATION_WORKER_TICK_SECONDS=300,
|
||||
**overrides,
|
||||
)
|
||||
return SubscriptionNotificationWorker(
|
||||
settings=settings,
|
||||
session_factory=object(),
|
||||
bot=object(),
|
||||
i18n=object(),
|
||||
panel_service=object(),
|
||||
subscription_service=object(),
|
||||
)
|
||||
|
||||
|
||||
def _sub(end_date):
|
||||
return SimpleNamespace(end_date=end_date)
|
||||
|
||||
|
||||
def test_stage_prefers_hour_reminder_over_day_backlog():
|
||||
now = datetime(2026, 5, 28, 12, tzinfo=timezone.utc)
|
||||
stage = _worker().stage_for_subscription(_sub(now + timedelta(hours=2, minutes=30)), now)
|
||||
|
||||
assert stage.key == "before_3h"
|
||||
assert stage.message_key == "subscription_hours_notification"
|
||||
assert stage.hours_before == 3
|
||||
|
||||
|
||||
def test_stage_uses_most_imminent_day_reminder():
|
||||
now = datetime(2026, 5, 28, 12, tzinfo=timezone.utc)
|
||||
stage = _worker().stage_for_subscription(_sub(now + timedelta(hours=23)), now)
|
||||
|
||||
assert stage.key == "before_1d"
|
||||
assert stage.message_key == "subscription_24h_notification"
|
||||
|
||||
|
||||
def test_stage_sends_expired_during_first_day_after_end():
|
||||
now = datetime(2026, 5, 28, 12, tzinfo=timezone.utc)
|
||||
stage = _worker().stage_for_subscription(_sub(now - timedelta(hours=1)), now)
|
||||
|
||||
assert stage.key == "expired"
|
||||
assert stage.message_key == "subscription_expired_notification"
|
||||
|
||||
|
||||
def test_stage_sends_yesterday_notice_only_after_first_day():
|
||||
now = datetime(2026, 5, 28, 12, tzinfo=timezone.utc)
|
||||
stage = _worker().stage_for_subscription(_sub(now - timedelta(hours=25)), now)
|
||||
|
||||
assert stage.key == "expired_24h_after"
|
||||
assert stage.message_key == "subscription_expired_yesterday_notification"
|
||||
@@ -83,6 +83,10 @@ class UserDalMergeTests(unittest.IsolatedAsyncioTestCase):
|
||||
delete_tables.index("traffic_warnings"),
|
||||
delete_tables.index("subscriptions"),
|
||||
)
|
||||
self.assertLess(
|
||||
delete_tables.index("subscription_notifications"),
|
||||
delete_tables.index("subscriptions"),
|
||||
)
|
||||
self.assertLess(
|
||||
delete_tables.index("promo_code_activations"),
|
||||
delete_tables.index("payments"),
|
||||
|
||||
Reference in New Issue
Block a user