import React from 'react'; import TestUtils from 'react-dom/test-utils'; import PureRenderMixin from 'react-addons-pure-render-mixin'; import sinon from 'sinon'; import Formsy, { withFormsy } from './..'; import TestInput, { InputFactory } from './utils/TestInput'; import immediate from './utils/immediate'; export default { 'should return passed and setValue() value when using getValue()': function (test) { const form = TestUtils.renderIntoDocument( ); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); test.equal(input.value, 'foo'); TestUtils.Simulate.change(input, {target: {value: 'foobar'}}); test.equal(input.value, 'foobar'); test.done(); }, 'should only set the value and not validate when calling setValue(val, false)': function (test) { const Input = withFormsy(class TestInput extends React.Component { updateValue = (event) => { this.props.setValue(event.target.value, false); } render() { return ; } }) const form = TestUtils.renderIntoDocument( ); const inputComponent = TestUtils.findRenderedComponentWithType(form, Input); const setStateSpy = sinon.spy(inputComponent, 'setState'); const inputElement = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); test.equal(setStateSpy.called, false); TestUtils.Simulate.change(inputElement, {target: {value: 'foobar'}}); test.equal(setStateSpy.calledOnce, true); test.equal(setStateSpy.calledWithExactly({ value: 'foobar' }), true); test.done(); }, 'should set back to pristine value when running reset': function (test) { let reset = null; const Input = InputFactory({ componentDidMount: function() { reset = this.props.resetValue; } }); const form = TestUtils.renderIntoDocument( ); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); TestUtils.Simulate.change(input, {target: {value: 'foobar'}}); reset(); test.equal(input.value, 'foo'); test.done(); }, 'should return error message passed when calling getErrorMessage()': function (test) { let getErrorMessage = null; const Input = InputFactory({ componentDidMount: function() { getErrorMessage = this.props.getErrorMessage; } }); TestUtils.renderIntoDocument( ); test.equal(getErrorMessage(), 'Has to be email'); test.done(); }, 'should return true or false when calling isValid() depending on valid state': function (test) { let isValid = null; const Input = InputFactory({ componentDidMount: function() { isValid = this.props.isValid; } }); const form = TestUtils.renderIntoDocument( ); test.equal(isValid(), false); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); TestUtils.Simulate.change(input, {target: {value: 'foo@foo.com'}}); test.equal(isValid(), true); test.done(); }, 'should return true or false when calling isRequired() depending on passed required attribute': function (test) { const isRequireds = []; const Input = InputFactory({ componentDidMount: function() { isRequireds.push(this.props.isRequired); } }); TestUtils.renderIntoDocument( ); test.equal(isRequireds[0](), false); test.equal(isRequireds[1](), true); test.equal(isRequireds[2](), true); test.done(); }, 'should return true or false when calling showRequired() depending on input being empty and required is passed, or not': function (test) { const showRequireds = []; const Input = InputFactory({ componentDidMount: function() { showRequireds.push(this.props.showRequired); } }); TestUtils.renderIntoDocument( ); test.equal(showRequireds[0](), false); test.equal(showRequireds[1](), true); test.equal(showRequireds[2](), false); test.done(); }, 'should return true or false when calling isPristine() depending on input has been "touched" or not': function (test) { let isPristine = null; const Input = InputFactory({ componentDidMount: function() { isPristine = this.props.isPristine; } }); const form = TestUtils.renderIntoDocument( ); test.equal(isPristine(), true); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); TestUtils.Simulate.change(input, {target: {value: 'foo'}}); test.equal(isPristine(), false); test.done(); }, 'should allow an undefined value to be updated to a value': function (test) { class TestForm extends React.Component { state = {value: undefined}; changeValue = () => { this.setState({ value: 'foo' }); } render() { return ( ); } } const form = TestUtils.renderIntoDocument(); form.changeValue(); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); immediate(() => { test.equal(input.value, 'foo'); test.done(); }); }, 'should be able to test a values validity': function (test) { class TestForm extends React.Component { render() { return ( ); } } const form = TestUtils.renderIntoDocument(); const input = TestUtils.findRenderedComponentWithType(form, TestInput); test.equal(input.isValidValue('foo@bar.com'), true); test.equal(input.isValidValue('foo@bar'), false); test.done(); }, 'should be able to use an object as validations property': function (test) { class TestForm extends React.Component { render() { return ( ); } } const form = TestUtils.renderIntoDocument(); const input = TestUtils.findRenderedComponentWithType(form, TestInput); test.equal(input.isValidValue('foo@bar.com'), true); test.equal(input.isValidValue('foo@bar'), false); test.done(); }, 'should be able to pass complex values to a validation rule': function (test) { class TestForm extends React.Component { render() { return ( ); } } const form = TestUtils.renderIntoDocument(); const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); test.equal(inputComponent.isValid(), true); const input = TestUtils.findRenderedDOMComponentWithTag(form, 'INPUT'); TestUtils.Simulate.change(input, {target: {value: 'bar'}}); test.equal(inputComponent.isValid(), false); test.done(); }, 'should be able to run a function to validate': function (test) { class TestForm extends React.Component { customValidationA(values, value) { return value === 'foo'; } customValidationB(values, value) { return value === 'foo' && values.A === 'foo'; } render() { return ( ); } } const form = TestUtils.renderIntoDocument(); const inputComponent = TestUtils.scryRenderedComponentsWithType(form, TestInput); test.equal(inputComponent[0].isValid(), true); test.equal(inputComponent[1].isValid(), true); const input = TestUtils.scryRenderedDOMComponentsWithTag(form, 'INPUT'); TestUtils.Simulate.change(input[0], {target: {value: 'bar'}}); test.equal(inputComponent[0].isValid(), false); test.equal(inputComponent[1].isValid(), false); test.done(); }, 'should not override error messages with error messages passed by form if passed eror messages is an empty object': function (test) { class TestForm extends React.Component { render() { return ( ); } } const form = TestUtils.renderIntoDocument(); const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); test.equal(inputComponent.getErrorMessage(), 'bar3'); test.done(); }, 'should override all error messages with error messages passed by form': function (test) { class TestForm extends React.Component { render() { return ( ); } } const form = TestUtils.renderIntoDocument(); const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); test.equal(inputComponent.getErrorMessage(), 'bar'); test.done(); }, 'should override validation rules with required rules': function (test) { class TestForm extends React.Component { render() { return ( ); } } const form = TestUtils.renderIntoDocument(); const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); test.equal(inputComponent.getErrorMessage(), 'bar3'); test.done(); }, 'should fall back to default error message when non exist in validationErrors map': function (test) { class TestForm extends React.Component { render() { return ( ); } } const form = TestUtils.renderIntoDocument(); const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); test.equal(inputComponent.getErrorMessage(), 'bar1'); test.done(); }, 'should not be valid if it is required and required rule is true': function (test) { class TestForm extends React.Component { render() { return ( ); } } const form = TestUtils.renderIntoDocument(); const inputComponent = TestUtils.findRenderedComponentWithType(form, TestInput); test.equal(inputComponent.isValid(), false); test.done(); }, 'should handle objects and arrays as values': function (test) { class TestForm extends React.Component { state = { foo: {foo: 'bar'}, bar: ['foo'] } render() { return ( ); } } const form = TestUtils.renderIntoDocument(); form.setState({ foo: {foo: 'foo'}, bar: ['bar'] }); const inputs = TestUtils.scryRenderedComponentsWithType(form, TestInput); test.deepEqual(inputs[0].getValue(), {foo: 'foo'}); test.deepEqual(inputs[1].getValue(), ['bar']); test.done(); }, 'should handle isFormDisabled with dynamic inputs': function (test) { class TestForm extends React.Component { state = { bool: true } flip = () => { this.setState({ bool: !this.state.bool }); } render() { return ( {this.state.bool ? : } ); } } const form = TestUtils.renderIntoDocument(); const input = TestUtils.findRenderedComponentWithType(form, TestInput); test.equal(input.isFormDisabled(), true); form.flip(); test.equal(input.isFormDisabled(), false); test.done(); }, 'should allow for dot notation in name which maps to a deep object': function (test) { class TestForm extends React.Component { onSubmit(model) { test.deepEqual(model, {foo: {bar: 'foo', test: 'test'}}); } render() { return ( ); } } const form = TestUtils.renderIntoDocument(); test.expect(1); const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); TestUtils.Simulate.submit(formEl); test.done(); }, 'should allow for application/x-www-form-urlencoded syntax and convert to object': function (test) { class TestForm extends React.Component { onSubmit(model) { test.deepEqual(model, {foo: ['foo', 'bar']}); } render() { return ( ); } } const form = TestUtils.renderIntoDocument(); test.expect(1); const formEl = TestUtils.findRenderedDOMComponentWithTag(form, 'form'); TestUtils.Simulate.submit(formEl); test.done(); }, 'input should rendered once with PureRenderMixin': function (test) { var renderSpy = sinon.spy(); const Input = InputFactory({ shouldComponentUpdate: function() { return false }, render: function() { renderSpy(); return ; } }); const form = TestUtils.renderIntoDocument( ); test.equal(renderSpy.calledOnce, true); test.done(); } };