import { beforeEach, describe, expect, it } from "vitest"; import { GET, POST } from "@/app/api/requests/route"; import { prisma } from "@/lib/prisma"; function postRequest(body: unknown): Request { return new Request("http://localhost/api/requests", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body), }); } beforeEach(async () => { // Each test starts from an empty table so listing/order assertions are // deterministic. await prisma.request.deleteMany(); }); describe("POST /api/requests", () => { it("creates a request in Draft status on valid input", async () => { const res = await POST( postRequest({ employee_id: "emp-1", type: "asset", reason: "New laptop for onboarding" }) ); expect(res.status).toBe(201); const body = await res.json(); expect(body).toMatchObject({ employee_id: "emp-1", type: "asset", reason: "New laptop for onboarding", status: "Draft", }); expect(typeof body.id).toBe("string"); expect(body.id.length).toBeGreaterThan(0); expect(typeof body.created_at).toBe("string"); expect(Number.isNaN(Date.parse(body.created_at))).toBe(false); }); it("rejects requests with missing required fields", async () => { const res = await POST(postRequest({ employee_id: "", type: "asset", reason: "" })); expect(res.status).toBe(400); const body = await res.json(); expect(typeof body.error).toBe("string"); expect(body.error.length).toBeGreaterThan(0); }); it("rejects requests missing the reason field entirely", async () => { const res = await POST(postRequest({ employee_id: "emp-1", type: "asset" })); expect(res.status).toBe(400); const body = await res.json(); expect(typeof body.error).toBe("string"); }); it("rejects an invalid type value", async () => { const res = await POST( postRequest({ employee_id: "emp-1", type: "not-a-real-type", reason: "Something" }) ); expect(res.status).toBe(400); const body = await res.json(); expect(body.error).toMatch(/type/i); }); }); describe("GET /api/requests", () => { it("lists created requests, newest first", async () => { await POST(postRequest({ employee_id: "emp-1", type: "asset", reason: "First request" })); // Ensure a distinct created_at ordering even on fast filesystems/clocks. await new Promise((resolve) => setTimeout(resolve, 5)); await POST(postRequest({ employee_id: "emp-2", type: "license", reason: "Second request" })); const res = await GET(); expect(res.status).toBe(200); const body = await res.json(); expect(Array.isArray(body)).toBe(true); expect(body).toHaveLength(2); // newest first expect(body[0]).toMatchObject({ employee_id: "emp-2", type: "license", status: "Draft" }); expect(body[1]).toMatchObject({ employee_id: "emp-1", type: "asset", status: "Draft" }); }); it("returns an empty list when there are no requests", async () => { const res = await GET(); expect(res.status).toBe(200); const body = await res.json(); expect(body).toEqual([]); }); });