"""比价记录页后端分页与概览聚合。""" from __future__ import annotations from datetime import UTC, date, datetime import pytest from sqlalchemy.dialects import postgresql from app.admin.repositories import queries from app.db.session import SessionLocal from app.models.comparison import ComparisonRecord def test_postgresql_duration_summary_uses_ordered_set_aggregates() -> None: stmt = queries._comparison_duration_aggregate_stmt( [], "success", (0.05, 0.5, 0.95, 0.99) ) sql = str( stmt.compile( dialect=postgresql.dialect(), compile_kwargs={"literal_binds": True}, ) ) assert sql.count("percentile_cont") == 4 assert "comparison_record.status IN ('success', 'below_minimum')" in sql def test_summary_uses_only_success_durations_and_filters_beijing_date() -> None: db = SessionLocal() try: rows = [ ("summary-success-a", "success", 1000, 1.0, 100), ("summary-success-b", "success", 3000, 2.0, 0), ("summary-failed", "failed", 100_000, 3.0, 0), ("summary-cancelled", "cancelled", 5000, 4.0, 0), ("summary-below-minimum", "below_minimum", 5000, None, 0), ("summary-store-closed", "store_closed", 200_000, None, 0), ("summary-running", "running", 4000, None, 0), ] for trace_id, status, total_ms, cost, saved in rows: db.add(ComparisonRecord( trace_id=trace_id, status=status, total_ms=total_ms, llm_cost_yuan=cost, saved_amount_cents=saved, created_at=datetime(2038, 1, 15, 12, tzinfo=UTC), )) db.add(ComparisonRecord( trace_id="summary-outside-day", status="success", total_ms=999_999, created_at=datetime(2038, 1, 16, 16, tzinfo=UTC), )) db.flush() summary = queries.comparison_records_summary( db, date_from=date(2038, 1, 15), date_to=date(2038, 1, 15) ) assert summary["started"] == 7 assert summary["completed"] == 5 assert summary["success"] == 3 assert summary["success_rate"] == pytest.approx(3 / 6) assert summary["avg_token_cost"] == pytest.approx(2.5) assert summary["lower_price_rate"] == pytest.approx(1 / 3) assert summary["avg_duration_ms"] == 3000 assert summary["p5_duration_ms"] == 1200 assert summary["p50_duration_ms"] == 3000 assert summary["p95_duration_ms"] == 4800 assert summary["p99_duration_ms"] == 4960 assert summary["cancelled"] == 1 assert summary["cancelled_rate"] == pytest.approx(1 / 7) assert summary["cancelled_p50_ms"] == 5000 items, _next_cursor, total = queries.list_comparison_records( db, date_from=date(2038, 1, 15), date_to=date(2038, 1, 15), limit=20 ) assert total == 7 assert {item.trace_id for item in items} == {row[0] for row in rows} success_items, _next_cursor, success_total = queries.list_comparison_records( db, status="success", date_from=date(2038, 1, 15), date_to=date(2038, 1, 15) ) assert success_total == 3 assert {item.status for item in success_items} == {"success", "below_minimum"} failed_items, _next_cursor, failed_total = queries.list_comparison_records( db, status="failed", date_from=date(2038, 1, 15), date_to=date(2038, 1, 15) ) assert failed_total == 2 assert {item.status for item in failed_items} == {"failed", "store_closed"} running_items, _next_cursor, running_total = queries.list_comparison_records( db, status="running", date_from=date(2038, 1, 15), date_to=date(2038, 1, 15) ) assert running_total == 1 assert running_items[0].status == "running" finally: db.rollback() db.close()