95 lines
3.4 KiB
JavaScript
95 lines
3.4 KiB
JavaScript
import { describe, expect, it, vi, beforeEach } from "vitest";
|
|
import { render, screen, waitFor } from "@testing-library/react";
|
|
import { fireEvent } from "@testing-library/dom";
|
|
|
|
// خروجی قبلی کاغذِ [۲۱۰ × ارتفاعِ تصویر] میساخت، یعنی ۲۱۰×۲۶۲٫۵ میلیمتر. روی هیچ
|
|
// پرینتری A4 حساب نمیشد. این تست همان قرارداد را قفل میکند: یک صفحهٔ A4.
|
|
const jsPdfCalls = { ctor: [], addImage: [], save: [] };
|
|
|
|
vi.mock("jspdf", () => ({
|
|
default: class {
|
|
constructor(options) {
|
|
jsPdfCalls.ctor.push(options);
|
|
}
|
|
addImage(...args) {
|
|
jsPdfCalls.addImage.push(args);
|
|
}
|
|
save(name) {
|
|
jsPdfCalls.save.push(name);
|
|
}
|
|
},
|
|
}));
|
|
|
|
vi.mock("html-to-image", () => ({
|
|
toPng: vi.fn(async () => "data:image/png;base64,AAAA"),
|
|
}));
|
|
|
|
vi.mock("html2canvas", () => ({ default: vi.fn() }));
|
|
|
|
vi.mock("react-toastify", () => ({
|
|
toast: { info: vi.fn(), error: vi.fn(), success: vi.fn() },
|
|
}));
|
|
|
|
// فونت وزیر با fetch به data-url تبدیل میشود؛ در jsdom باید تأمین شود وگرنه مسیر
|
|
// جایگزینِ html2canvas اجرا میشود و تست چیز دیگری را میسنجد.
|
|
vi.stubGlobal("fetch", vi.fn(async () => ({ blob: async () => new Blob(["x"]) })));
|
|
|
|
import List from "./List";
|
|
|
|
// پوستر A4 است: ۱۰۸۰×۱۵۲۷ فیزیکی، که با pixelRatio=2 دو برابر میشود.
|
|
function posterRef({ width = 1080, height = 1527 } = {}) {
|
|
const element = document.createElement("div");
|
|
Object.defineProperty(element, "offsetWidth", { value: width });
|
|
Object.defineProperty(element, "offsetHeight", { value: height });
|
|
element.querySelectorAll = () => [];
|
|
return { current: element };
|
|
}
|
|
|
|
async function download(ref) {
|
|
render(<List hiddenRef={ref} data={{ name: "مرضیه حسینی" }} qrReady />);
|
|
fireEvent.click(screen.getByLabelText("دانلود"));
|
|
await waitFor(() => expect(jsPdfCalls.save.length).toBe(1));
|
|
}
|
|
|
|
describe("PDF پوستر", () => {
|
|
beforeEach(() => {
|
|
jsPdfCalls.ctor = [];
|
|
jsPdfCalls.addImage = [];
|
|
jsPdfCalls.save = [];
|
|
});
|
|
|
|
it("کاغذ A4 است، نه اندازهای که از نسبت تصویر درمیآید", async () => {
|
|
await download(posterRef());
|
|
|
|
expect(jsPdfCalls.ctor[0]).toMatchObject({
|
|
orientation: "portrait",
|
|
unit: "mm",
|
|
format: "a4",
|
|
});
|
|
});
|
|
|
|
it("پوستر A4 کل صفحه را پر میکند و یک صفحه بیشتر نیست", async () => {
|
|
await download(posterRef());
|
|
|
|
const [, , x, y, width, height] = jsPdfCalls.addImage[0];
|
|
|
|
expect(jsPdfCalls.addImage).toHaveLength(1);
|
|
expect(width).toBeCloseTo(210, 1);
|
|
expect(height).toBeCloseTo(297, 0);
|
|
expect(x).toBeCloseTo(0, 1);
|
|
expect(y).toBeCloseTo(0, 0);
|
|
});
|
|
|
|
/** تور ایمنی: اگر ابعاد پوستر روزی بلندتر شد، تصویر باید کوچک شود نه اینکه از کاغذ بزند بیرون. */
|
|
it("پوستر بلندتر از A4 داخل کاغذ جا داده میشود، نه بریده", async () => {
|
|
await download(posterRef({ width: 1080, height: 2000 }));
|
|
|
|
const [, , x, y, width, height] = jsPdfCalls.addImage[0];
|
|
|
|
expect(height).toBeLessThanOrEqual(297);
|
|
expect(width).toBeLessThanOrEqual(210);
|
|
expect(x).toBeGreaterThan(0);
|
|
expect(y).toBeCloseTo(0, 1);
|
|
});
|
|
});
|