Skip to content
This repository was archived by the owner on Aug 30, 2021. It is now read-only.

Commit 09697f8

Browse files
committed
Merge pull request #1238 from mleanos/fix/ui-router-trailing-slash
fix(core): Remove trailing slash from routes
2 parents 8f00edc + b004986 commit 09697f8

7 files changed

Lines changed: 530 additions & 2 deletions

File tree

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(function (app) {
22
'use strict';
33

4-
app.registerModule('articles');
4+
app.registerModule('articles', ['core']);// The core module is required for special route handling; see /core/client/config/core.client.routes
55
app.registerModule('articles.services');
66
app.registerModule('articles.routes', ['ui.router', 'articles.services']);
77
})(ApplicationConfiguration);

modules/articles/tests/client/articles.client.routes.tests.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,25 @@
3838
});
3939
});
4040

41+
describe('List Route', function () {
42+
var liststate;
43+
beforeEach(inject(function ($state) {
44+
liststate = $state.get('articles.list');
45+
}));
46+
47+
it('Should have the correct URL', function () {
48+
expect(liststate.url).toEqual('');
49+
});
50+
51+
it('Should not be abstract', function () {
52+
expect(liststate.abstract).toBe(undefined);
53+
});
54+
55+
it('Should have template', function () {
56+
expect(liststate.templateUrl).toBe('modules/articles/client/views/list-articles.client.view.html');
57+
});
58+
});
59+
4160
describe('View Route', function () {
4261
var viewstate,
4362
ArticlesController,
@@ -190,6 +209,21 @@
190209
});
191210
});
192211

212+
describe('Handle Trailing Slash', function () {
213+
beforeEach(inject(function ($state, $rootScope) {
214+
$state.go('articles.list');
215+
$rootScope.$digest();
216+
}));
217+
218+
it('Should remove trailing slash', inject(function ($state, $location, $rootScope) {
219+
$location.path('articles/');
220+
$rootScope.$digest();
221+
222+
expect($location.path()).toBe('/articles');
223+
expect($state.current.templateUrl).toBe('modules/articles/client/views/list-articles.client.view.html');
224+
}));
225+
});
226+
193227
});
194228
});
195229
})();
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
(function (app) {
22
'use strict';
33

4-
app.registerModule('chat');
4+
app.registerModule('chat', ['core']);
55
app.registerModule('chat.routes', ['ui.router']);
66
})(ApplicationConfiguration);
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
(function () {
2+
'use strict';
3+
4+
describe('Chat Route Tests', function () {
5+
// Initialize global variables
6+
var $scope,
7+
Authentication;
8+
9+
//We can start by loading the main application module
10+
beforeEach(module(ApplicationConfiguration.applicationModuleName));
11+
12+
// The injector ignores leading and trailing underscores here (i.e. _$httpBackend_).
13+
// This allows us to inject a service but then attach it to a variable
14+
// with the same name as the service.
15+
beforeEach(inject(function ($rootScope, _Authentication_) {
16+
// Set a new global scope
17+
$scope = $rootScope.$new();
18+
Authentication = _Authentication_;
19+
}));
20+
21+
describe('Route Config', function () {
22+
describe('Main Route', function () {
23+
var mainstate;
24+
beforeEach(inject(function ($state) {
25+
mainstate = $state.get('chat');
26+
}));
27+
28+
it('Should have the correct URL', function () {
29+
expect(mainstate.url).toEqual('/chat');
30+
});
31+
32+
it('Should not be abstract', function () {
33+
expect(mainstate.abstract).toBe(undefined);
34+
});
35+
36+
it('Should have templateUrl', function () {
37+
expect(mainstate.templateUrl).toBe('modules/chat/client/views/chat.client.view.html');
38+
});
39+
});
40+
41+
describe('Handle Trailing Slash', function () {
42+
beforeEach(inject(function ($state, $rootScope, _Authentication_) {
43+
Authentication.user = {
44+
name: 'user',
45+
roles: ['user']
46+
};
47+
48+
$state.go('chat');
49+
$rootScope.$digest();
50+
}));
51+
52+
it('Should remove trailing slash', inject(function ($state, $location, $rootScope) {
53+
$location.path('chat/');
54+
$rootScope.$digest();
55+
56+
expect($location.path()).toBe('/chat');
57+
expect($state.current.templateUrl).toBe('modules/chat/client/views/chat.client.view.html');
58+
}));
59+
});
60+
61+
});
62+
});
63+
})();

modules/core/client/config/core.client.routes.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@
44
angular.module('core').config(['$stateProvider', '$urlRouterProvider',
55
function ($stateProvider, $urlRouterProvider) {
66

7+
$urlRouterProvider.rule(function ($injector, $location) {
8+
var path = $location.path();
9+
var hasTrailingSlash = path.length > 1 && path[path.length - 1] === '/';
10+
11+
if (hasTrailingSlash) {
12+
//if last character is a slash, return the same url without the slash
13+
var newPath = path.substr(0, path.length - 1);
14+
$location.replace().path(newPath);
15+
}
16+
});
17+
718
// Redirect to 404 when route not found
819
$urlRouterProvider.otherwise(function ($injector, $location) {
920
$injector.get('$state').transitionTo('not-found', null, {
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
(function () {
2+
'use strict';
3+
4+
describe('Users Admin Route Tests', function () {
5+
// Initialize global variables
6+
var $scope,
7+
Authentication;
8+
9+
//We can start by loading the main application module
10+
beforeEach(module(ApplicationConfiguration.applicationModuleName));
11+
12+
// The injector ignores leading and trailing underscores here (i.e. _$httpBackend_).
13+
// This allows us to inject a service but then attach it to a variable
14+
// with the same name as the service.
15+
beforeEach(inject(function ($rootScope, _Authentication_) {
16+
// Set a new global scope
17+
$scope = $rootScope.$new();
18+
Authentication = _Authentication_;
19+
}));
20+
21+
describe('Route Config', function () {
22+
describe('Main Route', function () {
23+
var mainstate;
24+
beforeEach(inject(function ($state) {
25+
mainstate = $state.get('admin.users');
26+
}));
27+
28+
it('Should have the correct URL', function () {
29+
expect(mainstate.url).toEqual('/users');
30+
});
31+
32+
it('Should not be abstract', function () {
33+
expect(mainstate.abstract).toBe(undefined);
34+
});
35+
36+
it('Should have templateUrl', function () {
37+
expect(mainstate.templateUrl).toBe('modules/users/client/views/admin/list-users.client.view.html');
38+
});
39+
});
40+
41+
describe('View Route', function () {
42+
var viewstate;
43+
beforeEach(inject(function ($state) {
44+
viewstate = $state.get('admin.user');
45+
}));
46+
47+
it('Should have the correct URL', function () {
48+
expect(viewstate.url).toEqual('/users/:userId');
49+
});
50+
51+
it('Should not be abstract', function () {
52+
expect(viewstate.abstract).toBe(undefined);
53+
});
54+
55+
it('Should have templateUrl', function () {
56+
expect(viewstate.templateUrl).toBe('modules/users/client/views/admin/view-user.client.view.html');
57+
});
58+
});
59+
60+
describe('Edit Route', function () {
61+
var editstate;
62+
beforeEach(inject(function ($state) {
63+
editstate = $state.get('admin.user-edit');
64+
}));
65+
66+
it('Should have the correct URL', function () {
67+
expect(editstate.url).toEqual('/users/:userId/edit');
68+
});
69+
70+
it('Should not be abstract', function () {
71+
expect(editstate.abstract).toBe(undefined);
72+
});
73+
74+
it('Should have templateUrl', function () {
75+
expect(editstate.templateUrl).toBe('modules/users/client/views/admin/edit-user.client.view.html');
76+
});
77+
});
78+
79+
describe('Handle Trailing Slash', function () {
80+
beforeEach(inject(function ($state, $rootScope, _Authentication_) {
81+
Authentication.user = {
82+
name: 'user',
83+
roles: ['admin']
84+
};
85+
86+
$state.go('admin.users');
87+
$rootScope.$digest();
88+
}));
89+
90+
it('Should remove trailing slash', inject(function ($state, $location, $rootScope) {
91+
$location.path('admin/users/');
92+
$rootScope.$digest();
93+
94+
expect($location.path()).toBe('/admin/users');
95+
expect($state.current.templateUrl).toBe('modules/users/client/views/admin/list-users.client.view.html');
96+
}));
97+
});
98+
99+
});
100+
});
101+
})();

0 commit comments

Comments
 (0)