Тексты воронки по ТЗ + смена ссылок из админки

Тексты:
- «Сколько лет игроку?» (было «…будущему ученику?») во всех местах;
- сообщение для «Младше 12 лет» приведено дословно к ТЗ (§4);
- убраны отсебятины-преамбулы, которых нет в ТЗ (приветствие, старт воронки,
  цены «Что дальше?», интенсив «Хотите записаться?»); кнопка младше-12 «Вернуться назад».

Смена ссылок в админке:
- таблица bot_links (key, url) + методы get_link/get_all_links/set_link;
- _link(key): БД-переопределение → дефолт из config/.env; используется на шагах оплаты;
- раздел «Ссылки 🔗» в админ-панели: список текущих адресов + «✏️ Изменить ссылку»
  (выбор из 8 кнопок → ввод URL с валидацией http/https). UTM добавляются автоматически.

Тесты: добавлен test_admin_edit_link. pytest 31 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kenik
2026-07-23 19:45:47 +03:00
parent fac2e3808b
commit 261e5c2da0
5 changed files with 144 additions and 17 deletions
+14
View File
@@ -139,6 +139,20 @@ def _admin():
return bot.config.SUPER_ADMIN_IDS[0]
def test_admin_edit_link(app):
"""Админ меняет ссылку кнопки → сохраняется в БД и подхватывается ботом."""
a = _admin()
app.handle_message(a, "Ссылки 🔗")
app.handle_message(a, "✏️ Изменить ссылку")
app.handle_message(a, "group_4. Групповой абонемент — 4 занятия")
app.handle_message(a, "не-ссылка") # отклоняется валидацией
assert bot.db.get_link("group_4") is None
app.handle_message(a, "https://infocyber.pro/pay/group4")
assert bot.db.get_link("group_4") == "https://infocyber.pro/pay/group4"
# бот отдаёт обновлённую ссылку (с UTM)
assert app._link("group_4") == "https://infocyber.pro/pay/group4"
def test_admin_faq_crud(app):
a = _admin()
app.handle_message(a, "Быстрые ответы 💬")