mirror of https://github.com/zulip/zulip.git
request: Add new str_validator validator type.
This is helpful for cases where an argument is supposed to be a normal string, and we want to use a Zulip validator function to do basic things like check its length.
This commit is contained in:
parent
f2e84f25a0
commit
51517fa188
|
@ -50,6 +50,7 @@ class REQ:
|
|||
|
||||
def __init__(self, whence: str=None, *, converter: Callable[[Any], Any]=None,
|
||||
default: Any=NotSpecified, validator: Callable[[Any], Any]=None,
|
||||
str_validator: Callable[[Any], Any]=None,
|
||||
argument_type: str=None, type: Type=None) -> None:
|
||||
"""whence: the name of the request variable that should be used
|
||||
for this parameter. Defaults to a request variable of the
|
||||
|
@ -66,6 +67,8 @@ class REQ:
|
|||
data structure. If specified, we will parse the JSON request
|
||||
variable value before passing to the function
|
||||
|
||||
str_validator: Like validator, but doesn't parse JSON first.
|
||||
|
||||
argument_type: pass 'body' to extract the parsed JSON
|
||||
corresponding to the request body
|
||||
|
||||
|
@ -78,12 +81,16 @@ class REQ:
|
|||
self.func_var_name = None # type: str
|
||||
self.converter = converter
|
||||
self.validator = validator
|
||||
self.str_validator = str_validator
|
||||
self.default = default
|
||||
self.argument_type = argument_type
|
||||
|
||||
if converter and validator:
|
||||
if converter and (validator or str_validator):
|
||||
# Not user-facing, so shouldn't be tagged for translation
|
||||
raise AssertionError('converter and validator are mutually exclusive')
|
||||
if validator and str_validator:
|
||||
# Not user-facing, so shouldn't be tagged for translation
|
||||
raise AssertionError('validator and str_validator are mutually exclusive')
|
||||
|
||||
# Extracts variables from the request object and passes them as
|
||||
# named function arguments. The request object must be the first
|
||||
|
@ -169,6 +176,12 @@ def has_request_variables(view_func):
|
|||
if error:
|
||||
raise JsonableError(error)
|
||||
|
||||
# str_validators is like validator, but for direct strings (no JSON parsing).
|
||||
if param.str_validator is not None and not default_assigned:
|
||||
error = param.str_validator(param.post_var_name, val)
|
||||
if error:
|
||||
raise JsonableError(error)
|
||||
|
||||
kwargs[param.func_var_name] = val
|
||||
|
||||
return view_func(request, *args, **kwargs)
|
||||
|
|
|
@ -25,6 +25,7 @@ def REQ(whence: Optional[str] = None,
|
|||
converter: Optional[Callable[[str], ResultT]] = None,
|
||||
default: Union[_NotSpecified, ResultT] = NotSpecified,
|
||||
validator: Optional[Validator] = None,
|
||||
str_validator: Optional[Validator] = None,
|
||||
argument_type: Optional[str] = None) -> ResultT: ...
|
||||
|
||||
def has_request_variables(view_func: ViewFuncT) -> ViewFuncT: ...
|
||||
|
|
|
@ -181,6 +181,31 @@ class DecoratorTestCase(TestCase):
|
|||
result = get_total(request)
|
||||
self.assertEqual(result, 21)
|
||||
|
||||
def test_REQ_str_validator(self) -> None:
|
||||
|
||||
@has_request_variables
|
||||
def get_middle_characters(request: HttpRequest,
|
||||
value: str=REQ(str_validator=check_string_fixed_length(5))) -> str:
|
||||
return value[1:-1]
|
||||
|
||||
class Request:
|
||||
GET = {} # type: Dict[str, str]
|
||||
POST = {} # type: Dict[str, str]
|
||||
|
||||
request = Request()
|
||||
|
||||
with self.assertRaises(RequestVariableMissingError):
|
||||
get_middle_characters(request)
|
||||
|
||||
request.POST['value'] = 'long_value'
|
||||
with self.assertRaises(JsonableError) as cm:
|
||||
get_middle_characters(request)
|
||||
self.assertEqual(str(cm.exception), 'value has incorrect length 10; should be 5')
|
||||
|
||||
request.POST['value'] = 'valid'
|
||||
result = get_middle_characters(request)
|
||||
self.assertEqual(result, 'ali')
|
||||
|
||||
def test_REQ_argument_type(self) -> None:
|
||||
@has_request_variables
|
||||
def get_payload(request: HttpRequest,
|
||||
|
|
Loading…
Reference in New Issue