0

I am using ReactJs and Mocha and trying few unit tests. I have two mandatory form fields First Name and Last Name. I am trying to test the validation where if only one field is entered, the other field displays the missing value validation error.

Below code simulates the changes to the value and simulates the form submit.

TestUtils.Simulate.change(firstNameElement , {target: {value: 'Joe'}});
TestUtils.Simulate.submit(formElement)

The changed value is reflected in the event handlers on First Name. But, not in the test. So, both the fields display missing value validation failing my test.

What I could be doing wrong here?

Below are code:

//NameForm.jsx
'use strict';

var React=require('react')
var forms = require('newforms')

var NameForm = forms.Form.extend({
    firstName: forms.CharField({maxLength: 100, label: "First name(s)"}),
    lastName: forms.CharField({maxLength: 100, label: "Last name"}),

    cleanFirstName(callback) {
        callback(null)
    },

    render() {
        return this.boundFields().map(bf => {
            return <div className={'form-group ' + bf.status()}>
                <label className="form-label" htmlFor={bf.name}>
                  <span className="form-label-bold">{bf.label}</span>
                </label>
                {bf.errors().messages().map(message => <span className="error-message">{message}</span>)}
                <input className="form-control" id={bf.name} type="text" name={bf.name} onChange = {this.onChangeHandler}/>
              </div>
        })
    }
    , onChangeHandler: function(e){
        console.log("onchnage on input is called ----- >> " + e.target.value)
    }
})

module.exports = {
    NameForm
}

Here is NamePage.jsx: 'use strict';

var React = require('react')
var {ErrorObject} = require('newforms')
var superagent = require('superagent-ls')

var {API_URL} = require('../../constants')
var {NameForm} = require('./NameForm')

var NamePage = React.createClass({

  contextTypes: {
    router: React.PropTypes.func.isRequired
  },
  propTypes: {
    data: React.PropTypes.object,
    errors: React.PropTypes.object
  },

  statics: {
    title: 'Name',

    willTransitionTo(transition, params, query, cb, req) {
      if (req.method != 'POST') { return cb() }

      superagent.post(`${API_URL}/form/NameForm`).send(req.body).withCredentials().end((err, res) => {
        if (err || res.serverError) {
          return cb(err || new Error(`Server error: ${res.body}`))
        }

        if (res.clientError) {
          transition.redirect('name', {}, {}, {
            data: req.body,
            errors: res.body
          })
        }
        else {
          transition.redirect('summary')
        }
        cb()
      })
    }
  },

  getInitialState() {
    return {
      client: false,
      form: new NameForm({
          onChange: this.forceUpdate.bind(this),
          data: this.props.data,
          errors: this._getErrorObject()
      })
    }
  },

  componentDidMount() {
    this.setState({client: true})
  },

  componentWillReceiveProps(nextProps) {
    if (nextProps.errors) {
      var errorObject = this._getErrorObject(nextProps.errors)
      this.refs.nameForm.getForm().setErrors(errorObject)
    }
  },

  _getErrorObject(errors) {
    if (!errors) { errors = this.props.errors }
    return errors ? ErrorObject.fromJSON(errors) : null
  },

  _onSubmit(e) {
    e.preventDefault()
    var form = this.state.form
    form.validate(this.refs.form, (err, isValid) => {
      if (isValid) {
          this.context.router.transitionTo('name', {}, {}, {
          method: 'POST',
          body: form.data
        })
      }
    })
  },

  render() {
    return  <div>
      <h1 className="heading-large">Your name</h1>
      <form action='name' method="POST" onSubmit={this._onSubmit} ref="form" autoComplete="off" noValidate={this.state.client}>
          {this.state.form.render()}
        <button type="submit" className="button">Next</button>
      </form>
    </div>
  },
})

module.exports = NamePage

Here is NameTest.js :

//NameTest.js
var React          = require('react')
var ReactAddons    = require('react/addons')
var TestUtils = React.addons.TestUtils
var InputFieldItem = require('../../src/page/name/NamePage')

describe('Name page component', function(){
    var renderedComponent;
    before('render element', function() {
        console.log("*** in before")
        renderedComponent = TestUtils.renderIntoDocument(
            <InputFieldItem />
        );
    });

    it('Only First Name entered should display one error message', function() {
        renderedComponent = TestUtils.renderIntoDocument(
            <InputFieldItem />
        );
        var formElement = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'form').getDOMNode()
        var firstNameElement = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, 'input')[0].getDOMNode()
        var lastNameElement = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, 'input')[1].getDOMNode()
        var buttonElement = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'button').getDOMNode()

        TestUtils.Simulate.change(firstNameElement , {target: {value: 'Joe'}});
        TestUtils.Simulate.submit(formElement)
        var errorSpans = TestUtils.scryRenderedDOMComponentsWithClass(renderedComponent, 'error-message')
        console.log("First name value is :|"+  firstNameElement.value + "|")
        expect (errorSpans.length).to.equal(1)
    })

});
Nikki
  • 97
  • 10

0 Answers0