WIP-CHECKPOINT[auth-refactor]: 固化工程师崩溃前部分成果 + 同树其他未提交WIP(仅源码,不含密钥/二进制)-- 待重激活工程师续作
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""内容审核服务 真实验证(#81 敏感词检测 / 隐私泄露识别)
|
||||
|
||||
真实验证点(来自功能规格说明书 + 状态看板验收标准):
|
||||
- moderate("你爱找谁找谁") → WARN + matched 含该词
|
||||
- check_privacy_leak("电话13800138000") → 含 "phone"
|
||||
- 命中敏感词动作是 WARN(仅警告,不阻断发送)
|
||||
- 自定义词库为写死的若干条(生产应从配置加载,当前未接)
|
||||
"""
|
||||
import pytest
|
||||
|
||||
from app.services.content_moderation_service import (
|
||||
ContentModerationService,
|
||||
ModerationAction,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def moderation_service():
|
||||
# 直接使用构造函数(单例亦可,这里用新实例避免跨测试状态)
|
||||
return ContentModerationService()
|
||||
|
||||
|
||||
def test_moderate_returns_warn_with_matched_word(moderation_service):
|
||||
"""验收点1: 命中自定义敏感词 → WARN 且 matched 含该词"""
|
||||
result = moderation_service.moderate("你爱找谁找谁")
|
||||
assert result.action == ModerationAction.WARN
|
||||
assert "你爱找谁找谁" in result.matched_words
|
||||
|
||||
|
||||
def test_moderate_all_known_custom_words_warn(moderation_service):
|
||||
"""所有已知自定义敏感词均能命中并返回 WARN"""
|
||||
words = ["投诉我", "你爱找谁找谁", "自己不会百度吗", "这点小事"]
|
||||
for w in words:
|
||||
r = moderation_service.moderate(w)
|
||||
assert r.action == ModerationAction.WARN, f"{w} 应被 warn"
|
||||
assert w in r.matched_words, f"{w} 应在 matched 中"
|
||||
|
||||
|
||||
def test_moderate_clean_text_passes(moderation_service):
|
||||
"""正常文本 → PASS,无命中词"""
|
||||
r = moderation_service.moderate("您好,我的电脑无法开机了")
|
||||
assert r.action == ModerationAction.PASS
|
||||
assert r.matched_words == []
|
||||
|
||||
|
||||
def test_moderate_empty_string_passes(moderation_service):
|
||||
"""空字符串 → PASS"""
|
||||
r = moderation_service.moderate("")
|
||||
assert r.action == ModerationAction.PASS
|
||||
assert r.matched_words == []
|
||||
|
||||
|
||||
def test_default_action_is_warn_not_block(moderation_service):
|
||||
"""关键事实: 当前命中动作是 WARN 而非 BLOCK(仅警告、不阻断发送)"""
|
||||
r = moderation_service.moderate("自己不会百度吗")
|
||||
assert r.action != ModerationAction.BLOCK
|
||||
assert r.action == ModerationAction.WARN
|
||||
|
||||
|
||||
def test_check_privacy_leak_phone(moderation_service):
|
||||
"""验收点2: 手机号被识别为 phone"""
|
||||
leaked = moderation_service.check_privacy_leak("我的电话13800138000")
|
||||
assert "phone" in leaked
|
||||
|
||||
|
||||
def test_check_privacy_leak_id_card(moderation_service):
|
||||
"""身份证号被识别为 id_card"""
|
||||
leaked = moderation_service.check_privacy_leak("身份证11010119900307123X")
|
||||
assert "id_card" in leaked
|
||||
|
||||
|
||||
def test_check_privacy_leak_clean_text_empty(moderation_service):
|
||||
"""正常沟通内容不触发隐私识别"""
|
||||
leaked = moderation_service.check_privacy_leak("这是正常的工作沟通内容")
|
||||
assert leaked == []
|
||||
|
||||
|
||||
def test_custom_word_list_is_hardcoded(moderation_service):
|
||||
"""确认自定义词库是写死的(生产应从配置加载,当前未接)"""
|
||||
words = moderation_service.custom_sensitive_words
|
||||
assert len(words) >= 4
|
||||
for w in ["投诉我", "你爱找谁找谁", "自己不会百度吗", "这点小事"]:
|
||||
assert w in words
|
||||
Reference in New Issue
Block a user