"""记账测试:比价后下单上报 → 写 savings_record(source='compare')。 覆盖:上报落库 + 门店/菜品/原价随之入库、(user,client_event_id) 幂等、 纯真实口径(demo 兜底已停用:新用户空、上报后才有数)、省额 = 源平台原价 − 实付。 """ from __future__ import annotations def _login(client, phone: str) -> str: client.post("/api/v1/auth/sms/send", json={"phone": phone}) r = client.post("/api/v1/auth/sms/login", json={"phone": phone, "code": "123456"}) assert r.status_code == 200, r.text return r.json()["access_token"] def _auth(token: str) -> dict[str, str]: return {"Authorization": f"Bearer {token}"} def _report_body(**over) -> dict: body = { "client_event_id": "evt-1", "platform": "淘宝闪购", "platform_package": "com.taobao.taobao", "pay_channel": "alipay", "compared_price_cents": 3300, "paid_amount_cents": 3300, "device_id": "device_test", "shop_name": "肯德基宅急送(天北路店)", "dishes": ["史迪奇玩具套餐 x1"], "original_price_cents": 3680, "source_platform_name": "美团", "source_deeplink": "https://example.com/reorder", } body.update(over) return body def test_order_report_creates_real_savings(client) -> None: """上报一笔 → savings 统计/明细只反映这笔真实数据,含门店/菜品/原价。""" token = _login(client, "13800002001") r = client.post("/api/v1/order/report", json=_report_body(), headers=_auth(token)) assert r.status_code == 200, r.text out = r.json() assert out["duplicated"] is False assert out["paid_amount_cents"] == 3300 assert out["platform"] == "淘宝闪购" # summary:真实优先,只算这一笔(demo 不再混入) s = client.get("/api/v1/savings/summary", headers=_auth(token)).json() assert s["order_count"] == 1 assert s["total_saved_cents"] == 380 # 3680 − 3300 assert s["avg_saved_cents"] == 380 # records:门店/菜品/原价/支付渠道/源平台都在 page = client.get("/api/v1/savings/records", headers=_auth(token)).json() assert len(page["items"]) == 1 it = page["items"][0] assert it["shop_name"] == "肯德基宅急送(天北路店)" assert it["dishes"] == ["史迪奇玩具套餐 x1"] assert it["order_amount_cents"] == 3300 assert it["saved_amount_cents"] == 380 assert it["original_price_cents"] == 3680 assert it["platform"] == "淘宝闪购" assert it["pay_channel"] == "alipay" assert it["source_platform_name"] == "美团" def test_order_report_idempotent(client) -> None: """同 (user, client_event_id) 重复上报:第二次 duplicated=True,不新增。""" token = _login(client, "13800002002") body = _report_body(client_event_id="evt-dup") r1 = client.post("/api/v1/order/report", json=body, headers=_auth(token)) assert r1.json()["duplicated"] is False r2 = client.post("/api/v1/order/report", json=body, headers=_auth(token)) assert r2.json()["duplicated"] is True s = client.get("/api/v1/savings/summary", headers=_auth(token)).json() assert s["order_count"] == 1 def test_fresh_user_empty_until_report(client) -> None: """纯真实(demo 兜底已停用):新用户 summary/battle/records 全空,上报后才有数。""" token = _login(client, "13800002003") # 未上报:无任何 demo,统计全 0、明细空 s0 = client.get("/api/v1/savings/summary", headers=_auth(token)).json() assert s0["order_count"] == 0 assert s0["total_saved_cents"] == 0 b0 = client.get("/api/v1/savings/battle", headers=_auth(token)).json() assert b0["compare_count"] == 0 assert b0["streak_days"] == 0 p0 = client.get("/api/v1/savings/records", headers=_auth(token)).json() assert p0["items"] == [] # 上报一笔真实 → 统计只算这一笔 client.post( "/api/v1/order/report", json=_report_body( client_event_id="evt-real", original_price_cents=5000, paid_amount_cents=4200 ), headers=_auth(token), ) s = client.get("/api/v1/savings/summary", headers=_auth(token)).json() assert s["order_count"] == 1 assert s["total_saved_cents"] == 800 # 5000 − 4200 page = client.get("/api/v1/savings/records", headers=_auth(token)).json() assert len(page["items"]) == 1 assert page["items"][0]["saved_amount_cents"] == 800 def test_order_report_requires_auth(client) -> None: r = client.post("/api/v1/order/report", json=_report_body()) assert r.status_code == 401