Files
pleno-vue/tests/e2e/superuser-customers-mass-import.spec.ts
T

234 lines
6.9 KiB
TypeScript

import { Buffer } from "node:buffer";
import { expect, test, type Page } from "@playwright/test";
import * as XLSX from "xlsx";
import { seedAuthenticatedState } from "./support/network.js";
import { isDesktopProject } from "./support/projects";
const json = (body: unknown, status = 200) => ({
status,
contentType: "application/json",
body: JSON.stringify(body),
});
const buildWorkbookBuffer = () => {
const workbook = XLSX.utils.book_new();
const worksheet = XLSX.utils.aoa_to_sheet([
["CVR", "Navn", "Email", "EAN", "Telefon nummer"],
["31744520", "SPF-DANMARK A/S", "spf@example.com", "5790000000001", "76964600"],
["26761751", "STEA A/S", "", "", "75773355"],
]);
XLSX.utils.book_append_sheet(workbook, worksheet, "Customers");
return Buffer.from(XLSX.write(workbook, { type: "buffer", bookType: "xlsx" }));
};
async function gotoCustomersImportPage(page: Page) {
const importButton = page.getByTestId("superuser-customers-mass-import-button");
for (let attempt = 1; attempt <= 3; attempt += 1) {
await page.goto("/superuser/customers", { waitUntil: "domcontentloaded" });
if ((await importButton.count()) > 0) {
return importButton;
}
await page.waitForTimeout(1_000 * attempt);
}
return importButton;
}
test.describe("Superuser customers mass import", () => {
test("parses spreadsheet rows with blank middle columns and submits them row-by-row", async ({ page }, testInfo) => {
test.skip(!isDesktopProject(testInfo), "Desktop only");
const importPayloads: Array<Record<string, unknown>> = [];
await page.route(/https?:\/\/(?:api\.truckwash\.io(?::\d+)?)\/.*/i, async (route) => {
const request = route.request();
const url = new URL(request.url());
const pathname = url.pathname;
const method = request.method();
if (pathname.endsWith("/auth/session") && method === "GET") {
await route.fulfill(
json({
data: {
id: 1,
customer_number: 12345,
group_id: 1,
email: "superuser@example.com",
phone: {
number: "12345678",
country_code: 45,
},
notifications: {
wash_certificate_email: null,
email_notifications_enabled: true,
sms_notifications_enabled: false,
},
display_name: "E2E Superuser",
permissions: ["superuser", "search_customers", "add_user", "user"],
economic_customer: [],
runtime_config: {
economic: {
transaction_draft_customer_number: null,
},
},
},
})
);
return;
}
if (
(pathname.endsWith("/auth/recaptcha/pre-check") || pathname.endsWith("/auth/reCAPTCHA/public")) &&
method === "GET"
) {
await route.fulfill(
json({
data: {
recaptcha: {
enabled: false,
site_key: "",
},
rate_limit: {
enabled: false,
limit: 0,
remaining: 0,
reset: 0,
warning: null,
},
},
})
);
return;
}
if (pathname.endsWith("/ping") && method === "GET") {
await route.fulfill(json({ data: { ok: true } }));
return;
}
if (pathname.endsWith("/worker/version") && method === "GET") {
await route.fulfill(json({ data: { version: "test-build" } }));
return;
}
if (pathname.endsWith("/departments") && method === "GET") {
await route.fulfill(json({ data: [{ id: 1, name: "Hvidovre", visible: true }] }));
return;
}
if (pathname.endsWith("/customers") && method === "GET") {
await route.fulfill(
json({
data: [
{
id: 88,
customerNumber: 44556677,
name: "Existing Customer",
email: "existing@example.com",
balance: 0,
currency: "DKK",
barred: false,
},
],
meta: {
pagination: {
page: 1,
per_page: 100,
total: 1,
},
},
})
);
return;
}
if (pathname.endsWith("/customers/import") && method === "POST") {
const body = request.postDataJSON() as Record<string, unknown>;
importPayloads.push(body);
if (String(body.customer_number) === "75773355") {
await route.fulfill(
json(
{
data: {
message: "Customer already exists locally and already has a login account.",
},
},
409
)
);
return;
}
await route.fulfill(
json({
data: {
action: "created_customer",
message: "Created the customer in e-conomic and imported it locally.",
customer_number: Number(body.customer_number),
has_account: false,
},
})
);
return;
}
await route.fulfill(json({ data: [] }));
});
await seedAuthenticatedState(page, "superuser-customers-import-token");
const importButton = await gotoCustomersImportPage(page);
await expect(importButton).toBeVisible();
await importButton.click();
await expect(page.getByTestId("mass-data-inserter-modal")).toBeVisible();
const [fileChooser] = await Promise.all([
page.waitForEvent("filechooser"),
page.getByTestId("mass-data-insert-add-button").click(),
]);
await fileChooser.setFiles({
name: "customers.xlsx",
mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
buffer: buildWorkbookBuffer(),
});
const modal = page.getByTestId("mass-data-inserter-modal");
await expect(modal).toContainText("SPF-DANMARK A/S");
await expect(modal).toContainText("76964600");
await expect(modal).toContainText("STEA A/S");
await expect(modal).toContainText("75773355");
await page.getByTestId("mass-data-insert-save-button").click();
await expect.poll(() => importPayloads.length).toBe(2);
expect(importPayloads[0]).toMatchObject({
cvr: "31744520",
name: "SPF-DANMARK A/S",
email: "spf@example.com",
ean: "5790000000001",
phone: "76964600",
customer_number: "76964600",
});
expect(importPayloads[1]).toMatchObject({
cvr: "26761751",
name: "STEA A/S",
email: null,
ean: null,
phone: "75773355",
customer_number: "75773355",
});
await expect(modal.locator(".tag.is-success")).toHaveCount(1);
await expect(modal.locator(".tag.is-danger")).toHaveCount(1);
});
});