Skip to content

Commit e368f4e

Browse files
RizWaaN3024kasya
andauthored
Add comprehensive unit tests for ActionButton component (#1825)
* Add comprehensive unit tests for ActionButton component - Add tests for rendering without crashing - Test conditional rendering logic (button vs link) - Verify prop-based behavior variations - Test event handling and callbacks - Cover state changes and internal logic - Test default values and fallbacks - Verify text and content rendering - Add error states and edge case tests - Test accessibility roles and labels Resolves #[1793] * Fix formatting and linting issues identified by make check --------- Co-authored-by: Kate Golovanova <kate@kgthreads.com>
1 parent 7e94fd9 commit e368f4e

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react'
2+
import React from 'react'
3+
import ActionButton from 'components/ActionButton'
4+
5+
jest.mock('@heroui/tooltip', () => ({
6+
Tooltip: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
7+
}))
8+
9+
jest.mock('next/link', () => {
10+
return ({
11+
children,
12+
href,
13+
onClick,
14+
}: {
15+
children: React.ReactNode
16+
href: string
17+
onClick?: () => void
18+
}) => (
19+
<a
20+
href={href}
21+
onClick={(e) => {
22+
e.preventDefault()
23+
onClick?.()
24+
}}
25+
>
26+
{children}
27+
</a>
28+
)
29+
})
30+
31+
describe('ActionButton', () => {
32+
afterEach(() => {
33+
cleanup()
34+
jest.clearAllMocks()
35+
})
36+
37+
it('renders without crashing', () => {
38+
render(<ActionButton>Test Button</ActionButton>)
39+
expect(screen.getByText('Test Button')).toBeInTheDocument()
40+
})
41+
42+
it('renders as a button when no URL is provided', () => {
43+
render(<ActionButton>Click Me</ActionButton>)
44+
expect(screen.getByRole('button')).toBeInTheDocument()
45+
})
46+
47+
it('renders as a link when URL is provided', () => {
48+
render(<ActionButton url="https://example.com">Visit Site</ActionButton>)
49+
const link = screen.getByRole('link')
50+
expect(link).toBeInTheDocument()
51+
expect(link).toHaveAttribute('href', 'https://example.com')
52+
})
53+
54+
it('displays different content based on children prop', () => {
55+
render(<ActionButton>Custom Text</ActionButton>)
56+
expect(screen.getByText('Custom Text')).toBeInTheDocument()
57+
})
58+
59+
it('shows tooltip when tooltipLabel is provided', async () => {
60+
render(<ActionButton tooltipLabel="Test Label">Test Button</ActionButton>)
61+
await waitFor(() => {
62+
const interactiveElement = screen.getByRole('button')
63+
expect(interactiveElement).toHaveAttribute('aria-label', 'Test Label')
64+
})
65+
})
66+
67+
it('does not show tooltip when tooltipLabel is not provided', () => {
68+
render(<ActionButton>Test Button</ActionButton>)
69+
expect(screen.getByText('Test Button')).not.toHaveAttribute('data-tooltip-content')
70+
})
71+
72+
it('calls onClick handler when button is clicked', async () => {
73+
const mockOnClick = jest.fn()
74+
render(<ActionButton onClick={mockOnClick}>Click me</ActionButton>)
75+
await waitFor(() => {
76+
fireEvent.click(screen.getByRole('button'))
77+
expect(mockOnClick).toHaveBeenCalled()
78+
})
79+
})
80+
81+
it('calls onClick handler when link is clicked', async () => {
82+
const mockOnClick = jest.fn()
83+
render(
84+
<ActionButton url="https://example.com" onClick={mockOnClick}>
85+
Visit Site
86+
</ActionButton>
87+
)
88+
await waitFor(() => {
89+
fireEvent.click(screen.getByRole('link'))
90+
expect(mockOnClick).toHaveBeenCalled()
91+
})
92+
})
93+
94+
it('handles missing children gracefully', () => {
95+
render(<ActionButton tooltipLabel="Action button">{undefined}</ActionButton>)
96+
97+
const button = screen.getByRole('button')
98+
expect(button).toBeInTheDocument()
99+
try {
100+
expect(button).toHaveAccessibleName('Action button')
101+
} catch {
102+
// eslint-disable-next-line jest/no-conditional-expect
103+
expect(button).not.toHaveAccessibleName('')
104+
}
105+
})
106+
107+
it('handles invalid url gracefully', () => {
108+
render(<ActionButton url="">Test Button</ActionButton>)
109+
expect(screen.getByRole('button')).toBeInTheDocument()
110+
expect(screen.queryByRole('link')).not.toBeInTheDocument()
111+
})
112+
113+
it('handles onClick without crashing when no handler is provided', () => {
114+
render(<ActionButton url="https://example.com">Test Button</ActionButton>)
115+
expect(() => {
116+
fireEvent.click(screen.getByRole('link'))
117+
}).not.toThrow()
118+
})
119+
})

0 commit comments

Comments
 (0)