"""admin 展示口径派生单测:记录级原始结局 → (admin_status, outcome_hint)。""" from __future__ import annotations import pytest from sqlalchemy import select from app.admin.repositories.comparison_outcome import admin_success_sql, derive_admin_outcome from app.db.session import SessionLocal from app.models.comparison import ComparisonRecord @pytest.mark.parametrize( ("raw_payload", "status", "expected"), [ # 真实形态:status 已 normalize,细分在 raw_payload.record_status ({"record_status": "success"}, "success", ("success", None)), ({"record_status": "below_minimum"}, "success", ("success", "未满起送")), ({"record_status": "store_closed"}, "failed", ("success", "门店打烊")), ({"record_status": "store_not_found"}, "failed", ("success", "未找到店")), ({"record_status": "items_not_found"}, "failed", ("success", "未找到菜")), ({"record_status": "no_delivery"}, "failed", ("success", "单点不配送")), ({"record_status": "unsupported"}, "failed", ("success", "平台·场景不支持")), ({"record_status": "failed"}, "failed", ("failed", None)), # 纯技术故障 # 空字符串视作缺失,兜到下一级(与 SQL nullif 对齐) ({"record_status": "", "status": "store_closed"}, "failed", ("success", "门店打烊")), # POST 路径:细分在 raw_payload.status ({"status": "store_not_found"}, "failed", ("success", "未找到店")), # 兜底 status 列:raw_payload 缺失(极老记录)或残留细分值 (None, "success", ("success", None)), (None, "failed", ("failed", None)), (None, "store_closed", ("success", "门店打烊")), # 迁移未覆盖的残留 # 生命周期态优先,不看结局 ({}, "cancelled", ("cancelled", None)), ({"record_status": "success"}, "running", ("running", None)), ], ) def test_derive_admin_outcome(raw_payload, status, expected): assert derive_admin_outcome(raw_payload, status) == expected def test_admin_success_sql_matches_python_on_empty_string() -> None: """record_status 为空串时,SQL 侧(nullif)与 Python 侧(or)都应兜到 status 列结局、判为成功。""" db = SessionLocal() try: rec = ComparisonRecord( trace_id="outcome-empty-record-status", status="failed", raw_payload={"record_status": "", "status": "store_closed"}, ) db.add(rec) db.flush() matched = db.execute( select(ComparisonRecord.id).where( ComparisonRecord.trace_id == "outcome-empty-record-status", admin_success_sql(), ) ).scalar_one_or_none() assert matched is not None # SQL 侧判成功 assert derive_admin_outcome(rec.raw_payload, rec.status) == ("success", "门店打烊") # Python 侧一致 finally: db.rollback() db.close()