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