Files
wecom_it_smart_desk/backend/tests/test_content_moderation.py
T

85 lines
3.2 KiB
Python

# -*- 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