219 lines
7.5 KiB
Python
219 lines
7.5 KiB
Python
"""规则校验器测试"""
|
|
import pytest
|
|
from app.services.content.rule_validator import (
|
|
RuleValidator,
|
|
ValidationIssue,
|
|
ValidationResult,
|
|
AI_Pattern
|
|
)
|
|
|
|
|
|
class TestRuleValidator:
|
|
"""规则校验器测试"""
|
|
|
|
def test_validate_title_length_pass(self):
|
|
"""标题长度符合规则时返回passed"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="这是一篇关于AI医疗的深度分析文章...",
|
|
title="AI医疗的发展趋势与未来展望",
|
|
platform="zhihu"
|
|
)
|
|
assert result.is_valid is True
|
|
assert any("标题长度合规" in p or "合规" in p for p in result.passed)
|
|
|
|
def test_validate_title_length_fail(self):
|
|
"""标题长度超出限制时返回issue"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="内容",
|
|
title="这个标题太长了超过了三十个字符的限制了哈哈哈哈哈哈",
|
|
platform="wechat"
|
|
)
|
|
assert result.is_valid is False
|
|
assert any("超过" in i.message for i in result.issues if i.severity == "high")
|
|
|
|
def test_validate_content_length_pass(self):
|
|
"""内容长度符合规则时返回passed"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="A" * 1500,
|
|
title="测试标题",
|
|
platform="zhihu"
|
|
)
|
|
assert result.score >= 80
|
|
|
|
def test_validate_content_length_fail(self):
|
|
"""内容超长返回issue"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="A" * 30000,
|
|
title="测试标题",
|
|
platform="wechat"
|
|
)
|
|
assert any("超过" in i.message for i in result.issues if i.severity == "high")
|
|
|
|
def test_validate_zhihu_specific_rules(self):
|
|
"""知乎特定规则"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="这是一个专业回答",
|
|
title="专业回答",
|
|
platform="zhihu"
|
|
)
|
|
assert result.score > 0
|
|
|
|
def test_validate_wechat_inducing_content(self):
|
|
"""微信公众号诱导分享检测"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="转发本文领取红包",
|
|
title="限时优惠",
|
|
platform="wechat"
|
|
)
|
|
# 诱导分享应该被检测
|
|
assert any("诱导" in i.message for i in result.issues)
|
|
|
|
def test_validate_wechat_marketing_words(self):
|
|
"""微信公众号营销用语检测"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="点击购买,限时优惠",
|
|
title="优惠信息",
|
|
platform="wechat"
|
|
)
|
|
# 营销用语应该被检测
|
|
assert any("营销" in i.message for i in result.issues)
|
|
|
|
def test_validate_xiaohongshu_cross_platform(self):
|
|
"""小红书跨平台引流检测"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="微信公众号搜索xxx获取更多内容",
|
|
title="种草笔记",
|
|
platform="xiaohongshu"
|
|
)
|
|
# 小红书应检测跨平台引流
|
|
assert any("引流" in i.message for i in result.issues)
|
|
|
|
def test_validate_xiaohongshu_content_length(self):
|
|
"""小红书内容长度检测"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="A" * 100,
|
|
title="笔记",
|
|
platform="xiaohongshu"
|
|
)
|
|
# 内容过短应该被检测
|
|
assert any("300" in i.message for i in result.issues)
|
|
|
|
def test_detect_ai_patterns_banned_words(self):
|
|
"""检测禁用词"""
|
|
validator = RuleValidator()
|
|
result = validator.detect_ai_patterns(
|
|
content="首先,其次,最后,总而言之,总之,总之",
|
|
platform="zhihu"
|
|
)
|
|
assert len(result) > 0
|
|
assert any("首先" in r.pattern or "总之" in r.pattern for r in result)
|
|
|
|
def test_detect_ai_patterns_banned_structures(self):
|
|
"""检测禁用结构"""
|
|
validator = RuleValidator()
|
|
result = validator.detect_ai_patterns(
|
|
content="第一,观点一。第二,观点二。第三,观点三。",
|
|
platform="zhihu"
|
|
)
|
|
assert len(result) > 0
|
|
|
|
def test_detect_ai_patterns_no_banned(self):
|
|
"""无禁用词时返回空列表"""
|
|
validator = RuleValidator()
|
|
result = validator.detect_ai_patterns(
|
|
content="这是一篇正常的人类写作内容",
|
|
platform="zhihu"
|
|
)
|
|
assert isinstance(result, list)
|
|
|
|
def test_detect_ai_patterns_invalid_platform(self):
|
|
"""无效平台返回空列表"""
|
|
validator = RuleValidator()
|
|
result = validator.detect_ai_patterns(
|
|
content="内容",
|
|
platform="invalid_platform"
|
|
)
|
|
assert result == []
|
|
|
|
def test_get_optimization_tips(self):
|
|
"""获取优化建议"""
|
|
validator = RuleValidator()
|
|
tips = validator.get_optimization_tips("zhihu")
|
|
assert isinstance(tips, list)
|
|
|
|
def test_get_optimization_tips_invalid_platform(self):
|
|
"""无效平台返回空列表"""
|
|
validator = RuleValidator()
|
|
tips = validator.get_optimization_tips("invalid_platform")
|
|
assert tips == []
|
|
|
|
def test_validation_result_structure(self):
|
|
"""验证结果结构完整性"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="测试内容",
|
|
title="测试标题",
|
|
platform="zhihu"
|
|
)
|
|
|
|
assert isinstance(result, ValidationResult)
|
|
assert isinstance(result.is_valid, bool)
|
|
assert isinstance(result.score, int)
|
|
assert isinstance(result.issues, list)
|
|
assert isinstance(result.passed, list)
|
|
|
|
for issue in result.issues:
|
|
assert isinstance(issue, ValidationIssue)
|
|
assert issue.severity in ["high", "medium", "low"]
|
|
assert isinstance(issue.message, str)
|
|
assert isinstance(issue.category, str)
|
|
|
|
def test_validation_ai_pattern_structure(self):
|
|
"""AI特征结构完整性"""
|
|
validator = RuleValidator()
|
|
results = validator.detect_ai_patterns(
|
|
content="首先,其次,最后",
|
|
platform="zhihu"
|
|
)
|
|
|
|
for pattern in results:
|
|
assert isinstance(pattern, AI_Pattern)
|
|
assert isinstance(pattern.pattern, str)
|
|
assert pattern.type in ["banned_word", "banned_structure"]
|
|
assert pattern.severity in ["medium", "high"]
|
|
|
|
def test_validate_platform_rules(self):
|
|
"""测试平台规则校验返回passed列表"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="华为手机非常好用",
|
|
title="华为手机评测",
|
|
platform="zhihu"
|
|
)
|
|
|
|
assert hasattr(result, 'passed')
|
|
assert isinstance(result.passed, list)
|
|
|
|
def test_validation_score_calculation(self):
|
|
"""验证分数计算逻辑"""
|
|
validator = RuleValidator()
|
|
result = validator.validate(
|
|
content="A" * 100,
|
|
title="正常标题",
|
|
platform="zhihu"
|
|
)
|
|
|
|
# 无严重问题时应该得到较高的分数
|
|
high_severity_issues = [i for i in result.issues if i.severity == "high"]
|
|
if len(high_severity_issues) == 0:
|
|
assert result.score >= 80
|