1
0
Fork 0
mirror of https://github.com/EDeev/chatping_abobot.git synced 2026-10-07 20:49:45 +03:00
chatping_abobot/tests/conftest.py
Egor Deev a2a0adcf8e AboBot 4.0: PostgreSQL, обработчики по роутерам, HTML-разметка, новые команды
База — PostgreSQL (asyncpg) вместо четырёх файлов SQLite с таблицей на каждый чат:
chats, users, members, chat_stats и member_stats с полем «период» — месяцы хранятся, а не
обнуляются; счётчики растут одним запросом без блокировки бота. scripts/migrate_sqlite.py
переносит старые базы со сверкой сумм (проверено на копии рабочих баз: 20 694 пользователя,
45 чатов, 3 142 038 сообщений — совпадает).

Учёт бота в чатах: статус и права бота (событие my_chat_member и сверка с Telegram при
запуске и раз в 6 часов), история изменений в bot_status_history; из чатов, где бота
исключили, данные не удаляются — меняется только статус.

Большие чаты (больше 100 участников): /all — только для админов, раз в 5 минут и только
писавшие за 30 дней; упоминание одного человека по имени — не чаще раза в минуту. В любом
чате /all делится на сообщения до 4096 символов (раньше в чате на 14 тысяч падал).

Новое: /settings (упоминания, имена в голосовых, ивенты, удаление служебных сообщений —
меняют админы), /top, /month (итоги месяца по команде). /stop_bot раньше ничего не
выключал — флаг не проверялся; теперь работает. Участник, вышедший из чата, больше не
упоминается, но его статистика сохраняется. Ошибки — в технический чат DEBUG_CHAT_ID.

Код: handlers.py разбит на роутеры, Markdown заменён на HTML (экранирование через html.escape),
тесты на PostgreSQL (18), CI на Python 3.10 и 3.12.
2026-10-06 11:16:00 +00:00

42 lines
1.1 KiB
Python

import os
import sys
import asyncpg
import pytest
os.environ.setdefault("BOT_TOKEN", "123456:TEST")
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "code"))
import db # noqa: E402
DSN = os.environ.get("TEST_DATABASE_URL", "postgresql://postgres:postgres@localhost:5432/abobot_test")
@pytest.fixture
async def pool():
"""Чистая схема на каждый тест"""
conn = await asyncpg.connect(DSN)
await conn.execute("DROP SCHEMA public CASCADE; CREATE SCHEMA public;")
await conn.close()
p = await db.connect(DSN)
yield p
await db.close()
class FakeBot:
"""Минимум Bot API для обработчиков: размер чата и права"""
def __init__(self, size=10, admins=()):
self.size, self.admins, self.id = size, set(admins), 999
async def get_chat_member_count(self, chat_id):
return self.size
async def get_chat_member(self, chat_id, user_id):
from types import SimpleNamespace
return SimpleNamespace(status="administrator" if user_id in self.admins else "member")
@pytest.fixture
def fake_bot():
return FakeBot