- Introduced `.prettierrc.json` to enforce consistent code formatting across the project. - Updated unit and e2e test files to address formatting issues, improve readability, and ensure alignment with the new Prettier configuration.
263 lines
7.2 KiB
JavaScript
263 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");
|
|
});
|
|
});
|