91 lines
2.9 KiB
TypeScript
91 lines
2.9 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { choosePdfSliceHeight, pdfBlockBreakOffsets } from '../pdfExport.ts';
|
|
|
|
const mocks = vi.hoisted(() => ({
|
|
addImage: vi.fn(),
|
|
save: vi.fn(),
|
|
jsPDF: vi.fn(),
|
|
html2canvas: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('jspdf', () => ({
|
|
jsPDF: mocks.jsPDF,
|
|
}));
|
|
|
|
vi.mock('html2canvas', () => ({
|
|
default: mocks.html2canvas,
|
|
}));
|
|
|
|
describe('exportCardToPdf compression', () => {
|
|
beforeEach(() => {
|
|
mocks.addImage.mockReset();
|
|
mocks.save.mockReset();
|
|
mocks.jsPDF.mockReset();
|
|
mocks.html2canvas.mockReset();
|
|
mocks.jsPDF.mockImplementation(function JsPDF() {
|
|
return {
|
|
internal: { pageSize: { getWidth: () => 210, getHeight: () => 297 } },
|
|
addPage: vi.fn(),
|
|
addImage: mocks.addImage,
|
|
save: mocks.save,
|
|
};
|
|
});
|
|
mocks.html2canvas.mockImplementation(async () => {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = 800;
|
|
canvas.height = 400;
|
|
return canvas;
|
|
});
|
|
});
|
|
|
|
it('embeds JPEG pages in a compressed jsPDF document', async () => {
|
|
vi.spyOn(HTMLCanvasElement.prototype, 'getContext').mockReturnValue({
|
|
fillStyle: '',
|
|
fillRect: vi.fn(),
|
|
drawImage: vi.fn(),
|
|
} as unknown as CanvasRenderingContext2D);
|
|
const toDataURL = vi
|
|
.spyOn(HTMLCanvasElement.prototype, 'toDataURL')
|
|
.mockReturnValue('data:image/jpeg;base64,xx');
|
|
|
|
const { exportCardToPdf } = await import('../pdfExport.ts');
|
|
await exportCardToPdf(document.createElement('div'), 'Laporan.pdf');
|
|
|
|
expect(mocks.jsPDF).toHaveBeenCalledWith(expect.objectContaining({ compress: true }));
|
|
expect(toDataURL).toHaveBeenCalledWith('image/jpeg', expect.any(Number));
|
|
const quality = toDataURL.mock.calls.find((call) => call[0] === 'image/jpeg')?.[1] as number;
|
|
expect(quality).toBeGreaterThan(0);
|
|
expect(quality).toBeLessThan(1);
|
|
expect(mocks.addImage).toHaveBeenCalledWith(
|
|
expect.any(String),
|
|
'JPEG',
|
|
expect.any(Number),
|
|
expect.any(Number),
|
|
expect.any(Number),
|
|
expect.any(Number)
|
|
);
|
|
expect(mocks.save).toHaveBeenCalledWith('Laporan.pdf');
|
|
|
|
toDataURL.mockRestore();
|
|
vi.restoreAllMocks();
|
|
});
|
|
});
|
|
|
|
describe('pdf page breaks', () => {
|
|
it('does not defer an oversized table past the header', () => {
|
|
const usableHeight = 1200;
|
|
const breaks = pdfBlockBreakOffsets([{ top: 80, bottom: 5000 }], usableHeight);
|
|
expect(breaks).not.toContain(80);
|
|
expect(breaks).toContain(5000);
|
|
expect(choosePdfSliceHeight(0, 5000, usableHeight, breaks)).toBe(usableHeight);
|
|
});
|
|
|
|
it('keeps a small chart whole by breaking before it when it no longer fits', () => {
|
|
const usableHeight = 400;
|
|
const breaks = pdfBlockBreakOffsets([{ top: 350, bottom: 500 }], usableHeight);
|
|
expect(breaks).toEqual(expect.arrayContaining([350, 500]));
|
|
expect(choosePdfSliceHeight(0, 900, usableHeight, breaks)).toBe(350);
|
|
});
|
|
});
|
|
|