新增 _top_line: 优先评分最高主题,无命中时回退 _theme_clusters 的 主题名(非 markdown 示例),DAILY_WECOM_TOP_LINE=0 退回原逻辑。 复用现有 theme_line 行,不新增头部行(T5)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
61 lines
2.0 KiB
Python
61 lines
2.0 KiB
Python
# tests/test_top_line.py
|
|
"""T5: _top_line 看点行(theme_line 取数升级)测试。"""
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
from unittest import mock
|
|
|
|
import daily.generate as g
|
|
|
|
FEED_HIT = {
|
|
"topTrending": [
|
|
{"title": "remotion-video", "source": "src", "description": "video tool"},
|
|
],
|
|
"topHot": [],
|
|
}
|
|
FEED_MISS = {
|
|
"topTrending": [
|
|
{"title": "zzz-nomatch", "source": "src", "description": "nothing"},
|
|
],
|
|
"topHot": [],
|
|
}
|
|
|
|
|
|
class TopLineTests(unittest.TestCase):
|
|
def test_scores_hit_returns_theme(self):
|
|
# 命中 THEME_RULES(video) -> 评分最高主题
|
|
with mock.patch.object(g, "env_bool", return_value=True):
|
|
line = g._top_line(FEED_HIT)
|
|
self.assertIn("今日主题", line)
|
|
self.assertIn("AI 多媒体", line)
|
|
|
|
def test_fallback_to_theme_names_when_no_score(self):
|
|
# 无评分命中但 theme_clusters 能聚类 -> 用主题名
|
|
feed = {
|
|
"topTrending": [
|
|
{"id": "x", "title": "runcomfy-x", "source": "s", "description": "video x"},
|
|
],
|
|
"topHot": [],
|
|
}
|
|
with mock.patch.object(g, "env_bool", return_value=True):
|
|
# 让评分落空(前 10 无命中)但 clusters(前 20)命中
|
|
line = g._top_line(feed)
|
|
self.assertIn("今日主题", line)
|
|
self.assertIn("AI 多媒体", line)
|
|
|
|
def test_switch_off_uses_legacy_detect(self):
|
|
# DAILY_WECOM_TOP_LINE=0 -> 退回 _detect_theme_line
|
|
with mock.patch.object(g, "env_bool", return_value=False):
|
|
line = g._top_line(FEED_MISS)
|
|
self.assertEqual(line, g._detect_theme_line(FEED_MISS))
|
|
|
|
def test_empty_feed_hardcoded_fallback(self):
|
|
# 完全无数据 -> 硬编码兜底, 不抛异常
|
|
with mock.patch.object(g, "env_bool", return_value=True):
|
|
line = g._top_line({"topTrending": [], "topHot": []})
|
|
self.assertIn("今日主题", line)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|