Files
bot_vk_ikp_prodagi/tests/test_flow.py
T
Kenik 74a855819d Чистка старого ИКП-флоу: удалены форма-заявка, карьера/вакансии, меню FAQ и осиротевшая админка
Из ТЗ Кибершколы БАЗА эти сценарии заменены воронкой подбора, поэтому убран мёртвый код:
- клиентские FSM: FORM_* (форма-заявка, возвращающийся клиент, редактирование, согласия,
  выбор услуги, карусель) и VAC_* (карьера: игроки/сотрудники);
- меню «Частые вопросы» и config.FAQ_ANSWERS;
- осиротевшая админка: управление услугами + карусель, вакансии, кандидаты
  (в панели и в мастере ADMIN_SVC_*/ADMIN_VAC_*), блок статистики по откликам;
- старый _handoff_to_operator и _notify_operator_about_lead (заменены _baza_to_manager);
- неиспользуемые клавиатуры (форма/услуги/вакансии/согласия) и импорты (validators, random, string).

Оставлено (используется/по ТЗ): воронка БАЗА, быстрые ответы (custom_faq), стата по лидам,
рассылка, управление админами, чат с оператором, логотип. Слой БД не тронут — существующие
установки не ломаются (таблицы services/applications/vacancy_options просто не используются).

bot.py: -1490 строк. Тесты: pytest 28 passed.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 18:36:38 +03:00

142 lines
5.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import bot
def _state(uid):
return bot.db.get_user_data(uid)["state"]
def _prof(uid):
return bot.db.get_profile(uid)
def test_baza_group_funnel_to_payment(app):
"""Полный подбор → групповой абонемент → шаг оплаты (BAZA_PAY)."""
u = 70001
app.handle_message(u, "Подобрать тренировку 🎯"); assert _state(u) == "BAZA_FORWHO"
app.handle_message(u, "Для подростка"); assert _state(u) == "BAZA_AGE"
app.handle_message(u, "1415 лет"); assert _state(u) == "BAZA_GAME"
app.handle_message(u, "CS2"); assert _state(u) == "BAZA_LEVEL"
app.handle_message(u, "Играет для себя"); assert _state(u) == "BAZA_FORMAT"
app.handle_message(u, "Групповые тренировки"); assert _state(u) == "BAZA_GROUP"
app.handle_message(u, "Купить 4 тренировки"); assert _state(u) == "BAZA_PAY"
p = _prof(u)
assert p["role"].startswith("Для подростка") and p["game"] == "CS2"
assert p["format"] == "Групповые тренировки" and "4" in p["tariff"]
assert {"role_parent", "game_cs2", "format_group", "clicked_payment", "lead_hot"} <= set(p["metki"])
def test_baza_individual_and_back(app):
"""Индивидуальная ветка + кнопка «Назад» возвращает на предыдущий шаг."""
u = 70011
app.handle_message(u, "Подобрать тренировку 🎯")
app.handle_message(u, "Для себя"); assert _state(u) == "BAZA_AGE"
app.handle_message(u, "16 лет и старше"); assert _state(u) == "BAZA_GAME"
app.handle_message(u, "Назад ⬅️"); assert _state(u) == "BAZA_AGE"
app.handle_message(u, "16 лет и старше")
app.handle_message(u, "Dota 2"); assert _state(u) == "BAZA_LEVEL"
app.handle_message(u, "Есть рейтинг или ранг")
app.handle_message(u, "Индивидуальные тренировки"); assert _state(u) == "BAZA_INDIVIDUAL"
app.handle_message(u, "Купить 8 тренировок"); assert _state(u) == "BAZA_PAY"
assert "8" in _prof(u)["tariff"]
def test_baza_under12_goes_to_manager(app):
u = 70012
app.handle_message(u, "Подобрать тренировку 🎯")
app.handle_message(u, "Для подростка")
app.handle_message(u, "Младше 12 лет"); assert _state(u) == "BAZA_YOUNG"
app.handle_message(u, "Обсудить с менеджером 💬")
assert _state(u) == "OPERATOR_CHAT"
assert "age_under12" in _prof(u)["metki"]
def test_baza_other_game_goes_to_manager(app):
u = 70013
app.handle_message(u, "Подобрать тренировку 🎯")
app.handle_message(u, "Для себя")
app.handle_message(u, "16 лет и старше")
app.handle_message(u, "Другая игра"); assert _state(u) == "BAZA_GAME_OTHER"
app.handle_message(u, "Valorant"); assert _state(u) == "OPERATOR_CHAT"
assert "Valorant" in _prof(u)["game"]
def test_baza_intensive_by_keyword(app):
"""Кодовое слово «лето» запускает интенсив; ветка доходит до оплаты."""
u = 70014
app.handle_message(u, "лето"); assert _state(u) == "BAZA_INT_INFO"
app.handle_message(u, "Хочу участвовать 🔥"); assert _state(u) == "BAZA_INT_AGE"
app.handle_message(u, "1415 лет"); assert _state(u) == "BAZA_INT_LEVEL"
app.handle_message(u, "Играет в команде или турнирах"); assert _state(u) == "BAZA_PAY"
assert "intensive_interest" in _prof(u)["metki"]
def test_baza_question_button_handoff(app):
u = 70015
app.handle_message(u, "Задать вопрос 💬"); assert _state(u) == "OPERATOR_CHAT"
assert "lead_manager" in _prof(u)["metki"]
def test_baza_prices_and_menu(app):
u = 70016
app._sent.clear()
app.handle_message(u, "Посмотреть цены 💰")
assert _state(u) == "FREE_CHAT"
assert any("2 790" in s["msg"] for s in app._sent)
def test_flood_does_not_crash(app):
u = 70002
for _ in range(25):
app.handle_message(u, "спам")
# бот не падает; пользователь остаётся в FREE_CHAT (флуд/бан только игнорят)
assert _state(u) == "FREE_CHAT"
def test_admin_panel_visible_to_super(app):
admin = bot.config.SUPER_ADMIN_IDS[0]
app._sent.clear()
app.handle_message(admin, "Админка ⚙️")
assert any("Статистика" in (s["kb"] or "") for s in app._sent)
def test_non_admin_cannot_open_panel(app):
app._sent.clear()
app.handle_message(424242, "Админка ⚙️")
assert not any("Админ-панель" in s["msg"] for s in app._sent)
def _admin():
return bot.config.SUPER_ADMIN_IDS[0]
def test_admin_faq_crud(app):
a = _admin()
app.handle_message(a, "Быстрые ответы 💬")
app.handle_message(a, " Добавить ответ")
app.handle_message(a, "вопрос | ответ")
assert any(kw == "вопрос" for _, kw, _ in bot.db.get_custom_faq())
def test_admin_add_remove_admin(app):
a = _admin()
app.handle_message(a, "Администраторы 👑")
app.handle_message(a, " Добавить админа")
app.handle_message(a, "888001")
assert 888001 in bot.db.get_admins()
assert app._is_admin(888001)
def test_broadcast_preview_and_cancel(app):
a = _admin()
app.handle_message(a, "рассылка Привет, акция!")
assert a in app._pending_broadcasts
app.handle_message(a, "Отмена ❌")
assert a not in app._pending_broadcasts
def test_stats_runs(app):
a = _admin()
app._sent.clear()
app.handle_message(a, "Статистика 📊")
assert any("Статистика" in s["msg"] for s in app._sent)