201 lines
7.8 KiB
JavaScript
201 lines
7.8 KiB
JavaScript
import { expect, test } from "@playwright/test";
|
|
import { mockApi, seedAuthenticatedState } from "./support/network.js";
|
|
import { isDesktopProject } from "./support/projects";
|
|
|
|
const json = (body, status = 200) => ({
|
|
status,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(body),
|
|
});
|
|
|
|
const clone = (value) => JSON.parse(JSON.stringify(value));
|
|
|
|
const apiUrlPattern = (path) =>
|
|
new RegExp(
|
|
`https?:\\/\\/(?:api\\.truckwash\\.io(?::\\d+)?${path}|(?:localhost|127\\.0\\.0\\.1)(?::\\d+)?\\/api${path})(?:\\?.*)?$`
|
|
);
|
|
|
|
function createBrandingState({ departmentBranding = 14 } = {}) {
|
|
return {
|
|
nextBrandingId: 16,
|
|
department: {
|
|
id: 1,
|
|
name: "Esbjerg",
|
|
description: "Skagerrakvej 15, 6715 Esbjerg",
|
|
branding: departmentBranding,
|
|
created_at: "2026-01-01 00:00:00",
|
|
updated_at: "2026-01-01 00:00:00",
|
|
},
|
|
brands: [
|
|
{
|
|
id: 14,
|
|
name: "Esbjerg",
|
|
description: "Skagerrakvej 15, 6715 Esbjerg",
|
|
cvr: 41004355,
|
|
address: "Skagerrakvej 15, 6715 Esbjerg",
|
|
phone_country_code: 45,
|
|
phone: 76123456,
|
|
email: "esbjerg@example.test",
|
|
website: "https://esbjerg.example.test",
|
|
banner: "https://cdn.example.test/esbjerg-banner.png",
|
|
logo: "https://cdn.example.test/esbjerg-logo.png",
|
|
favicon: "https://cdn.example.test/esbjerg.ico",
|
|
signature: "https://cdn.example.test/esbjerg-signature.png",
|
|
},
|
|
{
|
|
id: 15,
|
|
name: "Copenhagen Brand",
|
|
description: "Copenhagen profile",
|
|
cvr: 43423010,
|
|
address: "Vaskevej 1, 1000 Copenhagen",
|
|
phone_country_code: 45,
|
|
phone: 70112233,
|
|
email: "cph@example.test",
|
|
website: "https://cph.example.test",
|
|
banner: null,
|
|
logo: "https://cdn.example.test/cph-logo.png",
|
|
favicon: null,
|
|
signature: null,
|
|
},
|
|
],
|
|
};
|
|
}
|
|
|
|
async function installBrandingRoutes(page, state) {
|
|
await page.route(apiUrlPattern("/superuser/department(?:/branding)?"), async (route) => {
|
|
const request = route.request();
|
|
const parsedUrl = new URL(request.url());
|
|
const method = request.method();
|
|
|
|
if (parsedUrl.pathname.endsWith("/superuser/department/branding") && method === "PUT") {
|
|
const body = request.postDataJSON?.() || {};
|
|
state.department.branding =
|
|
body.branding_id === null || body.branding_id === "" || body.branding_id === 0
|
|
? null
|
|
: Number(body.branding_id);
|
|
await route.fulfill(json({ data: clone(state.department) }));
|
|
return;
|
|
}
|
|
|
|
if (parsedUrl.pathname.endsWith("/superuser/department") && method === "GET") {
|
|
await route.fulfill(json({ data: clone(state.department) }));
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(json({ message: "Unhandled department branding mock" }, 500));
|
|
});
|
|
|
|
await page.route(apiUrlPattern("/branding"), async (route) => {
|
|
const request = route.request();
|
|
const parsedUrl = new URL(request.url());
|
|
const method = request.method();
|
|
|
|
if (method === "GET") {
|
|
const requestedId = Number(parsedUrl.searchParams.get("id") || 0);
|
|
if (requestedId > 0) {
|
|
const brand = state.brands.find((entry) => entry.id === requestedId);
|
|
await route.fulfill(brand ? json({ data: clone(brand) }) : json({ message: "Invalid id" }, 400));
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(json({ data: clone(state.brands) }));
|
|
return;
|
|
}
|
|
|
|
if (method === "PUT") {
|
|
const body = request.postDataJSON?.() || {};
|
|
const brandIndex = state.brands.findIndex((entry) => entry.id === Number(body.id));
|
|
if (brandIndex === -1) {
|
|
await route.fulfill(json({ message: "Invalid id" }, 400));
|
|
return;
|
|
}
|
|
|
|
state.brands[brandIndex] = {
|
|
...state.brands[brandIndex],
|
|
...body,
|
|
id: Number(body.id),
|
|
};
|
|
await route.fulfill(json({ data: clone(state.brands[brandIndex]) }));
|
|
return;
|
|
}
|
|
|
|
if (method === "POST") {
|
|
const body = request.postDataJSON?.() || {};
|
|
const brand = {
|
|
id: state.nextBrandingId++,
|
|
...body,
|
|
};
|
|
state.brands.push(brand);
|
|
await route.fulfill(json({ data: clone(brand) }));
|
|
return;
|
|
}
|
|
|
|
await route.fulfill(json({ message: "Unhandled branding mock" }, 500));
|
|
});
|
|
}
|
|
|
|
async function openBrandingPage(page, state) {
|
|
await seedAuthenticatedState(page, "superuser-branding-token");
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: ["superuser", "user"],
|
|
});
|
|
await installBrandingRoutes(page, state);
|
|
await page.goto("/superuser/departments/1/branding", { waitUntil: "domcontentloaded" });
|
|
await expect(page.getByTestId("department-branding-system")).toBeVisible();
|
|
}
|
|
|
|
test.describe("superuser department branding", () => {
|
|
test("edits branding values and switches the department to another brand", async ({ page }, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Department branding form coverage is desktop-focused.");
|
|
const state = createBrandingState();
|
|
await openBrandingPage(page, state);
|
|
|
|
await expect(page.getByTestId("department-branding-department-name")).toContainText("Esbjerg");
|
|
await expect(page.getByTestId("department-branding-input-name")).toHaveValue("Esbjerg");
|
|
await page.getByTestId("department-branding-input-name").fill("Esbjerg Premium");
|
|
await page.getByTestId("department-branding-input-email").fill("premium@example.test");
|
|
await page.getByTestId("department-branding-input-logo").fill("https://cdn.example.test/premium-logo.png");
|
|
|
|
await page.getByTestId("department-branding-save").click();
|
|
|
|
await expect(page.getByTestId("department-branding-status")).toContainText("Branding saved.");
|
|
await expect(page.getByTestId("department-branding-preview-name")).toContainText("Esbjerg Premium");
|
|
expect(state.brands.find((brand) => brand.id === 14)?.email).toBe("premium@example.test");
|
|
expect(state.brands.find((brand) => brand.id === 14)?.logo).toBe("https://cdn.example.test/premium-logo.png");
|
|
|
|
await page.getByTestId("department-branding-select").selectOption("15");
|
|
await page.getByTestId("department-branding-assign").click();
|
|
|
|
await expect(page.getByTestId("department-branding-status")).toContainText("Branding assigned.");
|
|
await expect(page.getByTestId("department-branding-input-name")).toHaveValue("Copenhagen Brand");
|
|
await expect(page.getByTestId("department-branding-select")).toHaveValue("15");
|
|
expect(state.department.branding).toBe(15);
|
|
});
|
|
|
|
test("creates a brand for an unbranded department and can clear it", async ({ page }, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Department branding form coverage is desktop-focused.");
|
|
const state = createBrandingState({ departmentBranding: null });
|
|
await openBrandingPage(page, state);
|
|
|
|
await expect(page.getByTestId("department-branding-select")).toHaveValue("");
|
|
await page.getByTestId("department-branding-input-name").fill("New Department Brand");
|
|
await page.getByTestId("department-branding-input-description").fill("New branding profile");
|
|
await page.getByTestId("department-branding-input-cvr").fill("41004355");
|
|
await page.getByTestId("department-branding-input-address").fill("Brandvej 7, 6700 Esbjerg");
|
|
|
|
await page.getByTestId("department-branding-save").click();
|
|
|
|
await expect(page.getByTestId("department-branding-status")).toContainText("Branding created.");
|
|
expect(state.department.branding).toBe(16);
|
|
expect(state.brands.find((brand) => brand.id === 16)?.name).toBe("New Department Brand");
|
|
await expect(page.getByTestId("department-branding-select")).toHaveValue("16");
|
|
|
|
await page.getByTestId("department-branding-clear").click();
|
|
|
|
await expect(page.getByTestId("department-branding-status")).toContainText("Branding removed.");
|
|
await expect(page.getByTestId("department-branding-select")).toHaveValue("");
|
|
expect(state.department.branding).toBeNull();
|
|
});
|
|
});
|