36 lines
1.3 KiB
TypeScript
36 lines
1.3 KiB
TypeScript
import { Button } from '@/components/actions/Button';
|
|
import { ActionLink } from '@/components/actions/ActionLink';
|
|
import { fireEvent, render, screen } from '@testing-library/react';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
|
|
describe('action components', () => {
|
|
it('prevents duplicate interaction while loading and preserves the accessible name', () => {
|
|
const onClick = vi.fn();
|
|
render(
|
|
<Button loading onClick={onClick}>
|
|
Save reservation
|
|
</Button>,
|
|
);
|
|
const button = screen.getByRole('button', { name: 'Save reservation' });
|
|
expect(button).toBeDisabled();
|
|
expect(button).toHaveAttribute('aria-busy', 'true');
|
|
fireEvent.click(button);
|
|
expect(onClick).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it('requires an accessible label for icon-only use through its public contract', () => {
|
|
render(<Button icon="close" aria-label="Close panel" />);
|
|
expect(screen.getByRole('button', { name: 'Close panel' })).toBeVisible();
|
|
});
|
|
|
|
it('renders unresolved navigation as a disabled non-link', () => {
|
|
render(
|
|
<ActionLink href="/en" disabledReason="Destination pending approval">
|
|
Book a demo
|
|
</ActionLink>,
|
|
);
|
|
expect(screen.queryByRole('link')).not.toBeInTheDocument();
|
|
expect(screen.getByText('Book a demo').closest('[aria-disabled="true"]')).toBeInTheDocument();
|
|
});
|
|
});
|