UNPKG

react-formulize

Version:

A simple form validation library for React.js which wires up custom, controlled inputs through a declarative API.

254 lines (208 loc) 8.49 kB
/* globals describe it before beforeEach after afterEach */ import React from 'react'; import { expect } from 'chai'; // eslint-disable-line import { shallow, mount } from 'enzyme'; // eslint-disable-line import sinon from 'sinon'; // eslint-disable-line import { Form, Field } from '../../dist/index'; import { updateInput } from '../spec_helpers'; describe('<Form /> Higher-Order-Component', () => { describe('Default Form', () => { let wrapper; let inputs; let fields; beforeEach('mount a testing form', () => { wrapper = mount( <Form> <Field name="name" value="Test Name" /> <Field name="email" value="user@company.com" /> </Form>, ); inputs = wrapper.find('input'); fields = wrapper.find(Field); }); it('contains a <form /> element', () => { expect(wrapper.find('form')).to.have.length(1); }); it('can generate fields from `fields` prop', () => { expect(fields).to.have.length(2); expect(fields.first().props()).to.have.property('name', 'name'); expect(fields.last().props()).to.have.property('name', 'email'); }); it('can populate fields mapped from `fields` prop', () => { expect(inputs).to.have.length(2); expect(inputs.first().getDOMNode().value).to.equal('Test Name'); expect(inputs.last().getDOMNode().value).to.equal('user@company.com'); }); it('passes appropriate props down through `props.children`', () => { wrapper = mount(( <Form> <Field name="name" value="Enter your name" debounce={300} required /> <Field name="email" value="test@example.com" /> </Form> )); fields = wrapper.find(Field); expect(fields).to.have.length(2); const nameProps = fields.first().props(); const emailProps = fields.last().props(); expect(nameProps).to.have.property('debounce', 300); expect(nameProps).to.have.property('required', true); expect(nameProps).to.have.property('value', 'Enter your name'); expect(emailProps).to.have.property('value', 'test@example.com'); }); it('updates its state upon a Field\'s input changing', () => { wrapper = mount(( <Form> <Field name="name" value="Enter your name" length={[6, 12]} alpha /> </Form> )); expect(wrapper.state().name).to.eql({ value: 'Enter your name', valid: false, pristine: true, }); updateInput(wrapper, 'Way too long of a name'); expect(wrapper.state().name).to.eql({ value: 'Way too long of a name', valid: false, pristine: false, }); updateInput(wrapper, 'Good Name'); expect(wrapper.state().name).to.eql({ value: 'Good Name', valid: true, pristine: false, }); }); describe('Functionality', () => { it('invoked an onSubmit callback upon form submission', () => { const onSubmitSpy = sinon.spy(); wrapper = mount( <Form onSubmit={onSubmitSpy}> <Field name="name" value="firstValue" /> <button type="submit" /> </Form>, ); expect(onSubmitSpy.callCount).to.eql(0); wrapper.find('form').simulate('submit'); expect(onSubmitSpy.callCount).to.eql(1); expect(onSubmitSpy.calledWith(wrapper.state())).to.eql(true); }); it('can be reset through invoking the `reset` method on the instance', () => { const formResetSpy = sinon.spy(Form.prototype, 'reset'); wrapper = mount( <Form> <Field name="name" value="firstValue" /> <button type="submit" /> </Form>, ); expect(formResetSpy.callCount).to.eql(0); expect(wrapper.state().name).to.eql({ value: 'firstValue', valid: true, pristine: true, }); updateInput(wrapper, 'secondValue'); expect(wrapper.state().name).to.eql({ value: 'secondValue', valid: true, pristine: false, }); wrapper.instance().reset(); expect(formResetSpy.callCount).to.eql(1); expect(wrapper.state().name).to.eql({ value: 'firstValue', valid: true, pristine: true, }); Form.prototype.reset.restore(); }); }); describe('Passing down status', () => { const TestComponent = () => <span>Test!</span>; it('passes validity information down to components with a `valid` prop', () => { wrapper = mount( <Form> <Field name="name" value="Test Name" valid> <span>Hi There!</span> </Field> <div> <Field name="email" value="user@company.com!!" email /> </div> </Form>, ); expect(wrapper.find(Field).first().props()).to.have.property('name_valid', true); expect(wrapper.find(Field).first().props()).to.have.property('email_valid', false); expect(wrapper.find(Field).last().props()).to.not.have.property('name_valid'); expect(wrapper.find(Field).last().props()).to.not.have.property('email_valid'); }); it('passes pristine information down to components with a `pristine` prop', () => { wrapper = mount( <Form> <div> <Field name="name" value="Test Name" pristine /> </div> <TestComponent id="test_div" pristine /> </Form>, ); const firstField = wrapper.find(Field).first(); const testComponent = wrapper.find(TestComponent); expect(firstField.props()).to.have.property('name_pristine', true); expect(testComponent.props()).to.have.property('name_pristine', true); updateInput(wrapper, 'secondValue'); expect(firstField.props()).to.have.property('name_pristine', false); expect(testComponent.props()).to.have.property('name_pristine', false); }); it( 'passes both valid and pristine information down to components with both `valid` and `pristine` props', () => { wrapper = mount( <Form> <div> <Field name="name" value="" required valid pristine /> <TestComponent valid pristine> <span>Hi there!</span> <div id="test" valid /> </TestComponent> </div> </Form>, ); const firstField = wrapper.find(Field).first(); const testComponent = wrapper.find(TestComponent).first(); expect(firstField.props()).to.have.property('name_pristine', true); expect(testComponent.props()).to.have.property('name_pristine', true); expect(firstField.props()).to.have.property('name_valid', false); expect(testComponent.props()).to.have.property('name_valid', false); updateInput(wrapper, 'Test Name'); expect(firstField.props()).to.have.property('name_pristine', false); expect(firstField.props()).to.have.property('name_valid', true); }, ); }); }); describe('Passes down a value prop that changed', () => { let wrapper; let fieldComponent; const cache = { value: 'firstValue' }; const retrieveCacheValue = () => cache.value; const FieldWithValue = () => <Field name="nameField" value={retrieveCacheValue()} />; before('Assemble a custom input element', () => { wrapper = mount( <Form> {FieldWithValue()} </Form>); fieldComponent = wrapper.find(Field); }); it('Should update its value when passed a new value prop', () => { expect(fieldComponent.props()).to.have.property('name', 'nameField'); expect(fieldComponent.props()).to.have.property('value', 'firstValue'); expect(fieldComponent.props()).to.have.property('passedValue', 'firstValue'); // Update the cache's value; cache.value = 'secondValue'; wrapper.setProps({ children: FieldWithValue() }); expect(fieldComponent.props()).to.have.property('name', 'nameField'); expect(fieldComponent.props()).to.have.property('value', 'secondValue'); expect(fieldComponent.props()).to.have.property('passedValue', 'secondValue'); expect(wrapper.state().nameField).to.eql({ value: 'secondValue', valid: true, pristine: true }); }); }); });