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;
}));
Community
  • 1
  • 1
Aerus
  • 4,332
  • 5
  • 43
  • 62
  • 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 – Krzysztof Safjanowski Jun 13 '16 at 10:58

2 Answers2

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('some@valid.address')
    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" />
Krzysztof Safjanowski
  • 7,292
  • 3
  • 35
  • 47
  • 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! – Aerus Jun 13 '16 at 11:16
  • Some usufull regExp that you can use to validate email address - http://emailregex.com/ – Krzysztof Safjanowski Jun 13 '16 at 11:19
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

Community
  • 1
  • 1
Paqman
  • 456
  • 3
  • 8
  • I've tried that and unfortunately it doesn't work. I can see that prior to the last expectation, the `modelValue` is already `invalid@host`which means it has already passed the parsers and validators (if I remember correctly). – Aerus Jun 13 '16 at 09:48