from datetime import datetime, timezone from types import SimpleNamespace from unittest import IsolatedAsyncioTestCase from unittest.mock import AsyncMock, patch from bot.services.promo_code_service import PromoCodeService class PromoCodeServiceTests(IsolatedAsyncioTestCase): async def test_apply_promo_passes_default_tariff_for_new_bonus_subscription(self): end_date = datetime(2026, 1, 8, tzinfo=timezone.utc) settings = SimpleNamespace( MIGRATION_REMNASHOP_PROMO_CODE_COMPAT_ENABLED=False, BRUTE_FORCE_LOCK_SECONDS=60, BRUTE_FORCE_MAX_FAILURES=5, BRUTE_FORCE_WINDOW_SECONDS=300, tariffs_config=SimpleNamespace(default_tariff="standard"), ) subscription_service = SimpleNamespace( extend_active_subscription_days=AsyncMock(return_value=end_date) ) i18n = SimpleNamespace(gettext=lambda lang, key, **kw: key) service = PromoCodeService(settings, subscription_service, AsyncMock(), i18n) session = AsyncMock() promo = SimpleNamespace( promo_code_id=5, code="HELLO", bonus_days=7, ) with ( patch( "bot.services.promo_code_service.security_dal.check_throttle", AsyncMock(return_value=SimpleNamespace(locked=False, retry_after=None)), ), patch( "bot.services.promo_code_service.promo_code_dal.get_active_promo_code_by_code_str", AsyncMock(return_value=promo), ), patch( "bot.services.promo_code_service.promo_code_dal.get_user_activation_for_promo", AsyncMock(return_value=None), ), patch( "bot.services.promo_code_service.promo_code_dal.record_promo_activation", AsyncMock(return_value=True), ), patch( "bot.services.promo_code_service.promo_code_dal.increment_promo_code_usage", AsyncMock(return_value=True), ), patch( "bot.services.promo_code_service.security_dal.clear_throttle_state", AsyncMock(), ), patch( "bot.services.promo_code_service.NotificationService", return_value=SimpleNamespace(notify_promo_activation=AsyncMock()), ), patch( "bot.services.promo_code_service.user_dal.get_user_by_id", AsyncMock(return_value=None), ), ): success, result = await service.apply_promo_code( session=session, user_id=42, code_input="hello", user_lang="en", ) self.assertTrue(success) self.assertEqual(result, end_date) subscription_service.extend_active_subscription_days.assert_awaited_once_with( session=session, user_id=42, bonus_days=7, reason="promo code HELLO", tariff_key="standard", )