All checks were successful
continuous-integration/drone/push Build is passing
78 lines
2.9 KiB
TypeScript
78 lines
2.9 KiB
TypeScript
import { HomeIcon } from '@heroicons/react/24/solid';
|
|
import { fireEvent, render, screen } from '@testing-library/react';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
import { Button } from '../../src/components/Button';
|
|
import { renderWithRouter } from '../helpers/renderWithRouter';
|
|
|
|
describe('Button', () => {
|
|
it('renders native button with expected type and disabled state', () => {
|
|
render(<Button label="Save" type="solid" htmlType="submit" disabled />);
|
|
|
|
const button = screen.getByRole('button', { name: 'Save' });
|
|
expect(button.tagName).toBe('BUTTON');
|
|
expect(button).toHaveAttribute('type', 'submit');
|
|
expect(button).toBeDisabled();
|
|
expect(button).toHaveClass('btn-solid');
|
|
expect(button).toHaveClass('btn-primary');
|
|
});
|
|
|
|
it('defaults non-solid button variants to secondary', () => {
|
|
render(<Button label="Details" type="noborder" />);
|
|
expect(screen.getByRole('button', { name: 'Details' })).toHaveClass('btn-secondary');
|
|
});
|
|
|
|
it('uses explicit variant when provided', () => {
|
|
render(<Button label="Danger" type="outlined" variant="important" />);
|
|
|
|
expect(screen.getByRole('button', { name: 'Danger' })).toHaveClass('btn-important');
|
|
});
|
|
|
|
it('renders icon-only button and custom aria label', () => {
|
|
render(<Button type="solid" icon={HomeIcon} ariaLabel="Open home" />);
|
|
|
|
const button = screen.getByRole('button', { name: 'Open home' });
|
|
expect(button).toBeInTheDocument();
|
|
expect(button).toHaveClass('!p-0');
|
|
expect(button.textContent).toBe('');
|
|
});
|
|
|
|
it('renders link button and prevents click when disabled', () => {
|
|
const onClick = vi.fn();
|
|
renderWithRouter(
|
|
<Button label="Go home" type="outlined" to="/home" onClick={onClick} disabled />,
|
|
);
|
|
|
|
const link = screen.getByRole('link', { name: 'Go home' });
|
|
fireEvent.click(link);
|
|
|
|
expect(link).toHaveAttribute('aria-disabled', 'true');
|
|
expect(link).toHaveAttribute('tabindex', '-1');
|
|
expect(onClick).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('calls onClick for enabled link buttons', () => {
|
|
const onClick = vi.fn();
|
|
renderWithRouter(<Button label="Profile" type="solid" to="/profile" onClick={onClick} />);
|
|
|
|
fireEvent.click(screen.getByRole('link', { name: 'Profile' }));
|
|
expect(onClick).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('renders icon+label spacing and custom class names', () => {
|
|
render(
|
|
<Button
|
|
label="Home"
|
|
type="outlined"
|
|
icon={HomeIcon}
|
|
className="custom-button"
|
|
width="full"
|
|
/>,
|
|
);
|
|
|
|
const button = screen.getByRole('button', { name: 'Home' });
|
|
expect(button).toHaveClass('gap-1.5');
|
|
expect(button).toHaveClass('custom-button');
|
|
expect(button).toHaveClass('w-full');
|
|
});
|
|
});
|