Files
pleno-vue/tests/e2e/superuser-department-branding.spec.js

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();
});
});