85 lines
3.2 KiB
Python
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
|