Files
pleno-vue/tests/unit/department-modules-display-self-serve.spec.js
T
Jeppe Bundgaard f040614f46 Refactor module paths, layout responsiveness, and testing configurations:
- Replaced repetitive department module URL logic with `buildDepartmentModulePath` utility in `DepartmentModulesDisplay.vue`.
- Enhanced layouts and responsive behavior across components, including `PosDepartmentStep1MobileTransactionHistory.vue` and `DepartmentDailyReport.vue`.
- Removed unused `SuperuserInvoicingLocalStore.vue` and refactored to `SuperuserInvoicingLocalStore.ts`.
- Updated media query handling and card layout adjustments in `DepartmentDailyReport.vue`.
- Added new Playwright configurations (`playwright.prod.config.ts` and `playwright.live.config.ts`) for e2e release workflows.
- Extended e2e and unit test coverage for mobile POS and department modules.
2026-04-09 16:32:25 +02:00

265 lines
7.2 KiB
JavaScript

// @vitest-environment jsdom
import { defineComponent, h } from "vue";
import { mount } from "@vue/test-utils";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => ({
authenticatedRequest: vi.fn(),
toastSuccess: vi.fn(),
toastError: vi.fn(),
}));
vi.mock("vue-router", async () => {
const { ref } = await import("vue");
const currentRoute = ref({
params: {
departmentId: "12",
},
});
const push = vi.fn();
return {
useRouter: () => ({
currentRoute,
push,
}),
__routeRef: currentRoute,
__pushMock: push,
};
});
vi.mock("@/components/session/authenticatedRequest.vue", () => ({
authenticatedRequest: mocks.authenticatedRequest,
}));
vi.mock("vue-toast-notification", () => ({
useToast: () => ({
success: mocks.toastSuccess,
error: mocks.toastError,
}),
}));
vi.mock("vue-i18n", () => ({
useI18n: () => ({
t: (key) => key,
}),
}));
vi.mock("buefy", () => ({
BSwitch: defineComponent({
name: "MockSwitch",
props: {
modelValue: {
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false,
},
},
emits: ["update:model-value"],
setup(props, { emit }) {
return () => h("button", {
"data-testid": "self-serve-switch",
"data-state": props.modelValue ? "on" : "off",
"disabled": props.disabled,
onClick: () => emit("update:model-value", !props.modelValue),
});
},
}),
}));
import DepartmentModulesDisplay from "@/components/displays/department/moduleNavigation/DepartmentModulesDisplay.vue";
import { __pushMock, __routeRef } from "vue-router";
const flushMicrotasks = async () => {
await Promise.resolve();
await Promise.resolve();
};
describe("DepartmentModulesDisplay self-serve management", () => {
let setIntervalSpy;
let consoleErrorSpy;
beforeEach(() => {
mocks.authenticatedRequest.mockReset();
mocks.toastSuccess.mockReset();
mocks.toastError.mockReset();
__routeRef.value = { params: { departmentId: "12" } };
setIntervalSpy = vi.spyOn(globalThis, "setInterval").mockImplementation(() => 1);
consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
mocks.authenticatedRequest.mockImplementation(async (url, method) => {
if (String(url).startsWith("/admin/bookings/department/count?department_id=12")) {
return {
data: {
data: {
message: 0,
},
},
};
}
if (url === "/departments/self-serve/enabled?id=12" && method === "GET") {
return {
data: {
data: {
enabled: false,
},
},
};
}
if (url === "/departments/self-serve/enabled?id=12&enabled=true" && method === "PUT") {
return {
data: {
data: {
enabled: true,
},
},
};
}
if (url === "/departments/self-serve/enabled?id=12&enabled=false" && method === "PUT") {
return {
data: {
data: {
enabled: false,
},
},
};
}
throw new Error(`Unexpected request: ${method} ${url}`);
});
});
afterEach(() => {
setIntervalSpy.mockRestore();
consoleErrorSpy.mockRestore();
});
it("loads the current self-serve status on mount", async () => {
const wrapper = mount(DepartmentModulesDisplay);
await flushMicrotasks();
expect(mocks.authenticatedRequest).toHaveBeenCalledWith("/departments/self-serve/enabled?id=12", "GET");
expect(wrapper.get("[data-testid='self-serve-switch']").attributes("data-state")).toBe("off");
});
it("renders responsive overview columns for each module card", async () => {
const wrapper = mount(DepartmentModulesDisplay);
await flushMicrotasks();
const firstColumn = wrapper.find(".column");
expect(firstColumn.classes()).toEqual(expect.arrayContaining([
"is-12-mobile",
"is-6-tablet",
"is-4-desktop",
"is-3-widescreen",
]));
});
it("updates self-serve status and keeps UI in sync on success", async () => {
const wrapper = mount(DepartmentModulesDisplay);
await flushMicrotasks();
await wrapper.get("[data-testid='self-serve-switch']").trigger("click");
await flushMicrotasks();
expect(mocks.authenticatedRequest).toHaveBeenCalledWith(
"/departments/self-serve/enabled?id=12&enabled=true",
"PUT"
);
expect(wrapper.get("[data-testid='self-serve-switch']").attributes("data-state")).toBe("on");
expect(mocks.toastSuccess).toHaveBeenCalledWith("admin.department_modules.self_wash.enabled");
});
it("keeps the self-serve switch isolated from card navigation", async () => {
const wrapper = mount(DepartmentModulesDisplay);
await flushMicrotasks();
__pushMock.mockClear();
await wrapper.get("[data-testid='self-serve-switch']").trigger("click");
await flushMicrotasks();
expect(__pushMock).not.toHaveBeenCalled();
});
it("keeps the bookings count badge isolated from the card click handler", async () => {
mocks.authenticatedRequest.mockImplementation(async (url, method) => {
if (String(url).startsWith("/admin/bookings/department/count?department_id=12")) {
return {
data: {
data: {
message: 5,
},
},
};
}
if (url === "/departments/self-serve/enabled?id=12" && method === "GET") {
return {
data: {
data: {
enabled: false,
},
},
};
}
throw new Error(`Unexpected request: ${method} ${url}`);
});
const wrapper = mount(DepartmentModulesDisplay);
await flushMicrotasks();
__pushMock.mockClear();
await wrapper.get(".department-module-card__count").trigger("click");
expect(__pushMock).toHaveBeenCalledTimes(1);
expect(__pushMock).toHaveBeenCalledWith("/admin/12/modules/bookings?search=pending");
});
it("reverts self-serve status and shows an error when update fails", async () => {
mocks.authenticatedRequest.mockImplementation(async (url, method) => {
if (String(url).startsWith("/admin/bookings/department/count?department_id=12")) {
return {
data: {
data: {
message: 0,
},
},
};
}
if (url === "/departments/self-serve/enabled?id=12" && method === "GET") {
return {
data: {
data: {
enabled: false,
},
},
};
}
if (url === "/departments/self-serve/enabled?id=12&enabled=true" && method === "PUT") {
throw new Error("save failed");
}
throw new Error(`Unexpected request: ${method} ${url}`);
});
const wrapper = mount(DepartmentModulesDisplay);
await flushMicrotasks();
await wrapper.get("[data-testid='self-serve-switch']").trigger("click");
await flushMicrotasks();
expect(wrapper.get("[data-testid='self-serve-switch']").attributes("data-state")).toBe("off");
expect(mocks.toastError).toHaveBeenCalledWith("admin.department_modules.self_wash.update_error");
});
});