PPPAIMT-Crest/backend/test/renderPdf.test.js

88 lines
2.5 KiB
JavaScript

import { EventEmitter } from 'node:events';
import { access, readFile, writeFile } from 'node:fs/promises';
import { beforeEach, describe, expect, it, vi } from 'vitest';
const spawn = vi.hoisted(() => vi.fn());
vi.mock('node:child_process', () => ({
spawn,
}));
const { renderPdf } = await import('../src/pdf/render.js');
function child() {
const proc = new EventEmitter();
proc.stderr = new EventEmitter();
proc.kill = vi.fn();
return proc;
}
describe('renderPdf', () => {
beforeEach(() => {
spawn.mockReset();
});
it('returns the PDF and removes the temp files', async () => {
spawn.mockImplementation((_bin, args) => {
const proc = child();
queueMicrotask(async () => {
await writeFile(args[1], Buffer.from('%PDF-1.4'));
proc.emit('close', 0);
});
return proc;
});
const pdf = await renderPdf('<html><body>Agreement</body></html>');
expect(pdf.subarray(0, 5).toString()).toBe('%PDF-');
expect(spawn).toHaveBeenCalledWith(
'weasyprint',
expect.any(Array),
expect.objectContaining({
stdio: ['ignore', 'ignore', 'pipe'],
cwd: expect.any(String),
}),
);
const htmlPath = spawn.mock.calls[0][1][0];
await expect(access(htmlPath)).rejects.toThrow();
});
it('writes data-URI images beside the HTML for WeasyPrint', async () => {
/** @type {string | undefined} */
let writtenHtml;
spawn.mockImplementation((_bin, args) => {
const proc = child();
queueMicrotask(async () => {
writtenHtml = await readFile(args[0], 'utf8');
await writeFile(args[1], Buffer.from('%PDF-1.4'));
proc.emit('close', 0);
});
return proc;
});
const tiny =
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg==';
await renderPdf(
`<html><body><img src="data:image/png;base64,${tiny}" alt="sig" /></body></html>`,
);
expect(writtenHtml).toContain('src="embed-0.png"');
expect(writtenHtml).not.toContain('data:image/png;base64');
});
it('reports a missing WeasyPrint binary', async () => {
spawn.mockImplementation(() => {
const proc = child();
queueMicrotask(() => {
const error = new Error('spawn weasyprint ENOENT');
error.code = 'ENOENT';
proc.emit('error', error);
});
return proc;
});
await expect(renderPdf('<html></html>')).rejects.toThrow('WeasyPrint is not installed');
});
});