Files
syndarix/frontend/tests/components/ui/DynamicIcon.test.tsx
Felipe Cardoso 3cb6c8d13b feat(agents): implement grid/list view toggle and enhance filters
- Added grid and list view modes to AgentTypeList with user preference management.
- Enhanced filtering with category selection alongside existing search and status filters.
- Updated AgentTypeDetail with category badges and improved layout.
- Added unit tests for grid/list views and category filtering in AgentTypeList.
- Introduced `@radix-ui/react-toggle-group` for view mode toggle in AgentTypeList.
2026-01-06 18:17:46 +01:00

159 lines
5.8 KiB
TypeScript

/**
* Tests for DynamicIcon Component
* Verifies dynamic icon rendering by name string
*/
import { render, screen } from '@testing-library/react';
import { DynamicIcon, getAvailableIconNames } from '@/components/ui/dynamic-icon';
describe('DynamicIcon', () => {
describe('Basic Rendering', () => {
it('renders an icon by name', () => {
render(<DynamicIcon name="bot" data-testid="icon" />);
const icon = screen.getByTestId('icon');
expect(icon).toBeInTheDocument();
expect(icon.tagName).toBe('svg');
});
it('renders different icons by name', () => {
const { rerender } = render(<DynamicIcon name="code" data-testid="icon" />);
expect(screen.getByTestId('icon')).toHaveClass('lucide-code');
rerender(<DynamicIcon name="brain" data-testid="icon" />);
expect(screen.getByTestId('icon')).toHaveClass('lucide-brain');
rerender(<DynamicIcon name="shield" data-testid="icon" />);
expect(screen.getByTestId('icon')).toHaveClass('lucide-shield');
});
it('renders kebab-case icon names correctly', () => {
render(<DynamicIcon name="clipboard-check" data-testid="icon" />);
expect(screen.getByTestId('icon')).toHaveClass('lucide-clipboard-check');
});
});
describe('Fallback Behavior', () => {
it('renders fallback icon when name is null', () => {
render(<DynamicIcon name={null} data-testid="icon" />);
expect(screen.getByTestId('icon')).toHaveClass('lucide-bot');
});
it('renders fallback icon when name is undefined', () => {
render(<DynamicIcon name={undefined} data-testid="icon" />);
expect(screen.getByTestId('icon')).toHaveClass('lucide-bot');
});
it('renders fallback icon when name is not found', () => {
render(<DynamicIcon name="nonexistent-icon" data-testid="icon" />);
expect(screen.getByTestId('icon')).toHaveClass('lucide-bot');
});
it('uses custom fallback when specified', () => {
render(<DynamicIcon name={null} fallback="code" data-testid="icon" />);
expect(screen.getByTestId('icon')).toHaveClass('lucide-code');
});
it('falls back to bot when custom fallback is also invalid', () => {
render(<DynamicIcon name="invalid" fallback="also-invalid" data-testid="icon" />);
expect(screen.getByTestId('icon')).toHaveClass('lucide-bot');
});
});
describe('Props Forwarding', () => {
it('forwards className to icon', () => {
render(<DynamicIcon name="bot" className="h-5 w-5 text-primary" data-testid="icon" />);
const icon = screen.getByTestId('icon');
expect(icon).toHaveClass('h-5');
expect(icon).toHaveClass('w-5');
expect(icon).toHaveClass('text-primary');
});
it('forwards style to icon', () => {
render(<DynamicIcon name="bot" style={{ color: 'red' }} data-testid="icon" />);
const icon = screen.getByTestId('icon');
expect(icon).toHaveStyle({ color: 'rgb(255, 0, 0)' });
});
it('forwards aria-hidden to icon', () => {
render(<DynamicIcon name="bot" aria-hidden="true" data-testid="icon" />);
const icon = screen.getByTestId('icon');
expect(icon).toHaveAttribute('aria-hidden', 'true');
});
});
describe('Available Icons', () => {
it('includes development icons', () => {
const icons = getAvailableIconNames();
expect(icons).toContain('clipboard-check');
expect(icons).toContain('briefcase');
expect(icons).toContain('code');
expect(icons).toContain('server');
});
it('includes design icons', () => {
const icons = getAvailableIconNames();
expect(icons).toContain('palette');
expect(icons).toContain('search');
});
it('includes quality icons', () => {
const icons = getAvailableIconNames();
expect(icons).toContain('shield');
expect(icons).toContain('shield-check');
});
it('includes ai_ml icons', () => {
const icons = getAvailableIconNames();
expect(icons).toContain('brain');
expect(icons).toContain('microscope');
expect(icons).toContain('eye');
});
it('includes data icons', () => {
const icons = getAvailableIconNames();
expect(icons).toContain('bar-chart');
expect(icons).toContain('database');
});
it('includes domain expert icons', () => {
const icons = getAvailableIconNames();
expect(icons).toContain('calculator');
expect(icons).toContain('heart-pulse');
expect(icons).toContain('flask-conical');
expect(icons).toContain('lightbulb');
expect(icons).toContain('book-open');
});
it('includes generic icons', () => {
const icons = getAvailableIconNames();
expect(icons).toContain('bot');
expect(icons).toContain('cpu');
});
});
describe('Icon Categories Coverage', () => {
const iconTestCases = [
// Development
{ name: 'clipboard-check', expectedClass: 'lucide-clipboard-check' },
{ name: 'briefcase', expectedClass: 'lucide-briefcase' },
{ name: 'file-text', expectedClass: 'lucide-file-text' },
{ name: 'git-branch', expectedClass: 'lucide-git-branch' },
{ name: 'layout', expectedClass: 'lucide-panels-top-left' },
{ name: 'smartphone', expectedClass: 'lucide-smartphone' },
// Operations
{ name: 'settings', expectedClass: 'lucide-settings' },
{ name: 'settings-2', expectedClass: 'lucide-settings-2' },
// AI/ML
{ name: 'message-square', expectedClass: 'lucide-message-square' },
// Leadership
{ name: 'users', expectedClass: 'lucide-users' },
{ name: 'target', expectedClass: 'lucide-target' },
];
it.each(iconTestCases)('renders $name icon correctly', ({ name, expectedClass }) => {
render(<DynamicIcon name={name} data-testid="icon" />);
expect(screen.getByTestId('icon')).toHaveClass(expectedClass);
});
});
});