UNPKG

hpdf

Version:

NodeJS library for generation PDF from HTML

211 lines 9.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const stream_1 = require("stream"); const globals_1 = require("@jest/globals"); const generic_pool_1 = require("generic-pool"); const index_1 = require("./index"); const readStream = async (stream) => { const chunks = []; for await (const chunk of stream) { chunks.push(chunk); } return Buffer.concat(chunks); }; const getMockedPool = (poolFactory) => { const getDefaultStreamCallback = () => globals_1.jest.fn(() => { const stream = new stream_1.Stream.Readable({ read: () => undefined, }); setTimeout(async () => { stream.push(Buffer.from('abc', 'utf-8')); await stream.destroy(); }, 50); return stream; }); const getDefaultBufferCallback = () => globals_1.jest.fn(() => { return new Promise((resolve) => setTimeout(() => resolve(Buffer.from('abc', 'utf-8')), 50)); }); const mockedPage = { page: { setContent: globals_1.jest.fn(() => undefined), emulateMediaType: globals_1.jest.fn(() => undefined), pdf: getDefaultBufferCallback(), createPDFStream: getDefaultStreamCallback(), }, }; return { setPdfMethod: (fn) => { mockedPage.page.pdf = fn || getDefaultBufferCallback(); }, setSetContentMethod: (fn) => { mockedPage.page.setContent = fn || globals_1.jest.fn(() => undefined); }, setCreatePDFStreamMethod: (fn) => { mockedPage.page.createPDFStream = fn || getDefaultStreamCallback(); }, mockedPage, pool: (0, generic_pool_1.createPool)({ async create() { await new Promise((resolve) => setTimeout(resolve, 50)); return Promise.resolve(mockedPage); }, destroy() { return Promise.resolve(); }, validate() { return Promise.resolve(true); }, ...poolFactory, }, { autostart: true, testOnBorrow: true, }), }; }; (0, globals_1.describe)('PdfGenerator module', () => { (0, globals_1.describe)('Positive scenario', () => { let generator = new index_1.PdfGenerator(); (0, globals_1.beforeEach)(async () => { generator = new index_1.PdfGenerator({ max: 1, min: 1, }); await generator.awaitPool(); }); (0, globals_1.afterEach)(async () => { await generator.stop(); }); (0, globals_1.test)('Render pdf from html test', async () => { await generator.generatePDF('<html lang="html">Hello World!</html>'); }); (0, globals_1.test)('Render pdf from html', async () => { const pdf = await generator.generatePDF('<html lang="html">Hello World!</html>'); const pdfFromStream = await readStream(await generator.generatePDF('<html lang="html">Hello World!</html>', true)); (0, globals_1.expect)(pdfFromStream.length).toBe(pdf.length); }, 60000); (0, globals_1.test)('Render pdf from url', async () => { const pdf = await generator.generatePDF(new URL('https://github.com/frimuchkov/hpdf')); (0, globals_1.expect)(pdf.length).toBeGreaterThan(100); }, 60000); (0, globals_1.test)('PDF have to be rendered in FIFO', async () => { const timestamps = []; await Promise.all(new Array(3).fill(0).map(async (_, i) => { await new Promise((resolve) => setTimeout(resolve, i * 50)); await generator.generatePDF('<html lang="html">Hello World!</html>'); timestamps.push(Date.now()); })); (0, globals_1.expect)([...timestamps].sort()).toStrictEqual(timestamps); }, 60000); (0, globals_1.test)('Stream have to lock and release resource', async () => { let bufferTimestamp = 0; let streamTimestamp = 0; const pdfStream = generator.generatePDF('<html lang="html">Hello World!</html>', true); const pdfBuffer = generator.generatePDF('<html lang="html">Hello World!</html>'); await Promise.all([ (async () => { await readStream(await pdfStream); streamTimestamp = Date.now(); })(), pdfBuffer.then(() => { bufferTimestamp = Date.now(); }), ]); (0, globals_1.expect)(bufferTimestamp - streamTimestamp).toBeGreaterThan(100); }, 60000); }); (0, globals_1.describe)('Negative scenario', () => { let generator = new index_1.PdfGenerator(); (0, globals_1.beforeEach)(async () => { generator = new index_1.PdfGenerator({ max: 1, min: 1, }); await generator.awaitPool(); }); (0, globals_1.afterEach)(async () => { await generator.stop(); }); (0, globals_1.test)('Pool have to destroy invalid instance and acquire the new one', async () => { const destroyPool = globals_1.jest.fn(() => undefined); const validatePool = globals_1.jest.fn(() => true); const pagesPool = getMockedPool({ destroy() { destroyPool(); return Promise.resolve(); }, validate() { return Promise.resolve(validatePool()); }, }); await generator.stop(); generator.pagesPool = pagesPool.pool; validatePool.mockImplementation(() => false); const runner = generator.generatePDF('<html lang="html">Hello World!</html>'); await new Promise((resolve) => setTimeout(resolve, 240)); (0, globals_1.expect)(validatePool.mock.calls.length).toBeGreaterThan(1); validatePool.mockReset(); (0, globals_1.expect)(validatePool).toBeCalledTimes(0); validatePool.mockImplementation(() => true); await (0, globals_1.expect)(runner).resolves.toBeDefined(); }, 60000); (0, globals_1.test)('Generator have to release resource in case of exception', async () => { const pagesPool = getMockedPool(); await generator.stop(); generator.pagesPool = pagesPool.pool; pagesPool.setPdfMethod(() => { return new Promise((_, reject) => setTimeout(() => reject(new Error('Error from generator')), 50)); }); // Handle exception during rendering { await (0, globals_1.expect)(generator.generatePDF('<html lang="html">Hello World!</html>')).rejects.toEqual(new Error('Error from generator')); pagesPool.setPdfMethod(); await generator.generatePDF('<html lang="html">Hello World!</html>'); (0, globals_1.expect)(pagesPool.mockedPage.page.pdf).toBeCalled(); } // Handle exception during setting content { pagesPool.setSetContentMethod(() => { throw new Error('Error from setContent'); }); await (0, globals_1.expect)(generator.generatePDF('<html lang="html">Hello World!</html>')).rejects.toEqual(new Error('Error from setContent')); pagesPool.setSetContentMethod(); pagesPool.setPdfMethod(); await generator.generatePDF('<html lang="html">Hello World!</html>'); (0, globals_1.expect)(pagesPool.mockedPage.page.pdf).toBeCalled(); } }, 60000); (0, globals_1.test)('Stream have to release resource in case of exception', async () => { const pagesPool = getMockedPool(); await generator.stop(); generator.pagesPool = pagesPool.pool; // Handle exception from generator { pagesPool.setCreatePDFStreamMethod(() => { throw new Error('Error from generator'); }); await (0, globals_1.expect)(generator.generatePDF('<html lang="html">Hello World!</html>', true)).rejects.toEqual(new Error('Error from generator')); pagesPool.setCreatePDFStreamMethod(); await readStream(await generator.generatePDF('<html lang="html">Hello World!</html>', true)); (0, globals_1.expect)(pagesPool.mockedPage.page.createPDFStream).toBeCalled(); } // Handle exception from stream { pagesPool.setCreatePDFStreamMethod(() => { const stream = new stream_1.Stream.Readable({ read: () => undefined, }); setTimeout(() => { stream.push(Buffer.from('abc', 'utf-8')); stream.emit('error', new Error('Error from stream')); }, 50); return stream; }); await (0, globals_1.expect)(readStream(await generator.generatePDF('<html lang="html">Hello World!</html>', true))).rejects.toEqual(new Error('Error from stream')); pagesPool.setCreatePDFStreamMethod(); await readStream(await generator.generatePDF('<html lang="html">Hello World!</html>', true)); (0, globals_1.expect)(pagesPool.mockedPage.page.createPDFStream).toBeCalled(); } }, 60000); }); }); //# sourceMappingURL=index.test.js.map