"""日报结构化组装单元测试(_build_report_data,纯逻辑)。""" from __future__ import annotations import json from datetime import date from scheduler.reporter import _build_report_data def _fake_event(title: str, importance: int, event_type: str = "其他", sentiment: str = "neutral", source_id: str = "cls", url: str = "https://x.com/1") -> dict: return { "title": title, "url": url, "source_id": source_id, "event": { "stock_codes": [], "company_names": [], "industries": [], "sentiment": sentiment, "importance": importance, "event_type": event_type, "summary": f"{title}的摘要", }, } class TestBuildReportData: def test_sections_and_ranks(self) -> None: news = { "total": 2, "hi_threshold": 4, "high": [_fake_event("新闻A", 5), _fake_event("新闻B", 4)], "sentiments": {"neutral": 2}, "importances": {5: 1, 4: 1}, "event_types": {"其他": 2}, } cninfo = { "total": 1, "hi_threshold": 2, "high": [_fake_event("公告C", 3, event_type="公告")], "by_day": {"07月10日": 1}, "announcement": 1, "research": 0, "irm": 0, } pipeline = {"raw_total": 100, "proc": 90} xwlb = {"items": [_fake_event("联播D", 4, event_type="新闻联播", source_id="xwlb")], "date": "07月10日"} r = _build_report_data(news, cninfo, pipeline, "AI摘要", "20260710", xwlb=xwlb) assert r.report_date == date(2026, 7, 10) assert r.report_type == "finance" assert r.file_name == "" assert r.ai_summary == "AI摘要" assert [(e.section, e.rank) for e in r.events] == [ ("news", 1), ("news", 2), ("cninfo", 1), ("xwlb", 1), ] assert r.events[0].source == "cls" assert r.events[3].source == "xwlb" def test_stats_snapshot(self) -> None: news = {"total": 1, "hi_threshold": 4, "high": [], "sentiments": {}, "importances": {}, "event_types": {}} cninfo = {"total": 0, "hi_threshold": 0, "high": [], "by_day": {}, "announcement": 0, "research": 0, "irm": 0} r = _build_report_data(news, cninfo, {"raw_total": 100}, "s", "20260710") # stats 可 JSON 序列化(入库时 json.dumps) json.dumps(r.stats, ensure_ascii=False) assert r.stats["pipeline"] == {"raw_total": 100} assert r.stats["news"]["total"] == 1 assert "xwlb" not in r.stats def test_title_truncated(self) -> None: news = {"total": 1, "hi_threshold": 4, "high": [_fake_event("长" * 600, 4)], "sentiments": {}, "importances": {}, "event_types": {}} cninfo = {"total": 0, "hi_threshold": 0, "high": [], "by_day": {}, "announcement": 0, "research": 0, "irm": 0} r = _build_report_data(news, cninfo, {}, "s", "20260710") assert len(r.events[0].title) == 512 def test_empty_events(self) -> None: news = {"total": 0, "hi_threshold": 0, "high": [], "sentiments": {}, "importances": {}, "event_types": {}} cninfo = {"total": 0, "hi_threshold": 0, "high": [], "by_day": {}, "announcement": 0, "research": 0, "irm": 0} r = _build_report_data(news, cninfo, {}, None, "20260710") assert r.events == [] assert r.ai_summary is None