import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { describe, expect, it, vi } from 'vitest';
import { Avatar } from '../../src/product/Avatar.tsx';
import { Button } from '../../src/product/Button.tsx';
import { Counter } from '../../src/product/Counter.tsx';
import { IconButton } from '../../src/product/IconButton.tsx';
import { RiskChip } from '../../src/product/RiskChip.tsx';
import { SegmentedControl } from '../../src/product/SegmentedControl.tsx';
import { StatusPill } from '../../src/product/StatusPill.tsx';
import { Tab } from '../../src/product/Tab.tsx';
import { Tag } from '../../src/product/Tag.tsx';
describe('Avatar', () => {
it('shows initials for a person', () => {
render();
expect(screen.getByRole('img', { name: 'Amara Okoye' })).toHaveTextContent('AO');
});
it('shows the brand mark for Wursor', () => {
render();
expect(screen.getByRole('img', { name: 'Wursor' })).toHaveClass('p-avatar-wursor');
});
it('has a small and a medium size', () => {
render();
expect(screen.getByRole('img', { name: 'A' })).toHaveClass('p-avatar-md');
});
});
describe('Counter', () => {
it('shows the count', () => {
render();
expect(screen.getByText('3')).toHaveClass('p-counter');
});
});
describe('StatusPill', () => {
it.each([
['idea', 'Idea'],
['working', 'Working'],
['needs-you', 'Needs you'],
['done', 'Done'],
] as const)('labels the %s status in plain words', (status, label) => {
render();
expect(screen.getByText(label).closest('.p-status')).toHaveAttribute('data-status', status);
});
});
describe('RiskChip', () => {
it('shows the plain-word risk level', () => {
render();
expect(screen.getByText('Everyday')).toBeInTheDocument();
});
});
describe('IconButton', () => {
it('is named by its label and calls onClick', async () => {
const onClick = vi.fn();
render();
await userEvent.click(screen.getByRole('button', { name: 'Search' }));
expect(onClick).toHaveBeenCalledOnce();
});
it('supports the inverse variant', () => {
render();
expect(screen.getByRole('button', { name: 'Stop' })).toHaveClass('p-iconbtn-inverse');
});
});
describe('Button', () => {
it('renders its label and calls onClick', async () => {
const onClick = vi.fn();
render();
await userEvent.click(screen.getByRole('button', { name: 'See what changed' }));
expect(onClick).toHaveBeenCalledOnce();
});
it('defaults to secondary and small, and supports primary and ghost', () => {
const { rerender } = render();
expect(screen.getByRole('button', { name: 'A' })).toHaveClass('p-btn-secondary', 'p-btn-sm');
rerender();
expect(screen.getByRole('button', { name: 'A' })).toHaveClass('p-btn-primary', 'p-btn-md');
rerender();
expect(screen.getByRole('button', { name: 'A' })).toHaveClass('p-btn-ghost');
});
});
describe('SegmentedControl', () => {
const options = [
{ value: 'headline', label: 'Headline' },
{ value: 'steps', label: 'Steps' },
{ value: 'everything', label: 'Everything' },
];
it('is a radio group with the current choice checked', () => {
render( {}} />);
expect(screen.getByRole('radiogroup', { name: 'Detail' })).toBeInTheDocument();
expect(screen.getByRole('radio', { name: 'Steps' })).toBeChecked();
expect(screen.getByRole('radio', { name: 'Headline' })).not.toBeChecked();
});
it('reports the chosen value', async () => {
const onChange = vi.fn();
render();
await userEvent.click(screen.getByRole('radio', { name: 'Everything' }));
expect(onChange).toHaveBeenCalledWith('everything');
});
});
describe('Tab', () => {
it('marks the selected tab', () => {
render(
,
);
expect(screen.getByRole('tab', { name: 'Preview' })).toHaveAttribute('aria-selected', 'true');
expect(screen.getByRole('tab', { name: 'Compare' })).toHaveAttribute('aria-selected', 'false');
});
it('can show a count', () => {
render();
expect(screen.getByRole('tab', { name: /Proof/ })).toHaveTextContent('3');
});
});
describe('Tag', () => {
it('shows its label', () => {
render();
expect(screen.getByText('Draft copy')).toBeInTheDocument();
});
it('can be removed when closable', async () => {
const onClose = vi.fn();
render();
await userEvent.click(screen.getByRole('button', { name: 'Remove Draft copy' }));
expect(onClose).toHaveBeenCalledOnce();
});
});