For HTTP POSTs, map JSON request bodies to controller keyword arguments.
Fixes-bug: 1336943 Change-Id: I2e59e5d43d87a5279c41b155188ebe3281de0e11
This commit is contained in:
@@ -14,6 +14,7 @@ import six
|
||||
|
||||
from webob import (Request as WebObRequest, Response as WebObResponse, exc,
|
||||
acceptparse)
|
||||
from webob.multidict import NestedMultiDict
|
||||
|
||||
from .compat import urlparse, unquote_plus, izip
|
||||
from .secure import handle_security
|
||||
@@ -499,6 +500,14 @@ class PecanBase(object):
|
||||
# fetch any parameters
|
||||
if req.method == 'GET':
|
||||
params = dict(req.GET)
|
||||
elif req.content_type in ('application/json',
|
||||
'application/javascript'):
|
||||
try:
|
||||
if not isinstance(req.json, dict):
|
||||
raise TypeError('%s is not a dict' % req.json)
|
||||
params = dict(NestedMultiDict(req.GET, req.json))
|
||||
except (TypeError, ValueError):
|
||||
params = dict(req.params)
|
||||
else:
|
||||
params = dict(req.params)
|
||||
|
||||
|
||||
@@ -440,6 +440,16 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('index: 4')
|
||||
|
||||
def test_explicit_json_kwargs(self):
|
||||
r = self.app_.post_json('/', {'id': '4'})
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('index: 4')
|
||||
|
||||
def test_path_with_explicit_json_kwargs(self):
|
||||
r = self.app_.post_json('/4', {'id': 'four'})
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('index: 4')
|
||||
|
||||
def test_multiple_kwargs(self):
|
||||
r = self.app_.get('/?id=5&dummy=dummy')
|
||||
assert r.status_int == 200
|
||||
@@ -450,6 +460,11 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('index: 6')
|
||||
|
||||
def test_json_kwargs_from_root(self):
|
||||
r = self.app_.post_json('/', {'id': '6', 'dummy': 'dummy'})
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('index: 6')
|
||||
|
||||
# multiple args
|
||||
|
||||
def test_multiple_positional_arguments(self):
|
||||
@@ -477,6 +492,11 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('multiple: five, six')
|
||||
|
||||
def test_positional_args_with_json_kwargs(self):
|
||||
r = self.app_.post_json('/multiple', {'one': 'five', 'two': 'six'})
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('multiple: five, six')
|
||||
|
||||
def test_positional_args_with_url_encoded_dictionary_kwargs(self):
|
||||
r = self.app_.post('/multiple', {'one': 'Five%20', 'two': 'Six%20%21'})
|
||||
assert r.status_int == 200
|
||||
@@ -527,6 +547,11 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('optional: 4')
|
||||
|
||||
def test_optional_arg_with_json_kwargs(self):
|
||||
r = self.app_.post_json('/optional', {'id': '4'})
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('optional: 4')
|
||||
|
||||
def test_optional_arg_with_url_encoded_kwargs(self):
|
||||
r = self.app_.post('/optional', {'id': 'Some%20Number'})
|
||||
assert r.status_int == 200
|
||||
@@ -537,6 +562,11 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('optional: 5')
|
||||
|
||||
def test_multiple_positional_arguments_with_json_kwargs(self):
|
||||
r = self.app_.post_json('/optional/5', {'id': 'five'})
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('optional: 5')
|
||||
|
||||
def test_multiple_positional_url_encoded_arguments_with_kwargs(self):
|
||||
r = self.app_.post('/optional/Some%20Number', {'id': 'five'})
|
||||
assert r.status_int == 200
|
||||
@@ -557,6 +587,11 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('optional: 7')
|
||||
|
||||
def test_optional_arg_with_multiple_json_kwargs(self):
|
||||
r = self.app_.post_json('/optional', {'id': '7', 'dummy': 'dummy'})
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('optional: 7')
|
||||
|
||||
def test_optional_arg_with_multiple_url_encoded_dictionary_kwargs(self):
|
||||
r = self.app_.post('/optional', {
|
||||
'id': 'Some%20Number',
|
||||
@@ -621,6 +656,11 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('multiple_optional: 1, None, None')
|
||||
|
||||
def test_multiple_optional_positional_args_with_json_kwargs(self):
|
||||
r = self.app_.post_json('/multiple_optional', {'one': '1'})
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('multiple_optional: 1, None, None')
|
||||
|
||||
def test_multiple_optional_positional_args_with_encoded_dict_kwargs(self):
|
||||
r = self.app_.post('/multiple_optional', {'one': 'One%21'})
|
||||
assert r.status_int == 200
|
||||
@@ -631,6 +671,11 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('multiple_optional: 1, None, None')
|
||||
|
||||
def test_multiple_optional_positional_args_and_json_kwargs(self):
|
||||
r = self.app_.post_json('/multiple_optional/1', {'one': 'one'})
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('multiple_optional: 1, None, None')
|
||||
|
||||
def test_multiple_optional_encoded_positional_args_and_dict_kwargs(self):
|
||||
r = self.app_.post('/multiple_optional/One%21', {'one': 'one'})
|
||||
assert r.status_int == 200
|
||||
@@ -656,6 +701,14 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('multiple_optional: 1, 2, 3')
|
||||
|
||||
def test_multiple_optional_args_with_multiple_json_kwargs(self):
|
||||
r = self.app_.post_json(
|
||||
'/multiple_optional',
|
||||
{'one': '1', 'two': '2', 'three': '3', 'four': '4'}
|
||||
)
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('multiple_optional: 1, 2, 3')
|
||||
|
||||
def test_multiple_optional_args_with_multiple_encoded_dict_kwargs(self):
|
||||
r = self.app_.post(
|
||||
'/multiple_optional',
|
||||
@@ -709,6 +762,14 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('variable_args: ')
|
||||
|
||||
def test_variable_args_with_json_kwargs(self):
|
||||
r = self.app_.post_json(
|
||||
'/variable_args',
|
||||
{'id': '3', 'dummy': 'dummy'}
|
||||
)
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('variable_args: ')
|
||||
|
||||
def test_variable_kwargs(self):
|
||||
r = self.app_.get('/variable_kwargs')
|
||||
assert r.status_int == 200
|
||||
@@ -735,6 +796,14 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('variable_kwargs: dummy=dummy, id=3')
|
||||
|
||||
def test_multiple_variable_kwargs_with_json_kwargs(self):
|
||||
r = self.app_.post_json(
|
||||
'/variable_kwargs',
|
||||
{'id': '3', 'dummy': 'dummy'}
|
||||
)
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('variable_kwargs: dummy=dummy, id=3')
|
||||
|
||||
def test_multiple_variable_kwargs_with_encoded_dict_kwargs(self):
|
||||
r = self.app_.post(
|
||||
'/variable_kwargs',
|
||||
@@ -779,6 +848,14 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('variable_all: 6, day=12, month=1')
|
||||
|
||||
def test_variable_post_with_json_kwargs(self):
|
||||
r = self.app_.post_json(
|
||||
'/variable_all/6',
|
||||
{'month': '1', 'day': '12'}
|
||||
)
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('variable_all: 6, day=12, month=1')
|
||||
|
||||
def test_variable_post_mixed(self):
|
||||
r = self.app_.post(
|
||||
'/variable_all/7',
|
||||
@@ -787,6 +864,14 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('variable_all: 7, day=12, id=seven, month=1')
|
||||
|
||||
def test_variable_post_mixed_with_json(self):
|
||||
r = self.app_.post_json(
|
||||
'/variable_all/7',
|
||||
{'id': 'seven', 'month': '1', 'day': '12'}
|
||||
)
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('variable_all: 7, day=12, id=seven, month=1')
|
||||
|
||||
def test_no_remainder(self):
|
||||
try:
|
||||
r = self.app_.get('/eater')
|
||||
@@ -843,6 +928,11 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('eater: 9, None, day=12, month=1')
|
||||
|
||||
def test_post_remainder_with_json_kwargs(self):
|
||||
r = self.app_.post_json('/eater/9', {'month': '1', 'day': '12'})
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('eater: 9, None, day=12, month=1')
|
||||
|
||||
def test_post_many_remainders_with_many_kwargs(self):
|
||||
r = self.app_.post(
|
||||
'/eater/10',
|
||||
@@ -851,6 +941,14 @@ class TestControllerArguments(PecanTestCase):
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('eater: 10, dummy, day=12, month=1')
|
||||
|
||||
def test_post_many_remainders_with_many_json_kwargs(self):
|
||||
r = self.app_.post_json(
|
||||
'/eater/10',
|
||||
{'id': 'ten', 'month': '1', 'day': '12', 'dummy': 'dummy'}
|
||||
)
|
||||
assert r.status_int == 200
|
||||
assert r.body == b_('eater: 10, dummy, day=12, month=1')
|
||||
|
||||
|
||||
class TestDefaultErrorRendering(PecanTestCase):
|
||||
|
||||
|
||||
Reference in New Issue
Block a user