UNPKG

box-ui-elements-mlh

Version:
342 lines (275 loc) 12.2 kB
import PropTypes from 'prop-types'; import React from 'react'; import { shallow, mount } from 'enzyme'; import sinon from 'sinon'; import TextInput from '..'; const sandbox = sinon.sandbox.create(); describe('components/form-elements/text-input/TextInput', () => { afterEach(() => { sandbox.verifyAndRestore(); }); test('should correctly render default component', () => { const wrapper = shallow(<TextInput label="label" name="input" />); expect(wrapper.find('TextInput').length).toEqual(1); }); test('should update state if value prop changes', () => { const wrapper = shallow(<TextInput label="label" name="textarea" value="test" />); wrapper.setProps({ value: 'new prop' }); expect(wrapper.state('value')).toEqual('new prop'); }); test('should mark required fields invalid when empty', () => { const wrapper = mount(<TextInput className="coverage" isRequired label="label" name="input" />); const input = wrapper.find('input'); input.simulate('blur'); expect(wrapper.find('.text-input-container').hasClass('show-error')).toBeTruthy(); }); test('should mark required fields valid when not empty', () => { const wrapper = mount(<TextInput isRequired label="label" name="input" value="baba" />); const input = wrapper.find('input'); input.simulate('blur'); expect(wrapper.find('.text-input-container').hasClass('show-error')).toBeFalsy(); }); test('should correctly validate when change event is fired', () => { const wrapper = mount(<TextInput isRequired label="label" name="input" value="" />); const input = wrapper.find('input'); input.simulate('blur'); expect(wrapper.find('.text-input-container').hasClass('show-error')).toBeTruthy(); wrapper.setProps({ value: 'a' }); input.simulate('blur'); const inputEl = input.getDOMNode(); inputEl.value = 'a'; input.simulate('change', { currentTarget: inputEl, }); expect(wrapper.find('.text-input-container').hasClass('show-error')).toBeFalsy(); }); test('should mark email fields invalid when invalid', () => { const wrapper = mount(<TextInput label="label" name="input" type="email" value="bob" />); const input = wrapper.find('input'); input.simulate('blur'); expect(wrapper.state('isValid')).toBeFalsy(); }); test('should mark email fields valid when valid', () => { const wrapper = mount(<TextInput label="label" name="input" type="email" value="bob@bob.com" />); const input = wrapper.find('input'); input.simulate('blur'); expect(wrapper.find('.text-input-container').hasClass('show-error')).toBeFalsy(); }); test('should mark url fields invalid when invalid', () => { const wrapper = mount(<TextInput label="label" name="input" type="url" value="bob" />); const instance = wrapper.instance(); instance.input = { validity: { typeMismatch: true } }; instance.checkValidity(); wrapper.update(); expect(wrapper.find('.text-input-container').hasClass('show-error')).toBeTruthy(); }); test('should mark url fields valid when valid', () => { const wrapper = mount(<TextInput label="label" name="input" type="url" value="http://bob.com" />); const instance = wrapper.instance(); instance.input = { validity: { valid: true } }; instance.checkValidity(); wrapper.update(); expect(wrapper.find('.text-input-container').hasClass('show-error')).toBeFalsy(); expect(wrapper.state('errorMessage')).toBeFalsy(); }); test('should set an input as valid when the validityFn returns an void', () => { function validityFn() {} const wrapper = mount(<TextInput label="label" name="input" type="custom" validation={validityFn} />); const input = wrapper.find('input'); input.simulate('blur'); expect(input.getDOMNode().validity.valid).toBeTruthy(); }); test('should set an input as invalid when the validityFn returns an error string and input is not empty', () => { function validityFn() { return { code: 'errCode', message: 'errMessage', }; } const wrapper = mount( <TextInput label="label" name="input" type="custom" validation={validityFn} value="yes" />, ); const input = wrapper.find('input'); const setCustomValiditySpy = jest.spyOn(input.getDOMNode(), 'setCustomValidity'); input.simulate('blur'); expect(setCustomValiditySpy).toHaveBeenCalledWith('errCode'); }); test('should set an input as valid when intially then fixed when using validityFn', () => { const stub = sinon.stub(); stub.onCall(0).returns({ code: 'errCode', message: 'errMessage', }); stub.onCall(1).returns(); const wrapper = mount(<TextInput label="label" name="input" type="custom" validation={stub} value="yes" />); let input = wrapper.find('input'); let setCustomValiditySpy = jest.spyOn(input.getDOMNode(), 'setCustomValidity'); input.simulate('blur'); expect(setCustomValiditySpy).toHaveBeenCalledWith('errCode'); // Get the re-rendered input again input = wrapper.find('input'); setCustomValiditySpy = jest.spyOn(input.getDOMNode(), 'setCustomValidity'); input.simulate('blur'); expect(setCustomValiditySpy).toHaveBeenCalledWith(''); }); test('should not set input invalid when the validityFn returns an error string and input is empty and not required', () => { function validityFn() { return { code: 'errCode', message: 'errMessage', }; } const wrapper = mount(<TextInput label="label" name="input" type="custom" validation={validityFn} />); const input = wrapper.find('input'); input.simulate('blur'); expect(input.getDOMNode().validity.valid).toBeTruthy(); }); test('should set input invalid when the validityFn returns an error string, input is empty and is required', () => { function validityFn() { return { code: 'errCode', message: 'errMessage', }; } const wrapper = mount( <TextInput isRequired label="label" name="input" type="custom" validation={validityFn} />, ); const input = wrapper.find('input'); const setCustomValiditySpy = jest.spyOn(input.getDOMNode(), 'setCustomValidity'); input.simulate('blur'); expect(setCustomValiditySpy).toHaveBeenCalledWith('errCode'); }); test('should re-validate when input is set via props programaticallly', () => { const wrapper = mount(<TextInput isRequired label="label" name="input" value="" />); const input = wrapper.find('input'); input.simulate('blur'); expect(wrapper.find('.text-input-container').hasClass('show-error')).toBeTruthy(); wrapper.setProps({ value: 'abba' }); input.simulate('blur'); const inputEl = input.getDOMNode(); inputEl.value = 'a'; input.simulate('change', { currentTarget: inputEl, }); wrapper.update(); expect(wrapper.find('.text-input-container').hasClass('show-error')).toBeFalsy(); }); test('should validate onChange when input is already in error state', () => { const wrapper = mount(<TextInput isRequired label="label" name="input" value="" />); const input = wrapper.find('input'); input.simulate('blur'); expect(wrapper.find('.text-input-container').hasClass('show-error')).toBeTruthy(); const inputEl = input.getDOMNode(); inputEl.value = 'a'; input.simulate('change', { currentTarget: inputEl, }); wrapper.update(); expect(wrapper.find('.text-input-container').hasClass('show-error')).toBeFalsy(); }); test('should set validity state when set validity state handler is called with custom error', () => { const validityStateHandlerSpy = sinon.spy(); const context = { form: { registerInput: validityStateHandlerSpy, unregisterInput: sandbox.mock().never(), }, }; const childContextTypes = { form: PropTypes.object, }; const error = { errorCode: 'errorCode', errorMessage: 'Error Message', }; const component = mount(<TextInput label="label" name="input" value="" />, { context, childContextTypes }); validityStateHandlerSpy.callArgWith(1, error); expect(component.state('error')).toEqual(error); }); test('should set validity state when set validity state handler is called with ValidityState object', () => { const validityStateHandlerSpy = sinon.spy(); const context = { form: { registerInput: validityStateHandlerSpy, unregisterInput: sandbox.mock().never(), }, }; const childContextTypes = { form: PropTypes.object, }; const error = { valid: false, badInput: true, }; const component = mount(<TextInput label="label" name="input" value="" />, { context, childContextTypes }); validityStateHandlerSpy.callArgWith(1, error); expect(component.state('error').code).toEqual('badInput'); }); /** * Using the context to test these code paths since phantomJS doesn't * support the functionality */ test('should correctly validate patternMismatch', () => { const validityStateHandlerSpy = sinon.spy(); const context = { form: { registerInput: validityStateHandlerSpy, unregisterInput: sandbox.mock().never(), }, }; const childContextTypes = { form: PropTypes.object, }; const error = { valid: false, patternMismatch: true, }; const component = mount(<TextInput label="label" name="input" value="" />, { context, childContextTypes }); validityStateHandlerSpy.callArgWith(1, error); expect(component.state('error').code).toEqual('patternMismatch'); }); test('should correctly validate tooShort', () => { const validityStateHandlerSpy = sinon.spy(); const context = { form: { registerInput: validityStateHandlerSpy, unregisterInput: sandbox.mock().never(), }, }; const childContextTypes = { form: PropTypes.object, }; const error = { valid: false, tooLong: true, }; const component = mount(<TextInput label="label" maxLength={10} name="input" value="" />, { context, childContextTypes, }); validityStateHandlerSpy.callArgWith(1, error); expect(component.state('error').code).toEqual('tooLong'); }); test('should correctly validate tooShort', () => { const validityStateHandlerSpy = sinon.spy(); const context = { form: { registerInput: validityStateHandlerSpy, unregisterInput: sandbox.mock().never(), }, }; const childContextTypes = { form: PropTypes.object, }; const error = { valid: false, tooShort: true, }; const component = mount(<TextInput label="label" minLength={1} name="input" value="" />, { context, childContextTypes, }); validityStateHandlerSpy.callArgWith(1, error); expect(component.state('error').code).toEqual('tooShort'); }); });