0001-wscalls-implement-PUT-PATCH-and-DELETE-verbs-12416.patch
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 |
- |