40 lines
2.4 KiB
TypeScript
40 lines
2.4 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import { readFile } from "node:fs/promises";
|
|
|
|
const apiUrl = "http://localhost:5302/api";
|
|
|
|
test("CSV export has safe cells and headers, and browser download preserves its UTF-8 bytes", async ({ page }) => {
|
|
await page.addInitScript(() => window.localStorage.setItem("uiLanguage", "en"));
|
|
expect((await page.request.post(`${apiUrl}/auth/login`, { data: { email: "e2e@example.test", password: "E2ePassword123!" } })).status()).toBe(200);
|
|
const me = await (await page.request.get(`${apiUrl}/auth/me`)).json();
|
|
const csrf = (await page.context().cookies()).find(cookie => cookie.name === "XSRF-TOKEN")!.value;
|
|
const headers = { "X-CSRF-TOKEN": csrf, "X-Session-Context": me.sessionContext };
|
|
const companyName = `B05 Ærlig Økonomi Ås ${Date.now()}`;
|
|
const createdCompany = await page.request.post(`${apiUrl}/companies`, { headers, data: { name: companyName } });
|
|
expect(createdCompany.status()).toBe(201);
|
|
const company = await createdCompany.json();
|
|
const createdJob = await page.request.post(`${apiUrl}/jobapplications`, {
|
|
headers, data: { companyId: company.id, jobTitle: "=1+1", status: "Saved", notes: " \t+SUM(1,2)\r\næøå" },
|
|
});
|
|
expect(createdJob.status()).toBe(201);
|
|
const job = await createdJob.json();
|
|
|
|
const response = await page.request.get(`${apiUrl}/export/jobs?format=csv`);
|
|
expect(response.status()).toBe(200);
|
|
expect(response.headers()["content-type"]).toBe("text/csv; charset=utf-8");
|
|
expect(response.headers()["content-disposition"]).toMatch(/^attachment; filename=job-tracker-export-\d{4}-\d{2}-\d{2}\.csv;/);
|
|
const bytes = await response.body();
|
|
expect([...bytes.subarray(0, 3)]).toEqual([0xef, 0xbb, 0xbf]);
|
|
expect(bytes.toString("utf8")).toContain(`${companyName},,,'=1+1,Saved,`);
|
|
expect(bytes.toString("utf8")).toContain('"\' \t+SUM(1,2)\r\næøå"');
|
|
const raw = await (await page.request.get(`${apiUrl}/export/jobs?format=json`)).json();
|
|
expect(raw.find((item: { Id: number }) => item.Id === job.id)).toMatchObject({ JobTitle: "=1+1", Notes: " \t+SUM(1,2)\r\næøå" });
|
|
|
|
await page.goto("/settings");
|
|
const pending = page.waitForEvent("download");
|
|
await page.getByRole("button", { name: "Export CSV", exact: true }).click();
|
|
const download = await pending;
|
|
expect(download.suggestedFilename()).toMatch(/^job-tracker-export-\d{4}-\d{2}-\d{2}\.csv$/);
|
|
expect(await readFile((await download.path())!)).toEqual(bytes);
|
|
});
|