Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade @pdfme/generator to 5.0.0 #2413

1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default {
'<rootDir>/scripts/__mocks__/@dicebear/collection.ts',
'\\.svg\\?react$': '<rootDir>/scripts/__mocks__/fileMock.js',
'\\.svg$': '<rootDir>/scripts/__mocks__/fileMock.js',
'^@pdfme/generator$': '<rootDir>/scripts/__mocks__/@pdfme/generator.ts'
},
moduleFileExtensions: [
'web.js',
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"@mui/x-charts": "^7.22.1",
"@mui/x-data-grid": "^7.22.1",
"@mui/x-date-pickers": "^7.22.1",
"@pdfme/generator": "^4.5.2",
"@pdfme/generator": "^5.0.0",
"@reduxjs/toolkit": "^2.3.0",
"@vitejs/plugin-react": "^4.3.2",
"babel-plugin-transform-import-meta": "^2.2.1",
Expand Down
47 changes: 47 additions & 0 deletions scripts/__mocks__/@pdfme/generator.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { generate } from './generator';
import type { Template } from '@pdfme/common';

describe('Testing mock generate util', () => {
test('should return a Promise', async () => {
const result = generate({
template: { schemas: [] } as Template,
inputs: [],
});
expect(result).toBeInstanceOf(Promise);
});

test('should resolve to a Uint8Array', async () => {
const result = generate({
template: { schemas: [] } as Template,
inputs: [],
});
expect(result).toBeInstanceOf(Uint8Array);
});

it('should throw an error when template is empty', async () => {
const emptyTemplate = { schemas: [] } as Template;
const validInputs = [{ field1: 'value1' }];

await expect(
generate({ template: emptyTemplate, inputs: validInputs }),
).rejects.toThrow('Template or inputs cannot be empty.');
});

it('should throw an error when inputs are empty', async () => {
const validTemplate = { schemas: [{ name: 'field1' }] } as Template;
const emptyInputs: Record<string, string>[] = [];

await expect(
generate({ template: validTemplate, inputs: emptyInputs }),
).rejects.toThrow('Template or inputs cannot be empty.');
});

it('should throw an error when both template and inputs are empty', async () => {
const emptyTemplate = { schemas: [] } as Template;
const emptyInputs: Record<string, string>[] = [];

await expect(
generate({ template: emptyTemplate, inputs: emptyInputs }),
).rejects.toThrow('Template or inputs cannot be empty.');
});
});
22 changes: 22 additions & 0 deletions scripts/__mocks__/@pdfme/generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { Template } from '@pdfme/common';

export const generate = async ({
template,
inputs,
}: {
template: Template;
inputs: Record<string, string>[];
}): Promise<Uint8Array> => {
if (template.schemas.length === 0 || inputs.length === 0) {
// console.log('pdf error: length : ', template, inputs, inputs.length);
throw new Error('Template or inputs cannot be empty.');
}
// Generate mock PDF-like header bytes
const pdfHeader = [0x25, 0x50, 0x44, 0x46]; // %PDF
// Add some random content based on input size
const contentSize = Math.min(template.schemas.length, inputs.length) * 10;
const mockContent = Array.from({ length: contentSize }, () =>
Math.floor(Math.random() * 256),
);
return Promise.resolve(new Uint8Array([...pdfHeader, ...mockContent]));
};
43 changes: 42 additions & 1 deletion src/components/CheckIn/TableRow.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { fireEvent, render, waitFor } from '@testing-library/react';
import { fireEvent, render } from '@testing-library/react';
import { TableRow } from './TableRow';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
Expand Down Expand Up @@ -130,4 +130,45 @@ describe('Testing Table Row for CheckIn Table', () => {
expect(await findByText('Error checking in')).toBeInTheDocument();
expect(await findByText('Oops')).toBeInTheDocument();
});

test('If PDF generation fails, the error message should be shown', async () => {
const props = {
data: {
id: `123`,
name: '',
userId: `user123`,
checkIn: {
_id: '123',
time: '12:00:00',
},
eventId: `event123`,
},
refetch: jest.fn(),
};

const { findByText } = render(
<BrowserRouter>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<MockedProvider addTypename={false} mocks={checkInMutationSuccess}>
<Provider store={store}>
<I18nextProvider i18n={i18nForTest}>
<ToastContainer />
<TableRow {...props} />
</I18nextProvider>
</Provider>
</MockedProvider>
</LocalizationProvider>
</BrowserRouter>,
);

// Mocking the PDF generation function to throw an error
global.URL.createObjectURL = jest.fn(() => 'mockURL');
global.window.open = jest.fn();

fireEvent.click(await findByText('Download Tag'));

expect(
await findByText('Error generating pdf: Invalid or empty name provided'),
).toBeInTheDocument();
});
});
6 changes: 5 additions & 1 deletion src/components/CheckIn/TableRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,11 @@ export const TableRow = ({
*/
const generateTag = async (): Promise<void> => {
try {
const inputs = [{ name: data.name }];
const inputs = [];
if (typeof data.name !== 'string' || !data.name.trim()) {
throw new Error('Invalid or empty name provided');
}
inputs.push({ name: data.name.trim() });
const pdf = await generate({ template: tagTemplate, inputs });
// istanbul ignore next
const blob = new Blob([pdf.buffer], { type: 'application/pdf' });
Expand Down
Loading