from datetime import UTC, datetime from sqlalchemy import create_engine from sqlalchemy.orm import Session from app.db import Base from app.models import Comment, ContentItem, Hotspot, Task from app.services.report_service import build_comment_metrics, generate_item_report def test_build_comment_metrics_counts_sentiments_and_top_labels(): comments = [ Comment(content="好", sentiment="positive", labels='["质量好", "价格好"]', like_count=5), Comment(content="差", sentiment="negative", labels='["质量好"]', like_count=2), Comment(content="一般", sentiment="neutral", labels="[]", like_count=1), Comment(content="未知", sentiment="unknown", labels="[]", like_count=0), ] metrics = build_comment_metrics(comments) assert metrics["sample_count"] == 4 assert metrics["sentiment"]["positive"]["count"] == 1 assert metrics["sentiment"]["negative"]["count"] == 1 assert metrics["sentiment"]["neutral"]["count"] == 1 assert metrics["sentiment"]["unknown"]["count"] == 1 assert metrics["top_labels"][0] == {"name": "质量好", "count": 2} def test_generate_item_report_persists_markdown_and_default_summary(): engine = create_engine("sqlite:///:memory:", connect_args={"check_same_thread": False}) Base.metadata.create_all(engine) try: with Session(engine) as session: task = Task(platform="douyin", status="success") session.add(task) session.flush() hotspot = Hotspot(task_id=task.id, platform="douyin", title="热点", raw_data="{}") session.add(hotspot) session.flush() item = ContentItem( task_id=task.id, hotspot_id=hotspot.id, platform="douyin", source_item_id="v1", item_type="video", title="视频", status="success", raw_data="{}", ) session.add(item) session.flush() session.add( Comment( task_id=task.id, hotspot_id=hotspot.id, content_item_id=item.id, platform="douyin", source_comment_id="c1", content="好评", sentiment="positive", labels='["认可"]', like_count=10, comment_time=datetime(2026, 1, 1, tzinfo=UTC), raw_data="{}", ) ) session.commit() report = generate_item_report(session, item.id, summary_provider=lambda *_args, **_kwargs: (_ for _ in ()).throw(RuntimeError("ai failed"))) assert report.report_type == "item" assert report.content_item_id == item.id assert "总结生成失败,请查看上方统计数据。" in report.markdown_content assert "样本评论数量" in report.markdown_content finally: engine.dispose()