fix(mention): address PR #45 review feedback (M1-M3, S1-S3)
CI / lint (pull_request) Successful in 7s
CI / test (pull_request) Successful in 8s
CI / notify-on-failure (pull_request) Successful in 0s

M1: Remove '帮忙' from help_keywords to fix keyword priority bug
M3: Add unit tests for mention_utils (§25.7)
S1: Merge two 'if action == opened' blocks in _handle_issues
S2: Extract _send_review_mentions helper to deduplicate @mention code
S3: Remove redundant 'import re' inside conditional block
This commit is contained in:
cfdaily
2026-06-12 18:56:49 +08:00
parent f25af64f00
commit e7f28cd36e
3 changed files with 172 additions and 48 deletions
+129
View File
@@ -0,0 +1,129 @@
"""mention_utils 单元测试 — §25.7 覆盖。"""
import pytest
from src.api.mention_utils import (
extract_mentions,
should_suppress_mention,
infer_intent,
)
# ---------------------------------------------------------------------------
# extract_mentions
# ---------------------------------------------------------------------------
class TestExtractMentions:
"""测试 @mention 提取逻辑。"""
def test_exact_match(self):
"""@zhangfei-dev 精确匹配。"""
assert extract_mentions("@zhangfei-dev 请看一下", "someone") == ["zhangfei-dev"]
def test_chinese_alias(self):
"""@张飞 中文别名匹配。"""
assert extract_mentions("@张飞 帮忙看看", "someone") == ["zhangfei-dev"]
def test_english_short_name(self):
"""@zhangfei 英文短名匹配。"""
assert extract_mentions("@zhangfei 快来", "someone") == ["zhangfei-dev"]
def test_prefix_unique(self):
"""@zhangf 前缀唯一匹配。"""
assert extract_mentions("@zhangf 来一下", "someone") == ["zhangfei-dev"]
def test_prefix_ambiguous_no_match(self):
"""@z 前缀模糊,多个候选,不匹配。"""
assert extract_mentions("@z 看看", "someone") == []
def test_dedup_same_person(self):
"""@张飞 @zhangfei-dev 同时出现去重。"""
result = extract_mentions("@张飞 @zhangfei-dev 来一下", "someone")
assert result == ["zhangfei-dev"]
def test_exclude_self(self):
"""@zhangfei-dev 排除自己(sender=zhangfei-dev)。"""
assert extract_mentions("@zhangfei-dev 自己说", "zhangfei-dev") == []
def test_unknown_person(self):
"""@unknown 不匹配任何 Agent。"""
assert extract_mentions("@unknown 你好", "someone") == []
def test_multiple_mentions(self):
"""多个 @mention 返回多个 Agent。"""
result = set(extract_mentions("@张飞 @关羽 来讨论", "someone"))
assert result == {"zhangfei-dev", "guanyu-dev"}
def test_mention_with_hyphen_in_middle(self):
"""@mention 后面紧跟标点也能识别。"""
result = extract_mentions("@赵云,请看下", "someone")
assert result == ["zhaoyun-data"]
# ---------------------------------------------------------------------------
# should_suppress_mention
# ---------------------------------------------------------------------------
class TestShouldSuppressMention:
"""测试 @mention 通知抑制逻辑。"""
def test_suppress_when_in_list(self):
"""被提及者在自动通知列表中 → 抑制。"""
assert should_suppress_mention("zhangfei-dev", ["zhangfei-dev", "guanyu-dev"]) is True
def test_not_suppress_when_not_in_list(self):
"""被提及者不在自动通知列表中 → 不抑制。"""
assert should_suppress_mention("zhangfei-dev", ["guanyu-dev"]) is False
def test_suppress_empty_list(self):
"""自动通知列表为空 → 不抑制。"""
assert should_suppress_mention("zhangfei-dev", []) is False
# ---------------------------------------------------------------------------
# infer_intent
# ---------------------------------------------------------------------------
class TestInferIntent:
"""测试意图推断逻辑。
优先级:assign → collaborate → help → notify(默认)
"""
def test_help_question_mark(self):
"""疑问句 → help。"""
assert infer_intent("@赵云 数据格式是什么?") == "help"
def test_notify_plain_mention(self):
"""纯通知(无关键词) → notify。"""
assert infer_intent("@关羽 这个 PR 涉及风控变更") == "notify"
def test_collaborate_please_help(self):
"""'请帮忙' → collaborateNOT help!)。"""
assert infer_intent("@庞统 请帮忙澄清需求") == "collaborate"
def test_assign_keywords(self):
"""'交给你' → assign。"""
assert infer_intent("@张飞 前端部分交给你") == "assign"
def test_help_how_to(self):
"""'如何' → help。"""
assert infer_intent("@姜维 如何部署这个服务") == "help"
def test_collaborate_please_review(self):
"""'请review' → collaborate。"""
assert infer_intent("@司马懿 请review 这个方案") == "collaborate"
def test_notify_default(self):
"""无任何关键词 → notify。"""
assert infer_intent("@赵云 已更新数据") == "notify"
def test_assign_takes_priority_over_help(self):
"""assign 关键词优先于 help 关键词。"""
# "交给" in body → assign, even though "" also present
assert infer_intent("@张飞 这个模块交给你,有问题?") == "assign"
def test_collaborate_takes_priority_over_help(self):
"""collaborate 关键词优先于 help 关键词。"""
# "请帮忙" in body → collaborate, even though "" absent
assert infer_intent("@赵云 请帮忙看看数据") == "collaborate"