Files
jobtrackingapp/job-tracker-ui/src/csv-export.test.tsx
cesnimda 0954876295 fix(security): enforce audited account, network and resource boundaries
Implement B01-B06 with regression coverage and retained validation evidence. Preserve the production ingress preflight; F04 runtime verification remains open.
2026-09-09 18:21:47 +02:00

34 lines
1.9 KiB
TypeScript

import React from "react";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import ImportExportJobs from "./components/ImportExportJobs";
import { I18nProvider } from "./i18n/I18nProvider";
import { ToastProvider } from "./toast";
import { api } from "./api";
const mockedApi = api as jest.Mocked<typeof api>;
const readBytes = (blob: Blob) => new Promise<Uint8Array>((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(new Uint8Array(reader.result as ArrayBuffer));
reader.onerror = reject;
reader.readAsArrayBuffer(blob);
});
afterEach(() => jest.restoreAllMocks());
test.each(["csv", "json"])("%s download preserves server bytes and a generated safe filename", async (format) => {
const bytes = new TextEncoder().encode(format === "csv" ? "\ufeffCompany,JobTitle\r\nÆrlig,'=1+1\r\n" : '[{"jobTitle":"=1+1","company":"Ærlig"}]');
const incoming = new Blob([bytes]);
mockedApi.get.mockResolvedValue({ data: incoming });
const createUrl = jest.fn<string, [Blob]>(() => "blob:csv-export");
Object.defineProperty(URL, "createObjectURL", { configurable: true, value: createUrl });
Object.defineProperty(URL, "revokeObjectURL", { configurable: true, value: jest.fn() });
let filename = "";
jest.spyOn(HTMLAnchorElement.prototype, "click").mockImplementation(function (this: HTMLAnchorElement) { filename = this.download; });
render(<ToastProvider><I18nProvider><ImportExportJobs /></I18nProvider></ToastProvider>);
fireEvent.click(screen.getByRole("button", { name: `Export ${format.toUpperCase()}` }));
await waitFor(() => expect(createUrl).toHaveBeenCalledTimes(1));
expect(mockedApi.get).toHaveBeenCalledWith(`/export/jobs?format=${format}&includeDeleted=false`, { responseType: "blob" });
expect(await readBytes(createUrl.mock.calls[0][0])).toEqual(bytes);
expect(filename).toMatch(new RegExp(`^job-tracker-export-\\d{4}-\\d{2}-\\d{2}\\.${format}$`));
});