Skip to content

Commit c4a6ac0

Browse files
test(ResumeProfileSection): add workflow interaction coverage
1 parent 723fa76 commit c4a6ac0

2 files changed

Lines changed: 202 additions & 0 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { render, screen, fireEvent } from '@testing-library/react';
2+
import { describe, it, expect, vi, beforeEach } from 'vitest';
3+
import ProfileOptimizerModal from './ProfileOptimizerModal';
4+
import type { ReactNode, HTMLAttributes } from 'react';
5+
import '@testing-library/jest-dom';
6+
7+
vi.mock('framer-motion', () => ({
8+
AnimatePresence: ({ children }: { children?: ReactNode }) => <>{children}</>,
9+
10+
motion: {
11+
div: ({
12+
children,
13+
...props
14+
}: HTMLAttributes<HTMLDivElement> & {
15+
children?: ReactNode;
16+
}) => <div {...props}>{children}</div>,
17+
18+
p: ({
19+
children,
20+
...props
21+
}: HTMLAttributes<HTMLParagraphElement> & {
22+
children?: ReactNode;
23+
}) => <p {...props}>{children}</p>,
24+
},
25+
}));
26+
27+
const mockUserData = {
28+
profile: {
29+
developerScore: 75,
30+
bio: 'Full Stack Developer',
31+
stats: {
32+
repositories: 12,
33+
followers: 20,
34+
},
35+
},
36+
languages: ['TypeScript', 'JavaScript'],
37+
stats: {
38+
totalContributions: 500,
39+
},
40+
};
41+
42+
describe('ProfileOptimizerModal', () => {
43+
const onClose = vi.fn();
44+
45+
beforeEach(() => {
46+
vi.clearAllMocks();
47+
});
48+
49+
it('does not render when isOpen is false', () => {
50+
render(<ProfileOptimizerModal isOpen={false} onClose={onClose} userData={mockUserData} />);
51+
52+
expect(screen.queryByText('Profile Optimizer')).not.toBeInTheDocument();
53+
});
54+
55+
it('renders modal when isOpen is true', () => {
56+
render(<ProfileOptimizerModal isOpen onClose={onClose} userData={mockUserData} />);
57+
58+
expect(screen.getByText('Profile Optimizer')).toBeInTheDocument();
59+
});
60+
61+
it('calls onClose when close button is clicked', () => {
62+
render(<ProfileOptimizerModal isOpen onClose={onClose} userData={mockUserData} />);
63+
64+
const buttons = screen.getAllByRole('button');
65+
fireEvent.click(buttons[0]);
66+
67+
expect(onClose).toHaveBeenCalledTimes(1);
68+
});
69+
70+
it('shows loading state initially', () => {
71+
render(<ProfileOptimizerModal isOpen onClose={onClose} userData={mockUserData} />);
72+
73+
expect(screen.getByText('Analysing GitHub profile...')).toBeInTheDocument();
74+
});
75+
76+
it('renders loading container when modal opens', () => {
77+
render(<ProfileOptimizerModal isOpen onClose={onClose} userData={mockUserData} />);
78+
79+
expect(screen.getByText('Analysing GitHub profile...')).toBeInTheDocument();
80+
});
81+
});
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { render, screen, fireEvent } from '@testing-library/react';
2+
import { describe, it, expect, vi, beforeEach } from 'vitest';
3+
import ResumeProfileSection from './ResumeProfileSection';
4+
import type { ReactNode, HTMLAttributes } from 'react';
5+
import '@testing-library/jest-dom';
6+
7+
const { mockToastError, mockToastSuccess } = vi.hoisted(() => ({
8+
mockToastError: vi.fn(),
9+
mockToastSuccess: vi.fn(),
10+
}));
11+
12+
vi.mock('sonner', () => ({
13+
toast: {
14+
error: mockToastError,
15+
success: mockToastSuccess,
16+
},
17+
}));
18+
19+
vi.mock('framer-motion', () => ({
20+
motion: {
21+
div: ({
22+
children,
23+
...props
24+
}: HTMLAttributes<HTMLDivElement> & {
25+
children?: ReactNode;
26+
}) => <div {...props}>{children}</div>,
27+
},
28+
AnimatePresence: ({ children }: { children: ReactNode }) => <>{children}</>,
29+
}));
30+
31+
const parsedResume = {
32+
name: 'John Doe',
33+
email: 'john@example.com',
34+
phone: '1234567890',
35+
skills: ['React'],
36+
education: [],
37+
experience: [],
38+
};
39+
40+
vi.mock('./ResumeUpload', () => ({
41+
default: ({
42+
onParsed,
43+
onError,
44+
}: {
45+
onParsed: (data: unknown, name: string) => void;
46+
onError: (error: string) => void;
47+
}) => (
48+
<div>
49+
<button onClick={() => onParsed(parsedResume, 'resume.pdf')}>Mock Upload Success</button>
50+
51+
<button onClick={() => onError('Upload failed')}>Mock Upload Error</button>
52+
</div>
53+
),
54+
}));
55+
56+
vi.mock('./ResumePreviewForm', () => ({
57+
default: ({ onBack, onComplete }: { onBack: () => void; onComplete: () => void }) => (
58+
<div>
59+
<p>Preview Form</p>
60+
61+
<button onClick={onBack}>Back</button>
62+
63+
<button onClick={onComplete}>Complete</button>
64+
</div>
65+
),
66+
}));
67+
68+
describe('ResumeProfileSection', () => {
69+
beforeEach(() => {
70+
vi.clearAllMocks();
71+
});
72+
73+
it('renders upload state initially', () => {
74+
render(<ResumeProfileSection githubUsername="john" />);
75+
76+
expect(screen.getByText('Resume Profile')).toBeInTheDocument();
77+
78+
expect(screen.getByText(/upload your pdf or docx resume/i)).toBeInTheDocument();
79+
});
80+
81+
it('shows preview form after successful parse', () => {
82+
render(<ResumeProfileSection githubUsername="john" />);
83+
84+
fireEvent.click(screen.getByText('Mock Upload Success'));
85+
86+
expect(screen.getByText('Preview Form')).toBeInTheDocument();
87+
});
88+
89+
it('returns to upload state when back is clicked', () => {
90+
render(<ResumeProfileSection githubUsername="john" />);
91+
92+
fireEvent.click(screen.getByText('Mock Upload Success'));
93+
94+
fireEvent.click(screen.getByText('Back'));
95+
96+
expect(screen.getByText(/upload your pdf or docx resume/i)).toBeInTheDocument();
97+
});
98+
99+
it('shows success state after completion', () => {
100+
render(<ResumeProfileSection githubUsername="john" />);
101+
102+
fireEvent.click(screen.getByText('Mock Upload Success'));
103+
104+
fireEvent.click(screen.getByText('Complete'));
105+
106+
expect(screen.getByText('Profile synced from resume')).toBeInTheDocument();
107+
108+
expect(mockToastSuccess).toHaveBeenCalledWith('Profile updated from resume!');
109+
});
110+
111+
it('shows error toast when upload fails', () => {
112+
render(<ResumeProfileSection githubUsername="john" />);
113+
114+
fireEvent.click(screen.getByText('Mock Upload Error'));
115+
116+
expect(mockToastError).toHaveBeenCalledWith('Upload failed');
117+
});
118+
it('renders component', () => {
119+
expect(true).toBe(true);
120+
});
121+
});

0 commit comments

Comments
 (0)