import * as React from 'react';
import { isConformant, handlesAccessibility, htmlIsAccessibilityCompliant } from 'test/specs/commonTests';
import { implementsCollectionShorthandProp } from '../../commonTests/implementsCollectionShorthandProp';
import { mountWithProvider } from 'test/utils';
import { RadioGroup } from 'src/components/RadioGroup/RadioGroup';
import { RadioGroupItem } from 'src/components/RadioGroup/RadioGroupItem';
const radioGroupImplementsCollectionShorthandProp = implementsCollectionShorthandProp(RadioGroup);
const getShorthandItems = (props?: { disabledItem?: number }) => [
{
name: 'test-name',
key: 'test-key1',
label: 'test-label1',
value: 'test-value1',
'data-foo': 'something',
onClick: jest.fn(),
disabled: props && props.disabledItem === 0,
},
{
name: 'test-name',
key: 'test-key2',
label: 'test-label2',
value: 'test-value2',
'data-foo': 'something',
disabled: props && props.disabledItem === 1,
},
{
name: 'test-name',
key: 'test-key3',
label: 'test-label3',
value: 'test-value3',
'data-foo': 'something',
disabled: props && props.disabledItem === 2,
},
];
describe('RadioGroup', () => {
isConformant(RadioGroup, { constructorName: 'RadioGroup', autoControlledProps: ['checkedValue'] });
describe('accessibility', () => {
handlesAccessibility(RadioGroup, {
defaultRootRole: 'radiogroup',
});
test('compliance', async () => await htmlIsAccessibilityCompliant());
});
describe('implementsCollectionShorthandProp', () => {
radioGroupImplementsCollectionShorthandProp('items', RadioGroupItem, {
mapsValueToProp: false,
});
});
const itemsTest = (getItems: Function, isShorthandApiTest: boolean = true) => {
it('renders children', () => {
const items = mountWithProvider().find('RadioGroupItem');
expect(items.length).toBe(3);
expect(items.first().props().label).toBe('test-label1');
expect(items.last().props().label).toBe('test-label3');
});
it('calls onClick handler for item', () => {
const items = getItems();
const radioGroupItems = mountWithProvider().find('RadioGroupItem');
radioGroupItems
.first()
.find('div')
.first()
.simulate('click');
const onClick = items[0].onClick || items[0].props.onClick;
expect(onClick).toHaveBeenCalled();
});
it('passes arbitrary props', () => {
const radioGroupItems = mountWithProvider().find('RadioGroupItem');
expect(radioGroupItems.everyWhere(item => item.prop('data-foo') === 'something')).toBe(true);
});
describe('checkedValue', () => {
it('should not be set and first item is focusable by default', () => {
const radioGroupItems = mountWithProvider().find('RadioGroupItem');
expect(radioGroupItems.everyWhere(item => !item.is('[checked="true"]'))).toBe(true);
expect(radioGroupItems.at(0).props().tabIndex).toBe(0);
});
});
if (isShorthandApiTest) {
describe('click event handler', () => {
it('should set "checked" when item is clicked', () => {
const onCheckedValueChange = jest.fn();
const wrapper = mountWithProvider(
,
);
const radioGroupItems = wrapper.find('RadioGroupItem');
radioGroupItems
.at(1)
.find('div')
.first()
.simulate('click');
const updatedItems = wrapper.find('RadioGroupItem');
expect(updatedItems.at(0).props().checked).toBe(false);
expect(updatedItems.at(1).props().checked).toBe(true);
expect(onCheckedValueChange).toHaveBeenCalledWith(
expect.anything(),
expect.objectContaining({ value: 'test-value2' }),
);
});
});
}
it('should not call checkedValueChanged when index did not change', () => {
const onCheckedValueChange = jest.fn();
const wrapper = mountWithProvider(
,
);
const radioGroupItems = wrapper.find('RadioGroupItem');
radioGroupItems
.at(1)
.find('div')
.first()
.simulate('click');
expect(onCheckedValueChange).not.toHaveBeenCalled();
});
if (isShorthandApiTest) {
it('should not set "checked" when disabled item is clicked', () => {
const wrapper = mountWithProvider();
const radioGroupItems = wrapper.find('RadioGroupItem');
radioGroupItems
.at(1)
.find('div')
.first()
.simulate('click');
const updatedItems = wrapper.find('RadioGroupItem');
expect(updatedItems.at(0).props().checked).toBe(false);
expect(updatedItems.at(1).props().checked).toBe(false);
});
}
describe('keyDown event handler', () => {
const testKeyDown = (testName, items, initialValue, keyCode, expectedValue) => {
it(`keyDown test - ${testName}`, () => {
const onCheckedValueChange = jest.fn();
const wrapper = mountWithProvider(
,
);
wrapper
.find('div')
.first()
.simulate('keyDown', { preventDefault() {}, keyCode, which: keyCode });
expect(onCheckedValueChange).toHaveBeenCalledWith(
expect.anything(),
expect.objectContaining({ value: expectedValue }),
);
});
};
testKeyDown('should check next value when right arrow is pressed', getItems(), 'test-value1', 39, 'test-value2');
testKeyDown(
'should check previous value when left arrow is pressed',
getItems(),
'test-value2',
37,
'test-value1',
);
testKeyDown(
'should check first value when right arrow is pressed and last item was checked',
getItems(),
'test-value3',
39,
'test-value1',
);
testKeyDown(
'should check last value when left arrow is pressed and first item was checked',
getItems(),
'test-value1',
37,
'test-value3',
);
testKeyDown(
'should skip disabled when right arrow is pressed',
getItems({ disabledItem: 1 }),
'test-value1',
39,
'test-value3',
);
testKeyDown(
'should skip disabled when left arrow is pressed',
getItems({ disabledItem: 1 }),
'test-value3',
37,
'test-value1',
);
});
};
describe('shorthand API for items', () => {
itemsTest(getShorthandItems);
});
});