Files
auto-virtual-tryon-frontend/tests/app/api/orders-create.route.test.ts

221 lines
5.1 KiB
TypeScript

import { afterEach, expect, test, vi } from "vitest";
import { POST } from "../../../app/api/orders/route";
afterEach(() => {
vi.unstubAllEnvs();
vi.unstubAllGlobals();
});
test("proxies order creation to the backend and returns normalized success data", async () => {
vi.stubEnv("BACKEND_BASE_URL", "http://backend.test/api/v1");
const fetchMock = vi.fn().mockResolvedValue(
new Response(
JSON.stringify({
order_id: 77,
workflow_id: "wf-77",
status: "created",
}),
{
status: 201,
headers: {
"content-type": "application/json",
},
},
),
);
vi.stubGlobal("fetch", fetchMock);
const request = new Request("http://localhost/api/orders", {
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
customer_level: "mid",
service_mode: "semi_pro",
model_id: 101,
garment_asset_id: 303,
scene_ref_asset_id: 404,
}),
});
const response = await POST(request);
const payload = await response.json();
expect(response.status).toBe(201);
expect(payload).toEqual({
mode: "proxy",
data: {
orderId: 77,
workflowId: "wf-77",
status: "created",
},
});
expect(fetchMock).toHaveBeenCalledWith(
"http://backend.test/api/v1/orders",
expect.objectContaining({
method: "POST",
}),
);
});
test("rejects invalid order creation payloads before proxying", async () => {
const fetchMock = vi.fn();
vi.stubGlobal("fetch", fetchMock);
const request = new Request("http://localhost/api/orders", {
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
customer_level: "low",
service_mode: "semi_pro",
model_id: 101,
garment_asset_id: 303,
scene_ref_asset_id: 404,
}),
});
const response = await POST(request);
const payload = await response.json();
expect(response.status).toBe(400);
expect(payload).toMatchObject({
error: "VALIDATION_ERROR",
});
expect(fetchMock).not.toHaveBeenCalled();
});
test("rejects malformed JSON before validation or proxying", async () => {
const fetchMock = vi.fn();
vi.stubGlobal("fetch", fetchMock);
const request = new Request("http://localhost/api/orders", {
method: "POST",
headers: {
"content-type": "application/json",
},
body: "{bad json",
});
const response = await POST(request);
const payload = await response.json();
expect(response.status).toBe(400);
expect(payload).toEqual({
error: "INVALID_JSON",
message: "请求体必须是合法 JSON。",
});
expect(fetchMock).not.toHaveBeenCalled();
});
test("normalizes upstream validation errors from the backend", async () => {
vi.stubEnv("BACKEND_BASE_URL", "http://backend.test/api/v1");
const fetchMock = vi.fn().mockResolvedValue(
new Response(
JSON.stringify({
detail: "scene_ref_asset_id is invalid",
}),
{
status: 422,
headers: {
"content-type": "application/json",
},
},
),
);
vi.stubGlobal("fetch", fetchMock);
const request = new Request("http://localhost/api/orders", {
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
customer_level: "mid",
service_mode: "semi_pro",
model_id: 101,
garment_asset_id: 303,
scene_ref_asset_id: 404,
}),
});
const response = await POST(request);
const payload = await response.json();
expect(response.status).toBe(400);
expect(payload).toEqual({
error: "VALIDATION_ERROR",
message: "scene_ref_asset_id is invalid",
details: {
detail: "scene_ref_asset_id is invalid",
},
});
});
test("accepts order creation payloads without a scene asset id", async () => {
vi.stubEnv("BACKEND_BASE_URL", "http://backend.test/api/v1");
const fetchMock = vi.fn().mockResolvedValue(
new Response(
JSON.stringify({
order_id: 88,
workflow_id: "wf-88",
status: "created",
}),
{
status: 201,
headers: {
"content-type": "application/json",
},
},
),
);
vi.stubGlobal("fetch", fetchMock);
const request = new Request("http://localhost/api/orders", {
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
customer_level: "low",
service_mode: "auto_basic",
model_id: 101,
garment_asset_id: 303,
}),
});
const response = await POST(request);
const payload = await response.json();
expect(response.status).toBe(201);
expect(payload).toEqual({
mode: "proxy",
data: {
orderId: 88,
workflowId: "wf-88",
status: "created",
},
});
expect(fetchMock).toHaveBeenCalledWith(
"http://backend.test/api/v1/orders",
expect.objectContaining({
method: "POST",
body: JSON.stringify({
customer_level: "low",
service_mode: "auto_basic",
model_id: 101,
garment_asset_id: 303,
}),
}),
);
});