hpdf
Version:
NodeJS library for generation PDF from HTML
211 lines • 9.79 kB
JavaScript
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
;