const { MaterialPreviewError, createReimbursementMaterialPreviewStore, } = require("../../../src/services/reimbursementMaterialPreview"); describe("reimbursement material preview store", () => { it("keeps material and PDF page order in a bounded short-lived bundle", async () => { let currentTime = 1_000; const store = createReimbursementMaterialPreviewStore({ now: () => currentTime, randomUUID: () => "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa", rasterizePdf: vi.fn().mockResolvedValue([Buffer.from("pdf-page-1"), Buffer.from("pdf-page-2")]), normalizeImage: vi.fn().mockResolvedValue(Buffer.from("image-page")), }); const created = await store.createBundle({ actorId: "actor-1", reimbursementId: "reimbursement-1", expiresAt: 2_000, materials: [ { id: "invoice-1", materialType: "invoice", materialIndex: 1, mimeType: "application/pdf", fileSize: 10 }, { id: "attachment-1", materialType: "attachment", materialIndex: 1, mimeType: "image/png", fileSize: 10 }, ], readSource: async (material) => Buffer.from(material.id), }); expect(created.bundle.pages.map((page) => [page.materialType, page.materialIndex, page.pageNumber])).toEqual([ ["invoice", 1, 1], ["invoice", 1, 2], ["attachment", 1, 1], ]); expect(store.getPage({ bundleId: created.bundleId, pageIndex: 1 })?.page.buffer.toString()).toBe("pdf-page-2"); currentTime = 2_001; expect(store.getPage({ bundleId: created.bundleId, pageIndex: 0 })).toBeNull(); }); it("rejects source and page limits without keeping a partial bundle", async () => { const store = createReimbursementMaterialPreviewStore({ limits: { maxMaterials: 1, maxSourceBytes: 10, maxPages: 1 }, rasterizePdf: vi.fn().mockResolvedValue([Buffer.from("one"), Buffer.from("two")]), }); await expect(store.createBundle({ actorId: "actor-1", reimbursementId: "reimbursement-1", expiresAt: Date.now() + 1_000, materials: [ { id: "one", materialType: "invoice", materialIndex: 1, mimeType: "application/pdf", fileSize: 6 }, { id: "two", materialType: "attachment", materialIndex: 1, mimeType: "image/png", fileSize: 6 }, ], readSource: async () => Buffer.from("source"), })).rejects.toMatchObject({ code: "material_preview_material_limit" }); await expect(store.createBundle({ actorId: "actor-1", reimbursementId: "reimbursement-1", expiresAt: Date.now() + 1_000, materials: [ { id: "one", materialType: "invoice", materialIndex: 1, mimeType: "application/pdf", fileSize: 6 }, ], readSource: async () => Buffer.from("source"), })).rejects.toBeInstanceOf(MaterialPreviewError); }); });