Skip to content

Commit db362fb

Browse files
resume
1 parent 65413a4 commit db362fb

1 file changed

Lines changed: 143 additions & 0 deletions

File tree

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
2+
import { describe, it, expect, vi, beforeEach } from 'vitest';
3+
import ResumeUpload from './ResumeUpload';
4+
import type { ReactNode, HTMLAttributes } from 'react';
5+
import '@testing-library/jest-dom';
6+
7+
vi.mock('framer-motion', () => ({
8+
motion: {
9+
div: ({ children, ...props }: HTMLAttributes<HTMLDivElement> & { children?: ReactNode }) => (
10+
<div {...props}>{children}</div>
11+
),
12+
},
13+
AnimatePresence: ({ children }: { children: ReactNode }) => <>{children}</>,
14+
}));
15+
16+
describe('ResumeUpload', () => {
17+
const onParsed = vi.fn();
18+
const onError = vi.fn();
19+
20+
beforeEach(() => {
21+
vi.clearAllMocks();
22+
});
23+
24+
it('shows error for invalid file type', () => {
25+
render(<ResumeUpload onParsed={onParsed} onError={onError} />);
26+
27+
const input = screen.getByLabelText('Upload resume');
28+
29+
const file = new File(['test'], 'image.png', {
30+
type: 'image/png',
31+
});
32+
33+
fireEvent.change(input, {
34+
target: { files: [file] },
35+
});
36+
37+
expect(onError).toHaveBeenCalledWith('Please upload a PDF or DOCX file.');
38+
});
39+
40+
it('shows error when file exceeds 5MB', () => {
41+
render(<ResumeUpload onParsed={onParsed} onError={onError} />);
42+
43+
const input = screen.getByLabelText('Upload resume');
44+
45+
const file = new File([new Uint8Array(6 * 1024 * 1024)], 'resume.pdf', {
46+
type: 'application/pdf',
47+
});
48+
49+
fireEvent.change(input, {
50+
target: { files: [file] },
51+
});
52+
53+
expect(onError).toHaveBeenCalledWith('File size must be under 5MB.');
54+
});
55+
56+
it('calls onParsed after successful upload', async () => {
57+
global.fetch = vi.fn().mockResolvedValue({
58+
ok: true,
59+
json: async () => ({
60+
success: true,
61+
fileName: 'resume.pdf',
62+
data: {
63+
name: 'John Doe',
64+
},
65+
}),
66+
}) as typeof fetch;
67+
68+
render(<ResumeUpload onParsed={onParsed} onError={onError} />);
69+
70+
const input = screen.getByLabelText('Upload resume');
71+
72+
const file = new File(['pdf'], 'resume.pdf', {
73+
type: 'application/pdf',
74+
});
75+
76+
fireEvent.change(input, {
77+
target: { files: [file] },
78+
});
79+
80+
await waitFor(() => {
81+
expect(onParsed).toHaveBeenCalled();
82+
});
83+
});
84+
85+
it('shows loading state while uploading', async () => {
86+
global.fetch = vi.fn(
87+
() =>
88+
new Promise((resolve) =>
89+
setTimeout(
90+
() =>
91+
resolve({
92+
ok: true,
93+
json: async () => ({
94+
success: true,
95+
data: {},
96+
}),
97+
}),
98+
100
99+
)
100+
)
101+
) as typeof fetch;
102+
103+
render(<ResumeUpload onParsed={onParsed} onError={onError} />);
104+
105+
const input = screen.getByLabelText('Upload resume');
106+
107+
const file = new File(['pdf'], 'resume.pdf', {
108+
type: 'application/pdf',
109+
});
110+
111+
fireEvent.change(input, {
112+
target: { files: [file] },
113+
});
114+
115+
expect(screen.getByText('Parsing resume...')).toBeInTheDocument();
116+
});
117+
118+
it('shows upload error when API fails', async () => {
119+
global.fetch = vi.fn().mockResolvedValue({
120+
ok: false,
121+
json: async () => ({
122+
success: false,
123+
error: 'Upload failed',
124+
}),
125+
}) as typeof fetch;
126+
127+
render(<ResumeUpload onParsed={onParsed} onError={onError} />);
128+
129+
const input = screen.getByLabelText('Upload resume');
130+
131+
const file = new File(['pdf'], 'resume.pdf', {
132+
type: 'application/pdf',
133+
});
134+
135+
fireEvent.change(input, {
136+
target: { files: [file] },
137+
});
138+
139+
await waitFor(() => {
140+
expect(onError).toHaveBeenCalledWith('Upload failed');
141+
});
142+
});
143+
});

0 commit comments

Comments
 (0)