diff --git a/src/app/api/v1/purchase-orders/[id]/attachments/[filename]/route.test.ts b/src/app/api/v1/purchase-orders/[id]/attachments/[filename]/route.test.ts new file mode 100644 index 0000000..8a0d44f --- /dev/null +++ b/src/app/api/v1/purchase-orders/[id]/attachments/[filename]/route.test.ts @@ -0,0 +1,66 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +const getOneMock = vi.fn(); +const updateMock = vi.fn(); + +vi.mock("@/lib/server/pocketbase-admin", () => ({ + getAdminPocketBase: vi.fn().mockResolvedValue({ + collection: () => ({ + getOne: getOneMock, + update: updateMock, + }), + }), +})); + +import { DELETE } from "./route"; + +describe("DELETE /api/v1/purchase-orders/[id]/attachments/[filename]", () => { + beforeEach(() => { + getOneMock.mockReset(); + updateMock.mockReset(); + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it("removes the matching token from additional_attachments", async () => { + getOneMock.mockResolvedValueOnce({ + id: "po-1", + additional_attachments: ["keep-me.pdf", "delete-me.pdf"], + }); + updateMock.mockResolvedValueOnce({}); + + const res = await DELETE( + new Request( + "http://localhost/api/v1/purchase-orders/po-1/attachments/delete-me.pdf", + { method: "DELETE" }, + ) as any, + { params: Promise.resolve({ id: "po-1", filename: "delete-me.pdf" }) }, + ); + + expect(res.status).toBe(200); + expect(updateMock).toHaveBeenCalledTimes(1); + expect(updateMock.mock.calls[0][1]).toEqual({ + additional_attachments: ["keep-me.pdf"], + }); + }); + + it("returns 404 when the token is not in the array", async () => { + getOneMock.mockResolvedValueOnce({ + id: "po-1", + additional_attachments: ["only-this.pdf"], + }); + + const res = await DELETE( + new Request( + "http://localhost/api/v1/purchase-orders/po-1/attachments/other.pdf", + { method: "DELETE" }, + ) as any, + { params: Promise.resolve({ id: "po-1", filename: "other.pdf" }) }, + ); + + expect(res.status).toBe(404); + expect(updateMock).not.toHaveBeenCalled(); + }); +});