feat(ingest): db-only library ingest and telegram manual ingest

This commit is contained in:
kairee committed 2026-11-01 13:50:03 +08:00
1 parent d2adb65e08
commit 62abbd7ea1
6 files changed
+866 -28

No files matched your search

+66 -17
View File
@@ -11,11 +11,16 @@ sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.stdout.reconfigure(encoding="utf-8")
from reaction_board.notify.telegram import ( # noqa: E402
HELP_TEXT,
TelegramClient,
TelegramError,
format_duration,
)
from reaction_board.services.favorites import ActionResult # noqa: E402
from reaction_board.services.library import ( # noqa: E402
ActionResult,
IngestResult,
ManualIngestResult,
)
from reaction_board.services.telegram_poller import TelegramPoller # noqa: E402
@@ -58,7 +63,7 @@ def test_send_candidates_and_chunking():
keyboard = json.loads(call["data"]["reply_markup"])
assert len(keyboard["inline_keyboard"]) == 2
assert [button["callback_data"] for button in keyboard["inline_keyboard"][0]] == [
"fav:1", "ign:1", "blk:1",
"add:1", "ign:1", "blk:1",
]
transport = FakeTransport()
@@ -76,7 +81,7 @@ def test_send_candidates_dedupes_by_aid():
keyboard = json.loads(transport.calls[0]["data"]["reply_markup"])
assert len(keyboard["inline_keyboard"]) == 2
assert [row[0]["callback_data"] for row in keyboard["inline_keyboard"]] == [
"fav:1", "fav:2",
"add:1", "add:2",
]
@@ -88,7 +93,7 @@ def test_get_updates_and_answer():
assert data["offset"] == 99
assert data["timeout"] == 17
assert transport.calls[0]["timeout"] == 32
assert json.loads(data["allowed_updates"]) == ["callback_query"]
assert json.loads(data["allowed_updates"]) == ["callback_query", "message"]
transport = FakeTransport(result=True)
bot = TelegramClient("token", 42, transport=transport)
@@ -148,10 +153,13 @@ class FakeBot:
class FakeActions:
def __init__(self):
self.calls = []
self.manual = []
def favorite(self, aid):
self.calls.append(("fav", aid))
return ActionResult(True, aid, "favorite", "done", position=3, message="已加入收藏夹")
def ingest_candidate(self, aid):
self.calls.append(("add", aid))
return IngestResult(
True, aid, "added", title="咻咻满 reaction", message="已入库"
)
def ignore(self, aid):
self.calls.append(("ign", aid))
@@ -161,6 +169,16 @@ class FakeActions:
self.calls.append(("blk", aid))
return ActionResult(True, aid, "blacklist", "rejected", message="已拉黑")
def ingest_text(self, text):
self.manual.append(text)
return ManualIngestResult(
refs=1, added=1,
results=[IngestResult(True, 9, "added", title="咻咻满 reaction", message="已入库")],
)
ADD_REPLY = "✅ 已入库《咻咻满 reaction》(aid 9)"
def update(update_id, data, *, chat_id=42, from_id=42):
return {
@@ -174,33 +192,63 @@ def update(update_id, data, *, chat_id=42, from_id=42):
}
def message_update(update_id, text, *, chat_id=42, from_id=42):
return {
"update_id": update_id,
"message": {
"message_id": update_id * 10,
"chat": {"id": chat_id},
"from": {"id": from_id},
"text": text,
},
}
def test_poller_dispatch_and_authorization():
bot = FakeBot([
update(1, "fav:9"),
update(1, "add:9"),
update(2, "ign:10"),
update(3, "blk:11"),
update(4, "fav:12", chat_id=999),
update(4, "add:12", chat_id=999),
update(5, "bad"),
update(6, "fav:13"),
])
actions = FakeActions()
poller = TelegramPoller(bot, actions)
offset = poller.run_once(None)
assert offset == 6
assert actions.calls == [("fav", 9), ("ign", 10), ("blk", 11)]
assert bot.answers[0] == ("cb1", "已加入收藏夹(位置 #3)")
assert offset == 7
assert actions.calls == [("add", 9), ("ign", 10), ("blk", 11), ("add", 13)]
assert bot.answers[0] == ("cb1", ADD_REPLY)
assert bot.answers[1] == ("cb2", "• 已忽略(aid 10)")
assert bot.answers[2] == ("cb3", "• 已拉黑(aid 11)")
assert bot.answers[3] == ("cb4", "无权限")
assert bot.answers[4] == ("cb5", "未知操作")
assert bot.edits == [10, 20, 30]
assert bot.edits == [10, 20, 30, 60]
def test_answer_failure_falls_back_to_text():
bot = FakeBot([update(1, "fav:9")], fail_answer=True)
def test_poller_manual_message():
bot = FakeBot([
message_update(1, "https://www.bilibili.com/video/BV1x8x166EzY"),
message_update(2, "hello", chat_id=999),
message_update(3, "/help"),
])
actions = FakeActions()
poller = TelegramPoller(bot, actions)
poller.run_once(None)
assert actions.calls == [("fav", 9)]
assert actions.manual == ["https://www.bilibili.com/video/BV1x8x166EzY"]
assert "入库" in bot.sent[0]
assert HELP_TEXT in bot.sent
assert len(bot.sent) == 2
def test_answer_failure_falls_back_to_text():
bot = FakeBot([update(1, "add:9")], fail_answer=True)
actions = FakeActions()
poller = TelegramPoller(bot, actions)
poller.run_once(None)
assert actions.calls == [("add", 9)]
assert bot.answers == []
assert bot.sent == ["已加入收藏夹(位置 #3)"]
assert bot.sent == [ADD_REPLY]
assert bot.edits == [10]
@@ -257,6 +305,7 @@ def main():
test_get_updates_and_answer()
test_telegram_error_description_preserved()
test_poller_dispatch_and_authorization()
test_poller_manual_message()
test_answer_failure_falls_back_to_text()
test_poller_backoff_and_recovery()
print("OK: Telegram 消息、分片、长轮询与回调授权测试全部通过")