0

I am testing following directive in angular Jasmine unit test

angular.module('components.privileges', [])


.directive('hasPrivilege', function(privileges) {
 return {
     link: function (scope, element, attrs, $rootScope) {
         if (!angular.isString(attrs.hasPrivilege)) {
             throw "hasPrivilege value must be a string";
         }

         function toggleVisibilityBasedOnPrivilege() {
             var hasPrivilege = privileges.evaluatePrivilegeExpression(attrs.hasPrivilege.trim());
             console.log(hasPrivilege);
             if (hasPrivilege) {
                 element.show();
             } else {
                 element.hide();
             }
         }

         toggleVisibilityBasedOnPrivilege();
         $rootScope.$on('privilegesChanged', function(event, data){
             toggleVisibilityBasedOnPrivilege();
         });
     }
 };
 }).factory('privileges', function ($rootScope) {
    var privilegesList = {};
    return {
        clearPrivileges: function () {
            privilegesList = {};
        },
        setPrivileges: function (privileges) {
            privilegesList["PRIVILEGES_SET_FLAG"] = true;
            if(angular.isDefined(privileges) && angular.isArray(privileges) && privileges.length > 0){
                for(var p in privileges) {
                    var k = privileges[p];
                    if( k && angular.isString(k) && k.trim()!==""){
                        privilegesList[privileges[p]] = true;
                    }
                }
            }
            $rootScope.$emit('privilegesChanged');
        },
        privilegesLoaded: function () {
            return angular.isDefined(privilegesList["PRIVILEGES_SET_FLAG"]);
        },
        hasPrivilege: function (p) {
            var k = p && angular.isString(p) ? p.trim() : "";
            return p === "NA" || ( k!=="" && angular.isDefined(privilegesList[k]) );
        },
        evaluatePrivilegeExpression: function (exp) {
            var isPrivileged = false;
            if( exp !== undefined && exp !== null && angular.isString(exp)){
                exp = exp.trim();
                if(exp !== "" && exp !== "!"){
                    var value = exp;
                    var notPrivilegeFlag = value[0] === '!';
                    if (notPrivilegeFlag) {
                        value = value.slice(1).trim();
                    }
                    var hasPrivilege = this.hasPrivilege(value);
                    isPrivileged =  (hasPrivilege && !notPrivilegeFlag || !hasPrivilege && notPrivilegeFlag);
                }
            }
            return isPrivileged;
        }

    };
});

In the directive, when i call setprivileges, I use '$rootScope.$emit('privilegesChanged');' event to notify that the privileges are changed. If, my div does not have the privilege, it must be hidden otherwise available.

And my test case is as follows:-

describe("directive: hasPrivilege: ",function(){
        var element, scope, priviledgesArray, $privilegesFactory, $compile;
        beforeEach(function(){
            module("components.privileges");

            inject(function(privileges, _$rootScope_, _$compile_) {
                $privilegesFactory = privileges;
                scope= _$rootScope_;
                $compile = _$compile_ ;

            });


            priviledgesArray = ["123"];
        });


         it("should hide the element when privileges have not been set", function(){
             element = $compile('<div has-privilege="123"></div>')(scope);
             scope.$digest();
             $privilegesFactory.setPrivileges(priviledgesArray);
             console.log($(element).find("div"));
             expect($(element).find("div").style.display).toBe("block");

         });
    });

});

When i ran the test case, I got following error TypeError: 'undefined' is not a function (evaluating 'element.hide()')

I am not getting what is the issue. Can someone help?

1 Answer 1

0

Try referencing element as an array in the directive, i.e. element[0].show(); and element[0].hide();.

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.