0954876295
Implement B01-B06 with regression coverage and retained validation evidence. Preserve the production ingress preflight; F04 runtime verification remains open.
34 lines
1.9 KiB
TypeScript
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}$`));
|
|
});
|