From 13febebee7b4b5f975aeb041ca2da0ab0432c8b9 Mon Sep 17 00:00:00 2001 From: 2977094657 <2977094657@qq.com> Date: Sun, 22 Feb 2026 18:59:08 +0800 Subject: [PATCH] =?UTF-8?q?fix(chat):=20=E4=BF=AE=E5=A4=8D=20list=5Fchat?= =?UTF-8?q?=5Fmessages=20=E4=B8=AD=20re=20=E4=BD=9C=E7=94=A8=E5=9F=9F?= =?UTF-8?q?=E9=81=AE=E8=94=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除函数内局部 import re,避免遮蔽模块级 re。 - 保持 emojiUrl 处理后续正则逻辑可稳定执行。 - 新增回归测试,覆盖模板解析路径,防止同类作用域问题复发。 --- src/wechat_decrypt_tool/routers/chat.py | 2 - tests/test_chat_list_messages_re_scope.py | 67 +++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) create mode 100644 tests/test_chat_list_messages_re_scope.py diff --git a/src/wechat_decrypt_tool/routers/chat.py b/src/wechat_decrypt_tool/routers/chat.py index 494e040..f741b8a 100644 --- a/src/wechat_decrypt_tool/routers/chat.py +++ b/src/wechat_decrypt_tool/routers/chat.py @@ -5494,8 +5494,6 @@ def list_chat_messages( if existing_local: try: - import re - cur = str(m.get("emojiUrl") or "") if cur and re.match(r"^https?://", cur, flags=re.I) and ("/api/chat/media/emoji" not in cur): m["emojiRemoteUrl"] = cur diff --git a/tests/test_chat_list_messages_re_scope.py b/tests/test_chat_list_messages_re_scope.py new file mode 100644 index 0000000..583d441 --- /dev/null +++ b/tests/test_chat_list_messages_re_scope.py @@ -0,0 +1,67 @@ +import sys +import unittest +from pathlib import Path +from tempfile import TemporaryDirectory +from unittest.mock import patch + + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "src")) + + +class TestChatListMessagesReScope(unittest.TestCase): + def test_list_chat_messages_does_not_shadow_re(self): + from starlette.requests import Request + + import wechat_decrypt_tool.routers.chat as chat + + class _Sentinel(Exception): + pass + + def fake_collect_chat_messages(**_kwargs): + merged = [ + { + "id": "1", + "sortSeq": 0, + "createTime": 1, + "localId": 1, + "type": 266287972401, + "_rawText": "", + "renderType": "appmsg", + } + ] + return merged, False, [], [], set() + + scope = { + "type": "http", + "method": "GET", + "path": "/api/chat/messages", + "raw_path": b"/api/chat/messages", + "query_string": b"", + "headers": [], + "client": ("testclient", 12345), + "server": ("testserver", 80), + "scheme": "http", + } + request = Request(scope) + + with TemporaryDirectory() as td: + account_dir = Path(td) / "acc" + account_dir.mkdir(parents=True, exist_ok=True) + + sentinel = _Sentinel("stop-after-template-parse") + + with patch.object(chat, "_resolve_account_dir", return_value=account_dir), patch.object( + chat, "_iter_message_db_paths", return_value=[account_dir / "msg_0.db"] + ), patch.object(chat, "_collect_chat_messages", side_effect=fake_collect_chat_messages), patch.object( + chat, "_postprocess_transfer_messages", lambda _merged: None + ), patch.object(chat, "_extract_xml_tag_text", return_value="${wxid_abc}"), patch.object( + chat, "_load_contact_rows", side_effect=sentinel + ): + with self.assertRaises(_Sentinel): + chat.list_chat_messages(request=request, username="44372432598@chatroom", account="acc") + + +if __name__ == "__main__": + unittest.main() +