Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 510404e

Browse files
susisugkalpak
authored andcommitted
fix($route): correctly extract path params if path contains question mark or hash
The `routeToRegExp()` function, introduced by 840b5f0, could not extract path params if the path contained question mark or hash. Although these characters would normally be encoded in the path, they are decoded by `$location.path()`, before being passed to the RegExp returned by `routeToRegExp()`. `routeToRegExp()` has to be able to deal with both encoded URL and decoded path, because it is being shared between `ngRoute` and `ngMocks`. This commit fixes the issue, by introducing an `isUrl` option that allows creating an appropriate RegExp for each usecase.
1 parent 937fb89 commit 510404e

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed

src/ngMock/angular-mocks.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -1771,7 +1771,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
17711771
* See {@link ngMock.$httpBackend#when `when`} for more info.
17721772
*/
17731773
$httpBackend.whenRoute = function(method, url) {
1774-
var pathObj = routeToRegExp(url, {caseInsensitiveMatch: true, ignoreTrailingSlashes: true});
1774+
var pathObj = routeToRegExp(url, {caseInsensitiveMatch: true, ignoreTrailingSlashes: true, isUrl: true});
17751775
return $httpBackend.when(method, pathObj.regexp, undefined, undefined, pathObj.keys);
17761776
};
17771777

@@ -1955,7 +1955,7 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
19551955
* See {@link ngMock.$httpBackend#expect `expect`} for more info.
19561956
*/
19571957
$httpBackend.expectRoute = function(method, url) {
1958-
var pathObj = routeToRegExp(url, {caseInsensitiveMatch: true, ignoreTrailingSlashes: true});
1958+
var pathObj = routeToRegExp(url, {caseInsensitiveMatch: true, ignoreTrailingSlashes: true, isUrl: true});
19591959
return $httpBackend.expect(method, pathObj.regexp, undefined, undefined, pathObj.keys);
19601960
};
19611961

src/routeToRegExp.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
/* global routeToRegExp: true */
44

55
/**
6-
* @param path {string} path
6+
* @param pathOrUrl {string} path or url
77
* @param opts {Object} options
88
* @return {?Object}
99
*
@@ -13,10 +13,10 @@
1313
*
1414
* Inspired by pathRexp in visionmedia/express/lib/utils.js.
1515
*/
16-
function routeToRegExp(path, opts) {
16+
function routeToRegExp(pathOrUrl, opts) {
1717
var keys = [];
1818

19-
var pattern = path
19+
var pattern = pathOrUrl
2020
.replace(/([().])/g, '\\$1')
2121
.replace(/(\/)?:(\w+)(\*\?|[?*])?/g, function(_, slash, key, option) {
2222
var optional = option === '?' || option === '*?';
@@ -25,7 +25,7 @@ function routeToRegExp(path, opts) {
2525
slash = slash || '';
2626
return (
2727
(optional ? '(?:' + slash : slash + '(?:') +
28-
(star ? '([^?#]+?)' : '([^/?#]+)') +
28+
(opts.isUrl ? (star ? '([^?#]+?)' : '([^/?#]+)') : (star ? '(.+?)' : '([^/]+)')) +
2929
(optional ? '?)?' : ')')
3030
);
3131
})
@@ -36,7 +36,7 @@ function routeToRegExp(path, opts) {
3636
}
3737

3838
return {
39-
originalPath: path,
39+
originalPath: pathOrUrl,
4040
keys: keys,
4141
regexp: new RegExp(
4242
'^' + pattern + '(?:[?#]|$)',

test/ngRoute/routeParamsSpec.js

+40
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,45 @@ describe('$routeParams', function() {
7777
});
7878
});
7979

80+
it('should correctly extract path params containing hashes and/or question marks', function() {
81+
module(function($routeProvider) {
82+
$routeProvider.when('/foo/:bar', {});
83+
$routeProvider.when('/zoo/:bar/:baz/:qux', {});
84+
});
85+
86+
inject(function($location, $rootScope, $routeParams) {
87+
$location.path('/foo/bar?baz');
88+
$rootScope.$digest();
89+
expect($routeParams).toEqual({bar: 'bar?baz'});
90+
91+
$location.path('/foo/bar?baz=val');
92+
$rootScope.$digest();
93+
expect($routeParams).toEqual({bar: 'bar?baz=val'});
94+
95+
$location.path('/foo/bar#baz');
96+
$rootScope.$digest();
97+
expect($routeParams).toEqual({bar: 'bar#baz'});
98+
99+
$location.path('/foo/bar?baz#qux');
100+
$rootScope.$digest();
101+
expect($routeParams).toEqual({bar: 'bar?baz#qux'});
102+
103+
$location.path('/foo/bar?baz=val#qux');
104+
$rootScope.$digest();
105+
expect($routeParams).toEqual({bar: 'bar?baz=val#qux'});
106+
107+
$location.path('/foo/bar#baz?qux');
108+
$rootScope.$digest();
109+
expect($routeParams).toEqual({bar: 'bar#baz?qux'});
110+
111+
$location.path('/zoo/bar?p1=v1#h1/baz?p2=v2#h2/qux?p3=v3#h3');
112+
$rootScope.$digest();
113+
expect($routeParams).toEqual({
114+
bar: 'bar?p1=v1#h1',
115+
baz: 'baz?p2=v2#h2',
116+
qux: 'qux?p3=v3#h3'
117+
});
118+
});
119+
});
80120

81121
});

0 commit comments

Comments
 (0)