Files
pleno-vue/tests/e2e/superuser-department-pricing-custom-only.spec.ts

219 lines
7.8 KiB
TypeScript

import { expect, test } from "@playwright/test";
import { mockApi, 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 now = "2026-07-06 10:00:00";
const buildProduct = (product: Record<string, unknown>) => ({
description: "E2E product",
subscription_allowed: true,
category: 1,
piktogram: "truck",
economic_product_id: 0,
apply_category_discount: false,
requires_note: false,
created_at: now,
updated_at: now,
addons: [],
is_wash: true,
display_in_booking_form: true,
order_priority: 1,
...product,
});
test.describe("Superuser department custom-only pricing", () => {
test("toggles no-fallback pricing and shows 999999 for missing department prices", async ({ page }, testInfo) => {
test.skip(!isDesktopProject(testInfo), "Desktop only");
const customPricingOnlyByDepartment: Record<number, "0" | "1"> = {
42: "0",
43: "0",
};
let receivedToggleBody: Record<string, unknown> | null = null;
let receivedCustomerPricingBody: Record<string, unknown> | null = null;
const products = [
buildProduct({ id: 10, name: "Fallback Wash", price: 12345 }),
buildProduct({ id: 11, name: "Explicit Wash", price: 98765, order_priority: 2 }),
];
const customerPricingPayload = (overrides: Array<Record<string, unknown>> = []) => ({
department: {
id: 42,
name: "Custom Pricing Department",
description: "E2E department",
custom_pricing_only: customPricingOnlyByDepartment[42],
},
customer: {
id: 601,
customer_number: 6001,
display_name: "Acme Haulage",
},
overrides,
categories: [
{
id: 1,
name: "Wash",
description: "",
products: [
{
id: 11,
name: "Explicit Wash",
description: "E2E product",
category: 1,
apply_category_discount: true,
base_price: 98765,
department_price: 2222,
effective_price: overrides.length ? 1667 : 2222,
missing_department_price: false,
},
],
},
],
});
await page.setViewportSize({ width: 1280, height: 720 });
await seedAuthenticatedState(page, "superuser-department-pricing-token");
await mockApi(page, {
authenticated: true,
permissions: [
"superuser",
"user",
"list_products",
"list_departments",
"edit_department",
"superuser_fetch_department",
"superuser_fetch_department_prices",
"superuser_set_department_prices",
"superuser_fetch_department_customer_pricing",
"superuser_set_department_customer_pricing",
],
sessionData: {
group_id: 1,
},
});
await page.route("**/api/products**", async (route) => {
await route.fulfill(json({ data: products }));
});
await page.route("**/api/superuser/department/prices**", async (route) => {
const departmentId = Number(new URL(route.request().url()).searchParams.get("department_id"));
await route.fulfill(
json({
data: departmentId === 42 ? [{ id: 100, department_id: 42, product_id: 11, price: 2222 }] : [],
})
);
});
await page.route(/\/api\/superuser\/department(?:\?.*)?$/i, async (route) => {
const departmentId = Number(new URL(route.request().url()).searchParams.get("department_id"));
await route.fulfill(
json({
data: {
id: departmentId,
name: departmentId === 43 ? "Fallback Pricing Department" : "Custom Pricing Department",
description: "E2E department",
custom_pricing_only: customPricingOnlyByDepartment[departmentId] ?? "0",
created_at: now,
updated_at: now,
},
})
);
});
await page.route("**/api/departments", async (route) => {
const request = route.request();
if (request.method() !== "PUT") {
await route.fallback();
return;
}
receivedToggleBody = request.postDataJSON() as Record<string, unknown>;
customPricingOnlyByDepartment[Number(receivedToggleBody.id)] = receivedToggleBody.custom_pricing_only ? "1" : "0";
await route.fulfill(json({ data: { message: "Department updated successfully" } }));
});
await page.route("**/api/superuser/department/customer-pricing**", async (route) => {
const request = route.request();
if (request.method() === "PUT") {
receivedCustomerPricingBody = request.postDataJSON() as Record<string, unknown>;
await route.fulfill(
json({
data: customerPricingPayload([
{
is_category: false,
product_or_category_id: 11,
percentage: 25,
fixed_price: null,
},
]),
})
);
return;
}
await route.fulfill(json({ data: customerPricingPayload() }));
});
await page.goto("/superuser/departments/42/prices", { waitUntil: "domcontentloaded" });
await expect(page.getByRole("heading", { name: "Custom Pricing Department" })).toBeVisible();
await expect(page.getByTestId("department-custom-pricing-settings")).toBeVisible();
await expect(page.getByTestId("department-custom-pricing-only-toggle")).not.toBeChecked();
await expect(page.getByTestId("department-customer-pricing-link")).toHaveCount(0);
await expect(page.getByTestId("department-price-cell-10")).toContainText("-");
await expect(page.getByTestId("department-price-cell-11")).toContainText("2.222");
await page.locator('label[for="department-custom-pricing-only"]').click();
await expect(page.getByTestId("department-custom-pricing-only-toggle")).toBeChecked();
await expect(page.getByTestId("department-price-cell-10")).toContainText("999.999");
await expect(page.getByTestId("department-price-cell-11")).toContainText("2.222");
await expect(page.getByTestId("department-customer-pricing-link")).toBeVisible();
expect(receivedToggleBody).toMatchObject({
id: "42",
custom_pricing_only: true,
});
await page.getByTestId("department-customer-pricing-link").click();
await expect(page).toHaveURL(/\/superuser\/departments\/42\/customer-pricing$/);
await page.getByTestId("department-customer-pricing-customer-number").fill("6001");
await page.getByTestId("department-customer-pricing-load").click();
await expect(page.getByTestId("department-customer-pricing-customer")).toContainText("Acme Haulage");
await expect(page.getByTestId("department-customer-pricing-product-11")).toContainText("Explicit Wash");
await page.getByTestId("department-customer-pricing-item-discount-11").click();
await page.locator(".swal2-input").fill("25");
await page.locator(".swal2-confirm").click();
await expect(page.getByTestId("department-customer-pricing-item-discount-11")).toContainText("25%");
expect(receivedCustomerPricingBody).toMatchObject({
department_id: 42,
customer_number: 6001,
overrides: [
{
is_category: false,
product_or_category_id: 11,
percentage: 25,
fixed_price: null,
},
],
});
await page.goto("/superuser/departments/43/prices", { waitUntil: "domcontentloaded" });
await expect(page.getByRole("heading", { name: "Fallback Pricing Department" })).toBeVisible();
await expect(page.getByTestId("department-custom-pricing-only-toggle")).not.toBeChecked();
await expect(page.getByTestId("department-customer-pricing-link")).toHaveCount(0);
await expect(page.getByTestId("department-price-cell-10")).toContainText("-");
});
});