"""平台规则引擎单元测试""" import pytest # --------------------------------------------------------------------------- # PlatformRuleEngine 测试 # --------------------------------------------------------------------------- class TestPlatformRuleEngine: @pytest.fixture def engine(self): from app.services.distribution.platform_rules import PlatformRuleEngine return PlatformRuleEngine() def test_get_platforms_returns_all(self, engine): """返回所有 6 个平台""" platforms = engine.get_platforms() assert len(platforms) == 6 ids = {p["id"] for p in platforms} assert ids == {"wechat", "zhihu", "xiaohongshu", "baijiahao", "douyin", "toutiao"} def test_get_platforms_fields(self, engine): """每个平台包含必要字段""" platforms = engine.get_platforms() required_fields = {"id", "name", "icon", "max_title_length", "max_content_length", "min_content_length", "supported_media", "max_images"} for p in platforms: assert required_fields.issubset(p.keys()) def test_validate_title_too_long(self, engine): """标题超长返回 high severity issue""" # 微信公众号标题上限 22 字 title = "这个标题非常非常非常非常非常非常非常长超过了微信的限制" content = "这是正文内容,字数足够满足最低要求。" * 30 result = engine.validate_content(content, title, "wechat") assert result["is_valid"] is False issues = result["issues"] high_issues = [i for i in issues if i["severity"] == "high"] assert any("标题" in i["message"] for i in high_issues) def test_validate_content_too_short(self, engine): """内容过短返回 medium severity issue""" title = "正常标题" content = "短内容" # 远少于 300 字最低要求 result = engine.validate_content(content, title, "wechat") issues = result["issues"] assert any("内容长度" in i["message"] for i in issues) def test_validate_valid_content(self, engine): """合规内容 score >= 90""" title = "合规标题测试" # 长度在 22 字以内 content = "这是符合要求的内容。" * 50 # 足够长度,无违规 result = engine.validate_content(content, title, "wechat") assert result["score"] >= 90 def test_validate_unknown_platform(self, engine): """未知平台返回 is_valid=False""" result = engine.validate_content("content", "title", "unknown_platform_xyz") assert result["is_valid"] is False assert result["score"] == 0 def test_validate_wechat_external_link(self, engine): """微信正文包含外部链接返回 high severity issue""" title = "标题" content = "正文内容 " * 50 + " 点击 https://example.com/test 查看" result = engine.validate_content(content, title, "wechat") issues = result["issues"] assert any("外部链接" in i["message"] for i in issues) def test_validate_wechat_consecutive_symbols_in_title(self, engine): """微信标题含连续特殊符号返回 medium issue""" title = "惊喜!!!三连" content = "正文内容,满足最低字数要求。" * 30 result = engine.validate_content(content, title, "wechat") issues = result["issues"] assert any("连续特殊符号" in i["message"] for i in issues) def test_get_optimization_tips_returns_list(self, engine): """get_optimization_tips 返回非空列表""" tips = engine.get_optimization_tips("wechat") assert isinstance(tips, list) assert len(tips) > 0 def test_get_optimization_tips_unknown_platform(self, engine): """未知平台返回空列表""" tips = engine.get_optimization_tips("unknown_xyz") assert tips == [] # --------------------------------------------------------------------------- # ContentFormatter 测试 # --------------------------------------------------------------------------- class TestContentFormatter: @pytest.fixture def formatter(self): from app.services.distribution.formatter import ContentFormatter return ContentFormatter() def test_formatter_xiaohongshu_strips_markdown(self, formatter): """小红书格式:移除 Markdown 标记""" md_content = "# 标题\n\n**加粗内容**\n\n[链接文本](http://example.com)" result = formatter.format_for_platform(md_content, "xiaohongshu") assert "**" not in result assert "#" not in result or result.strip().startswith("#") is False assert "http://example.com" not in result def test_formatter_wechat_removes_links(self, formatter): """微信格式:去除非公众号外链,保留链接文本""" content = "请访问 [示例网站](https://external-site.com/page) 了解详情" result = formatter.format_for_platform(content, "wechat") # 外部链接被移除,但文本保留 assert "https://external-site.com" not in result assert "示例网站" in result def test_formatter_wechat_converts_headers(self, formatter): """微信格式:Markdown 标题转 HTML""" content = "## 二级标题\n\n正文内容" result = formatter.format_for_platform(content, "wechat") assert "