AngularJS unit test DateTimePicker

I'm trying to write a unit test for a directive that uses eonasdan-bootstrap-datetimepicker ( https://github.com/Eonasdan/bootstrap-datetimepicker ). The code for the directive looks something like this:

'use strict';

angular.module('directives')
.directive('datepicker', ['$moment', function ($moment) {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function (scope, element, attributes, ctrl) {
            angular.element(document).ready(function(){
                var jElem = $(element);
                jElem.datetimepicker({
                    icons: {
                        time: "fa fa-clock-o",
                        date: "fa fa-calendar",
                        up: "fa fa-arrow-up",
                        down: "fa fa-arrow-down",
                        next: "fa fa-arrow-right",
                        previous: "fa fa-arrow-left"
                    },
                    format: 'D MMMM'
                });
                var picker = jElem.data("DateTimePicker");

                ctrl.$parsers.push(function (value) {
                    var date = $moment(value);
                    if (date.isValid()) {
                        return date.format('D/M');
                    }
                    return '';
                });

                $(element).on('dp.change', function (event) {
                    scope.$apply(function() {
                        var date = picker.date();
                        if (date && date.valueOf) {
                            ctrl.$setViewValue(date.valueOf());
                        }
                    });
                    element[0].blur();
                });
            });
        }
    };
}]);

      

I'm trying to cover the "dp.change" event, but I can't figure out how to trigger the jQuery event. I tried to do something like this:

'use strict';

describe('Specs for datepicker', function()
{
    var scope;
    var $compile;
    var form;

    beforeEach(module('directives'));
    beforeEach(inject(function($rootScope, _$compile_) {
        $compile = _$compile_;
        scope = $rootScope.$new();
        var html =  "<form name='test_form'"+
                          " novalidate>"+
                          "<fieldset>"+
                                "<input type='text' "+
                                       "ng-model='dt' "+
                                       "datepicker "+
                                       "class='form-control date' "+
                                       "name='date' "+
                                       "value=''/>"+
                          "</fieldset>"+
                    "</form>"
        form = $compile(angular.element(html))(scope);
        scope.$digest();
    }))

    it('should react to dp.change', function()
    {
        scope.test_form.date.$setViewValue('1 Jan');
        scope.$digest();
        var element = $(form).find('input');
        var dp = $(element.find('datepicker'));
        dp.triggerHandler(new $.Event('dp.change'));
        scope.$digest();
        expect(scope.dt).toEqual('1/1');
    });
});

      

I tried a bunch of other things, but nothing got me covered in the handler. Any suggestions how to fix this?

+3


source to share


2 answers


In your test, replace

form = $compile(angular.element(html))(scope);

      

or

form = $compile(angular.element('<div>' + html + '</div>'))(scope);

      



or simply

form = $compile(html)(scope);

      

The problem is that it angular.element

removes the top parent before going to $compile

.

0


source


You must try



scope.test_form.date.$setViewValue('1 Jan');
scope.$digest();
var element = $(form).find('input');
element.triggerHandler(new $.Event('dp.change'));
expect(scope.dt).toEqual('1/1');

      

0


source







All Articles