jeudi 27 août 2015

How to unit test angular directive with event handler

I have a directive to autosave a form on enter and blur events. I'm trying to test if the save callback is called when these events are triggered, but my test is not working.

I tried to get an input of the form and trigger a blur event, but for some reason the callback is not being called.

  angular
    .module('myModule')
    .directive('autoSaveForm', autoSaveForm);

  function autoSaveForm() {
    var directive;

    directive = {
      restrict: 'A',
      require: 'form',
      scope: {
        autoSaveFormFn: '&',
        autoSaveFormModel: '='
      },
      link: link
    };

    return directive;

    function link(scope, elem, attrs, form) {
      var latestModel;

      function saveForm() {
        if (!angular.equals(latestModel, scope.autoSaveFormModel) && form.$valid) {
          latestModel = angular.copy(scope.autoSaveFormModel);

          scope.$apply(function() {
            scope.autoSaveFormFn();
          });
        }
      }

      function keydownHandler(event) {
        var code = event.keyCode || event.which,
            ENTER_CODE = 13;

        if (code === ENTER_CODE) {
          event.preventDefault();
          event.target.blur();
        }
      }

      elem.find('input, textarea').on('blur', saveForm);
      elem.find('input, textarea').on('keydown', keydownHandler);

      elem.on('$destroy', function() {
        elem.find('input, textarea').off('blur', saveForm);
        elem.find('input, textarea').off('keydown', keydownHandler);
      });
    }
  }
describe('Auto Save Form Directive', function() {
  var compile,
      rootScope,
      scope,
      template,
      form,
      input,
      isolateScope;

  beforeEach(module('myModule'));

  beforeEach(inject(function(_$compile_, _$rootScope_) {
    compile = _$compile_;
    rootScope = _$rootScope_;
    scope = rootScope.$new();

    template = '<form auto-save-form ' +
                      'auto-save-form-fn ' +
                      'auto-save-form-model>' +
                  '<input type="text">' +
                  '<input type="text">' +
               '</form>';

    form = compile(template)(scope);
    scope.$digest();
    isolateScope = form.isolateScope();
    input = angular.element(form.find('input')[0]);
  }));

  it('should call auto save form function on blur', function() {
    spyOn(isolateScope, 'autoSaveFormFn');

    input.triggerHandler('blur');
    scope.$digest();

    expect(isolateScope.autoSaveFormFn).toHaveBeenCalled();
  });
});

Aucun commentaire:

Enregistrer un commentaire