Cannot test a directive that removes an HTML node element during $compile time

495 views
Skip to first unread message

Oleg Belousov

unread,
Nov 10, 2013, 1:52:20 PM11/10/13
to ang...@googlegroups.com

Test: I have provided a full mock of the service function that I need for my directive. When running the test in debug mode(by adding a break point) the everything seems correct. Tried so far: Diminishing the priority of the directive, suing $digest instead compile, and many others.

 describe('directives', function() {
      var authService;
      beforeEach(function(){
        module('myApp.directives');
        module('myApp.services');
      });
      beforeEach(
        inject(function($injector) {
          authService = $injector.get('authService') || function(){
            var __root = this;/*use this to simulate my service*/
            __root.role = undefined
            return{
              setRole: function(newRole){ __root.role = newRole},
              getRole: function(){return __root.role}
            }
          };
        })
      );
      describe('restrict', function(){
        it('should allow basic role-based content discretion', function(){
          inject(function($compile, $injector, $rootScope){
            authService.setRole('guest');
            var scope = $rootScope.$new();
            var element = $compile('<span data-restrict data-access="admin"></span>')(scope);
            scope.$apply();
            console.log(element);
            expect(element).toBeUndefined();
          });
        });
      });
    });

Directive:

angular.module('myApp.directives', []).
directive('restrict', function(authService){
    return{
        restrict: 'A',
        prioriry: 100000,
        scope: false,
        link: function(){
            // alert('ergo sum!');
        },
        compile: function(element, attr, linker){
      debugger;
            var accessDenied = true;
            var user = authService.getUser();
            var attributes = attr.access.split(" ");
            for(var i in attributes){
                if(user.role == attributes[i]){
                    accessDenied = false;
                }
            }

            if(accessDenied){

          angular.forEach(element.children(), function(elm){
            try{
              elm.remove();
            }
            catch(ignore){}
          });//TODO: find a better solution for IE or remove this code       

        element.children().remove();
                element.remove();           
            }

        }
    }
});


Test output:

Chrome 30.0.1599 (Linux) directives restrict should allow basic role-based content discretion FAILED
    Expected { 0 : HTMLNode, length : 1 } to be undefined.
    Error: Expected { 0 : HTMLNode, length : 1 } to be undefined.
        at /var/www/front/dev/angular-seed/test/unit/directivesSpec.js:30:25
        at Object.invoke (/var/www/front/dev/angular-seed/app/js/angular.js:2795:28)
        at workFn (/var/www/front/dev/angular-seed/test/lib/angular/angular-mocks.js:1778:20)
        at window.jasmine.window.inject.angular.mock.inject (/var/www/front/dev/angular-seed/test/lib/angular/angular-mocks.js:1765:30)
        at null.<anonymous> (/var/www/front/dev/angular-seed/test/unit/directivesSpec.js:24:7)
Chrome 30.0.1599 (Linux): Executed 1 of 1 (1 FAILED) ERROR (0.422 secs / 0.041 secs)
INFO [watcher]: Changed file "/var/www/front/dev/angular-seed/test/unit/directivesSpec.js".
LOG: {0: <span data-restrict="" data-access="admin" class="ng-scope"></span>, length: 1}

Oleg Belousov

unread,
Nov 10, 2013, 1:59:23 PM11/10/13
to ang...@googlegroups.com

Oleg Belousov

unread,
Nov 10, 2013, 5:05:21 PM11/10/13
to ang...@googlegroups.com
updated test:
```javascript
 describe('restrict', function(){
    var scope, compiled, html, elem, authService;
    html = '<span data-restrict data-access="admin"></span>';
    beforeEach(function(){
      module('myApp.directives');
      module('myApp.services');
      inject(function($compile, $rootScope, $injector){
        authService = $injector.get('authService');
        authService.setRole('guest');
        scope = $rootScope.$new();
        elem = angular.element(html);
        console.log(elem);
        compiled = $compile(elem);
        compiled(scope);
        scope.$digest();

      });
    });
    it('should allow basic role-based content discretion', function(){
      expect(elem).toBeUndefined();
      console.log(compiled)
      console.log(elem);  
    });   
  });
```


On Sunday, 10 November 2013 20:52:20 UTC+2, Oleg Belousov wrote:

OpenNota

unread,
Nov 11, 2013, 6:39:16 AM11/11/13
to ang...@googlegroups.com
It will never be undefined. You can remove the element from DOM, but this will not make it undefined.
Reply all
Reply to author
Forward
0 new messages