Files
pleno-vue/tests/unit/user-dashboard-invoice-shortcut.spec.js
T
Jeppe BandJeppe Bundgaard acbbac588f [codex] disable invoice downloads until invoices exist (#158)
* disable invoice downloads until invoices exist

* enable github-hosted frontend ci runners

* Update POS invoice download visual expectations

* Fix full E2E i18n and self-serve coverage

* Review dynamic view i18n keys

---------

Co-authored-by: Jeppe Bundgaard <jb@truckwash.dk>
2026-07-06 22:35:58 +02:00

160 lines
4.5 KiB
JavaScript

// @vitest-environment jsdom
import { flushPromises } from "@vue/test-utils";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { mountWithApp } from "./helpers/mountWithApp.js";
const mocks = vi.hoisted(() => {
const device = {
isMobile: vi.fn(() => false),
isTablet: vi.fn(() => false),
isDesktop: vi.fn(() => true),
isWidescreen: vi.fn(() => false),
isUltraWideScreen: vi.fn(() => false),
};
return {
authenticatedRequest: vi.fn(),
sessionUser: {
isSubuser: {
value: false,
},
subuser: {
selectedGrantCustomerNumber: {
value: null,
},
},
permissions: {
value: ["user"],
},
hasPermission: vi.fn((permission) => permission === "user"),
canAccessCustomerFeature: vi.fn(() => true),
canManageSubusers: vi.fn(() => false),
getName: vi.fn(() => "E2E User"),
functions: {
device,
},
},
};
});
vi.mock("@/components/session/authenticatedRequest.vue", () => ({
authenticatedRequest: mocks.authenticatedRequest,
}));
vi.mock("@/components/session/token/SessionUser.vue", () => ({
default: mocks.sessionUser,
}));
import UserDashboard from "@/views/dashboards/UserDashboard.vue";
const flushDashboard = async () => {
await flushPromises();
await flushPromises();
};
const RouterLinkStub = {
props: ["to"],
template: "<a v-bind=\"$attrs\" :href=\"typeof to === 'string' ? to : '#'\"><slot /></a>",
};
const mountDashboard = () =>
mountWithApp(UserDashboard, {
global: {
stubs: {
RouterLink: RouterLinkStub,
"router-link": RouterLinkStub,
},
},
});
describe("UserDashboard invoice shortcut", () => {
beforeEach(() => {
mocks.authenticatedRequest.mockReset();
mocks.sessionUser.isSubuser.value = false;
mocks.sessionUser.permissions.value = ["user"];
mocks.sessionUser.hasPermission.mockReset();
mocks.sessionUser.hasPermission.mockImplementation((permission) => permission === "user");
mocks.sessionUser.canAccessCustomerFeature.mockReset();
mocks.sessionUser.canAccessCustomerFeature.mockReturnValue(true);
mocks.sessionUser.canManageSubusers.mockReset();
mocks.sessionUser.canManageSubusers.mockReturnValue(false);
});
it("keeps the invoice shortcut disabled while invoice availability is loading", () => {
mocks.authenticatedRequest.mockReturnValue(new Promise(() => {}));
const wrapper = mountDashboard();
const button = wrapper.get("button#download-invoices-button");
expect(button.attributes("disabled")).toBeDefined();
expect(button.classes()).toContain("is-loading");
expect(wrapper.find("a#download-invoices-button").exists()).toBe(false);
wrapper.unmount();
});
it("keeps the invoice shortcut disabled when no invoice exists", async () => {
mocks.authenticatedRequest.mockResolvedValue({
data: {
data: [],
meta: {
pagination: {
total: 0,
},
},
},
});
const wrapper = mountDashboard();
await flushDashboard();
const button = wrapper.get("button#download-invoices-button");
expect(button.attributes("disabled")).toBeDefined();
expect(button.classes()).not.toContain("is-loading");
expect(wrapper.find("a#download-invoices-button").exists()).toBe(false);
expect(mocks.authenticatedRequest).toHaveBeenCalledWith("/user/invoices", "GET", {
page: 1,
limit: 1,
order: "created_at:desc",
});
wrapper.unmount();
});
it("enables the invoice shortcut when at least one invoice exists", async () => {
mocks.authenticatedRequest.mockResolvedValue({
data: {
data: [{ id: 501 }],
meta: {
pagination: {
total: 1,
},
},
},
});
const wrapper = mountDashboard();
await flushDashboard();
const link = wrapper.get("a#download-invoices-button");
expect(link.attributes("href")).toBe("/user/invoices");
expect(wrapper.find("button#download-invoices-button").exists()).toBe(false);
wrapper.unmount();
});
it("fails closed when invoice availability cannot be loaded", async () => {
mocks.authenticatedRequest.mockRejectedValue(new Error("Network unavailable"));
const wrapper = mountDashboard();
await flushDashboard();
const button = wrapper.get("button#download-invoices-button");
expect(button.attributes("disabled")).toBeDefined();
expect(wrapper.find("a#download-invoices-button").exists()).toBe(false);
wrapper.unmount();
});
});