743d69efd0
- Move DB operations from routes/admin.py to services/admin.py (get_logs_context, query_summary_statuses, retry_failed, delete/reset operations) - Add services/jobs.py with Job/JobEvent-based async job queue (create_job, run_job, enqueue_job) - Add services/derived.py with FTS5 reindex and paper index deletion helpers - Refactor scheduler to use job queue instead of direct pipeline calls - Add heartbeat_at/expires_at to TaskLock for lock health tracking - Remove DESIGN_REVIEW.md - Update tests: remove redundant integration tests, add unit tests for new services
103 lines
4.5 KiB
Python
103 lines
4.5 KiB
Python
"""页面路由测试 — detail、trends、compare、graceful degradation。"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from datetime import date
|
||
from unittest.mock import patch as upatch
|
||
|
||
|
||
# ═══════════════════════════════════════════════════════════════════════
|
||
# Detail 页 & 相似论文
|
||
# ═══════════════════════════════════════════════════════════════════════
|
||
|
||
|
||
class TestDetailPage:
|
||
"""论文详情页测试。"""
|
||
|
||
def test_detail_page_renders(self, client, sample_papers_with_summary):
|
||
"""详情页正常渲染。"""
|
||
resp = client.get("/paper/2401.20001")
|
||
assert resp.status_code == 200
|
||
assert "测试论文" in resp.text or "Test Paper" in resp.text
|
||
|
||
def test_detail_page_not_found(self, client):
|
||
"""不存在的论文返回 404。"""
|
||
resp = client.get("/paper/nonexistent.99999")
|
||
assert resp.status_code == 404
|
||
|
||
|
||
# ═══════════════════════════════════════════════════════════════════════
|
||
# Trends Dashboard
|
||
# ═══════════════════════════════════════════════════════════════════════
|
||
|
||
|
||
class TestTrendsDashboard:
|
||
"""趋势看板测试。"""
|
||
|
||
def test_trends_api_daily_counts(self, client, sample_papers_with_summary):
|
||
"""每日论文数量数据正确。"""
|
||
# 使用测试数据的日期范围
|
||
with upatch("app.services.trends.date") as mock_date:
|
||
mock_date.today.return_value = date(2024, 1, 20)
|
||
mock_date.side_effect = lambda *a, **kw: date(*a, **kw)
|
||
|
||
resp = client.get("/api/stats/trends")
|
||
data = resp.json()
|
||
assert len(data["daily_counts"]) == 5
|
||
for item in data["daily_counts"]:
|
||
assert "date" in item
|
||
assert "count" in item
|
||
assert item["count"] == 1
|
||
|
||
def test_trends_api_top_tags(self, client, sample_papers_with_summary):
|
||
"""热门标签数据正确。"""
|
||
resp = client.get("/api/stats/trends")
|
||
data = resp.json()
|
||
tags = {t["tag"]: t["count"] for t in data["top_tags"]}
|
||
assert "NLP" in tags
|
||
assert tags["NLP"] == 5 # 所有论文都有 NLP
|
||
|
||
def test_trends_api_summary_completion(self, client, sample_papers_with_summary):
|
||
"""总结完成率数据正确。"""
|
||
resp = client.get("/api/stats/trends")
|
||
data = resp.json()
|
||
statuses = {s["status"]: s["count"] for s in data["summary_completion"]}
|
||
assert "done" in statuses
|
||
assert statuses["done"] == 4 # 4 篇已完成
|
||
|
||
def test_trends_empty_db(self, client):
|
||
"""无数据时不崩溃。"""
|
||
resp = client.get("/api/stats/trends")
|
||
assert resp.status_code == 200
|
||
data = resp.json()
|
||
assert data["daily_counts"] == []
|
||
assert data["top_tags"] == []
|
||
|
||
|
||
# ═══════════════════════════════════════════════════════════════════════
|
||
# Compare Page
|
||
# ═══════════════════════════════════════════════════════════════════════
|
||
|
||
|
||
class TestComparePage:
|
||
"""论文对比页测试。"""
|
||
|
||
def test_compare_page_with_ids(self, client, sample_papers_with_summary):
|
||
"""对比多篇论文正常渲染。"""
|
||
resp = client.get("/compare?ids=2401.20001,2401.20002")
|
||
assert resp.status_code == 200
|
||
assert "2401.20001" in resp.text
|
||
assert "2401.20002" in resp.text
|
||
# 应包含对比字段
|
||
assert "一句话摘要" in resp.text
|
||
assert "研究问题" in resp.text
|
||
|
||
def test_compare_page_shows_no_summary_placeholder(
|
||
self, client, sample_papers_with_summary
|
||
):
|
||
"""无总结的论文显示占位文本。"""
|
||
# 2401.20005 没有 summary(status=pending)
|
||
resp = client.get("/compare?ids=2401.20005")
|
||
assert resp.status_code == 200
|
||
assert "暂无总结" in resp.text
|