feat: add AssetItem.purchaseOrderId (nullable FK)
This commit is contained in:
+97
-2
@@ -24,10 +24,42 @@ function postRequest(body: unknown): Request {
|
||||
});
|
||||
}
|
||||
|
||||
// AssetItem.purchaseOrderId is a real FK to PurchaseOrder (see
|
||||
// schema.prisma / src/lib/assets.ts), and PurchaseOrder.vendorId is a real
|
||||
// FK to Vendor — tests that need a valid purchaseOrderId create real rows
|
||||
// first and use their ids. Mirrors tests/purchase-orders.test.ts's
|
||||
// createTestVendor() helper.
|
||||
function createTestVendor(overrides: { name?: string } = {}) {
|
||||
return prisma.vendor.create({
|
||||
data: {
|
||||
name: overrides.name ?? "Test Vendor",
|
||||
contactEmail: "[email protected]",
|
||||
contactPhone: "0281234567",
|
||||
address: "123 Test Street",
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function createTestPurchaseOrder(overrides: { vendorId?: string } = {}) {
|
||||
return prisma.purchaseOrder.create({
|
||||
data: {
|
||||
vendorId: overrides.vendorId as string,
|
||||
orderDate: new Date("2026-08-01"),
|
||||
expectedDate: new Date("2026-08-10"),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
// Each test starts from an empty table so listing/order assertions are
|
||||
// deterministic.
|
||||
// Each test starts from empty tables so listing/order assertions are
|
||||
// deterministic. asset_items must be cleared before purchase_orders/
|
||||
// vendors since asset_items has FKs (ON DELETE SET NULL to
|
||||
// purchase_orders) — deleteMany order avoids relying on that cascade
|
||||
// behavior in tests. purchase_orders must be cleared before vendors
|
||||
// (ON DELETE RESTRICT to vendors, mirrors tests/purchase-orders.test.ts).
|
||||
await prisma.assetItem.deleteMany();
|
||||
await prisma.purchaseOrder.deleteMany();
|
||||
await prisma.vendor.deleteMany();
|
||||
// Default to a logged-in session — the tests below exercise business
|
||||
// logic, not auth gating (that's covered by the "auth gating" describe
|
||||
// block further down).
|
||||
@@ -111,6 +143,69 @@ describe("POST /api/assets", () => {
|
||||
expect(body.error).toMatch(/warrantyEndDate/i);
|
||||
});
|
||||
|
||||
it("creates an asset item with a purchaseOrderId that references a real purchase order", async () => {
|
||||
const vendor = await createTestVendor();
|
||||
const purchaseOrder = await createTestPurchaseOrder({ vendorId: vendor.id });
|
||||
|
||||
const res = await POST(
|
||||
postRequest({
|
||||
serialNumber: "SN-007",
|
||||
model: "Dell Latitude 5440",
|
||||
purchaseDate: "2026-01-15",
|
||||
purchaseOrderId: purchaseOrder.id,
|
||||
})
|
||||
);
|
||||
|
||||
expect(res.status).toBe(201);
|
||||
const body = await res.json();
|
||||
expect(body.purchase_order_id).toBe(purchaseOrder.id);
|
||||
});
|
||||
|
||||
it("creates an asset item with no purchaseOrderId (stays null)", async () => {
|
||||
const res = await POST(
|
||||
postRequest({ serialNumber: "SN-008", model: "Dell Latitude 5440", purchaseDate: "2026-01-15" })
|
||||
);
|
||||
|
||||
expect(res.status).toBe(201);
|
||||
const body = await res.json();
|
||||
expect(body.purchase_order_id).toBeNull();
|
||||
});
|
||||
|
||||
it("rejects a purchaseOrderId that is a well-formed UUID but doesn't reference an existing purchase order", async () => {
|
||||
const res = await POST(
|
||||
postRequest({
|
||||
serialNumber: "SN-009",
|
||||
model: "Dell Latitude 5440",
|
||||
purchaseDate: "2026-01-15",
|
||||
purchaseOrderId: "00000000-0000-0000-0000-000000000000",
|
||||
})
|
||||
);
|
||||
|
||||
expect(res.status).toBe(400);
|
||||
const body = await res.json();
|
||||
expect(body.error).toMatch(/purchaseOrderId/i);
|
||||
expect(body.error).toMatch(/does not reference an existing purchase order/i);
|
||||
|
||||
// And it must not have created anything.
|
||||
const remaining = await prisma.assetItem.findMany();
|
||||
expect(remaining).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("rejects a purchaseOrderId that is not a valid UUID", async () => {
|
||||
const res = await POST(
|
||||
postRequest({
|
||||
serialNumber: "SN-012",
|
||||
model: "Dell Latitude 5440",
|
||||
purchaseDate: "2026-01-15",
|
||||
purchaseOrderId: "not-a-uuid",
|
||||
})
|
||||
);
|
||||
|
||||
expect(res.status).toBe(400);
|
||||
const body = await res.json();
|
||||
expect(body.error).toMatch(/purchaseOrderId/i);
|
||||
});
|
||||
|
||||
it("rejects a duplicate serialNumber", async () => {
|
||||
await POST(postRequest({ serialNumber: "SN-006", model: "Dell", purchaseDate: "2026-01-15" }));
|
||||
const res = await POST(postRequest({ serialNumber: "SN-006", model: "HP", purchaseDate: "2026-02-01" }));
|
||||
|
||||
Reference in New Issue
Block a user