116 lines
5.8 KiB
Python
116 lines
5.8 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""t-261013131228: резолв цели реплая без текста (документ/фото).
|
|
|
|
Кейс 13.10: Alex в личке реплайнул на присланный ранее документ (концепт
|
|
панельной сессии для ИИШНИЦЫ) словами «вот этого мероприятия». Telegram не
|
|
отдаёт содержимое документа в reply_to_message → reply_to_text пустой →
|
|
мин-триаж видел «[reply на сообщение без текста]» без контекста и анонсировал
|
|
не то событие (перформанс 8 сентября вместо ИИШНИЦЫ 20.10). Фикс:
|
|
receive_message резолвит цель по инбоксу (chat_id, reply_to_message_id)
|
|
и пишет reply_to_desc; build_context показывает desc, когда текста нет.
|
|
|
|
Запуск: ./venv/bin/python tests/test_reply_target_resolve.py
|
|
"""
|
|
import os
|
|
import sys
|
|
|
|
_DST = "/tmp/simbiot-test-reply-target.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, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
from harness import es, tg_inbox
|
|
|
|
fails = []
|
|
|
|
|
|
def check(name, cond, extra=""):
|
|
print(("PASS" if cond else "FAIL") + " " + name + ("" if cond else " | " + extra))
|
|
if not cond:
|
|
fails.append(name)
|
|
|
|
|
|
def _recv(update_id, message_id, chat_id, text=None, document=None, reply_to=None,
|
|
chat_type="private", date=1780000000):
|
|
msg = {
|
|
"message_id": message_id, "date": date,
|
|
"chat": {"id": chat_id, "type": chat_type},
|
|
"from": {"id": 1, "first_name": "Alex"},
|
|
}
|
|
if text is not None:
|
|
msg["text"] = text
|
|
if document is not None:
|
|
msg["document"] = document
|
|
if reply_to is not None:
|
|
msg["reply_to_message"] = reply_to
|
|
tg_inbox.receive_message({"update_id": update_id, "message": msg})
|
|
|
|
|
|
DOC_CAPTION = "Концепт панельной сессии «Общее видение» для ИИШНИЦЫ (HTML): миссия 42 как рамка"
|
|
|
|
es.init_db()
|
|
|
|
# ── 1. Реплай на документ: цель резолвится из инбокса ──────────────────────
|
|
_recv(1001, 4060, 7569223131, text=DOC_CAPTION,
|
|
document={"file_id": "f1", "file_unique_id": "u1",
|
|
"file_name": "panel-concept.html", "mime_type": "text/html"})
|
|
_recv(1002, 4076, 7569223131, text="вот этого мероприятия",
|
|
reply_to={"message_id": 4060}) # Telegram текст цели не отдал
|
|
|
|
model = es.run_projections()
|
|
m = model["inbox"]["m-1002"]
|
|
check("реплай на документ: reply_to_message_id зафиксирован",
|
|
m["reply_to_message_id"] == 4060)
|
|
check("реплай на документ: reply_to_text пустой (Telegram не отдал)",
|
|
not (m.get("reply_to_text") or "").strip())
|
|
desc = m.get("reply_to_desc") or ""
|
|
check("реплай на документ: reply_to_desc резолвнулся из инбокса", bool(desc), repr(desc))
|
|
check("реплай на документ: desc несёт содержимое (caption документа)",
|
|
("Концепт панельной сессии" in desc) or ("документ" in desc.lower()), repr(desc))
|
|
|
|
# ── 2. Реплай на текстовое: desc не нужен, текст из Telegram ───────────────
|
|
_recv(2001, 5001, 7569223131, text="старое текстовое сообщение")
|
|
_recv(2002, 5002, 7569223131, text="принято",
|
|
reply_to={"message_id": 5001, "text": "старое текстовое сообщение"})
|
|
model = es.run_projections()
|
|
m = model["inbox"]["m-2002"]
|
|
check("реплай на текст: reply_to_text из Telegram",
|
|
(m.get("reply_to_text") or "").strip() == "старое текстовое сообщение")
|
|
check("реплай на текст: reply_to_desc не пишется (не нужен)",
|
|
not (m.get("reply_to_desc") or "").strip())
|
|
|
|
# ── 3. Цель вне инбокса: не выдумываем desc ────────────────────────────────
|
|
_recv(3001, 6002, 7569223131, text="вот этого мероприятия",
|
|
reply_to={"message_id": 999999})
|
|
model = es.run_projections()
|
|
m = model["inbox"]["m-3001"]
|
|
check("цель вне инбокса: reply_to_desc не выдумывается",
|
|
not (m.get("reply_to_desc") or "").strip())
|
|
|
|
# ── 4. build_context: якорь реплая несёт контекст документа ────────────────
|
|
_recv(4001, 7000, 7569223131, text=DOC_CAPTION,
|
|
document={"file_id": "f2", "file_unique_id": "u2",
|
|
"file_name": "panel-concept.html", "mime_type": "text/html"})
|
|
_recv(4002, 7001, 7569223131, text="вот этого мероприятия",
|
|
reply_to={"message_id": 7000})
|
|
# закрываем ранние входящие, чтобы в контекст попал только свежий батч
|
|
for mid in ("m-1001", "m-1002", "m-2001", "m-2002", "m-3001"):
|
|
mm = model["inbox"].get(mid)
|
|
if mm is not None:
|
|
es.append_event("inbox", mid, "MessageIgnored", {"reason": "test"})
|
|
|
|
from harness.scheduler import build_context
|
|
from harness.levels import LEVELS
|
|
|
|
ctx = build_context(LEVELS["min"], es.run_projections(), batch=[])
|
|
check("build_context: якорь реплая показывает контекст документа",
|
|
"в ответ на" in ctx and "[reply на сообщение без текста]" not in ctx
|
|
and "Концепт панельной сессии" in ctx)
|
|
|
|
print()
|
|
if fails:
|
|
print("FAILS: " + ", ".join(fails))
|
|
sys.exit(1)
|
|
print("ALL PASS")
|