2

I have a form with the following input:

<input type="email" name="email" ng-model="register.form.email" ng-pattern="emailRegex">

I want to test that the form is invalid if the user types an invalid email:

it('...', function() {
    form.email.$setViewValue('invalid');
    expect(form.email.$valid).toBeFalsy(); // OK
    form.email.$setViewValue('invalid@');    
    expect(form.email.$valid).toBeFalsy(); // OK
    form.email.$setViewValue('invalid@host');     
    expect(form.email.$valid).toBeFalsy(); // Not OK    
});

The last expectatijon fails because the input is valid, although the email regex expects a domain. It feels as if the pattern is not used in my test because when I change the type to text, it already fails at the first expectation. How can I make sure the pattern is picked up in the tests?

For completeness, this is the regex (not written by me):

^[_A-Za-z0-9-]+(\.[_A-Za-z0-9-]+)*@[_A-Za-z0-9]+[_A-Za-z0-9-]*[_A-Za-z0-9]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$

Changing the type to text didn't work.

I'm using jasmine 2.4.1 and angular 1.4.2. I'm using ngHtml2JsPreprocessor as explained here to initialize the form in my tests.

Edit:

This is how to form is initialized:

beforeEach(inject(function($rootScope, $templateCache, $compile) {
   var $scope = $rootScope.$new();
    vm = $controller('RegisterController', {$scope: $scope});
    var templateHtml = $templateCache.get("register.html");
    var template = angular.element("<div>" + templateHtml + "</div>");
    $compile(template)($scope);
    var form = $scope.registerForm;
    $scope.$apply();
    scope = $scope;
}));
1
  • What that test will proof? That ng-pattern works? Yes - it works, probably the team responsive for developing AngularJS will catch that error before you. You want to test regExp? Extract it and test it in unit test Commented Jun 13, 2016 at 10:58

2 Answers 2

2

AngularJS still works in the way, how it was developed

angular.module('app', [])

describe('Registration form', () => {
  'use strict'

  beforeEach(module('app'))

  let form
  let scope

  beforeEach(inject(($rootScope, $compile) => {
    scope = $rootScope.$new()
    var formElem = ['<form name="registrationForm">',
      '<input type="text" name="number" ng-model="input" ng-pattern="/^[_A-Za-z0-9-]+(\.[_A-Za-z0-9-]+)*@[_A-Za-z0-9]+[_A-Za-z0-9-]*[_A-Za-z0-9]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$/">',
      '</form>'
    ].join('')
    $compile(formElem)(scope)
    form = scope.registrationForm
  }))

  it('has no `$valid` state', () => {
    expect(form.$valid).toBeTruthy()
    form.number.$setViewValue('invalid email address')
    expect(form.number.$valid).toBeFalsy()
  })

  it('has `$valid` state', () => {
    expect(form.$valid).toBeTruthy()
    form.number.$setViewValue('[email protected]')
    expect(form.number.$valid).toBeTruthy()
  })
})
<script src="https://safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine-2.0.3-concated.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-mocks.js"></script>
<link href="https://safjanowski.github.io/jasmine-jsfiddle-pack/pack/jasmine.css" rel="stylesheet" />

Sign up to request clarification or add additional context in comments.

2 Comments

As you've shown it does work as I was expecting, so I'm going to start from your example and build up my test case. In regards to your other comment: sadly I do have to write this particular test even though I know it's not that useful. Many thanks!
Some usufull regExp that you can use to validate email address - emailregex.com
0

I think you should call scope.$digest(); after using form.email.$setViewValue, scope beeing the scope passed to your $compile. That's what I used in every tests.

You can also see more infos right here : https://stackoverflow.com/a/22772504/4583079

1 Comment

I've tried that and unfortunately it doesn't work. I can see that prior to the last expectation, the modelValue is already invalid@hostwhich means it has already passed the parsers and validators (if I remember correctly).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.