feat(import): harden workbook parser boundaries

This commit is contained in:
2026-03-31 22:48:30 +02:00
parent 3e8b1702bc
commit db50e2e555
20 changed files with 936 additions and 174 deletions
@@ -1,4 +1,3 @@
import * as XLSX from "xlsx";
import {
EstimateExportFormat,
EstimateStatus,
@@ -144,8 +143,8 @@ function buildSource(): EstimateExportSource {
}
describe("estimate export serializer", () => {
it("creates a structured JSON export payload", () => {
const payload = serializeEstimateExport(buildSource(), EstimateExportFormat.JSON);
it("creates a structured JSON export payload", async () => {
const payload = await serializeEstimateExport(buildSource(), EstimateExportFormat.JSON);
expect(payload.encoding).toBe("utf8");
expect(payload.mimeType).toBe("application/json; charset=utf-8");
@@ -154,9 +153,16 @@ describe("estimate export serializer", () => {
expect(payload.previewText).toContain('"schemaVersion": 1');
});
it("creates a multi-sheet xlsx export payload", () => {
const payload = serializeEstimateExport(buildSource(), EstimateExportFormat.XLSX);
const workbook = XLSX.read(payload.content, { type: "base64" });
it("creates a multi-sheet xlsx export payload", async () => {
const payload = await serializeEstimateExport(buildSource(), EstimateExportFormat.XLSX);
const ExcelJS = await import("exceljs");
const workbook = new ExcelJS.Workbook();
const workbookBytes = Uint8Array.from(Buffer.from(payload.content, "base64"));
const workbookBuffer = workbookBytes.buffer.slice(
workbookBytes.byteOffset,
workbookBytes.byteOffset + workbookBytes.byteLength,
);
await workbook.xlsx.load(workbookBuffer);
expect(payload.encoding).toBe("base64");
expect(payload.sheetNames).toEqual([
@@ -167,7 +173,7 @@ describe("estimate export serializer", () => {
"Resources",
"Metrics",
]);
expect(workbook.SheetNames).toContain("DemandLines");
expect(workbook.getWorksheet("DemandLines")).toBeDefined();
expect(payload.byteLength).toBeGreaterThan(100);
});
});