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'); }); });