src/components/textfield/TextField.unit.js
import assert from 'power-assert';
import _ from 'lodash';
import Harness from '../../../test/harness';
import TextFieldComponent from './TextField';
import Formio from './../../Formio';
import {
  comp1,
  comp2,
  comp4,
  comp5
} from './fixtures';
describe('TextField Component', () => {
  it('Should create a new TextField', () => {
    const textField = new TextFieldComponent({
      label: 'First Name',
      key: 'firstName',
      input: true,
      type: 'textfield'
    });
    assert.equal(textField.component.key, 'firstName');
  });
  it('Should build a TextField component', () => {
    return Harness.testCreate(TextFieldComponent, comp1).then((component) => {
      Harness.testElements(component, 'input[type="text"]', 1);
    });
  });
  it('Should disable multiple mask selector if component is disabled', (done) => {
    Harness.testCreate(TextFieldComponent, comp4).then((component) => {
      Harness.testElements(component, '[disabled]', 2);
      done();
    });
  });
  it('Should provide required validation', () => {
    return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
      validate: { required: true }
    })).then((component) => {
      return Harness.testInvalid(component, '', 'firstName', 'First Name is required').then(() => component);
    }).then((component) => {
      return Harness.testValid(component, 'te').then(() => component);
    });
  });
  it('Should provide minWords validation', () => {
    return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
      validate: { minWords: 2 }
    })).then((component) => {
      return Harness.testInvalid(component, 'test', 'firstName', 'First Name must have at least 2 words.').then(() => component);
    }).then((component) => {
      return Harness.testValid(component, 'te st').then(() => component);
    });
  });
  it('Should correctly calculate remaining words', (done) => {
    Harness.testCreate(TextFieldComponent, comp5).then((component) => {
      const inputEvent = new Event('input', { bubbles: true, cancelable: true });
      const element = component.refs.input[0];
      element.value = 'paper format A4';
      element.dispatchEvent(inputEvent);
      setTimeout(()=>{
        assert.equal(component.refs.wordcount[0].textContent, '2 words remaining.');
        element.value = 'Hey, guys! We are here!!';
        element.dispatchEvent(inputEvent);
        setTimeout(()=>{
          assert.equal(component.refs.wordcount[0].textContent, '0 words remaining.');
          element.value = ' Some   test   text  111 ';
          element.dispatchEvent(inputEvent);
          setTimeout(()=>{
            assert.equal(component.refs.wordcount[0].textContent, '1 words remaining.');
            done();
          }, 300);
        }, 275);
      }, 250);
    });
  });
  it('Should provide maxWords validation', () => {
    return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
      validate: { maxWords: 2 }
    })).then((component) => {
      return Harness.testInvalid(component, 'test test test', 'firstName', 'First Name must have no more than 2 words.').then(() => component);
    }).then((component) => {
      return Harness.testValid(component, 'te st').then(() => component);
    });
  });
  it('Should provide minLength validation', () => {
    return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
      validate: { minLength: 2 }
    })).then((component) => {
      return Harness.testInvalid(component, 't', 'firstName', 'First Name must have at least 2 characters.').then(() => component);
    }).then((component) => {
      return Harness.testValid(component, 'te').then(() => component);
    });
  });
  it('Should provide maxLength validation', () => {
    return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
      validate: { maxLength: 5 }
    })).then(component => {
      return Harness.testInvalid(component, 'testte', 'firstName', 'First Name must have no more than 5 characters.').then(() => component);
    }).then((component) => {
      return Harness.testValid(component, 'te').then(() => component);
    });
  });
  it('Should provide custom validation', () => {
    return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
      validate: {
        custom: 'valid = (input !== "Joe") ? true : "You cannot be Joe"'
      }
    })).then((component) => {
      return Harness.testInvalid(component, 'Joe', 'firstName', 'You cannot be Joe').then(() => component);
    }).then((component) => {
      return Harness.testValid(component, 'Tom').then(() => component);
    });
  });
  it('Should provide one custom error message', (done) => {
    const formJson =  {
      components: [{
          label: 'Text Field',
          tableView: true,
          validate: {
            pattern: '^[0-9]*$]',
            customMessage: 'Custom Error Message',
            minWords: 10
          },
          key: 'textField',
          type: 'textfield',
          input: true
       }]
    };
    const element = document.createElement('div');
    Formio.createForm(element, formJson)
      .then(form => {
        form.submission = {
          data: {
            textField: 'textField'
          }
        };
        const textField = form.getComponent('textField');
        setTimeout(() => {
          assert.equal(textField.refs.messageContainer.children.length, 1);
          assert.equal(textField.refs.messageContainer.children[0].innerHTML, 'Custom Error Message');
          done();
        }, 300);
      })
      .catch(done);
  });
  it('Should provide json validation', () => {
    return Harness.testCreate(TextFieldComponent, _.merge({}, comp2, {
      validate: {
        json: {
          'if': [
            {
              '===': [
                { var: 'data.firstName' },
                'Joe'
              ]
            },
            true,
            'You must be Joe'
          ]
        }
      }
    })).then((component) => {
      return Harness.testInvalid(component, 'Tom', 'firstName', 'You must be Joe').then(() => component);
    }).then((component) => {
      return Harness.testValid(component, 'Joe').then(() => component);
    });
  });
});