Skip to content

Commit 73aea7f

Browse files
committed
test(resume-parser): add error-resilience test suite (JhaSourav07#2878)
1 parent 0440f8c commit 73aea7f

1 file changed

Lines changed: 108 additions & 0 deletions

File tree

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { describe, it, expect, vi } from 'vitest';
2+
import { parseResume } from './resume-parser';
3+
4+
describe('resume-parser-error-resilience', () => {
5+
it('should handle non-printable characters gracefully by replacing them and parsing the remaining text', async () => {
6+
// \x00 is non-printable. It should be replaced with a space.
7+
const text = 'John Doe\n\x00\x01\x02john.doe@example.com\nSkills\nJavaScript, Python';
8+
const buffer = Buffer.from(text);
9+
const result = await parseResume(buffer, 'application/pdf');
10+
11+
expect(result.name).toBe('John Doe');
12+
expect(result.email).toBe('john.doe@example.com');
13+
expect(result.skills).toContain('JavaScript');
14+
expect(result.skills).toContain('Python');
15+
});
16+
17+
it('should throw an error/TypeError if the buffer is null or undefined (exception safety)', async () => {
18+
// Ensure that passing invalid parameters rejects or throws a TypeError rather than hanging
19+
await expect(parseResume(null as unknown as Buffer, 'application/pdf')).rejects.toThrow();
20+
await expect(parseResume(undefined as unknown as Buffer, 'application/pdf')).rejects.toThrow();
21+
});
22+
23+
it('should not throw and handle corrupt/binary buffers by returning empty fields', async () => {
24+
// Binary/corrupt data that doesn't resemble a text resume
25+
const binaryData = Buffer.from([
26+
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00,
27+
]);
28+
const result = await parseResume(binaryData, 'application/pdf');
29+
30+
expect(result).toEqual({
31+
name: '',
32+
email: '',
33+
phone: '',
34+
skills: [],
35+
education: [],
36+
experience: [],
37+
});
38+
});
39+
40+
it('should handle buffer toString failures gracefully (exception safety)', async () => {
41+
const mockBuffer = Buffer.from('Some text');
42+
vi.spyOn(mockBuffer, 'toString').mockImplementation(() => {
43+
throw new Error('Buffer conversion failed');
44+
});
45+
46+
await expect(parseResume(mockBuffer, 'application/pdf')).rejects.toThrow(
47+
'Buffer conversion failed'
48+
);
49+
vi.restoreAllMocks();
50+
});
51+
52+
it('should skip malformed education entries (e.g. invalid date ranges) instead of throwing', async () => {
53+
const text = `John Doe
54+
Education
55+
University of Toronto 201-202
56+
Harvard College 2020 to invalid
57+
MIT 2015 to 2019
58+
`;
59+
const buffer = Buffer.from(text);
60+
const result = await parseResume(buffer, 'application/pdf');
61+
62+
expect(result.education).toEqual([
63+
{
64+
institution: 'MIT 2015 to 2019',
65+
degree: '',
66+
field: '',
67+
startDate: '2015',
68+
endDate: '2019',
69+
},
70+
]);
71+
});
72+
73+
it('should skip malformed experience entries instead of throwing', async () => {
74+
const text = `John Doe
75+
Experience
76+
Software Developer at Google (no date)
77+
Intern at Apple 202 to present
78+
Senior Engineer at Meta 2018 - 2021
79+
`;
80+
const buffer = Buffer.from(text);
81+
const result = await parseResume(buffer, 'application/pdf');
82+
83+
expect(result.experience).toEqual([
84+
{
85+
company: 'Senior Engineer at Meta 2018 - 2021',
86+
role: '',
87+
startDate: '2018',
88+
endDate: '2021',
89+
description: '',
90+
},
91+
]);
92+
});
93+
94+
it('should handle extremely long single-word inputs without causing RegExp backtracking or crashing', async () => {
95+
const longWord = 'A'.repeat(10000);
96+
const text = `John Doe\n${longWord}@example.com\nSkills\n${longWord}`;
97+
const buffer = Buffer.from(text);
98+
99+
const startTime = Date.now();
100+
const result = await parseResume(buffer, 'application/pdf');
101+
const duration = Date.now() - startTime;
102+
103+
// Check that it didn't hang (completed within 500ms)
104+
expect(duration).toBeLessThan(500);
105+
expect(result.name).toBe('John Doe');
106+
expect(result.email).toContain('@example.com');
107+
});
108+
});

0 commit comments

Comments
 (0)