88 lines
2.5 KiB
JavaScript
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');
|
|
});
|
|
});
|