test(collection-map): cover ready_notes required-on-ready

This commit is contained in:
SJCoetz 2026-07-10 00:05:54 +02:00
parent 13165bfb8c
commit 00fb9a38f0

View file

@ -0,0 +1,99 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { NextRequest } from "next/server";
const getOneMock = vi.fn();
const updateMock = vi.fn();
vi.mock("@/lib/server/pocketbase-admin", () => ({
getAdminPocketBase: vi.fn().mockResolvedValue({
collection: () => ({
getOne: getOneMock,
update: updateMock,
}),
}),
}));
import { PATCH } from "./route";
function makeReq(body: unknown) {
return new NextRequest(
"http://localhost/api/v1/collection-map/items/item-1/assign",
{
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
},
);
}
describe("PATCH /api/v1/collection-map/items/[id]/assign", () => {
beforeEach(() => {
getOneMock.mockReset();
updateMock.mockReset();
});
afterEach(() => {
vi.clearAllMocks();
});
it("writes trimmed notes to the item when ready_notes is provided", async () => {
getOneMock.mockResolvedValueOnce({ id: "item-1" });
updateMock.mockResolvedValueOnce({ id: "item-1" });
const res = await PATCH(
makeReq({
ready_for_collection: true,
ready_notes: " spoke to David, ETA tomorrow ",
}),
{ params: Promise.resolve({ id: "item-1" }) },
);
expect(res.status).toBe(200);
const payload = updateMock.mock.calls[0][1] as Record<string, unknown>;
expect(payload.notes).toBe("spoke to David, ETA tomorrow");
expect(payload.ready_for_collection).toBe(true);
});
it("returns 400 when ready_for_collection is true and ready_notes is empty", async () => {
const res = await PATCH(
makeReq({ ready_for_collection: true, ready_notes: "" }),
{ params: Promise.resolve({ id: "item-1" }) },
);
expect(res.status).toBe(400);
expect(updateMock).not.toHaveBeenCalled();
});
it("returns 400 when ready_for_collection is true and ready_notes is whitespace only", async () => {
const res = await PATCH(
makeReq({ ready_for_collection: true, ready_notes: " \n\t " }),
{ params: Promise.resolve({ id: "item-1" }) },
);
expect(res.status).toBe(400);
expect(updateMock).not.toHaveBeenCalled();
});
it("returns 400 when ready_for_collection is true and ready_notes is missing", async () => {
const res = await PATCH(
makeReq({ ready_for_collection: true }),
{ params: Promise.resolve({ id: "item-1" }) },
);
expect(res.status).toBe(400);
expect(updateMock).not.toHaveBeenCalled();
});
it("accepts the unmark path without a note (ready_for_collection: false)", async () => {
getOneMock.mockResolvedValueOnce({ id: "item-1", notes: "existing" });
updateMock.mockResolvedValueOnce({ id: "item-1" });
const res = await PATCH(
makeReq({ ready_for_collection: false }),
{ params: Promise.resolve({ id: "item-1" }) },
);
expect(res.status).toBe(200);
const payload = updateMock.mock.calls[0][1] as Record<string, unknown>;
expect(payload.ready_for_collection).toBe(false);
// The unmark path must not silently overwrite the existing note.
expect(payload.notes).toBeUndefined();
});
});