angularjs - Interceptor de respuesta de prueba de jazmín angular
ng-href angular 5 (2)
Debe estructurar su definición de interceptor utilizando la sintaxis más reciente . La construcción de su URL también debe estar en un servicio para que pueda burlarse fácilmente en las pruebas.
.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);
}
});
Hacerlo le permitirá probarlo como cualquier otra fábrica sin tener que preocuparse por las implementaciones internas de $http
interceptores $http
, o tener que $httpBackend
respuestas 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);
});
});
});
});
Intento probar mi interceptor de respuesta, pero me cuesta imaginar cómo simular el objeto $ window. Aquí está mi código interceptor:
''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);
};
});
Y aquí está mi especificación:
''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();
}));
});
});
});
});
Tengo un: Expected ''http://localhost:8080/context.html'' to equal ''http://accounts.domain.com/oauth/.....''
. ¿Alguna ayuda sobre cómo simular correctamente el objeto $ window o, más en general, cómo probar un caso de redirección 401 +?
Aquí hay un ejemplo del interceptor responseError y la especificación de jazmín correspondiente.
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
};
}]);
El interceptor intercepta la solicitud de ajax, si la solicitud falla, y si el código de estado es 401, el usuario se redirige a la página de inicio de sesión.
Especificación de Jasmine para lo mismo es:
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();
});
});
});
Hemos espiado los $ q así que también podemos probar que el rechazo se llama para el error 401.