112 lines
5.7 KiB
Python
112 lines
5.7 KiB
Python
# -*- coding: utf-8 -*-
|
||
"""t-261013113629: маршрутизация ответов TG — ответ уходит в чат-источник.
|
||
|
||
Проверяет: ответ на сообщение из ГРУППЫ уходит в группу, из ЛИЧКИ — в личку;
|
||
send_batch_reply разбивает смешанный батч по чатам (не смешивает разговоры);
|
||
notify_chat/_default_chat_id выбирает личку Alex, даже если последнее
|
||
активное сообщение — из группы (старые записи без chat_type → chat_id<0).
|
||
|
||
Запуск: ./venv/bin/python tests/test_reply_routing.py
|
||
"""
|
||
import os
|
||
import sys
|
||
|
||
_DST = "/tmp/simbiot-test-reply-routing.db"
|
||
for p in (_DST, _DST + "-wal", _DST + "-shm"):
|
||
if os.path.exists(p):
|
||
os.unlink(p)
|
||
os.environ["SIMBIOT_DB"] = _DST
|
||
sys.path.insert(0, "/root/simbiot-harness")
|
||
|
||
from harness import es, tg_inbox
|
||
|
||
fails = []
|
||
|
||
|
||
def check(name, cond, extra=""):
|
||
print(("PASS" if cond else "FAIL") + " " + name + (" | " + extra if not cond else ""))
|
||
if not cond:
|
||
fails.append(name)
|
||
|
||
|
||
def _recv(update_id, text, chat_id, chat_type, chat_title=None, date=1780000000):
|
||
chat = {"id": chat_id, "type": chat_type}
|
||
if chat_title:
|
||
chat["title"] = chat_title
|
||
tg_inbox.receive_message({"update_id": update_id, "message": {
|
||
"message_id": update_id % 100000, "date": date, "chat": chat,
|
||
"from": {"id": 1, "username": "alex", "first_name": "Alex"}, "text": text}})
|
||
|
||
|
||
es.init_db()
|
||
|
||
PRIVATE_ID = 424242 # личка Alex (>0)
|
||
GROUP_ID = -100999 # группа (<0)
|
||
|
||
# ── 1. send_reply: ответ в чат-источник (группа → группа, личка → личка) ──
|
||
_recv(900, "вопрос в личке", PRIVATE_ID, "private", date=1780000000)
|
||
_recv(901, "вопрос в группе", GROUP_ID, "supergroup", "Кооп 42", date=1780000001)
|
||
|
||
sends, actions = [], []
|
||
tg_inbox.send_message = lambda chat_id, text, reply_to=None, timeout=35: (
|
||
sends.append((chat_id, text)) or {"ok": True})
|
||
tg_inbox._api = lambda method, params, timeout=35: (
|
||
actions.append((method, params.get("chat_id"))) or {"ok": True})
|
||
|
||
tg_inbox.send_reply("m-900", "ответ в личку")
|
||
check("send_reply: личка → личка", sends and sends[-1][0] == PRIVATE_ID, str(sends))
|
||
tg_inbox.send_reply("m-901", "ответ в группу")
|
||
check("send_reply: группа → группа", sends and sends[-1][0] == GROUP_ID, str(sends))
|
||
model = es.run_projections()
|
||
check("send_reply: оба закрыты (replied)",
|
||
model["inbox"]["m-900"]["replied"] and model["inbox"]["m-901"]["replied"])
|
||
check("send_reply: chat_type сохранён",
|
||
model["inbox"]["m-901"]["chat_type"] == "supergroup"
|
||
and model["inbox"]["m-901"]["chat_title"] == "Кооп 42")
|
||
# реплай ушёл именно в чат-источник — проверено по sends выше; здесь — что
|
||
# ReplySent-событие тоже адресовано группе (to_chat)
|
||
_last = [e for e in es.get_events()
|
||
if e.get("event_type") == "ReplySent" and e.get("aggregate_id") == "m-901"]
|
||
check("send_reply: ReplySent-событие адресовано группе",
|
||
bool(_last) and str(GROUP_ID) in _last[-1]["data"], str(_last[-1:]))
|
||
|
||
# ── 2. send_batch_reply: смешанный батч НЕ смешивает чаты ──
|
||
_recv(910, "группа: первое", GROUP_ID, "group", "Кооп 42", date=1780000010)
|
||
_recv(911, "группа: второе", GROUP_ID, "group", "Кооп 42", date=1780000011)
|
||
_recv(912, "личка: первое", PRIVATE_ID, "private", date=1780000012)
|
||
|
||
sends.clear()
|
||
head = tg_inbox.send_batch_reply(["m-910", "m-911", "m-912"], "Сводный ответ")
|
||
sent_chats = sorted(c for c, _ in sends)
|
||
check("send_batch_reply: ДВЕ отправки (по числу чатов)", len(sends) == 2, str(sends))
|
||
check("send_batch_reply: ответ в группу ушёл в группу",
|
||
sends and any(c == GROUP_ID for c, _ in sends), str(sends))
|
||
check("send_batch_reply: ответ в личку ушёл в личку",
|
||
sends and any(c == PRIVATE_ID for c, _ in sends), str(sends))
|
||
model = es.run_projections()
|
||
check("send_batch_reply: все 3 закрыты",
|
||
all(model["inbox"][f"m-91{i}"]["replied"] for i in (0, 1, 2)))
|
||
|
||
# ── 3. _default_chat_id: дефолт — личка, не последняя группа ──
|
||
# последнее сообщение по ts — из группы (m-912 личка раньше m-911? нет:
|
||
# m-912 новее). Добавим ещё более новую группу, чтобы проверить приоритет.
|
||
_recv(920, "самое свежее — из группы", GROUP_ID, "group", "Кооп 42", date=1780000020)
|
||
default = tg_inbox._default_chat_id()
|
||
check("_default_chat_id: личка Alex, а не свежая группа",
|
||
default == PRIVATE_ID, str(default))
|
||
|
||
# старые записи без chat_type: группа = chat_id < 0
|
||
es.append_event("inbox", "m-930", "MessageReceived", {
|
||
"update_id": 930, "chat_id": PRIVATE_ID, "text": "старая личка без типа",
|
||
"kind": "text", "ts": "2026-10-13T10:00:00+00:00"})
|
||
es.append_event("inbox", "m-931", "MessageReceived", {
|
||
"update_id": 931, "chat_id": GROUP_ID, "text": "старая группа без типа",
|
||
"kind": "text", "ts": "2026-10-13T10:01:00+00:00"})
|
||
default = tg_inbox._default_chat_id()
|
||
check("_default_chat_id: без chat_type — тоже личка (chat_id>0)",
|
||
default == PRIVATE_ID, str(default))
|
||
|
||
# только группы — фолбэк на группу (лучше, чем None)
|
||
print()
|
||
print("FAILS:", fails if fails else "нет")
|
||
sys.exit(1 if fails else 0)
|