Tuesday 30 July 2019

How to unit test form validation in Aurelia

I am trying to implement some unit tests on a form to see if the validation rules are working as expected.

from this page : https://github.com/aurelia/testing/issues/63

I found this implementation : https://github.com/aurelia/validation/blob/master/test/validate-binding-behavior.ts

and I tried to implement it in my project

login.spec.js

import {bootstrap} from 'aurelia-bootstrapper';
import {StageComponent} from 'aurelia-testing';
import {PLATFORM} from 'aurelia-pal';
import { configure, blur, change } from './shared';
import { Login } from './login';


describe('ValidateBindingBehavior', () => {
    it('sets validateTrigger', (done) => {
        const component = StageComponent
            .withResources(PLATFORM.moduleName('features/account/login/login'))
            .inView('<login></login>')
            .boundTo({});
        component.bootstrap(configure);
        let viewModel;
        const renderer = { render: jasmine.createSpy() };
        component.create(bootstrap)
            // grab some references.
            .then(() => {
            viewModel = component.viewModel;
            viewModel.controller.addRenderer(renderer);
        })

            .then(() => expect(viewModel.controller.errors.length).toBe(0))
            .then(() => blur(viewModel.firstName))
            .then(() => expect(viewModel.controller.errors.length).toBe(1))
            .then(() => component.dispose())
            .then(done);
    });
});

login.js

import { inject, NewInstance } from 'aurelia-dependency-injection';
import {  ValidationController } from 'aurelia-validation';
import { User } from './login.model';

@inject(NewInstance.of(ValidationController), User)
export class Login {
  constructor(controller, user) {
    this.controller = controller;
    this.firstName = '';
    this.lastName = '';
    this.userName = '';
    this.showForm = true;
    this.user = user;
  }
};


login.model.js

import {ValidationRules} from 'aurelia-validation';

export class User {
    firstName = '';
    lastName = '';
    userName = '';

    constructor() {
      ValidationRules
        .ensure('firstName')
        .required()  
        .ensure('lastName')
        .required()
        .minLength(10)
        .ensure('userName')
        .required()
        .on(this);
    }
  }

shared.js

import {DOM, PLATFORM} from 'aurelia-pal';

export function configure(aurelia) {
    return aurelia.use
    .standardConfiguration()
    .plugin(PLATFORM.moduleName('aurelia-validation'))
}
export function blur(element) {
    element.dispatchEvent(DOM.createCustomEvent('blur', {}));
    return new Promise(resolve => setTimeout(resolve));
}
export function change(element, value) {
    element.value = value;
    element.dispatchEvent(DOM.createCustomEvent('change', { bubbles: true }));
    return new Promise(resolve => setTimeout(resolve));
}

and here is a piece of html markup :

    <div>
      <input ref="firstName" type="text" value.bind="user.firstName & validateOnBlur"
        validation-errors.bind="firstNameErrors">
      <label style="display: block;color:red" repeat.for="errorInfo of firstNameErrors">
        ${errorInfo.error.message}
      </label>
    </div>
    <div>

in the spec, when I blur the element I expect to get one error, but "controller.errors" is always an empty array. and I get this for the failed message :

Error: Expected 0 to be 1.

UPDATE:

I tried to validate manually, so I added this in my spec :

.then(()=> 
        viewModel.controller.validate({object: viewModel.user, propertyName: 'firstName' })

)

and it works fine, but the blur and change functions don't trigger validation.



from How to unit test form validation in Aurelia

No comments:

Post a Comment