Merge "Move to '404' page when resource type or resource not found"

This commit is contained in:
Zuul 2018-09-26 14:21:17 +00:00 committed by Gerrit Code Review
commit 872ae60c76
4 changed files with 89 additions and 8 deletions

View File

@ -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',

View File

@ -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"
});
}
})();

View File

@ -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;

View File

@ -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();