Skip to content

Commit bcce155

Browse files
added test for RecentPullRequest.test.tsx
1 parent c30fc63 commit bcce155

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import { render, screen, fireEvent } from '@testing-library/react'
2+
import { ReactNode } from 'react'
3+
import RecentPullRequests from 'components/RecentPullRequests'
4+
5+
// =========================
6+
// Mocks
7+
// =========================
8+
9+
jest.mock('@heroui/tooltip', () => ({
10+
Tooltip: ({ children }: { children?: ReactNode }) => <div>{children}</div>,
11+
}))
12+
13+
const mockRouterPush = jest.fn()
14+
jest.mock('next/navigation', () => ({
15+
useRouter: () => ({
16+
push: mockRouterPush,
17+
}),
18+
}))
19+
20+
jest.mock('components/TruncatedText', () => ({
21+
TruncatedText: ({ text }: { text: string }) => <span>{text}</span>,
22+
}))
23+
24+
jest.mock('utils/dateFormatter', () => ({
25+
formatDate: () => 'Jun 1, 2024',
26+
}))
27+
28+
// =========================
29+
// Test Data
30+
// =========================
31+
32+
const mockUser = {
33+
avatarUrl: 'https://example.com/avatar.png',
34+
bio: 'Test bio',
35+
company: 'Test Company',
36+
contributionsCount: 42,
37+
createdAt: 1577836800000, // number, as required by User type
38+
email: 'test@example.com',
39+
followersCount: 10,
40+
followingCount: 5,
41+
key: 'user-key',
42+
location: 'Test City',
43+
login: 'testuser',
44+
name: 'Test User',
45+
publicRepositoriesCount: 3,
46+
url: 'https://github.com/testuser',
47+
}
48+
49+
const minimalData = [
50+
{
51+
author: mockUser,
52+
createdAt: '2024-06-01T12:00:00Z',
53+
organizationName: 'test-org',
54+
repositoryName: 'test-repo',
55+
title: 'Test Pull Request',
56+
url: 'https://github.com/test-org/test-repo/pull/1',
57+
},
58+
]
59+
60+
const noRepoData = [
61+
{
62+
author: mockUser,
63+
createdAt: '2024-06-01T12:00:00Z',
64+
organizationName: 'test-org',
65+
repositoryName: undefined,
66+
title: 'Test Pull Request',
67+
url: 'https://github.com/test-org/test-repo/pull/2',
68+
},
69+
]
70+
71+
// =========================
72+
// Tests
73+
// =========================
74+
75+
describe('RecentPullRequests', () => {
76+
afterEach(() => {
77+
jest.clearAllMocks()
78+
})
79+
80+
// --- Rendering ---
81+
it('renders successfully with minimal required props', () => {
82+
render(<RecentPullRequests data={minimalData} />)
83+
expect(screen.getByText('Recent Pull Requests')).toBeInTheDocument()
84+
expect(screen.getByText('test-repo')).toBeInTheDocument()
85+
expect(screen.getByText('Jun 1, 2024')).toBeInTheDocument()
86+
expect(screen.getByText('Test Pull Request')).toBeInTheDocument()
87+
})
88+
89+
// --- Conditional Rendering ---
90+
it('does not render repository button if repositoryName is missing', () => {
91+
render(<RecentPullRequests data={noRepoData} />)
92+
expect(screen.queryByText('test-repo')).not.toBeInTheDocument()
93+
})
94+
95+
// --- Prop-based Behavior ---
96+
it('passes showAvatar prop to ItemCardList', () => {
97+
render(<RecentPullRequests data={minimalData} showAvatar={false} />)
98+
expect(screen.getByText('test-repo')).toBeInTheDocument()
99+
})
100+
101+
// --- Event Handling ---
102+
it('calls router.push with correct URL when repository name is clicked', () => {
103+
render(<RecentPullRequests data={minimalData} />)
104+
fireEvent.click(screen.getByText('test-repo'))
105+
expect(mockRouterPush).toHaveBeenCalledWith('/organizations/test-org/repositories/test-repo')
106+
})
107+
108+
// --- Edge Cases ---
109+
it('renders correctly when data is empty', () => {
110+
render(<RecentPullRequests data={[]} />)
111+
expect(screen.getByText('Recent Pull Requests')).toBeInTheDocument()
112+
expect(screen.queryByText('test-repo')).not.toBeInTheDocument()
113+
})
114+
115+
it('handles undefined data prop gracefully', () => {
116+
render(<RecentPullRequests data={undefined} />)
117+
expect(screen.getByText('Recent Pull Requests')).toBeInTheDocument()
118+
})
119+
120+
// --- Defaults and Fallbacks ---
121+
it('uses default value for showAvatar when not provided', () => {
122+
render(<RecentPullRequests data={minimalData} />)
123+
expect(screen.getByText('test-repo')).toBeInTheDocument()
124+
})
125+
126+
// --- Content Rendering ---
127+
it('renders the title and formatted date', () => {
128+
render(<RecentPullRequests data={minimalData} />)
129+
expect(screen.getByText('Recent Pull Requests')).toBeInTheDocument()
130+
expect(screen.getByText('Jun 1, 2024')).toBeInTheDocument()
131+
expect(screen.getByText('Test Pull Request')).toBeInTheDocument()
132+
})
133+
134+
// --- Accessibility ---
135+
it('has accessible title and buttons', () => {
136+
render(<RecentPullRequests data={minimalData} />)
137+
expect(screen.getByRole('heading', { name: /Recent Pull Requests/i })).toBeInTheDocument()
138+
expect(screen.getByText('test-repo').closest('button')).toBeInTheDocument()
139+
})
140+
141+
// --- DOM Structure / ClassNames ---
142+
it('renders with expected classNames', () => {
143+
render(<RecentPullRequests data={minimalData} />)
144+
expect(screen.getByText('Recent Pull Requests').parentElement).toHaveClass('flex')
145+
})
146+
})

0 commit comments

Comments
 (0)