Skip to content

Commit

Permalink
feat($state): add state params validation Closes #1433
Browse files Browse the repository at this point in the history
feat($urlMatcherFactory): add function to get a RegExp Type
  • Loading branch information
christopherthielen committed Oct 20, 2014
1 parent 3f60fbe commit b1379e6
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -778,6 +778,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
}
if (toState[abstractKey]) throw new Error("Cannot transition to abstract state '" + to + "'");
if (options.inherit) toParams = inheritParams($stateParams, toParams || {}, $state.$current, toState);
if (!toState.params.$$validates(toParams)) return TransitionFailed;

var defaultParams = toState.params.$$values();
toParams = extend(defaultParams, toParams);
to = toState;
Expand Down
10 changes: 9 additions & 1 deletion src/urlMatcherFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ function UrlMatcher(pattern, config) {
return result + flag + '(' + pattern + ')' + flag;
}

function regexpType(regexp) {
var type = new Type({
pattern: new RegExp(regexp),
is: function(value) { return type.pattern.exec(type.encode(value)); }
});
return type;
}

this.source = pattern;

// Split into static segments separated by path parameter placeholders.
Expand All @@ -104,7 +112,7 @@ function UrlMatcher(pattern, config) {
id = m[2] || m[3]; // IE[78] returns '' for unmatched groups instead of null
regexp = m[4] || (m[1] == '*' ? '.*' : '[^/]*');
segment = pattern.substring(last, m.index);
type = this.$types[regexp] || new Type({ pattern: new RegExp(regexp) });
type = this.$types[regexp] || regexpType(regexp);
cfg = config.params[id];

if (segment.indexOf('?') >= 0) break; // we're into the search part
Expand Down
27 changes: 27 additions & 0 deletions test/stateSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ describe('state', function () {
.state('badParam', {
url: "/bad/{param:int}"
})
.state('badParam2', {
url: "/bad2/{param:[0-9]{5}}"
})

.state('first', { url: '^/first/subpath' })
.state('second', { url: '^/second' })
Expand Down Expand Up @@ -755,6 +758,7 @@ describe('state', function () {
'about.sidebar',
'about.sidebar.item',
'badParam',
'badParam2',
'dynamicController',
'first',
'home',
Expand Down Expand Up @@ -875,6 +879,29 @@ describe('state', function () {
$rootScope.$apply();
expect($state.current.name).toBe("about");
}));

it('should ignore bad state parameters', inject(function ($state, $rootScope, $location, $stateParams) {
$state.go("badParam", { param: 5 });
$rootScope.$apply();
expect($state.current.name).toBe("badParam");
expect($stateParams).toEqual({param: 5});

$state.go("badParam2", { param: '12345' }); // must be 5 digits
$rootScope.$apply();
expect($state.current.name).toBe("badParam2");

$state.go("about");
$rootScope.$apply();
expect($state.current.name).toBe('about');

$state.go("badParam", { param: 'foo' });
$rootScope.$apply();
expect($state.current.name).toBe("about");

$state.go("badParam2", { param: '1234' }); // must be 5 digits
$rootScope.$apply();
expect($state.current.name).toBe("about");
}));
});

it('should revert to last known working url on state change failure', inject(function ($state, $rootScope, $location, $q) {
Expand Down

0 comments on commit b1379e6

Please sign in to comment.