feat: 早报系统重构与功能增强
- 新增常驻调度器 daily/scheduler.py + run-scheduler.ps1(定时生成/推送) - 新增 daily/bridge_manager.py:Windows 兼容的 Cursor SDK 桥接 - 新增 skills/daily-featured-pick 首推 Skill 与叙事轴/去重逻辑 - 新闻抓取窗口、GitHub 搜索、企微 delta 模式等多项改进 - 补充设计文档与 superpowers 计划/规范 - 新增对应测试(scheduler、featured_pick、github_search、news_fetch_window 等) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
117
tests/test_ai_news_research.py
Normal file
117
tests/test_ai_news_research.py
Normal file
@@ -0,0 +1,117 @@
|
||||
"""AI 时讯 deep-research 解析与企微格式。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
|
||||
from daily.format_wecom import _ai_news_lines, replace_wecom_news_sections
|
||||
from daily.news.research import parse_research_response
|
||||
|
||||
|
||||
class TestAiNewsResearchParse(unittest.TestCase):
|
||||
def test_parse_items(self):
|
||||
raw = """
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"title": "Apple sues OpenAI",
|
||||
"link": "https://techcrunch.com/2026/07/10/apple/",
|
||||
"source_name": "TechCrunch",
|
||||
"desc_short": "苹果起诉 OpenAI 涉嫌窃取商业机密",
|
||||
"published_fmt": "07-11 05:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
"""
|
||||
items, tech = parse_research_response(raw, limit=10)
|
||||
self.assertEqual(len(items), 1)
|
||||
self.assertEqual(items[0]["source_name"], "TechCrunch")
|
||||
self.assertIn("苹果", items[0]["desc_short"])
|
||||
self.assertEqual(tech, [])
|
||||
|
||||
def test_dedupe_links(self):
|
||||
raw = """{"items": [
|
||||
{"title": "A", "link": "https://example.com/a", "source_name": "Ex", "desc_short": "一"},
|
||||
{"title": "B", "link": "https://example.com/a", "source_name": "Ex", "desc_short": "二"}
|
||||
]}"""
|
||||
items, _ = parse_research_response(raw, limit=10)
|
||||
self.assertEqual(len(items), 1)
|
||||
|
||||
def test_parse_tech_items(self):
|
||||
raw = """{"items": [
|
||||
{"title": "A", "link": "https://example.com/a", "source_name": "Ex", "desc_short": "一"}
|
||||
], "tech_items": [
|
||||
{"title": "B", "link": "https://example.com/b", "source_name": "Ex", "desc_short": "二"}
|
||||
]}"""
|
||||
items, tech = parse_research_response(raw, limit=10, tech_limit=5)
|
||||
self.assertEqual(len(items), 1)
|
||||
self.assertEqual(len(tech), 1)
|
||||
self.assertEqual(tech[0]["title"], "B")
|
||||
|
||||
|
||||
class TestMergedWecomNews(unittest.TestCase):
|
||||
def test_merged_block_format(self):
|
||||
items = [
|
||||
{
|
||||
"title": "Apple sues OpenAI",
|
||||
"link": "https://techcrunch.com/x",
|
||||
"source_name": "TechCrunch",
|
||||
"desc_short": "苹果起诉 OpenAI",
|
||||
"published_fmt": "07-11 05:00",
|
||||
}
|
||||
]
|
||||
lines = _ai_news_lines(items, merged=True)
|
||||
self.assertIn("TechCrunch - Apple sues OpenAI", lines[0])
|
||||
self.assertIn("— 苹果起诉 OpenAI", lines[0])
|
||||
self.assertNotIn("07-11", lines[0])
|
||||
|
||||
def test_merged_with_tech_block(self):
|
||||
md = """📰 **早报**
|
||||
|
||||
📈 **Skills Trending Top 1**
|
||||
1. skill
|
||||
"""
|
||||
main = [
|
||||
{"title": "Main", "link": "https://example.com/m", "source_name": "Src", "desc_short": "主条", "published_fmt": "07-11"}
|
||||
]
|
||||
tech = [
|
||||
{"title": "Tech", "link": "https://example.com/t", "source_name": "Src2", "desc_short": "技术条", "published_fmt": "07-12"}
|
||||
]
|
||||
out = replace_wecom_news_sections(md, ai_news=main, tech_ai_news=tech, merged=True)
|
||||
self.assertIn("📰 **AI 时讯精选 Top 2**", out)
|
||||
self.assertNotIn("技术类时讯", out)
|
||||
self.assertNotIn("🔧", out)
|
||||
self.assertNotIn("07-11", out)
|
||||
self.assertNotIn("07-12", out)
|
||||
self.assertIn("2. [Src2 - Tech]", out)
|
||||
|
||||
def test_replace_merged_removes_split_blocks(self):
|
||||
md = """📰 **早报**
|
||||
|
||||
🌍 **国际 AI 时讯 Top 1**
|
||||
1. [old](https://example.com/old) · `X`
|
||||
|
||||
🇨🇳 **国内 AI 时讯 Top 1**
|
||||
1. [old2](https://example.com/old2) · `Y`
|
||||
|
||||
📈 **Skills Trending Top 1**
|
||||
1. skill
|
||||
"""
|
||||
items = [
|
||||
{
|
||||
"title": "New story",
|
||||
"link": "https://example.com/new",
|
||||
"source_name": "Fortune",
|
||||
"desc_short": "新故事",
|
||||
"published_fmt": "",
|
||||
}
|
||||
]
|
||||
out = replace_wecom_news_sections(md, ai_news=items, merged=True)
|
||||
self.assertIn("📰 **AI 时讯精选 Top 1**", out)
|
||||
self.assertNotIn("国际 AI 时讯", out)
|
||||
self.assertNotIn("国内 AI 时讯", out)
|
||||
self.assertIn("📈 **Skills Trending Top 1**", out)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user