import { beforeEach, describe, expect, it, vi } from "vitest"; vi.mock("@/lib/api/auth-context", () => ({ parseServiceAuth: vi.fn(), assertCustomerMatch: vi.fn(), })); vi.mock("@/lib/api/rate-limit", () => ({ enforceRateLimits: vi.fn().mockResolvedValue(null), })); vi.mock("@/modules/mothership/refine-service", () => ({ declineMsRefineHold: vi.fn(), continueMsRefineHold: vi.fn(), submitMsRefineDetails: vi.fn(), })); import { parseServiceAuth, assertCustomerMatch } from "@/lib/api/auth-context"; import { POST as declinePost } from "@/app/api/quotes/refine-hold/decline/route"; import { POST as continuePost } from "@/app/api/quotes/refine-hold/continue/route"; import { POST as refineDetailsPost } from "@/app/api/quotes/refine-details/route"; import { continueMsRefineHold, declineMsRefineHold, submitMsRefineDetails, } from "@/modules/mothership/refine-service"; const SESSION = "00000000-0000-4000-8000-000000000001"; function authOk() { vi.mocked(parseServiceAuth).mockResolvedValue({ authType: "service", customerId: "CUST_001", permissions: [], } as never); vi.mocked(assertCustomerMatch).mockImplementation(() => undefined); } function jsonReq(url: string, body: unknown) { return new Request(url, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body), }); } describe("refine-hold / refine-details API", () => { beforeEach(() => { vi.clearAllMocks(); authOk(); }); it("decline:参数非法 → 400", async () => { const res = await declinePost( jsonReq("http://localhost/api/quotes/refine-hold/decline", { customer_id: "CUST_001", quote_id: "q1", quote_session_id: "not-uuid", }), ); expect(res.status).toBe(400); const body = await res.json(); expect(body.code).not.toBe(0); }); it("decline:成功 → ok released", async () => { vi.mocked(declineMsRefineHold).mockResolvedValue({ released: true }); const res = await declinePost( jsonReq("http://localhost/api/quotes/refine-hold/decline", { customer_id: "CUST_001", quote_id: "q1", quote_session_id: SESSION, }), ); expect(res.status).toBe(200); const body = await res.json(); expect(body.code).toBe(0); expect(body.data.released).toBe(true); }); it("continue:成功 → filling", async () => { vi.mocked(continueMsRefineHold).mockResolvedValue({ status: "filling" }); const res = await continuePost( jsonReq("http://localhost/api/quotes/refine-hold/continue", { customer_id: "CUST_001", quote_id: "q1", quote_session_id: SESSION, }), ); const body = await res.json(); expect(body.code).toBe(0); expect(body.data.status).toBe("filling"); }); it("continue:业务超时 → 400 中文", async () => { vi.mocked(continueMsRefineHold).mockRejectedValue( new Error("确认窗口已超时,请重新询价"), ); const res = await continuePost( jsonReq("http://localhost/api/quotes/refine-hold/continue", { customer_id: "CUST_001", quote_id: "q1", quote_session_id: SESSION, }), ); expect(res.status).toBe(400); const body = await res.json(); expect(body.message).toMatch(/确认窗口已超时/); }); it("refine-details:成功入队", async () => { vi.mocked(submitMsRefineDetails).mockResolvedValue({ quote_id: "q1", status: "processing", }); const res = await refineDetailsPost( jsonReq("http://localhost/api/quotes/refine-details", { customer_id: "CUST_001", quote_id: "q1", quote_session_id: SESSION, mothership_details: { pickup: { company_name: "Acme" } }, }), ); const body = await res.json(); expect(body.code).toBe(0); expect(body.data.status).toBe("processing"); }); it("refine-details:缺 quote_id → 校验失败", async () => { const res = await refineDetailsPost( jsonReq("http://localhost/api/quotes/refine-details", { customer_id: "CUST_001", quote_session_id: SESSION, }), ); expect(res.status).toBe(400); }); });