Skip to content

Commit e6a8149

Browse files
authored
test(ResumePreviewForm): add unit tests for form rendering, editing, and submission (JhaSourav07#2991)
## Description Adds comprehensive unit tests for components/dashboard/ResumePreviewForm.tsx to improve confidence in resume data review and submission workflows. ## Changes - Added tests to verify initial parsed resume data is rendered correctly. - Added tests to verify name and email fields update when edited. - Added tests to verify new skills can be added dynamically. - Added tests to verify submission is blocked when required fields are empty. - Added tests to verify successful profile save triggers completion flow. - Mocked external dependencies (sonner, framer-motion, and network requests) to keep tests isolated and deterministic. Fixes JhaSourav07#2274 ## Pillar - [x] 🎨 Pillar 1 — New Theme Design - [x] 📐 Pillar 2 — Geometric SVG Improvement - [x] 🛠️ Other (Bug fix, refactoring, docs) ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [x] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). - [x] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). - [x] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). - [x] I have updated `README.md` if I added a new theme or URL parameter. - [x] I have started the repo. - [x] I have made sure that i have only one commit to merge in this PR. - [x] The SVG output matches the CommitPulse "premium quality" aesthetic standard (no raw elements, smooth animations, correct fonts). - [x] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support.
2 parents 887049f + 6dafb40 commit e6a8149

1 file changed

Lines changed: 149 additions & 0 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
2+
import { describe, it, expect, vi, beforeEach } from 'vitest';
3+
import ResumePreviewForm from './ResumePreviewForm';
4+
import type { ReactNode, HTMLAttributes } from 'react';
5+
import '@testing-library/jest-dom';
6+
7+
const mocks = vi.hoisted(() => ({
8+
error: vi.fn(),
9+
success: vi.fn(),
10+
}));
11+
12+
vi.mock('sonner', () => ({
13+
toast: {
14+
error: mocks.error,
15+
success: mocks.success,
16+
},
17+
}));
18+
19+
vi.mock('framer-motion', () => ({
20+
motion: {
21+
div: ({ children, ...props }: HTMLAttributes<HTMLDivElement> & { children?: ReactNode }) => (
22+
<div {...props}>{children}</div>
23+
),
24+
},
25+
}));
26+
27+
const parsed = {
28+
name: 'John Doe',
29+
email: 'john@example.com',
30+
phone: '1234567890',
31+
skills: ['React'],
32+
education: [],
33+
experience: [],
34+
};
35+
36+
describe('ResumePreviewForm', () => {
37+
const onBack = vi.fn();
38+
const onComplete = vi.fn();
39+
40+
beforeEach(() => {
41+
vi.clearAllMocks();
42+
});
43+
44+
it('renders initial parsed values', () => {
45+
render(
46+
<ResumePreviewForm
47+
githubUsername="john"
48+
parsed={parsed}
49+
fileName="resume.pdf"
50+
onBack={onBack}
51+
onComplete={onComplete}
52+
/>
53+
);
54+
55+
expect(screen.getByDisplayValue('John Doe')).toBeTruthy();
56+
expect(screen.getByDisplayValue('john@example.com')).toBeTruthy();
57+
expect(screen.getByDisplayValue('React')).toBeTruthy();
58+
});
59+
60+
it('updates name, email, and phone fields', () => {
61+
render(
62+
<ResumePreviewForm
63+
githubUsername="john"
64+
parsed={parsed}
65+
fileName="resume.pdf"
66+
onBack={onBack}
67+
onComplete={onComplete}
68+
/>
69+
);
70+
71+
const nameInput = screen.getByDisplayValue('John Doe');
72+
const emailInput = screen.getByDisplayValue('john@example.com');
73+
fireEvent.change(nameInput, {
74+
target: { value: 'Jane Doe' },
75+
});
76+
77+
fireEvent.change(emailInput, {
78+
target: { value: 'jane@example.com' },
79+
});
80+
81+
expect((nameInput as HTMLInputElement).value).toBe('Jane Doe');
82+
expect((emailInput as HTMLInputElement).value).toBe('jane@example.com');
83+
});
84+
85+
it('adds a new skill', () => {
86+
render(
87+
<ResumePreviewForm
88+
githubUsername="john"
89+
parsed={parsed}
90+
fileName="resume.pdf"
91+
onBack={onBack}
92+
onComplete={onComplete}
93+
/>
94+
);
95+
96+
fireEvent.click(screen.getAllByText('Add')[0]);
97+
98+
const skillInputs = screen.getAllByRole('textbox');
99+
expect(skillInputs.length).toBeGreaterThan(3);
100+
});
101+
102+
it('does not submit when required fields are empty', () => {
103+
const fetchMock = vi.fn();
104+
vi.stubGlobal('fetch', fetchMock);
105+
106+
render(
107+
<ResumePreviewForm
108+
githubUsername="john"
109+
parsed={{
110+
...parsed,
111+
name: '',
112+
email: '',
113+
}}
114+
fileName="resume.pdf"
115+
onBack={onBack}
116+
onComplete={onComplete}
117+
/>
118+
);
119+
120+
fireEvent.click(screen.getByText('Save Profile'));
121+
122+
expect(fetchMock).not.toHaveBeenCalled();
123+
});
124+
125+
it('submits successfully and calls onComplete', async () => {
126+
global.fetch = vi.fn().mockResolvedValue({
127+
ok: true,
128+
json: async () => ({
129+
success: true,
130+
}),
131+
}) as unknown as typeof fetch;
132+
133+
render(
134+
<ResumePreviewForm
135+
githubUsername="john"
136+
parsed={parsed}
137+
fileName="resume.pdf"
138+
onBack={onBack}
139+
onComplete={onComplete}
140+
/>
141+
);
142+
143+
fireEvent.click(screen.getByText('Save Profile'));
144+
145+
await waitFor(() => {
146+
expect(onComplete).toHaveBeenCalled();
147+
});
148+
});
149+
});

0 commit comments

Comments
 (0)