feat(Request): Add optional min, max arguments to req.get_param_as_int

This patch makes it easy to validate integer parameters.

Closes #103
This commit is contained in:
kgriffs
2013-04-04 00:19:06 -04:00
parent 1917f70d44
commit d85cfc0b59
2 changed files with 91 additions and 3 deletions

View File

@@ -355,7 +355,7 @@ class Request(object):
description = 'The "' + name + '" query parameter is required.'
raise HTTPBadRequest('Missing query parameter', description)
def get_param_as_int(self, name, required=False):
def get_param_as_int(self, name, required=False, min=None, max=None):
"""Return the value of a query string parameter as an int
Args:
@@ -363,6 +363,11 @@ class Request(object):
required: Set to True to raise HTTPBadRequest instead of returning
gracefully when the parameter is not found or is not an
integer (default False)
min: Set to the minimum value allowed for this param. If the param
is found and it is less than min, an HTTPError is raised.
max: Set to the maximum value allowed for this param. If the param
is found and its value is greater than max, an HTTPError is
raised.
Returns:
The value of the param if it is found and can be converted to an
@@ -371,7 +376,9 @@ class Request(object):
Raises
HTTPBadRequest: The param was not found in the request, even though
it was required to be there.
it was required to be there. Also raised if the param's value
falls outside the given interval, i.e., the value must be in
the interval: min <= value <= max to avoid triggering an error.
"""
@@ -380,12 +387,24 @@ class Request(object):
if name in self._params:
val = self._params[name]
try:
return int(val)
val = int(val)
except ValueError:
description = ('The value of the "' + name + '" query '
'parameter must be an integer.')
raise InvalidParamValueError(description)
if min is not None and val < min:
description = ('The value of the "' + name + '" query '
'parameter must be at least %d') % min
raise InvalidHeaderValueError(description)
if max is not None and max < val:
description = ('The value of the "' + name + '" query '
'parameter may not exceed %d') % max
raise InvalidHeaderValueError(description)
return val
if not required:
return None

View File

@@ -71,6 +71,75 @@ class TestQueryParams(testing.TestBase):
'marker')
self.assertEquals(req.get_param_as_int('limit'), 25)
self.assertEquals(
req.get_param_as_int('limit', min=1, max=50), 25)
self.assertRaises(
falcon.HTTPBadRequest,
req.get_param_as_int, 'limit', min=0, max=10)
self.assertRaises(
falcon.HTTPBadRequest,
req.get_param_as_int, 'limit', min=0, max=24)
self.assertRaises(
falcon.HTTPBadRequest,
req.get_param_as_int, 'limit', min=30, max=24)
self.assertRaises(
falcon.HTTPBadRequest,
req.get_param_as_int, 'limit', min=30, max=50)
self.assertEquals(
req.get_param_as_int('limit', min=1), 25)
self.assertEquals(
req.get_param_as_int('limit', max=50), 25)
self.assertEquals(
req.get_param_as_int('limit', max=25), 25)
self.assertEquals(
req.get_param_as_int('limit', max=26), 25)
self.assertEquals(
req.get_param_as_int('limit', min=25), 25)
self.assertEquals(
req.get_param_as_int('limit', min=24), 25)
self.assertEquals(
req.get_param_as_int('limit', min=-24), 25)
def test_int_neg(self):
query_string = 'marker=deadbeef&pos=-7'
self.simulate_request('/', query_string=query_string)
req = self.resource.req
self.assertEquals(req.get_param_as_int('pos'), -7)
self.assertEquals(
req.get_param_as_int('pos', min=-10, max=10), -7)
self.assertEquals(
req.get_param_as_int('pos', max=10), -7)
self.assertRaises(
falcon.HTTPBadRequest,
req.get_param_as_int, 'pos', min=-6, max=0)
self.assertRaises(
falcon.HTTPBadRequest,
req.get_param_as_int, 'pos', min=-6)
self.assertRaises(
falcon.HTTPBadRequest,
req.get_param_as_int, 'pos', min=0, max=10)
self.assertRaises(
falcon.HTTPBadRequest,
req.get_param_as_int, 'pos', min=0, max=10)
def test_boolean(self):
query_string = 'echo=true&doit=false&bogus=0&bogus2=1'
self.simulate_request('/', query_string=query_string)