2014-11-22 10 views
12

Sto provando a testare il mio interceptor di risposta ma ho difficoltà a capire come si deride l'oggetto $ window. Qui è il mio codice intercettore:Interceptor di risposta al test angolare del gelsomino

'use strict'; 

angular.module('Domain.handlers') 

.config(function($httpProvider) { 
    $httpProvider.responseInterceptors.push('UnauthorizedInterceptor'); 
}) 

.factory('UnauthorizedInterceptor', function($q, $injector, $window, ENV) { 
    return function(promise) { 
    var success = function(response) { return response; }; 
    var error = function(response) { 
     if (response.status === 401) { 
     $window.location.href = ENV.account + '/oauth/authorize?client_id=' + ENV.clientId + '&redirect_uri=' + ENV.app + '/oauth/callback&response_type=token'; 
     } 
     return $q.reject(response); 
    }; 
    return promise.then(success, error); 
    }; 
}); 

Ed ecco la mia spec:

'use strict'; 

describe('Domain.handlers.response', function() { 
    var UnauthorizedInterceptor, 
     httpProvider, 
     $httpBackend, 
     $http, 
     token = '123456789'; 

    beforeEach(module('Domain.handlers', function($httpProvider) { 
    httpProvider = $httpProvider; 
    })); 

    beforeEach(inject(function(_UnauthorizedInterceptor_, _$httpBackend_, _$http_) { 
    UnauthorizedInterceptor = _UnauthorizedInterceptor_; 
    $httpBackend = _$httpBackend_; 
    $http = _$http_; 
    })); 

    describe('UnauthorizedInterceptor', function() { 
    it('should be defined', function() { 
     expect(UnauthorizedInterceptor).toBeDefined(); 
    }); 

    describe('HTTP status', function() { 
     describe('is 200 OK', function() { 
     it('should return a 200 status', function() { 
      $httpBackend.expectGET('http://api.domain.com/clients').respond(200, {}); 
      $http.get('http://api.domain.com/clients'); 
      $httpBackend.flush(); 
     }); 
     }); 

     describe('is 401 Unauthorized', function() { 
     it('should redirect to accounts.domain.com', inject(function($window) { 
      $httpBackend.expectGET('http://api.domain.com/clients').respond(401, {}); 
      $http.get('http://api.domain.com/clients'); 
      expect($window.location.href).toEqual('http://accounts.domain.com/oauth/.....'); 
      $httpBackend.flush(); 
     })); 
     }); 
    }); 
    }); 
}); 

Ho un: Expected 'http://localhost:8080/context.html' to equal 'http://accounts.domain.com/oauth/.....'. Qualsiasi aiuto su come simulare correttamente l'oggetto $ window o più in generale come testare un caso di reindirizzamento 401 +?

risposta

14

È necessario strutturare la definizione dell'intercettore utilizzando more recent syntax. La costruzione dell'URL dovrebbe essere anche in un servizio in modo che possa essere facilmente deriso nei test.

.factory('UnauthorizedInterceptor', function($q, $window, OtherService) { 
    var service = { 
    responseError: handleUnauthorized 
    }; 

    return service; 

    function handleUnauthorized(rejection) { 
    if (rejection.status === 401) { 
     $window.location.href = OtherService.getUnauthorizedRedirectURL(); 
    } 
    return $q.reject(rejection); 
    } 
}); 

In questo modo vi permetterà di testare come qualsiasi altra fabbrica, senza doversi preoccupare delle implementazioni interne di $http intercettori, o di dover prendere in giro le risposte con $httpBackend.

describe('Domain.handlers.response', function() { 
    var $window, 
     UnauthorizedInterceptor, 
     OtherService, 
     redirectUrl = 'someUrl'; 

    beforeEach(module('Domain.handlers')); 

    beforeEach(function() { 
    $window = { location: { href: null } }; 

    module(function($provide) { 
     $provide.value('$window', $window); 
    }); 
    }); 

    beforeEach(inject(function(_UnauthorizedInterceptor_, _OtherService_) { 
    UnauthorizedInterceptor = _UnauthorizedInterceptor_; 
    OtherService = _OtherService_; 

    spyOn(OtherService, 'getUnauthorizedRedirectURL').andReturn(redirectUrl); 
    })); 

    describe('UnauthorizedInterceptor', function() { 
    it('should be defined', function() { 
     expect(UnauthorizedInterceptor).toBeDefined(); 
    }); 

    it('should have a handler for responseError', function() { 
     expect(angular.isFunction(UnauthorizedInterceptor.responseError)).toBe(true); 
    }); 

    describe('when HTTP 401', function() { 
     beforeEach(function() { 
     var rejection = { status: 401 }; 
     UnauthorizedInterceptor.responseError(rejection); 
     }); 

     it('should set window location', function() { 
     expect($window.location.href).toBe(redirectUrl); 
     }); 
    }); 

    describe('when not HTTP 401', function() { 
     beforeEach(function() { 
     var rejection = { status: 500 }; 
     UnauthorizedInterceptor.responseError(rejection); 
     }); 

     it('should not set window location', function() { 
     expect($window.location.href).not.toBe(redirectUrl); 
     }); 
    }); 
    }); 
}); 
+1

Grazie mille per la risposta. Mi ha aiutato molto a capire alcune cose che non sapevo. Tuttavia, ho ancora lo stesso errore 'Previsto 'http: // localhost: 8080/context.html' per essere 'http: //dev-accounts.domain.dev: 3000/oauth/authorize ...'. Penso che questo sia legato a '$ window.location.href' che in qualche modo restituisce sempre' http: // localhost: 8080/context.html'. Qualche idea? – lkartono

+0

in che browser stai eseguendo i test? – user2943490

+0

Sto usando PhantomJs – lkartono

4

Di seguito è riportato un esempio dell'intercettore di rispostaErrore e della specifica di gelsomino corrispondente.

angular.module('interceptorDemo').factory('redirectInterceptor', ['$q', '$window', function($q, $window) { 
    'use strict'; 

    function handleUnauthorizedAccess(config) { 
     if (401 === config.status) { 
      $window.location = '/signIn/'; 
     } 
     return $q.reject(config); 
    } 

    return { 
     responseError: handleUnauthorizedAccess 
    }; 
}]); 

L'intercettore intercetta la richiesta Ajax, se la richiesta è fallita, quindi se il codice di stato è 401 allora l'utente viene reindirizzato alla pagina di accesso.

Jasmine spec per lo stesso è:

describe('redirectInterceptor specs', function() { 

    var redirectInterceptor, $q; 

    beforeEach(module('interceptorDemo')); 

    beforeEach(function() { 
     $window = { 
      location: { 
       href: null 
      } 
     }; 

     module(function($provide) { 
      $provide.value('$window', $window); 
     }); 
    }); 

    beforeEach(inject(function(_redirectInterceptor_, _$q_) { 
     redirectInterceptor = _redirectInterceptor_; 
     $q = _$q_; 
     spyOn($q, 'reject'); 
    })); 

    describe('redirectInterceptor specs', function() { 
     it('should redirect to signIn page for unauthorized access', function() { 
      var response = { 
       status: 401, 
       config: {} 
      }; 
      var promise = redirectInterceptor.responseError(response); 
      expect($window.location).toBe('/singIn/'); 
      expect($q.reject).toHaveBeenCalled(); 
     }); 

     it('should not redirect to signIn page for error code other than unauthorized access', function() { 
      var response = { 
       status: 404, 
       config: {} 
      }; 
      var promise = redirectInterceptor.responseError(response); 
      expect($window.location).toEqual({ 
       href: null 
      }); 
      expect($q.reject).toHaveBeenCalled(); 
     }); 

    }); 
}); 

Abbiamo spiato il $ q così possiamo anche testare che lo scarto è chiamato per l'errore 401.

Problemi correlati