Move to '404' page when resource type or resource not found
When refresh or link directly to ngdetails without existing resource type or ID for the resource, ngdetails view shows blank view. This patch jump to 404 page in this situation. Change-Id: Ie95132d0fdb1e7aae5e32faad752f92ff76b238a Closes-Bug: #1746709
This commit is contained in:
parent
841bce0623
commit
58af806796
@ -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…
x
Reference in New Issue
Block a user