Files
pleno-vue/tests/unit/order-attachments-action-button.spec.js

133 lines
3.9 KiB
JavaScript

// @vitest-environment jsdom
import { mount } from "@vue/test-utils";
import { beforeEach, describe, expect, it, vi } from "vitest";
const mocks = vi.hoisted(() => ({
downloadAttachment: vi.fn(),
fetchAttachments: vi.fn(),
uploadAttachment: vi.fn(),
showAttachWashCertificateForm: vi.fn(),
canAccessAdmin: vi.fn(() => true),
canAccessSuperUser: vi.fn(() => false),
hasPermission: vi.fn(() => false),
}));
vi.mock("vue-i18n", () => ({
useI18n: () => ({
t: (key) => key,
}),
}));
vi.mock("sweetalert2", () => ({
default: {
fire: vi.fn(),
},
}));
vi.mock("@/components/session/token/SessionUser.vue", () => ({
SessionUser: {
canAccessAdmin: mocks.canAccessAdmin,
canAccessSuperUser: mocks.canAccessSuperUser,
hasPermission: mocks.hasPermission,
objects: {
orders: {
functions: {
downloadAttachment: mocks.downloadAttachment,
fetchAttachments: mocks.fetchAttachments,
uploadAttachment: mocks.uploadAttachment,
showAttachWashCertificateForm: mocks.showAttachWashCertificateForm,
},
},
},
},
}));
import OrderAttachmentsActionButton from "@/components/displays/department/pos/orders/OrderAttachmentsActionButton.vue";
const flushPromises = async () => {
await Promise.resolve();
await Promise.resolve();
await Promise.resolve();
};
const ActionSettingsWheelItemStub = {
props: ["label", "clickAction", "disabled"],
template:
'<button type="button" class="action-settings-wheel-item-stub" :disabled="disabled" @click="clickAction">{{ label }}</button>',
};
const ActionSettingsWheelItemLabelStub = {
props: ["label"],
template: '<div class="action-settings-wheel-item-label-stub">{{ label }}</div>',
};
const mountButton = () =>
mount(OrderAttachmentsActionButton, {
props: {
order: {
id: 123,
attachments: [
{
id: 456,
content: {
document: "invoice.pdf",
},
},
],
},
refreshFunction: vi.fn(),
},
global: {
stubs: {
ActionSettingsWheelItem: ActionSettingsWheelItemStub,
ActionSettingsWheelItemLabel: ActionSettingsWheelItemLabelStub,
},
},
});
describe("OrderAttachmentsActionButton", () => {
beforeEach(() => {
vi.restoreAllMocks();
mocks.downloadAttachment.mockResolvedValue("https://attachments.example/download/456");
mocks.fetchAttachments.mockResolvedValue([]);
mocks.canAccessAdmin.mockReturnValue(true);
mocks.canAccessSuperUser.mockReturnValue(false);
mocks.hasPermission.mockReturnValue(false);
});
it("sandboxes document previews and coerces downloaded content to a safe PDF blob type", async () => {
const createObjectUrl = vi.fn(() => "blob:safe-preview");
Object.defineProperty(URL, "createObjectURL", {
configurable: true,
writable: true,
value: createObjectUrl,
});
vi.stubGlobal(
"fetch",
vi.fn(async () => ({
ok: true,
blob: async () => new Blob(["<script>localStorage.token</script>"], { type: "text/html" }),
}))
);
const wrapper = mountButton();
await wrapper.find(".dropdown-trigger button").trigger("click");
await wrapper.find(".order-attachments-previewable-item").trigger("mouseenter");
await flushPromises();
expect(mocks.downloadAttachment).toHaveBeenCalledWith(123, 456, false);
expect(fetch).toHaveBeenCalledWith("https://attachments.example/download/456", { method: "GET" });
expect(createObjectUrl).toHaveBeenCalledTimes(1);
expect(createObjectUrl.mock.calls[0][0]).toBeInstanceOf(Blob);
expect(createObjectUrl.mock.calls[0][0].type).toBe("application/pdf");
const iframe = wrapper.find("iframe.order-attachments-preview-panel__document");
expect(iframe.exists()).toBe(true);
expect(iframe.attributes("src")).toBe("blob:safe-preview");
expect(iframe.attributes()).toHaveProperty("sandbox");
});
});