Remove configuration cache problems report
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
// @vitest-environment jsdom
|
||||
import { mount } from "@vue/test-utils";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import ActionSettingsWheelButton from "@/components/displays/buttons/ActionSettingsWheelButton.vue";
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
import { createTestI18n } from "./helpers/mountWithApp.js";
|
||||
@@ -73,6 +73,7 @@ vi.mock("@/components/session/token/SessionUser.vue", () => ({
|
||||
functions: {
|
||||
fetchAttachments: vi.fn(() => Promise.resolve([])),
|
||||
get_department_id: vi.fn(() => Promise.resolve(1)),
|
||||
removeAttachment: vi.fn(() => Promise.resolve({ success: true })),
|
||||
showAttachWashCertificateForm: vi.fn(() => Promise.resolve()),
|
||||
showChangeCustomerForm: vi.fn(() => Promise.resolve()),
|
||||
showChangeInvoiceCollectionForm: vi.fn(() => Promise.resolve()),
|
||||
@@ -152,6 +153,13 @@ const SETTINGS_WHEEL_TRANSLATION_KEYS = [
|
||||
"admin.pos.settings_wheel.view_lane_setup_new_tab",
|
||||
"admin.pos.settings_wheel.view_order_new_tab",
|
||||
"admin.pos.settings_wheel.view_vehicle_new_tab",
|
||||
"admin.pos.attachments_no_preview",
|
||||
"admin.pos.attachments_office_preview_unavailable",
|
||||
"global.delete",
|
||||
"global.download",
|
||||
"global.loading",
|
||||
"global.preview",
|
||||
"global.print",
|
||||
"superuser.department_lane.force_disable_machine",
|
||||
"superuser.department_lane.force_enable_machine",
|
||||
];
|
||||
@@ -186,10 +194,114 @@ const flushMicrotasks = async () => {
|
||||
await Promise.resolve();
|
||||
};
|
||||
|
||||
const setDesktopFlyoutViewport = () => {
|
||||
Object.defineProperty(window, "innerWidth", {
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 1900,
|
||||
});
|
||||
Object.defineProperty(window, "innerHeight", {
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: 900,
|
||||
});
|
||||
window.matchMedia = vi.fn().mockImplementation(() => ({
|
||||
matches: true,
|
||||
media: "",
|
||||
onchange: null,
|
||||
addListener: vi.fn(),
|
||||
removeListener: vi.fn(),
|
||||
addEventListener: vi.fn(),
|
||||
removeEventListener: vi.fn(),
|
||||
dispatchEvent: vi.fn(),
|
||||
}));
|
||||
};
|
||||
|
||||
const mockMenuGeometry = () =>
|
||||
vi.spyOn(HTMLElement.prototype, "getBoundingClientRect").mockImplementation(function getBoundingClientRectMock() {
|
||||
if (this.classList?.contains("dropdown-trigger")) {
|
||||
return {
|
||||
x: 1750,
|
||||
y: 96,
|
||||
top: 96,
|
||||
left: 1750,
|
||||
right: 1850,
|
||||
bottom: 136,
|
||||
width: 100,
|
||||
height: 40,
|
||||
toJSON() {
|
||||
return this;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
x: 1320,
|
||||
y: 136,
|
||||
top: 136,
|
||||
left: 1320,
|
||||
right: 1850,
|
||||
bottom: 560,
|
||||
width: 530,
|
||||
height: 424,
|
||||
toJSON() {
|
||||
return this;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
const mountDesktopFlyoutButton = (props = {}) => {
|
||||
setDesktopFlyoutViewport();
|
||||
|
||||
return mount(ActionSettingsWheelButton, {
|
||||
props: {
|
||||
order_id: 42,
|
||||
refreshFunction: vi.fn(() => Promise.resolve()),
|
||||
...props,
|
||||
},
|
||||
slots: {
|
||||
actions: "",
|
||||
},
|
||||
global: {
|
||||
plugins: [i18n],
|
||||
stubs: {
|
||||
CustomerModal: { template: "<div />" },
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const originalFetch = global.fetch;
|
||||
const originalCreateObjectURL = global.URL.createObjectURL;
|
||||
const originalRevokeObjectURL = global.URL.revokeObjectURL;
|
||||
const originalMatchMedia = window.matchMedia;
|
||||
|
||||
describe("ActionSettingsWheelButton", () => {
|
||||
beforeEach(() => {
|
||||
getUserIdMock.mockClear();
|
||||
SessionUser.objects.orders.functions.showChangeInvoiceCollectionForm.mockClear();
|
||||
SessionUser.objects.orders.functions.fetchAttachments.mockReset();
|
||||
SessionUser.objects.orders.functions.fetchAttachments.mockResolvedValue([]);
|
||||
SessionUser.objects.orders.functions.downloadAttachment.mockReset();
|
||||
SessionUser.objects.orders.functions.downloadAttachment.mockResolvedValue("https://cdn.example.test/attachment");
|
||||
SessionUser.objects.orders.functions.removeAttachment.mockReset();
|
||||
SessionUser.objects.orders.functions.removeAttachment.mockResolvedValue({ success: true });
|
||||
global.fetch = vi.fn(() =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
blob: () => Promise.resolve(new Blob(["preview"], { type: "application/pdf" })),
|
||||
})
|
||||
);
|
||||
global.URL.createObjectURL = vi.fn((blob) => `blob:${blob.type}:${Date.now()}`);
|
||||
global.URL.revokeObjectURL = vi.fn();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
global.fetch = originalFetch;
|
||||
global.URL.createObjectURL = originalCreateObjectURL;
|
||||
global.URL.revokeObjectURL = originalRevokeObjectURL;
|
||||
window.matchMedia = originalMatchMedia;
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("resolves customer user id once on mount and not on unrelated rerenders", async () => {
|
||||
@@ -322,4 +434,123 @@ describe("ActionSettingsWheelButton", () => {
|
||||
|
||||
windowOpenSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("builds attachment flyout rows and switches the preview panel on hover and focus", async () => {
|
||||
SessionUser.objects.orders.functions.fetchAttachments.mockResolvedValue([
|
||||
{
|
||||
id: 301,
|
||||
content: {
|
||||
document: "safety-seal.pdf",
|
||||
other: "safety-seal.pdf",
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 302,
|
||||
content: {
|
||||
image: "truck.jpg",
|
||||
other: "truck.jpg",
|
||||
},
|
||||
},
|
||||
]);
|
||||
SessionUser.objects.orders.functions.downloadAttachment.mockImplementation((orderId, attachmentId) =>
|
||||
Promise.resolve(`https://cdn.example.test/orders/${orderId}/attachments/${attachmentId}`)
|
||||
);
|
||||
global.fetch = vi.fn((url) =>
|
||||
Promise.resolve({
|
||||
ok: true,
|
||||
blob: () =>
|
||||
Promise.resolve(
|
||||
new Blob(["preview"], {
|
||||
type: String(url).includes("/301") ? "application/pdf" : "image/png",
|
||||
})
|
||||
),
|
||||
})
|
||||
);
|
||||
|
||||
const geometrySpy = mockMenuGeometry();
|
||||
const wrapper = mountDesktopFlyoutButton();
|
||||
|
||||
await flushMicrotasks();
|
||||
await wrapper.find(".dropdown-trigger button").trigger("click");
|
||||
await flushMicrotasks();
|
||||
|
||||
const attachmentsSection = wrapper.get('[data-testid="action-settings-wheel-section-attachments"]');
|
||||
await attachmentsSection.trigger("mouseenter");
|
||||
await flushMicrotasks();
|
||||
|
||||
const pdfRow = wrapper.get('[data-testid="action-settings-wheel-attachment-row-301"]');
|
||||
const imageRow = wrapper.get('[data-testid="action-settings-wheel-attachment-row-302"]');
|
||||
|
||||
expect(pdfRow.text()).toContain("safety-seal.pdf");
|
||||
expect(imageRow.text()).toContain("truck.jpg");
|
||||
|
||||
await pdfRow.trigger("mouseenter");
|
||||
await flushMicrotasks();
|
||||
await flushMicrotasks();
|
||||
|
||||
const previewPanel = wrapper.get('[data-testid="action-settings-wheel-attachment-panel"]');
|
||||
expect(previewPanel.find("iframe").exists()).toBe(true);
|
||||
expect(wrapper.find('[data-testid="action-settings-wheel-attachment-action-preview-301"]').exists()).toBe(true);
|
||||
expect(wrapper.find('[data-testid="action-settings-wheel-attachment-action-download-301"]').exists()).toBe(true);
|
||||
expect(wrapper.find('[data-testid="action-settings-wheel-attachment-action-print-301"]').exists()).toBe(true);
|
||||
expect(wrapper.find('[data-testid="action-settings-wheel-attachment-action-delete-301"]').exists()).toBe(true);
|
||||
|
||||
await imageRow.trigger("focus");
|
||||
await flushMicrotasks();
|
||||
await flushMicrotasks();
|
||||
|
||||
expect(wrapper.get('[data-testid="action-settings-wheel-attachment-panel"]').find("img").exists()).toBe(true);
|
||||
expect(global.fetch).toHaveBeenCalledTimes(2);
|
||||
|
||||
geometrySpy.mockRestore();
|
||||
});
|
||||
|
||||
it("deletes attachments, refreshes the list, and clears preview object URLs on close", async () => {
|
||||
const attachmentsBeforeDelete = [
|
||||
{
|
||||
id: 301,
|
||||
content: {
|
||||
document: "safety-seal.pdf",
|
||||
other: "safety-seal.pdf",
|
||||
},
|
||||
},
|
||||
];
|
||||
SessionUser.objects.orders.functions.fetchAttachments
|
||||
.mockResolvedValueOnce(attachmentsBeforeDelete)
|
||||
.mockResolvedValueOnce([]);
|
||||
SessionUser.objects.orders.functions.downloadAttachment.mockResolvedValue(
|
||||
"https://cdn.example.test/orders/42/attachments/301"
|
||||
);
|
||||
|
||||
const refreshFunction = vi.fn(() => Promise.resolve());
|
||||
const geometrySpy = mockMenuGeometry();
|
||||
const wrapper = mountDesktopFlyoutButton({ refreshFunction });
|
||||
|
||||
await flushMicrotasks();
|
||||
await wrapper.find(".dropdown-trigger button").trigger("click");
|
||||
await flushMicrotasks();
|
||||
await wrapper.get('[data-testid="action-settings-wheel-section-attachments"]').trigger("mouseenter");
|
||||
await flushMicrotasks();
|
||||
await wrapper.get('[data-testid="action-settings-wheel-attachment-row-301"]').trigger("mouseenter");
|
||||
await flushMicrotasks();
|
||||
|
||||
expect(global.URL.createObjectURL).toHaveBeenCalledTimes(1);
|
||||
|
||||
await wrapper.get('[data-testid="action-settings-wheel-attachment-action-delete-301"]').trigger("click");
|
||||
await flushMicrotasks();
|
||||
|
||||
expect(SessionUser.objects.orders.functions.removeAttachment).toHaveBeenCalledTimes(1);
|
||||
expect(SessionUser.objects.orders.functions.removeAttachment).toHaveBeenCalledWith(42, 301);
|
||||
expect(refreshFunction).toHaveBeenCalledTimes(1);
|
||||
expect(SessionUser.objects.orders.functions.fetchAttachments).toHaveBeenCalledTimes(2);
|
||||
expect(wrapper.find('[data-testid="action-settings-wheel-section-attachments"]').exists()).toBe(false);
|
||||
|
||||
await wrapper.find(".dropdown-trigger button").trigger("click");
|
||||
await flushMicrotasks();
|
||||
|
||||
expect(global.URL.revokeObjectURL).toHaveBeenCalledTimes(1);
|
||||
|
||||
wrapper.unmount();
|
||||
geometrySpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user