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