Unit Testing a directives link function with element dom manipulation (show/hide/disable/enable directive)

86 views
Skip to first unread message

maximchernin

unread,
Jul 4, 2016, 4:21:53 AM7/4/16
to Jasmine
Hi, im trying to write tests for my directive
ill start by explaining what it does:
the directive wraps an element, or written as an attribute
the directive is written like this:


    <md-button has-permission="!UpdateHotelStaticDetails" action-type="disable"
           ng-click="$ctrl.onClickSaveAllBtn()">
    <custom-icon="save" size="24"></custom-icon> Save
</md-button>



OR like this:

       
<add-button-component title="Add New Group" on-add-new="$ctrl.addNewGroup()"
         has-permission="!ManageGroups" action-type="disable"
        ></add-button-component>


the action-type is non essential.
if no action-type is specified then is the user has the permission the element will be shown. if action-type="disable" is set the if user dosent have the permission the element will be disabled

in the second case my directive is attached to the rendered html by the add-button-component and should disable the button.

now the js code:

 
   module.exports = function (app) {
   'use strict';
   app.directive('hasPermission', hasPermission);
   var actionTypes = {
       hide: 'hide',
       disable: 'disable'
   };

    hasPermission.$inject = ['userService', 'loggerService'];
   function hasPermission(userService, loggerService) {
       return {
           restrict: 'EA',
           link: function (scope, element, attrs) {
               //Checking if attribute "has-permission" value is a string AT THE HTML      
                if (!_.isString(attrs.hasPermission)) {
                   loggerService.logWarn('hasPermission value at Html attribute must be a string');
               }

                //@value - permission name
               //@notPermissionFlag - true if user not premitted.
               var value = attrs.hasPermission.trim();
               var notPermissionFlag = value[0] === '!';
               if (notPermissionFlag) {
                   value = value.slice(1).trim();
               }
               /*
         each new logging to system, @rootscope event is fired 'permissionsChanged'.
         */
               toggleVisibilityBasedOnPermission();
               scope.$on('permissionsChanged', toggleVisibilityBasedOnPermission);

                function toggleVisibilityBasedOnPermission() {
                   var hasPermission = userService.hasPermission(value); //getting permission from service

                    /**
                   * Value                                                    notPermissionFlag   hasPermission   result
                   * ---------------------------------------------------------------------------------------------------- *
                   * Edit (show html if user has "edit permission")          |       false      |      true     |  show    *
                   * Edit (show html if user dosent have "edit permission")  |       false      |      false    |  hide    *
                   * !Edit(show html if user has "edit permission")         |       true       |      true     |  hide    *
                   * !Edit(show html if user dosent have "edit permission") |       true       |      false    |  show    *
                   * ---------------------------------------------------------------------------------------------------- *                                                          
                    */
                   if (!hasPermission && !notPermissionFlag || hasPermission && notPermissionFlag) {
                       if (attrs.actionType) {
                           attrs.actionType.toLowerCase() === actionTypes.disable ? attrs.$set('disabled', 'disabled') : false;
                           attrs.actionType.toLowerCase() === actionTypes.disable ? element.find('button').attr('disabled', 'disabled') : false;
                       } else {
                           element[0].parentNode.removeChild(element[0]);
                       }
                   }
               }
           }
       };
   }
};


this works on the app.
ive tried testing it like this:


    describe('hasPermission', function() {
    var self = {},
        loggerService,
        controller,
        configurationService,
        userService;

    var $rootScope, $compile;

    beforeEach(angular.mock.module('core'));
    beforeEach(angular.mock.module(function($provide) {
        $provide.constant('configurationService', {
            "AUTH_TEST_MODE": true,
        });
    }));


    function injectFn($injector, _$controller_, _$rootScope_, _$compile_) {
        loggerService = $injector.get('loggerService');
        configurationService = $injector.get("configurationService");
        userService = $injector.get("userService");
        $rootScope = _$rootScope_;
        $compile = _$compile_;
    }


    /**
     * helper function gets html as string compiles and returns element;
     * @param htmlCode (String)
     * @returns (object) compiledElement
     */
    function getCompiledElement(htmlCode) {
        var element = angular.element(htmlCode);
        var compiledElement = $compile(element)($rootScope);
        $rootScope.$digest();
        return compiledElement;
    }

    beforeEach(inject(injectFn));

   
    it('should get a UpdateHotelStaticDetails permission and show the inner button', function() {
        var element = getCompiledElement('<button has-permission  id="permissionBtn" permission="UpdateHotelStaticDetails">Save</button>');
         var x = element.find('button');
         var xx = document.getElementById('permissionBtn');
         console.log(element);
         console.log(xx);

    }); }); 



honestly i have no idea how to test this. tried reading some material but most of the uses i see is getting the element and compiling it
but when i search for the button in the spec i find nothing.
i have very little idea how should i test this

Should i even test this kind of functionality in unit tests? 
shouldn't this be done in e2e tests?
i would like to verify 4 cases. 
1. exsiting permission should show the element and it should be clickable
2. non exsiting permission should hide the element
3. non exsiting permission should disable the element

thanks for all the help.



Reply all
Reply to author
Forward
0 new messages