fix: use reply keyboard for subscription purchase

This commit is contained in:
admin committed 2026-10-12 21:14:58 +02:00
1 parent aba1eb4ced
commit 073c7d2c81
4 files changed
+89 -33

No files matched your search

+51 -8
View File
@@ -49,6 +49,13 @@ class ButtonTextTests(unittest.TestCase):
def test_generate_post_button_maps_to_post_command(self):
self.assertEqual(keyboards.resolve_button_text(keyboards.POST_GENERATE_BUTTON), "/post")
def test_subscription_actions_map_to_internal_action(self):
for label in (keyboards.BUY_SUBSCRIPTION_BUTTON, keyboards.RENEW_SUBSCRIPTION_BUTTON):
self.assertEqual(
keyboards.resolve_button_text(label),
keyboards.SUBSCRIPTION_ACTION_VALUE,
)
def test_regular_text_is_not_treated_as_button(self):
self.assertIsNone(keyboards.resolve_button_text("Напиши пост про запуск"))
self.assertIsNone(keyboards.resolve_button_text("привет"))
@@ -74,8 +81,18 @@ class KeyboardLayoutTests(unittest.TestCase):
expected.insert(0, keyboards.POST_GENERATE_BUTTON)
elif mode == "help":
expected.insert(0, keyboards.SUPPORT_BUTTON)
elif mode == "subscription":
expected.insert(0, keyboards.BUY_SUBSCRIPTION_BUTTON)
self.assertEqual(labels, expected, mode)
def test_subscription_keyboard_uses_renew_label_after_paid_subscription(self):
labels = [
button.text
for row in keyboards.mode_keyboard("subscription", subscription_purchased=True).keyboard
for button in row
]
self.assertEqual(labels, [keyboards.RENEW_SUBSCRIPTION_BUTTON, keyboards.MAIN_MENU_BUTTON])
def test_support_keyboard_keeps_only_main_menu(self):
for mode in bot.MODE_STATES:
labels = [
@@ -211,7 +228,7 @@ class ModeRoutingTests(unittest.IsolatedAsyncioTestCase):
await bot.handle_text(message, state)
self.assertEqual(await state.get_state(), bot.BotMode.help.state)
async def test_subscription_entry_shows_status_and_renew_button(self):
async def test_subscription_entry_shows_buy_reply_button_without_purchase(self):
message = _StubMessage("💳 Подписка")
state = _StubState("lobby")
with (
@@ -222,14 +239,40 @@ class ModeRoutingTests(unittest.IsolatedAsyncioTestCase):
self.assertEqual(await state.get_state(), bot.BotMode.subscription.state)
self.assertEqual(len(message.answers), 2)
mode_keyboard = message.answers[0][1]["reply_markup"]
self.assertEqual(message.answers[0][1]["reply_markup"].keyboard[0][0].text, keyboards.MAIN_MENU_BUTTON)
initial_keyboard = message.answers[0][1]["reply_markup"]
self.assertEqual(initial_keyboard.keyboard[0][0].text, keyboards.BUY_SUBSCRIPTION_BUTTON)
self.assertIn("Подписка не активирована", message.answers[1][0])
renew_keyboard = message.answers[1][1]["reply_markup"]
self.assertEqual(
renew_keyboard.inline_keyboard[0][0].callback_data,
"subscription:renew",
)
buy_keyboard = message.answers[1][1]["reply_markup"]
self.assertFalse(hasattr(buy_keyboard, "inline_keyboard"))
self.assertEqual(buy_keyboard.keyboard[0][0].text, keyboards.BUY_SUBSCRIPTION_BUTTON)
async def test_subscription_status_uses_renew_button_after_previous_payment(self):
message = _StubMessage()
sub = {"last_paid_at": "2026-01-01T00:00:00", "expires_at": "2026-02-01T00:00:00", "is_active": 1}
with patch.object(bot.user_store, "_days_until", return_value=0):
await bot._show_subscription_info(cast(Any, message), cast(Any, sub))
markup = message.answers[0][1]["reply_markup"]
self.assertFalse(hasattr(markup, "inline_keyboard"))
self.assertEqual(markup.keyboard[0][0].text, keyboards.RENEW_SUBSCRIPTION_BUTTON)
async def test_subscription_action_button_sends_invoice_in_subscription_mode(self):
message = _StubMessage(keyboards.BUY_SUBSCRIPTION_BUTTON)
with (
patch.object(bot, "notify_development_deploy", new=AsyncMock()),
patch.object(bot, "_send_subscription_invoice", new=AsyncMock()) as send_invoice,
):
await bot.handle_text(message, _StubState("subscription"))
send_invoice.assert_awaited_once_with(message, 42)
async def test_subscription_action_button_is_rejected_outside_subscription_mode(self):
message = _StubMessage(keyboards.RENEW_SUBSCRIPTION_BUTTON)
with (
patch.object(bot, "notify_development_deploy", new=AsyncMock()),
patch.object(bot, "_send_subscription_invoice", new=AsyncMock()) as send_invoice,
):
await bot.handle_text(message, _StubState("generation"))
send_invoice.assert_not_awaited()
self.assertIn("только в режиме «Подписка»", message.answers[0][0])
async def test_renew_callback_sends_invoice_without_intermediate_message(self):
message_bot = AsyncMock()
+2 -2
View File
@@ -1016,8 +1016,8 @@ class SubscriptionTests(unittest.IsolatedAsyncioTestCase):
self.assertIn("пробный период", message.answer.call_args.args[0].lower())
renew_markup = message.answer.call_args.kwargs["reply_markup"]
self.assertEqual(
renew_markup.inline_keyboard[0][0].callback_data,
"subscription:renew",
renew_markup.keyboard[0][0].text,
"🛒 Купить подписку",
)
async def test_blocked_when_subscription_expired(self):