329 lines
11 KiB
TypeScript
329 lines
11 KiB
TypeScript
import { expect, test } from "@playwright/test";
|
|
import { apiPathPattern, 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),
|
|
});
|
|
|
|
test.describe("Superuser drafts", () => {
|
|
test("shows a light grey loading indicator while the draft count is fetching", async ({ page }, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Desktop only");
|
|
|
|
const orderFilters: string[] = [];
|
|
|
|
await seedAuthenticatedState(page);
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: ["superuser", "user"],
|
|
sessionData: {
|
|
runtime_config: {
|
|
economic: {
|
|
transaction_draft_customer_number: 6001,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
let releaseDraftCountResponse = () => {};
|
|
const draftCountResponseCanFinish = new Promise<void>((resolve) => {
|
|
releaseDraftCountResponse = resolve;
|
|
});
|
|
let resolveDraftCountRequestStarted = () => {};
|
|
const draftCountRequestStarted = new Promise<void>((resolve) => {
|
|
resolveDraftCountRequestStarted = resolve;
|
|
});
|
|
let hasSeenDraftCountRequest = false;
|
|
await page.route(apiPathPattern("/orders"), async (route) => {
|
|
const url = new URL(route.request().url());
|
|
const filters = url.searchParams.get("filters") || "";
|
|
const limit = Number(url.searchParams.get("limit") || "100");
|
|
orderFilters.push(filters);
|
|
const isDraftRequest = filters.includes("customer_id:6001") && !filters.includes("department_id:");
|
|
|
|
if (isDraftRequest) {
|
|
if (!hasSeenDraftCountRequest) {
|
|
hasSeenDraftCountRequest = true;
|
|
resolveDraftCountRequestStarted();
|
|
}
|
|
await draftCountResponseCanFinish;
|
|
}
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data:
|
|
isDraftRequest && limit > 1
|
|
? [
|
|
{
|
|
id: 56816,
|
|
customer_id: 6001,
|
|
department_id: 1,
|
|
},
|
|
]
|
|
: [],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: limit,
|
|
total: isDraftRequest ? 1 : 0,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/departments"), async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{ id: 1, name: "Hvidovre", visible: true },
|
|
{ id: 2, name: "Glostrup", visible: true },
|
|
],
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.goto("/superuser/orders", { waitUntil: "domcontentloaded" });
|
|
await draftCountRequestStarted;
|
|
|
|
const draftsLabel = page.getByTestId("desktop-buefy-nav-drafts-label");
|
|
const loadingBadge = page.getByTestId("desktop-buefy-nav-drafts-badge-loading");
|
|
const draftsBadge = page.getByTestId("desktop-buefy-nav-drafts-badge");
|
|
|
|
await expect(draftsLabel).toContainText("Kladder");
|
|
await expect(loadingBadge).toBeVisible();
|
|
await expect(loadingBadge).toHaveCSS("background-color", "rgb(229, 231, 235)");
|
|
await expect(draftsBadge).toHaveCount(0);
|
|
|
|
const loadingBadgeStyles = await loadingBadge.evaluate((element) => {
|
|
const styles = getComputedStyle(element);
|
|
return {
|
|
backgroundImage: styles.backgroundImage,
|
|
};
|
|
});
|
|
expect(loadingBadgeStyles.backgroundImage).not.toBe("none");
|
|
|
|
releaseDraftCountResponse();
|
|
await expect(loadingBadge).toHaveCount(0);
|
|
await expect(draftsBadge).toHaveText("1");
|
|
|
|
expect(
|
|
orderFilters.some((filters) => filters.includes("customer_id:6001") && !filters.includes("department_id:"))
|
|
).toBe(true);
|
|
});
|
|
|
|
test("keeps the drafts badge hidden when the fast count request reports a stale total", async ({
|
|
page,
|
|
}, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Desktop only");
|
|
|
|
const orderRequests: Array<{ filters: string; limit: number }> = [];
|
|
|
|
await seedAuthenticatedState(page);
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: ["superuser", "user"],
|
|
sessionData: {
|
|
runtime_config: {
|
|
economic: {
|
|
transaction_draft_customer_number: 6001,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
await page.route(apiPathPattern("/departments"), async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{ id: 1, name: "Hvidovre", visible: true },
|
|
{ id: 2, name: "Glostrup", visible: true },
|
|
],
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/orders"), async (route) => {
|
|
const url = new URL(route.request().url());
|
|
const filters = url.searchParams.get("filters") || "";
|
|
const limit = Number(url.searchParams.get("limit") || "100");
|
|
orderRequests.push({ filters, limit });
|
|
const isDraftRequest = filters.includes("customer_id:6001") && !filters.includes("department_id:");
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data: [],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: limit,
|
|
total: isDraftRequest && limit === 1 ? 1 : 0,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.goto("/superuser/orders");
|
|
|
|
const draftsLabel = page.getByTestId("desktop-buefy-nav-drafts-label");
|
|
const draftsBadge = page.getByTestId("desktop-buefy-nav-drafts-badge");
|
|
|
|
await expect(draftsLabel).toContainText("Kladder");
|
|
await expect(draftsBadge).toHaveCount(0);
|
|
|
|
await draftsLabel.click();
|
|
|
|
await expect(page).toHaveURL(/\/superuser\/orders\/drafts$/);
|
|
await expect(page.getByTestId("superuser-drafts-page")).toBeVisible();
|
|
await expect(page.getByText("Vis 0 vaske")).toBeVisible();
|
|
|
|
expect(orderRequests.some((request) => request.filters.includes("customer_id:6001") && request.limit === 1)).toBe(
|
|
true
|
|
);
|
|
expect(orderRequests.some((request) => request.filters.includes("customer_id:6001") && request.limit > 1)).toBe(
|
|
true
|
|
);
|
|
});
|
|
|
|
test("shows a drafts menu item with a count and lists drafts across departments", async ({ page }, testInfo) => {
|
|
test.skip(!isDesktopProject(testInfo), "Desktop only");
|
|
|
|
const orderFilters: string[] = [];
|
|
|
|
await seedAuthenticatedState(page);
|
|
await mockApi(page, {
|
|
authenticated: true,
|
|
permissions: ["superuser", "user"],
|
|
sessionData: {
|
|
runtime_config: {
|
|
economic: {
|
|
transaction_draft_customer_number: 6001,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
await page.route(apiPathPattern("/departments"), async (route) => {
|
|
await route.fulfill(
|
|
json({
|
|
data: [
|
|
{ id: 1, name: "Hvidovre", visible: true },
|
|
{ id: 2, name: "Glostrup", visible: true },
|
|
],
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.route(apiPathPattern("/orders"), async (route) => {
|
|
const url = new URL(route.request().url());
|
|
const filters = url.searchParams.get("filters") || "";
|
|
const limit = Number(url.searchParams.get("limit") || "100");
|
|
orderFilters.push(filters);
|
|
|
|
const isDraftRequest = filters.includes("customer_id:6001");
|
|
const isDepartmentScoped = filters.includes("department_id:");
|
|
const total = isDraftRequest && !isDepartmentScoped ? 2 : 0;
|
|
|
|
await route.fulfill(
|
|
json({
|
|
data:
|
|
isDraftRequest && !isDepartmentScoped && limit > 1
|
|
? [
|
|
{
|
|
id: 56816,
|
|
customer_id: 6001,
|
|
customer_name: "Uspecificeret kunde",
|
|
user_id: 77,
|
|
cashier_id: 8,
|
|
cashier_name: "Badir",
|
|
department_id: 1,
|
|
reg_1: "FG0232I",
|
|
reg_2: "FG6144X",
|
|
reg_3: null,
|
|
reference: "",
|
|
notes: "",
|
|
po: "",
|
|
total_net_amount: 52400,
|
|
created_at: "2026-04-21 10:09:45",
|
|
invoice_collection_id: null,
|
|
economic_invoice_module: null,
|
|
stripe_invoice_module: null,
|
|
error_message: null,
|
|
pending_handheld: false,
|
|
completed_at: null,
|
|
booking_id: null,
|
|
wash_id: null,
|
|
lane: null,
|
|
safety_seal: null,
|
|
},
|
|
{
|
|
id: 56797,
|
|
customer_id: 6001,
|
|
customer_name: "Uspecificeret kunde",
|
|
user_id: 77,
|
|
cashier_id: 9,
|
|
cashier_name: "Afdeling",
|
|
department_id: 2,
|
|
reg_1: "DN59443",
|
|
reg_2: null,
|
|
reg_3: null,
|
|
reference: "1185",
|
|
notes: "",
|
|
po: "",
|
|
total_net_amount: 76700,
|
|
created_at: "2026-04-21 10:04:21",
|
|
invoice_collection_id: null,
|
|
economic_invoice_module: null,
|
|
stripe_invoice_module: null,
|
|
error_message: null,
|
|
pending_handheld: false,
|
|
completed_at: null,
|
|
booking_id: null,
|
|
wash_id: null,
|
|
lane: null,
|
|
safety_seal: null,
|
|
},
|
|
]
|
|
: [],
|
|
meta: {
|
|
pagination: {
|
|
page: 1,
|
|
per_page: limit,
|
|
total,
|
|
},
|
|
},
|
|
})
|
|
);
|
|
});
|
|
|
|
await page.goto("/superuser/orders");
|
|
|
|
const desktopNavigation = page.getByTestId("desktop-buefy-navigation");
|
|
await expect(desktopNavigation).toContainText("Kladder");
|
|
|
|
const draftsLabel = page.getByTestId("desktop-buefy-nav-drafts-label");
|
|
const draftsBadge = page.getByTestId("desktop-buefy-nav-drafts-badge");
|
|
|
|
await expect(draftsLabel).toContainText("Kladder");
|
|
await expect(draftsBadge).toHaveText("2");
|
|
await draftsBadge.hover();
|
|
await expect(page.getByTestId("desktop-buefy-nav-drafts-badge-tooltip")).toContainText("Kladder");
|
|
|
|
await draftsLabel.click();
|
|
|
|
await expect(page).toHaveURL(/\/superuser\/orders\/drafts$/);
|
|
await expect(page.getByTestId("superuser-drafts-page")).toBeVisible();
|
|
await expect(page.locator("body")).toContainText("56816");
|
|
await expect(page.locator("body")).toContainText("56797");
|
|
await expect(page.locator("body")).toContainText("FG0232I");
|
|
await expect(page.locator("body")).toContainText("DN59443");
|
|
|
|
expect(
|
|
orderFilters.filter((filters) => filters.includes("customer_id:6001") && filters.includes("department_id:"))
|
|
).toEqual([]);
|
|
});
|
|
});
|