Skip to content

Commit f1b7c8d

Browse files
committed
Fix #1912: Added test for SecondaryCard component
1 parent 4479525 commit f1b7c8d

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import { faUser } from '@fortawesome/free-solid-svg-icons';
2+
import { render, screen } from '@testing-library/react';
3+
import SecondaryCard from 'components/SecondaryCard';
4+
5+
describe('SecondaryCard Component', () => {
6+
const defaultProps = {
7+
title: 'Test Title',
8+
icon: faUser,
9+
children: <p>Test children</p>,
10+
className: 'custom-class',
11+
};
12+
13+
describe('Renders successfully with minimal required props', () => {
14+
it('renders successfully with only a title', () => {
15+
render(<SecondaryCard title={defaultProps.title} />);
16+
expect(screen.getByText(defaultProps.title)).toBeInTheDocument();
17+
});
18+
19+
it('renders successfully with only children', () => {
20+
render(<SecondaryCard>{defaultProps.children}</SecondaryCard>);
21+
expect(screen.getByText('Test children')).toBeInTheDocument();
22+
});
23+
24+
it('renders successfully with no props at all', () => {
25+
const { container } = render(<SecondaryCard />);
26+
expect(container.querySelector('.mb-8')).toBeInTheDocument();
27+
});
28+
});
29+
30+
describe('Conditional rendering logic', () => {
31+
it('does not render the h2 title element when title prop is not provided', () => {
32+
render(<SecondaryCard />);
33+
const titleElement = screen.queryByRole('heading');
34+
expect(titleElement).not.toBeInTheDocument();
35+
});
36+
37+
it('renders the h2 title element when title prop is provided', () => {
38+
render(<SecondaryCard title={defaultProps.title} />);
39+
const titleElement = screen.getByRole('heading', { name: 'Test Title' });
40+
expect(titleElement).toBeInTheDocument();
41+
});
42+
43+
it('does not render the icon when icon prop is not provided', () => {
44+
const { container } = render(<SecondaryCard title={defaultProps.title} />);
45+
const iconElement = container.querySelector('svg');
46+
expect(iconElement).not.toBeInTheDocument();
47+
});
48+
});
49+
50+
describe('Prop-based behavior - different props affect output', () => {
51+
it('renders a title and an icon when both are provided', () => {
52+
render(<SecondaryCard title={defaultProps.title} icon={defaultProps.icon} />);
53+
expect(screen.getByText(defaultProps.title)).toBeInTheDocument();
54+
expect(screen.getByRole('img', { hidden: true })).toBeInTheDocument();
55+
});
56+
57+
it('renders children content correctly', () => {
58+
render(<SecondaryCard>{defaultProps.children}</SecondaryCard>);
59+
expect(screen.getByText('Test children')).toBeInTheDocument();
60+
});
61+
});
62+
63+
describe('Text and content rendering', () => {
64+
it('displays the correct text for the title', () => {
65+
const customTitle = 'My Custom Title';
66+
render(<SecondaryCard title={customTitle} />);
67+
expect(screen.getByText(customTitle)).toBeInTheDocument();
68+
});
69+
70+
it('renders complex children nodes', () => {
71+
const complexChildren = (
72+
<div>
73+
<span>Nested Content</span>
74+
<button>Click Me</button>
75+
</div>
76+
);
77+
render(<SecondaryCard>{complexChildren}</SecondaryCard>);
78+
expect(screen.getByText('Nested Content')).toBeInTheDocument();
79+
expect(screen.getByRole('button', { name: 'Click Me' })).toBeInTheDocument();
80+
});
81+
});
82+
83+
describe('Handles edge cases and invalid inputs', () => {
84+
it('handles an empty string for the title prop by not rendering the title element', () => {
85+
render(<SecondaryCard title="" />);
86+
const titleElement = screen.queryByRole('heading');
87+
expect(titleElement).not.toBeInTheDocument();
88+
});
89+
90+
it('handles null children gracefully by rendering nothing for the children', () => {
91+
const { container } = render(
92+
<SecondaryCard title="Title">{null}</SecondaryCard>
93+
);
94+
const cardElement = container.firstChild;
95+
const titleElement = screen.getByRole('heading', { name: 'Title' });
96+
expect(titleElement).toBeInTheDocument();
97+
expect(cardElement.childNodes.length).toBe(1);
98+
});
99+
});
100+
101+
describe('Accessibility roles and labels', () => {
102+
it('renders the title within an h2 tag for proper heading structure', () => {
103+
render(<SecondaryCard title={defaultProps.title} />);
104+
const heading = screen.getByRole('heading', { level: 2, name: defaultProps.title });
105+
expect(heading).toBeInTheDocument();
106+
});
107+
});
108+
109+
describe('DOM structure / classNames / styles', () => {
110+
it('applies the base and custom classNames to the root div', () => {
111+
const { container } = render(<SecondaryCard className={defaultProps.className} />);
112+
const cardElement = container.firstChild;
113+
expect(cardElement).toHaveClass('mb-8', 'rounded-lg', 'bg-gray-100', 'p-6', 'shadow-md', 'dark:bg-gray-800');
114+
expect(cardElement).toHaveClass(defaultProps.className);
115+
});
116+
117+
it('has the correct classNames for the h2 title element', () => {
118+
render(<SecondaryCard title={defaultProps.title} />);
119+
const titleElement = screen.getByText(defaultProps.title);
120+
expect(titleElement).toHaveClass('mb-4', 'flex', 'flex-row', 'items-center', 'gap-2', 'text-2xl', 'font-semibold');
121+
});
122+
123+
it('has the correct className for the icon', () => {
124+
render(<SecondaryCard title={defaultProps.title} icon={defaultProps.icon} />);
125+
const iconElement = screen.getByRole('img', { hidden: true });
126+
expect(iconElement).toHaveClass('h-5', 'w-5');
127+
});
128+
});
129+
});

0 commit comments

Comments
 (0)