HMR
HMR

Reputation: 39270

Test directive used as general custom validator

I made a custom validator directive (less general version here) for 2 reasons:

  1. Don't have repeating rules in my template
  2. Have complex rules in my rules service instead spread over several directives

The html/template would look like this:

<input type='text' 
  name='name' 
  data-validator='name' 
  data-validator-entity='user'>

The directive:

angular.module('app').directive('validator'
 , ['appRules', function(appRules) {
  return {
    require: ['^form','ngModel'],
    link: function(scope, elm, attrs, ctrls) {
      // removed checks that can be tested
      var ctrl=ctrls[1],form=ctrls[0]
      //appRules.user.validate('name') returns the function
      //  appRules.user.validateFunctions.name to validate
      //  the name field of the user entity
      ,fn=appRules[attrs.validatorEntity].validate(attrs.validator);
      ctrl.$parsers.unshift(
        function(viewValue){
          fn(viewValue,ctrl,form);
        }
      );
      //appRules.user.validateMessages.name is an array of possible
      //  things that can be wrong with name. Like cannotEmpty and 
      //  minimuThreeChars the validate function will set validity
      //  with ctrl.$setValidity('cannotEmpty',true/false);
      //  this is used to display a message to the user if needed
      //  for example:
      //  appSettings.messages.user.cannotEmpty='Cannot leave this field empty'
      ctrl.$error.messages=appRules[attrs.validatorEntity]
        .validateMessages[attrs.validator];
    }
  };
}]);

The only thing I'd like to test still is that ctrl.$parsers has the right function set on it and that ctrl.$error.messages is set correctly. But I'm not sure what ctrl is, where it came from and how to access this in the test.

Here is the test so far:

var $compile;
var $rootScope;
var appSettings;
var appRules;
var element;
beforeEach(inject(function(_$compile_, _$rootScope_,appSettings,appRules){
  $compile = _$compile_;
  $rootScope = _$rootScope_;
  $rootScope.data={
    name:'testName'
  };
  appSettings = appSettings;
  appRules = appRules;
  element = $compile("<div><form name='test'>\
    <input type='text' \
      name = 'name' \
      data-ng-model='data.name'\
      data-validator-entity='user'\
      data-validator='name'></form></div>")($rootScope);
  $rootScope.$digest();
}));

//removed working tests that throw on invalid entity and field

it('Check if validator sets correct values in ctrl.', function() {
  //how to get ctrl from here? element.find('input') is not it
  // element.find('input').data is empty 
  // element.find('input').$eror is undefined
}

Upvotes: 0

Views: 39

Answers (1)

runTarm
runTarm

Reputation: 11547

You could get the ngModel controller like this in the test:

var ctrl = element.find('input').controller('ngModel');

And for the form controller, you could do the same:

var form = element.find('form').controller('form');

Hope this helps.

Upvotes: 1

Related Questions