Angular Перехватчик ответных реакций на жасмин
Я пытаюсь проверить свой ответный перехватчик, но мне трудно понять, как издеваться над объектом $window. Вот мой код перехватчика:
'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);
};
});
И вот моя спецификация:
'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();
}));
});
});
});
});
У меня есть: Expected 'http://localhost:8080/context.html' to equal 'http://accounts.domain.com/oauth/.....'
. Любая помощь в том, как правильно издеваться над объектом $window или, в общем, как проверить случай переадресации 401 +?
Ответы
Ответ 1
Вы должны структурировать определение перехватчика, используя более свежий синтаксис. Ваша структура URL также должна быть в службе, чтобы ее можно было легко высмеять в тестах.
.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);
}
});
Таким образом, вы можете протестировать его так же, как и любой другой factory, не беспокоясь о внутренних реализациях перехватчиков $http
или обманывая ответы с помощью $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);
});
});
});
});
Ответ 2
Вот пример перехватчика responseError и соответствующей спецификации жасмина.
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
};
}]);
Перехватчик перехватывает запрос ajax, если запрос не выполнен, тогда, если код состояния равен 401, тогда пользователь перенаправляется на страницу signIn.
Спецификация Жасмина для того же:
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();
});
});
});
Мы следили за $q, поэтому мы также можем проверить, что отклонение вызывается для ошибки 401.