wscall: add parameters to add elements to query string (#11207)
This commit is contained in:
parent
0f4809b388
commit
fe688437e0
|
@ -28,6 +28,15 @@ par exemple transmettre une information particulière.
|
|||
<code>https://www.example.net/notify?email=[session_user_email]</code>
|
||||
</example>
|
||||
|
||||
<p>
|
||||
Le tableau « Données à envoyer en paramètre » permet de décrire des données qui
|
||||
seront transmises sous la forme de paramètres d'URL. Sur chaque ligne, la
|
||||
colonne de gauche est le nom de la clé, celle de droite la valeur. La valeur
|
||||
peut être une expression Python, pour cela elle doit commencer par le signe
|
||||
« = ». Les paramètres d'URL ne peuvent être que des chaînes, si ce n'est pas le
|
||||
cas la donnée sera transformée en chaîne de force.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
La case à cocher « Envoyer le formulaire (POST, en JSON) » indique que
|
||||
l'ensemble des données du formulaire doivent être transmises, avec un appel de
|
||||
|
|
|
@ -308,6 +308,7 @@ def test_wscall_action():
|
|||
wscall.post = False
|
||||
wscall.request_signature_key = 'key'
|
||||
wscall.post_data = {'one': '1', 'two': '=2', 'good:name': 'ok'}
|
||||
wscall.qs_data = {'one': '2', 'two': '=3', 'good:name': 'ok'}
|
||||
st1.items.append(wscall)
|
||||
wscall.parent = st1
|
||||
|
||||
|
@ -318,6 +319,7 @@ def test_wscall_action():
|
|||
assert wscall2.post == False
|
||||
assert wscall2.request_signature_key == 'key'
|
||||
assert wscall2.post_data == {'one': '1', 'two': '=2', 'good:name': 'ok'}
|
||||
assert wscall2.qs_data == {'one': '2', 'two': '=3', 'good:name': 'ok'}
|
||||
|
||||
def test_backoffice_info_text():
|
||||
wf = Workflow(name='info texts')
|
||||
|
|
|
@ -3,6 +3,7 @@ import pytest
|
|||
import shutil
|
||||
import time
|
||||
import urllib2
|
||||
import urlparse
|
||||
|
||||
import mock
|
||||
|
||||
|
@ -849,6 +850,28 @@ def test_webservice_call(pub):
|
|||
rendered = formdata.evolution[-1].parts[-1].view()
|
||||
assert 'Error during webservice call "do that"' in str(rendered)
|
||||
|
||||
item = WebserviceCallStatusItem()
|
||||
item.method = 'GET'
|
||||
item.post = False
|
||||
item.url = 'http://remote.example.net?in_url=1'
|
||||
item.qs_data = {
|
||||
'str': 'abcd',
|
||||
'one': '=1',
|
||||
'evalme': '=form_number',
|
||||
'error': '=1=3',
|
||||
'in_url': '2',
|
||||
}
|
||||
pub.substitutions.feed(formdata)
|
||||
item.perform(formdata)
|
||||
assert http_requests.get_last('method') == 'GET'
|
||||
qs = urlparse.parse_qs(http_requests.get_last('url').split('?')[1])
|
||||
assert set(qs.keys()) == set(['in_url', 'str', 'one', 'evalme'])
|
||||
assert qs['in_url'] == ['1', '2']
|
||||
assert qs['one'] == ['1']
|
||||
assert qs['evalme'] == [formdata.get_display_id()]
|
||||
assert qs['str'] == ['abcd']
|
||||
|
||||
|
||||
def test_timeout(pub):
|
||||
workflow = Workflow(name='timeout')
|
||||
st1 = workflow.add_status('Status1', 'st1')
|
||||
|
|
|
@ -22,6 +22,9 @@ import xml.etree.ElementTree as ET
|
|||
import collections
|
||||
import mimetypes
|
||||
from StringIO import StringIO
|
||||
import urllib
|
||||
import urlparse
|
||||
|
||||
|
||||
from quixote.html import TemplateIO, htmltext
|
||||
from qommon.errors import ConnectionError
|
||||
|
@ -103,6 +106,7 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
|
|||
post = True
|
||||
request_signature_key = None
|
||||
post_data = None
|
||||
qs_data = None
|
||||
_method = None
|
||||
response_type = 'json'
|
||||
|
||||
|
@ -135,7 +139,8 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
|
|||
return ('url', 'post', 'varname', 'request_signature_key', 'post_data',
|
||||
'action_on_4xx', 'action_on_5xx', 'action_on_bad_data',
|
||||
'action_on_network_errors', 'notify_on_errors',
|
||||
'record_errors', 'label', 'method', 'response_type')
|
||||
'record_errors', 'label', 'method', 'response_type',
|
||||
'qs_data')
|
||||
|
||||
def add_parameters_widgets(self, form, parameters, prefix='', formdef=None):
|
||||
if 'label' in parameters:
|
||||
|
@ -150,6 +155,11 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
|
|||
form.add(ComputedExpressionWidget, '%srequest_signature_key' % prefix,
|
||||
title=_('Request Signature Key'),
|
||||
value=self.request_signature_key)
|
||||
if 'qs_data' in parameters:
|
||||
form.add(WidgetDict, '%sqs_data' % prefix,
|
||||
title=_('Query string data'),
|
||||
value=self.qs_data or {},
|
||||
element_value_type=ComputedExpressionWidget)
|
||||
methods = collections.OrderedDict(
|
||||
[('GET', _('GET')), ('POST', _('POST (JSON)'))])
|
||||
if 'method' in parameters:
|
||||
|
@ -234,6 +244,23 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
|
|||
variables = get_publisher().substitutions.get_context_variables()
|
||||
url = get_variadic_url(url, variables)
|
||||
|
||||
if self.qs_data: # merge qs_data into url
|
||||
publisher = get_publisher()
|
||||
parsed = urlparse.urlparse(url)
|
||||
qs = list(urlparse.parse_qsl(parsed.query))
|
||||
for key, value in self.qs_data.iteritems():
|
||||
try:
|
||||
value = self.compute(value, raises=True)
|
||||
value = str(value)
|
||||
except:
|
||||
get_publisher().notify_of_exception(sys.exc_info())
|
||||
else:
|
||||
key = publisher.sitecharset2utf8(key)
|
||||
value = publisher.sitecharset2utf8(value)
|
||||
qs.append((key, value))
|
||||
qs = urllib.urlencode(qs)
|
||||
url = urlparse.urlunparse(parsed[:4] + (qs,) + parsed[5:6])
|
||||
|
||||
if self.request_signature_key:
|
||||
signature_key = self.compute(self.request_signature_key)
|
||||
if signature_key:
|
||||
|
@ -372,11 +399,12 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
|
|||
def get_jump_label(self):
|
||||
return _('Error calling webservice')
|
||||
|
||||
def post_data_export_to_xml(self, xml_item, charset, include_id=False):
|
||||
if not self.post_data:
|
||||
def _kv_data_export_to_xml(self, xml_item, charset, include_id, attribute):
|
||||
assert attribute
|
||||
if not getattr(self, attribute):
|
||||
return
|
||||
el = ET.SubElement(xml_item, 'post_data')
|
||||
for (key, value) in self.post_data.items():
|
||||
el = ET.SubElement(xml_item, attribute)
|
||||
for (key, value) in getattr(self, attribute).items():
|
||||
item = ET.SubElement(el, 'item')
|
||||
if type(key) is unicode:
|
||||
ET.SubElement(item, 'name').text = key
|
||||
|
@ -391,14 +419,26 @@ class WebserviceCallStatusItem(WorkflowStatusItem):
|
|||
else:
|
||||
raise AssertionError('unknown type for value (%r)' % key)
|
||||
|
||||
|
||||
def post_data_init_with_xml(self, elem, charset, include_id=False):
|
||||
def _kv_data_init_with_xml(self, elem, charset, include_id, attribute):
|
||||
if elem is None:
|
||||
return
|
||||
self.post_data = {}
|
||||
setattr(self, attribute, {})
|
||||
for item in elem.findall('item'):
|
||||
key = item.find('name').text.encode(charset)
|
||||
value = item.find('value').text.encode(charset)
|
||||
self.post_data[key] = value
|
||||
getattr(self, attribute)[key] = value
|
||||
|
||||
def post_data_export_to_xml(self, xml_item, charset, include_id=False):
|
||||
self._kv_data_export_to_xml(xml_item, charset, include_id=include_id,
|
||||
attribute='post_data')
|
||||
|
||||
def post_data_init_with_xml(self, elem, charset, include_id=False):
|
||||
self._kv_data_init_with_xml(elem, charset, include_id=include_id, attribute='post_data')
|
||||
|
||||
def qs_data_export_to_xml(self, xml_item, charset, include_id=False):
|
||||
self._kv_data_export_to_xml(xml_item, charset, include_id=include_id, attribute='qs_data')
|
||||
|
||||
def qs_data_init_with_xml(self, elem, charset, include_id=False):
|
||||
self._kv_data_init_with_xml(elem, charset, include_id=include_id, attribute='qs_data')
|
||||
|
||||
register_item_class(WebserviceCallStatusItem)
|
||||
|
|
Loading…
Reference in New Issue