104 lines
3.8 KiB
Python
104 lines
3.8 KiB
Python
"""
|
|
私聊图片波次:前一句 10 秒、连发图、业务发出前收字。
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
import unittest
|
|
|
|
ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
|
if ROOT not in sys.path:
|
|
sys.path.insert(0, ROOT)
|
|
|
|
from agent.policy.image_wave import (
|
|
ImageWaveBook,
|
|
PRECEDE_SECONDS,
|
|
reset_image_wave_book_for_test,
|
|
)
|
|
|
|
|
|
class ImageWaveTests(unittest.TestCase):
|
|
def setUp(self) -> None:
|
|
self.book = reset_image_wave_book_for_test()
|
|
|
|
def test_precede_window_is_ten_seconds(self) -> None:
|
|
self.assertEqual(PRECEDE_SECONDS, 10.0)
|
|
|
|
def test_precede_within_10s(self) -> None:
|
|
self.book.note_text("s1", "空运 上海到纽约", now=100.0)
|
|
self.assertEqual(self.book.precede_text("s1", now=109.9), "空运 上海到纽约")
|
|
|
|
def test_precede_after_10s_dropped(self) -> None:
|
|
self.book.note_text("s1", "空运 上海到纽约", now=100.0)
|
|
self.assertEqual(self.book.precede_text("s1", now=110.1), "")
|
|
|
|
def test_forget_text_drops_precede(self) -> None:
|
|
self.book.note_text("s1", "空运 上海到纽约", now=100.0)
|
|
self.book.forget_text("s1")
|
|
self.assertEqual(self.book.precede_text("s1", now=100.5), "")
|
|
|
|
def test_second_image_joins_before_business(self) -> None:
|
|
w1, how = self.book.open_or_join("s1", "mid-a", now=1.0)
|
|
self.assertEqual(how, "opened")
|
|
w2, how2 = self.book.open_or_join("s1", "mid-b", now=1.2)
|
|
self.assertEqual(how2, "joined")
|
|
self.assertEqual(w1.wave_id, w2.wave_id)
|
|
self.assertEqual(w2.media_ids, ["mid-a", "mid-b"])
|
|
|
|
def test_image_after_business_is_new_wave(self) -> None:
|
|
self.book.open_or_join("s1", "mid-a", now=1.0)
|
|
self.book.mark_business_done("s1")
|
|
w2, how = self.book.open_or_join("s1", "mid-b", now=2.0)
|
|
self.assertEqual(how, "new_after_done")
|
|
self.assertEqual(w2.media_ids, ["mid-b"])
|
|
|
|
def test_follow_text_before_business(self) -> None:
|
|
self.book.open_or_join("s1", "mid-a", now=1.0)
|
|
self.assertTrue(self.book.append_follow_text("s1", "海运"))
|
|
self.book.add_vision("s1", "宁波到汉堡")
|
|
oral = self.book.compose_oral("s1")
|
|
self.assertIn("海运", oral)
|
|
self.assertIn("宁波到汉堡", oral)
|
|
|
|
def test_follow_text_after_business_rejected(self) -> None:
|
|
self.book.open_or_join("s1", "mid-a", now=1.0)
|
|
self.book.mark_business_done("s1")
|
|
self.assertFalse(self.book.append_follow_text("s1", "海运"))
|
|
|
|
def test_http_and_worker_share_kv(self) -> None:
|
|
"""复现测服事故:HTTP 收图、Worker 认完必须看到同一份结束标记。"""
|
|
kv = _MemoryWaveKV()
|
|
http = reset_image_wave_book_for_test(kv=kv)
|
|
worker = ImageWaveBook(kv=kv)
|
|
http.open_or_join("s1", "mid-a", now=1.0)
|
|
self.assertIsNotNone(worker.active("s1"))
|
|
worker.add_vision("s1", "SZX-CGK 货交深圳")
|
|
worker.mark_business_done("s1")
|
|
self.assertIsNone(http.active("s1"))
|
|
_w2, how = http.open_or_join("s1", "mid-b", now=2.0)
|
|
self.assertEqual(how, "new_after_done")
|
|
|
|
|
|
class _MemoryWaveKV:
|
|
"""单测假 Redis:两份 ImageWaveBook 共用同一字典。"""
|
|
|
|
def __init__(self) -> None:
|
|
self._d: dict[str, dict] = {}
|
|
|
|
def get_json(self, kind: str, sender_id: str):
|
|
row = self._d.get(f"{kind}:{sender_id}")
|
|
return json.loads(json.dumps(row)) if row is not None else None
|
|
|
|
def set_json(self, kind: str, sender_id: str, data: dict) -> None:
|
|
self._d[f"{kind}:{sender_id}"] = json.loads(json.dumps(data))
|
|
|
|
def delete(self, kind: str, sender_id: str) -> None:
|
|
self._d.pop(f"{kind}:{sender_id}", None)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|