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.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
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}$`));
|
||||
});
|
||||
Reference in New Issue
Block a user