Merge "Move to '404' page when resource type or resource not found"
This commit is contained in:
commit
872ae60c76
@ -62,6 +62,7 @@ module.exports = function (config) {
|
||||
// from jasmine.html
|
||||
xstaticPath + 'jquery/data/jquery.js',
|
||||
xstaticPath + 'angular/data/angular.js',
|
||||
xstaticPath + 'angular/data/angular-route.js',
|
||||
xstaticPath + 'angular/data/angular-mocks.js',
|
||||
xstaticPath + 'angular/data/angular-cookies.js',
|
||||
xstaticPath + 'angular_bootstrap/data/angular-bootstrap.js',
|
||||
|
@ -17,13 +17,15 @@
|
||||
|
||||
angular
|
||||
.module('horizon.framework', [
|
||||
'ngRoute',
|
||||
'horizon.framework.conf',
|
||||
'horizon.framework.util',
|
||||
'horizon.framework.widgets'
|
||||
])
|
||||
.config(config)
|
||||
.run(run)
|
||||
.factory('horizon.framework.redirect', httpRedirectLogin)
|
||||
.factory('horizon.framework.redirect', redirect)
|
||||
.config(registerNotFound)
|
||||
.constant('horizon.framework.events', {
|
||||
FORCE_LOGOUT: 'FORCE_LOGOUT'
|
||||
});
|
||||
@ -74,7 +76,7 @@
|
||||
// Global http error handler
|
||||
// if user is not authorized, log user out
|
||||
// this can happen when session expires
|
||||
$httpProvider.interceptors.push(httpRedirectLogin);
|
||||
$httpProvider.interceptors.push(redirect);
|
||||
$httpProvider.interceptors.push(stripAjaxHeaderForCORS);
|
||||
|
||||
stripAjaxHeaderForCORS.$inject = [];
|
||||
@ -115,7 +117,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
httpRedirectLogin.$inject = [
|
||||
redirect.$inject = [
|
||||
'$q',
|
||||
'$rootScope',
|
||||
'$window',
|
||||
@ -123,7 +125,7 @@
|
||||
'horizon.framework.widgets.toast.service'
|
||||
];
|
||||
|
||||
function httpRedirectLogin($q, $rootScope, $window, frameworkEvents, toastService) {
|
||||
function redirect($q, $rootScope, $window, frameworkEvents, toastService) {
|
||||
return {
|
||||
responseError: function (error) {
|
||||
if (error.status === 401) {
|
||||
@ -135,6 +137,9 @@
|
||||
handleRedirectMessage(msg2, $rootScope, $window, frameworkEvents, toastService);
|
||||
}
|
||||
return $q.reject(error);
|
||||
},
|
||||
notFound: function() {
|
||||
$window.location.href = $window.WEBROOT + 'not_found';
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -149,4 +154,21 @@
|
||||
$window.location.replace($window.WEBROOT + 'auth/logout');
|
||||
}
|
||||
|
||||
registerNotFound.$inject = [
|
||||
'$routeProvider'
|
||||
];
|
||||
|
||||
/**
|
||||
* @name registerNotFound
|
||||
* @param {Object} $routeProvider
|
||||
* @description Routes to "not_found".
|
||||
* @returns {undefined} Returns nothing
|
||||
*/
|
||||
function registerNotFound($routeProvider) {
|
||||
// if identifier not specified for "ngdetails"
|
||||
$routeProvider.when('/ngdetails/:resourceType', {
|
||||
redirectTo: "/not_found"
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
controller.$inject = [
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.framework.redirect',
|
||||
'horizon.framework.util.actions.action-result.service',
|
||||
'horizon.framework.util.navigations.service',
|
||||
'horizon.framework.widgets.modal-wait-spinner.service',
|
||||
@ -32,6 +33,7 @@
|
||||
|
||||
function controller(
|
||||
registry,
|
||||
redirect,
|
||||
resultService,
|
||||
navigationsService,
|
||||
spinnerService,
|
||||
@ -41,13 +43,17 @@
|
||||
) {
|
||||
var ctrl = this;
|
||||
|
||||
if (!registry.resourceTypes[$routeParams.type]) {
|
||||
redirect.notFound();
|
||||
}
|
||||
ctrl.resourceType = registry.getResourceType($routeParams.type);
|
||||
ctrl.context = {};
|
||||
ctrl.context.identifier = ctrl.resourceType.parsePath($routeParams.path);
|
||||
ctrl.context.loadPromise = ctrl.resourceType.load(ctrl.context.identifier);
|
||||
ctrl.context.loadPromise.then(loadData);
|
||||
ctrl.context.loadPromise.then(loadData, loadDataError);
|
||||
ctrl.defaultTemplateUrl = registry.getDefaultDetailsTemplateUrl();
|
||||
ctrl.resultHandler = actionResultHandler;
|
||||
ctrl.pageNotFound = redirect.notFound;
|
||||
|
||||
checkRoutedByDjango(ctrl.resourceType);
|
||||
|
||||
@ -89,6 +95,12 @@
|
||||
ctrl.itemName = ctrl.resourceType.itemName(response.data);
|
||||
}
|
||||
|
||||
function loadDataError(error) {
|
||||
if (error.status === 404) {
|
||||
redirect.notFound();
|
||||
}
|
||||
}
|
||||
|
||||
function loadIndexView() {
|
||||
spinnerService.hideModalSpinner();
|
||||
ctrl.showDetails = false;
|
||||
|
@ -18,7 +18,7 @@
|
||||
'use strict';
|
||||
|
||||
describe('RoutedDetailsViewController', function() {
|
||||
var ctrl, deferred, $timeout, $q, actionResultService, navigationsService;
|
||||
var ctrl, deferred, $timeout, $q, service, redirect, actionResultService, navigationsService;
|
||||
|
||||
beforeEach(module('horizon.framework.widgets.details'));
|
||||
beforeEach(inject(function($injector, $controller, _$q_, _$timeout_) {
|
||||
@ -26,7 +26,8 @@
|
||||
deferred = $q.defer();
|
||||
$timeout = _$timeout_;
|
||||
|
||||
var service = {
|
||||
service = {
|
||||
resourceTypes: {'OS::Glance::Image': {}},
|
||||
getResourceType: function() {
|
||||
return {
|
||||
load: function() { return deferred.promise; },
|
||||
@ -39,6 +40,11 @@
|
||||
getDefaultDetailsTemplateUrl: angular.noop
|
||||
};
|
||||
|
||||
redirect = {
|
||||
responseError: angular.noop,
|
||||
notFound: angular.noop
|
||||
};
|
||||
|
||||
actionResultService = {
|
||||
getIdsOfType: function() { return []; }
|
||||
};
|
||||
@ -46,11 +52,14 @@
|
||||
navigationsService = {
|
||||
expandNavigationByUrl: function() { return ['Project', 'Compute', 'Images']; },
|
||||
setBreadcrumb: angular.noop,
|
||||
getActivePanelUrl: function() { return 'project/fancypanel'; }
|
||||
getActivePanelUrl: function() { return 'project/fancypanel'; },
|
||||
nav: true,
|
||||
isNavigationExists: function() { return navigationsService.nav; }
|
||||
};
|
||||
|
||||
ctrl = $controller("RoutedDetailsViewController", {
|
||||
'horizon.framework.conf.resource-type-registry.service': service,
|
||||
'horizon.framework.redirect': redirect,
|
||||
'horizon.framework.util.actions.action-result.service': actionResultService,
|
||||
'horizon.framework.util.navigations.service': navigationsService,
|
||||
'horizon.framework.widgets.modal-wait-spinner.service': {
|
||||
@ -62,8 +71,33 @@
|
||||
path: '1234'
|
||||
}
|
||||
});
|
||||
spyOn(redirect, 'notFound');
|
||||
}));
|
||||
|
||||
describe('RoutedDetailsViewController', function() {
|
||||
beforeEach(inject(function($controller) {
|
||||
service.resourceTypes = {};
|
||||
ctrl = $controller("RoutedDetailsViewController", {
|
||||
'horizon.framework.conf.resource-type-registry.service': service,
|
||||
'horizon.framework.redirect': redirect,
|
||||
'horizon.framework.util.actions.action-result.service': actionResultService,
|
||||
'horizon.framework.util.navigations.service': navigationsService,
|
||||
'horizon.framework.widgets.modal-wait-spinner.service': {
|
||||
showModalSpinner: angular.noop,
|
||||
hideModalSpinner: angular.noop
|
||||
},
|
||||
'$routeParams': {
|
||||
type: 'not exist',
|
||||
path: 'xxxx'
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
it('call redirect.notFound when resource type is not registered', function() {
|
||||
expect(redirect.notFound).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('sets resourceType', function() {
|
||||
expect(ctrl.resourceType).toBeDefined();
|
||||
});
|
||||
@ -79,6 +113,18 @@
|
||||
expect(ctrl.itemData).toEqual({some: 'data'});
|
||||
});
|
||||
|
||||
it('call redirect.notFound when item not found', function() {
|
||||
deferred.reject({status: 404});
|
||||
$timeout.flush();
|
||||
expect(redirect.notFound).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not call redirect.notFound when server error occurred', function() {
|
||||
deferred.reject({status: 500});
|
||||
$timeout.flush();
|
||||
expect(redirect.notFound).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('sets itemName when item loads', function() {
|
||||
deferred.resolve({data: {some: 'data'}});
|
||||
expect(ctrl.itemData).toBeUndefined();
|
||||
|
Loading…
Reference in New Issue
Block a user