import * as React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { ComponentClassNames } from '../../shared';
import { ToggleButton } from '../../ToggleButton';
import { ToggleButtonGroup } from '../ToggleButtonGroup';
import { ToggleButtonGroupProps } from '../../types';
type TestToggleButtonGroupProps = Omit<
ToggleButtonGroupProps,
'children' | 'onChange' | 'value'
>;
function MultipleSelectionGroup(props: TestToggleButtonGroupProps) {
const [value, setValue] = React.useState(['test-button-1']);
return (
setValue(value as string[])}
value={value}
{...props}
>
);
}
function ExclusiveSelectionGroup(props: TestToggleButtonGroupProps) {
const [value, setValue] = React.useState('test-button-1');
return (
setValue(value as string)}
value={value}
isExclusive
{...props}
>
);
}
describe('ToggleButtonGroup', () => {
it('should set basic props for both group and child button correctly', async () => {
const testLabel = 'test-label';
const testClass = 'test-class';
const size = 'large';
const variation = 'primary';
const onChange = jest.fn();
render(
);
const toggleButtonGroup = await screen.findByRole('group');
expect(toggleButtonGroup).toHaveClass(
ComponentClassNames.ToggleButtonGroup,
testClass
);
expect(toggleButtonGroup).toHaveAttribute('aria-label', testLabel);
const toggleButton = await screen.findByRole('button');
expect(toggleButton).toHaveAttribute('data-size', size);
expect(toggleButton).toHaveAttribute('data-variation', variation);
userEvent.click(toggleButton);
expect(onChange).toHaveBeenCalledTimes(1);
});
it('should works in multiple selection way', async () => {
render();
const toggleButtons = await screen.findAllByRole('button');
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
// the only selected option can be unselected
userEvent.click(toggleButtons[0]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
userEvent.click(toggleButtons[0]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
userEvent.click(toggleButtons[1]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
userEvent.click(toggleButtons[2]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'true');
});
it('should have at least one option selected on multiple selection group if isSelectionRequired is set', async () => {
render();
const toggleButtons = await screen.findAllByRole('button');
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
// the only selected option cannot be unselected
userEvent.click(toggleButtons[0]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
// select one more option
userEvent.click(toggleButtons[1]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
// now the first option can be unselected
userEvent.click(toggleButtons[0]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
});
it('should works in exclusive selection way', async () => {
render();
const toggleButtons = await screen.findAllByRole('button');
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
userEvent.click(toggleButtons[1]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
userEvent.click(toggleButtons[2]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'true');
// the only selected option can be unselected
userEvent.click(toggleButtons[2]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
});
it('should have at least one option selected on exclusive selection group if isSelectionRequired is set', async () => {
render();
const toggleButtons = await screen.findAllByRole('button');
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
// the only selected option cannot be unselected
userEvent.click(toggleButtons[0]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'true');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'false');
// select other option
userEvent.click(toggleButtons[2]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'true');
// the selected new option cannot be unselected
userEvent.click(toggleButtons[2]);
expect(toggleButtons[0]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[1]).toHaveAttribute('aria-pressed', 'false');
expect(toggleButtons[2]).toHaveAttribute('aria-pressed', 'true');
});
it('should forward ref to DOM element', async () => {
const ref = React.createRef();
render(
);
await screen.findByRole('group');
expect(ref.current?.nodeName).toBe('DIV');
});
});