import _ from 'lodash'; import assert from 'assert'; import React from 'react'; import sinon from 'sinon'; import { mount, shallow } from 'enzyme'; import { common } from '../../util/generic-tests'; import { RadioGroupDumb as RadioGroup } from './RadioGroup'; import RadioButtonLabeled from '../RadioButtonLabeled/RadioButtonLabeled'; import RadioButton from '../RadioButton/RadioButton'; const defaultProps = RadioGroup.defaultProps; const radioButtonDefaultProps = RadioButton.defaultProps; describe('RadioGroup', () => { common(RadioGroup); describe('props', () => { describe('name', () => { it('sets the `name` attribute of the child radio buttons.', () => { const name = 'radio'; const wrapper = shallow( ); wrapper.find(RadioButtonLabeled).forEach((node) => { assert.strictEqual(node.props().name, name); }); }); it('defaults to a string that is passed along to the children.', () => { const wrapper = mount( ); const name = wrapper.first().prop('name'); wrapper.find(RadioButtonLabeled).forEach((node) => { assert.strictEqual(node.props().name, name); }); }); }); describe('isDisabled', () => { it('should set `isDisabled` to true for all child radio buttons', () => { const wrapper = shallow( ); wrapper.find(RadioButtonLabeled).forEach((node) => { assert(node.props().isDisabled); }); }); it('should set `isDisabled` to true for all child radio buttons even if the child radio buttons have isDisabled set as false', () => { const wrapper = shallow( ); wrapper.find(RadioButtonLabeled).forEach((node) => { assert(node.props().isDisabled); }); }); it('should allow specific radio buttons to be disabled', () => { const wrapper = shallow( ); const childNodes = wrapper.find(RadioButtonLabeled); assert.strictEqual(childNodes.at(1).props().isDisabled, true); }); }); describe('selectedIndex', () => { it('sets the `isSelected` prop of the child radio button at the matching index to true...', () => { const wrapper = shallow( ); const childNodes = wrapper.find(RadioButtonLabeled); assert.strictEqual(childNodes.at(0).props().isSelected, false); assert.strictEqual(childNodes.at(1).props().isSelected, false); assert.strictEqual(childNodes.at(2).props().isSelected, true); }); it('...except when a child component already has an explicitly defined `isSelected` prop which takes precedence.', () => { const wrapper = shallow( ); const childNodes = wrapper.find(RadioButtonLabeled); assert.strictEqual(childNodes.at(0).props().isSelected, false); assert.strictEqual(childNodes.at(1).props().isSelected, true); assert.strictEqual(childNodes.at(2).props().isSelected, false); }); it('defaults to 0.', () => { const wrapper = shallow( ); const childNodes = wrapper.find(RadioButtonLabeled); assert.strictEqual(childNodes.at(0).props().isSelected, true); assert.strictEqual(childNodes.at(1).props().isSelected, false); assert.strictEqual(childNodes.at(2).props().isSelected, false); }); }); describe('pass throughs', () => { it('passes through all props not defined in `propTypes` to the root element.', () => { const wrapper = shallow( ); const rootProps = _.keys(wrapper.first().props()); // It should pass 'className' and 'children' // and `foo`, `bar`, `baz`, `qux`, and `quux` asthrough // to the root element. _.forEach( ['className', 'children', 'foo', 'bar', 'baz', 'qux', 'quux'], (prop) => { assert(_.includes(rootProps, prop)); } ); }); }); describe('nonPassThroughs', () => { it('filters out the nonPassThroughs from the component wrapper.', () => { const nonPassThroughs = { children: , className: 'testClassName', name: 'test-name', onSelect: _.noop, selectedIndex: 1, isDisabled: true, }; const combinedProps = { ...defaultProps, ...nonPassThroughs }; const wrapper = shallow(); expect(wrapper.prop('name')).toBeUndefined; expect(wrapper.prop('onSelect')).toBeUndefined; expect(wrapper.prop('selectedIndex')).toBeUndefined; expect(wrapper.prop('isDisabled')).toBeUndefined; }); }); }); }); describe('RadioGroup.Label', () => { it('passes its children through as the `Label` prop for the corresponding `RadioButtonLabeled`.', () => { const wrapper = shallow( foo bar baz qux ); const labels = wrapper.find(RadioGroup.Label); assert.strictEqual(labels.at(0).children().text(), 'foo'); assert.strictEqual(labels.at(1).children().text(), 'bar'); assert.strictEqual(labels.at(2).children().at(0).text(), 'baz'); assert.strictEqual(labels.at(2).children().at(1).text(), 'qux'); }); }); describe('RadioGroup', () => { it('should handle multiple children', () => { const wrapper = mount( foo bar ); assert.strictEqual(wrapper.find('#foo').text(), 'foo'); assert.strictEqual(wrapper.find('#bar').text(), 'bar'); }); describe('user selects one of the radio button children', () => { it('calls the function passed in as the `onSelect` prop...', () => { const onSelect: any = jest.fn(); const wrapper = mount( ); wrapper.find('RadioButton[data-test-name="one"]').simulate('click'); expect(onSelect).toBeCalledTimes(1); }); it('...and passes along the index of that child as the first argument and a React synthetic event as the second argument.', () => { const onSelect = jest.fn(); const wrapper = mount( ); wrapper.find('RadioButton[data-test-name="one"]').simulate('click'); expect(onSelect).toBeCalledTimes(1); expect(onSelect.mock.calls[0][0]).toBe(1); expect(onSelect.mock.calls[0][1]).toHaveProperty('event'); expect(onSelect.mock.calls[0][1]).toHaveProperty('props', { callbackId: 1, className: undefined, 'data-test-name': 'one', isDisabled: false, isSelected: false, name: '1-lucid-RadioGroup-1', onSelect: expect.anything(), }); }); it('calls the `onSelect` prop, if a function, of the child prior to calling its own.', () => { const childOnSelect = sinon.spy(); const onSelect: any = sinon.spy(); const wrapper = mount( ); wrapper.find('RadioButton[data-test-name="one"]').simulate('click'); assert(childOnSelect.calledBefore(onSelect)); }); it('tests that the correct onSelect is called', () => { const onSelect: any = jest.fn(); const wrapper = mount( ); wrapper .find('RadioButton[data-test-name="one"] > span') .simulate('click'); expect(onSelect).toBeCalledTimes(1); expect(onSelect).toBeCalledWith(1, { event: expect.anything(), props: { callbackId: 1, className: undefined, 'data-test-name': 'one', isDisabled: false, isSelected: false, name: '1-lucid-RadioGroup-1', onSelect: expect.anything(), }, }); }); }); });