Projet

Général

Profil

0001-wscalls-implement-PUT-PATCH-and-DELETE-verbs-12416.patch

Frédéric Péters, 31 août 2018 09:02

Télécharger (8,33 ko)

Voir les différences:

Subject: [PATCH] wscalls: implement PUT, PATCH and DELETE verbs (#12416)

 tests/test_workflows.py | 39 +++++++++++++++++++++++++++++++++++++--
 tests/test_wscall.py    | 32 +++++++++++++++++++++++++++++++-
 wcs/wf/wscall.py        | 10 ++++++++--
 wcs/wscalls.py          | 21 +++++++++++++++------
 4 files changed, 91 insertions(+), 11 deletions(-)
tests/test_workflows.py
1482 1482
    assert qs['ezt'] == [formdata.get_display_id()]
1483 1483
    assert qs['str'] == ['abcd']
1484 1484

  
1485
    item = WebserviceCallStatusItem()
1486
    item.method = 'DELETE'
1487
    item.post = False
1488
    item.url = 'http://remote.example.net/json'
1489
    pub.substitutions.feed(formdata)
1490
    item.perform(formdata)
1491
    assert http_requests.get_last('method') == 'DELETE'
1492

  
1493
    item = WebserviceCallStatusItem()
1494
    item.url = 'http://remote.example.net'
1495
    item.method = 'PUT'
1496
    item.post = False
1497
    item.post_data = {'str': 'abcd', 'one': '=1',
1498
            'evalme': '=form_number', 'error':'=1=3'}
1499
    pub.substitutions.feed(formdata)
1500
    item.perform(formdata)
1501
    assert http_requests.get_last('url') == 'http://remote.example.net'
1502
    assert http_requests.get_last('method') == 'PUT'
1503
    payload = json.loads(http_requests.get_last('body'))
1504
    assert payload == {'one': 1, 'str': 'abcd', 'evalme': formdata.get_display_id()}
1505

  
1506
    item = WebserviceCallStatusItem()
1507
    item.url = 'http://remote.example.net'
1508
    item.method = 'PATCH'
1509
    item.post = False
1510
    item.post_data = {'str': 'abcd', 'one': '=1',
1511
            'evalme': '=form_number', 'error':'=1=3'}
1512
    pub.substitutions.feed(formdata)
1513
    item.perform(formdata)
1514
    assert http_requests.get_last('url') == 'http://remote.example.net'
1515
    assert http_requests.get_last('method') == 'PATCH'
1516
    payload = json.loads(http_requests.get_last('body'))
1517
    assert payload == {'one': 1, 'str': 'abcd', 'evalme': formdata.get_display_id()}
1518

  
1485 1519
def test_webservice_waitpoint(pub):
1486 1520
    item = WebserviceCallStatusItem()
1487 1521
    assert item.waitpoint
......
1994 2028
    item.body = 'my message'
1995 2029
    with mock.patch('wcs.wscalls.get_secret_and_orig') as mocked_secret_and_orig:
1996 2030
        mocked_secret_and_orig.return_value = ('secret', 'localhost')
1997
        with mock.patch('qommon.misc.http_post_request') as mocked_http_post:
2031
        with mock.patch('qommon.misc._http_request') as mocked_http_post:
1998 2032
            mocked_http_post.return_value = ('response', '200', 'data', 'headers')
1999 2033
            item.perform(formdata)
2000
            url, payload = mocked_http_post.call_args[0]
2034
            url = mocked_http_post.call_args[0][0]
2035
            payload = mocked_http_post.call_args[1]['body']
2001 2036
            assert 'http://passerelle.example.com' in url
2002 2037
            assert '?nostop=1' in url
2003 2038
            assert 'orig=localhost' in url
tests/test_wscall.py
1 1
import json
2
import mock
3 2
import pytest
4 3
from StringIO import StringIO
5 4

  
......
19 18
    pub.load_site_options()
20 19
    return pub
21 20

  
21

  
22 22
def teardown_module(module):
23 23
    clean_temporary_pub()
24 24

  
......
135 135
    assert template.render(variables) == '<p></p>'
136 136
    template = Template('<p>[webservice.hello.foo]</p>')
137 137
    assert template.render(variables) == '<p>[webservice.hello.foo]</p>'
138

  
139
def test_webservice_post_put_patch(http_requests, pub):
140
    NamedWsCall.wipe()
141

  
142
    for method in ('POST', 'PUT', 'PATCH'):
143
        wscall = NamedWsCall()
144
        wscall.name = 'Hello world'
145
        wscall.request = {'method': 'PUT', 'post_data': {'toto': 'coin'},
146
                          'url': 'http://remote.example.net/json'}
147
        try:
148
            wscall.call()
149
        except:
150
            pass
151
        assert http_requests.get_last('url') == wscall.request['url']
152
        assert http_requests.get_last('method') == wscall.request['method']
153
        assert json.loads(http_requests.get_last('body')) == wscall.request['post_data']
154

  
155
def test_webservice_delete(http_requests, pub):
156
    NamedWsCall.wipe()
157

  
158
    wscall = NamedWsCall()
159
    wscall.name = 'Hello world'
160
    wscall.request = {'method': 'DELETE', 'post_data': {'toto': 'coin'},
161
                      'url': 'http://remote.example.net/json'}
162
    try:
163
        wscall.call()
164
    except:
165
        pass
166
    assert http_requests.get_last('url') == wscall.request['url']
167
    assert http_requests.get_last('method') == 'DELETE'
wcs/wf/wscall.py
127 127

  
128 128
    @property
129 129
    def method(self):
130
        if self._method in ('GET', 'POST'):
130
        if self._method in ('GET', 'POST', 'PUT', 'PATCH', 'DELETE'):
131 131
            return self._method
132 132
        if self.post or self.post_data:
133 133
            return 'POST'
......
174 174
                    value=self.qs_data or {},
175 175
                    element_value_type=ComputedExpressionWidget)
176 176
        methods = collections.OrderedDict(
177
                [('GET', _('GET')), ('POST', _('POST (JSON)'))])
177
            [
178
                ('GET', _('GET')),
179
                ('POST', _('POST (JSON)')),
180
                ('PUT', _('PUT (JSON)')),
181
                ('PATCH', _('PATCH (JSON)')),
182
                ('DELETE', _('DELETE')),
183
            ])
178 184
        if 'method' in parameters:
179 185
            form.add(RadiobuttonsWidget, '%smethod' % prefix,
180 186
                    title=_('Method'),
wcs/wscalls.py
86 86
    payload = None
87 87

  
88 88
    # if post_data exists, payload is a dict built from it
89
    if method == 'POST' and post_data:
89
    if method in ('PATCH', 'PUT', 'POST') and post_data:
90 90
        payload = {}
91 91
        for (key, value) in post_data.items():
92 92
            try:
......
96 96

  
97 97
    # if formdata has to be sent, it's the payload. If post_data exists,
98 98
    # it's added in formdata['extra']
99
    if method == 'POST' and post_formdata:
99
    if method in ('PATCH', 'PUT', 'POST') and post_formdata:
100 100
        if formdata:
101 101
            formdata_dict = formdata.get_json_export_dict()
102 102
            if payload is not None:
103 103
                formdata_dict['extra'] = payload
104 104
            payload = formdata_dict
105 105

  
106
    if method == 'POST':
106
    if method in ('PATCH', 'PUT', 'POST'):
107 107
        if payload:
108 108
            headers['Content-type'] = 'application/json'
109 109
            payload = json.dumps(payload, cls=JSONEncoder,
110 110
                    encoding=get_publisher().site_charset)
111
        response, status, data, auth_header = qommon.misc.http_post_request(
112
                url, payload, headers=headers)
111
        response, status, data, auth_header = qommon.misc._http_request(
112
                url, method=method, body=payload, headers=headers)
113
    elif method == 'DELETE':
114
        response, status, data, auth_header = qommon.misc._http_request(
115
            url, method='DELETE', headers=headers)
113 116
    else:
114 117
        response, status, data, auth_header = qommon.misc.http_get_page(
115 118
                url, headers=headers)
......
223 226
                value=value.get('qs_data') or {},
224 227
                element_value_type=ComputedExpressionWidget)
225 228
        methods = collections.OrderedDict(
226
                [('GET', _('GET')), ('POST', _('POST (JSON)'))])
229
            [
230
                ('GET', _('GET')),
231
                ('POST', _('POST (JSON)')),
232
                ('PUT', _('PUT (JSON)')),
233
                ('PATCH', _('PATCH (JSON)')),
234
                ('DELETE', _('DELETE')),
235
            ])
227 236
        self.add(RadiobuttonsWidget, 'method',
228 237
                title=_('Method'),
229 238
                options=methods.items(),
230
-