145 lines
3.4 KiB
TypeScript
145 lines
3.4 KiB
TypeScript
import { afterEach, expect, test, vi } from "vitest";
|
|
|
|
import { POST } from "../../../app/api/reviews/[orderId]/submit/route";
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllEnvs();
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
test("proxies review submission through a dynamic route and normalizes success data", async () => {
|
|
vi.stubEnv("BACKEND_BASE_URL", "http://backend.test/api/v1");
|
|
|
|
const fetchMock = vi.fn().mockResolvedValue(
|
|
new Response(
|
|
JSON.stringify({
|
|
order_id: 101,
|
|
workflow_id: "wf-101",
|
|
decision: "approve",
|
|
status: "queued",
|
|
}),
|
|
{
|
|
status: 200,
|
|
headers: {
|
|
"content-type": "application/json",
|
|
},
|
|
},
|
|
),
|
|
);
|
|
|
|
vi.stubGlobal("fetch", fetchMock);
|
|
|
|
const request = new Request("http://localhost/api/reviews/101/submit", {
|
|
method: "POST",
|
|
headers: {
|
|
"content-type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
decision: "approve",
|
|
reviewer_id: 7,
|
|
selected_asset_id: null,
|
|
comment: null,
|
|
}),
|
|
});
|
|
|
|
const response = await POST(request, {
|
|
params: Promise.resolve({ orderId: "101" }),
|
|
});
|
|
const payload = await response.json();
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(payload).toEqual({
|
|
mode: "proxy",
|
|
data: {
|
|
orderId: 101,
|
|
workflowId: "wf-101",
|
|
decision: "approve",
|
|
decisionMeta: {
|
|
label: "通过",
|
|
tone: "success",
|
|
},
|
|
status: "queued",
|
|
},
|
|
});
|
|
expect(fetchMock).toHaveBeenCalledWith(
|
|
"http://backend.test/api/v1/reviews/101/submit",
|
|
expect.objectContaining({
|
|
method: "POST",
|
|
}),
|
|
);
|
|
});
|
|
|
|
test("rejects invalid dynamic path params before proxying review submission", async () => {
|
|
const fetchMock = vi.fn();
|
|
vi.stubGlobal("fetch", fetchMock);
|
|
|
|
const request = new Request("http://localhost/api/reviews/not-a-number/submit", {
|
|
method: "POST",
|
|
headers: {
|
|
"content-type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
decision: "approve",
|
|
reviewer_id: 7,
|
|
selected_asset_id: null,
|
|
comment: null,
|
|
}),
|
|
});
|
|
|
|
const response = await POST(request, {
|
|
params: Promise.resolve({ orderId: "not-a-number" }),
|
|
});
|
|
const payload = await response.json();
|
|
|
|
expect(response.status).toBe(400);
|
|
expect(payload).toEqual({
|
|
error: "VALIDATION_ERROR",
|
|
message: "orderId 必须是正整数。",
|
|
});
|
|
expect(fetchMock).not.toHaveBeenCalled();
|
|
});
|
|
|
|
test("normalizes upstream not-found responses on review submission", async () => {
|
|
vi.stubEnv("BACKEND_BASE_URL", "http://backend.test/api/v1");
|
|
|
|
const fetchMock = vi.fn().mockResolvedValue(
|
|
new Response(
|
|
JSON.stringify({
|
|
detail: "review task not found",
|
|
}),
|
|
{
|
|
status: 404,
|
|
headers: {
|
|
"content-type": "application/json",
|
|
},
|
|
},
|
|
),
|
|
);
|
|
|
|
vi.stubGlobal("fetch", fetchMock);
|
|
|
|
const request = new Request("http://localhost/api/reviews/999/submit", {
|
|
method: "POST",
|
|
headers: {
|
|
"content-type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
decision: "approve",
|
|
reviewer_id: 7,
|
|
selected_asset_id: null,
|
|
comment: null,
|
|
}),
|
|
});
|
|
|
|
const response = await POST(request, {
|
|
params: Promise.resolve({ orderId: "999" }),
|
|
});
|
|
const payload = await response.json();
|
|
|
|
expect(response.status).toBe(404);
|
|
expect(payload).toEqual({
|
|
error: "NOT_FOUND",
|
|
message: "review task not found",
|
|
});
|
|
});
|