0001-utils-soap-upgrade-zeep-soap-library-version-35370.patch
passerelle/utils/soap.py | ||
---|---|---|
19 | 19 |
from zeep import Client |
20 | 20 |
from zeep.cache import InMemoryCache |
21 | 21 |
from zeep.transports import Transport |
22 |
from zeep import __version__ as zeep_version |
|
22 | 23 | |
23 | 24 |
from django.utils.six.moves.urllib import parse as urlparse |
24 | 25 | |
... | ... | |
38 | 39 |
wsdl_url = kwargs.pop('wsdl_url', None) or resource.wsdl_url |
39 | 40 |
transport_class = getattr(resource, 'soap_transport_class', SOAPTransport) |
40 | 41 |
transport = transport_class(resource, wsdl_url, session=resource.requests, cache=InMemoryCache()) |
41 |
super(SOAPClient, self).__init__(wsdl_url, transport=transport, **kwargs) |
|
42 | ||
43 |
if zeep_version < '3': |
|
44 |
super(SOAPClient, self).__init__( |
|
45 |
wsdl_url, transport=transport, **kwargs) |
|
46 |
else: |
|
47 |
from zeep import Settings |
|
48 |
kept_kwargs = {} |
|
49 |
for key in 'wsse', 'service_name', 'port_name', 'plugins': |
|
50 |
kept_kwargs[key] = kwargs.pop(key, None) |
|
51 |
settings = Settings(**kwargs) |
|
52 |
super(SOAPClient, self).__init__( |
|
53 |
wsdl_url, transport=transport, settings=settings, **kept_kwargs) |
|
42 | 54 | |
43 | 55 | |
44 | 56 |
class SOAPTransport(Transport): |
setup.py | ||
---|---|---|
104 | 104 |
'python-dateutil', |
105 | 105 |
'Pillow', |
106 | 106 |
'jsonschema < 3.1', |
107 |
'zeep < 3.0',
|
|
107 |
'zeep', |
|
108 | 108 |
'pycrypto', |
109 | 109 |
'unidecode', |
110 | 110 |
'paramiko', |
tests/data/soap.wsdl | ||
---|---|---|
48 | 48 |
</element> |
49 | 49 |
<element name="TradePrice"> |
50 | 50 |
<complexType> |
51 |
<all> |
|
51 |
<sequence> |
|
52 |
<element name="skipMe" type="float"/> |
|
52 | 53 |
<element name="price" type="float"/> |
53 |
</all>
|
|
54 |
</sequence>
|
|
54 | 55 |
</complexType> |
55 | 56 |
</element> |
56 | 57 |
<complexType name="account"> |
tests/test_iparapheur.py | ||
---|---|---|
8 | 8 |
import xml.etree.ElementTree as ET |
9 | 9 |
from dateutil import parser |
10 | 10 |
from requests import Response |
11 |
from zeep import __version__ as zeep_version |
|
11 | 12 | |
12 | 13 |
from requests.exceptions import ConnectionError |
13 | 14 |
from django.core.urlresolvers import reverse |
... | ... | |
41 | 42 |
resource_pk=conn.pk) |
42 | 43 |
return conn |
43 | 44 | |
45 |
def assert_invalid_xml(err_desc): |
|
46 |
if zeep_version < '3': |
|
47 |
assert "Server returned HTTP status 200 (<nada>)" in err_desc |
|
48 |
else: |
|
49 |
assert "Server returned response (200) with invalid XML" in err_desc |
|
50 | ||
44 | 51 |
def xmlmime(): |
45 | 52 |
return os.path.join(os.path.dirname(__file__), 'data','xmlmime.xml') |
46 | 53 | |
... | ... | |
187 | 194 |
assert (BASE_URL,) == mocked_post.call_args[0] |
188 | 195 |
assert resp.json['err'] == 1 |
189 | 196 |
assert 'zeep.exceptions.TransportError' in resp.json['err_class'] |
190 |
assert 'Server returned HTTP status 200 (<nada>)' in resp.json['err_desc']
|
|
197 |
assert_invalid_xml(resp.json['err_desc'])
|
|
191 | 198 | |
192 | 199 |
# Unknown value for "visibility" |
193 | 200 |
err_data = data.copy() |
... | ... | |
211 | 218 |
assert (BASE_URL,) == mocked_post.call_args[0] |
212 | 219 |
assert resp.json['err'] == 1 |
213 | 220 |
assert 'zeep.exceptions.TransportError' in resp.json['err_class'] |
214 |
assert 'Server returned HTTP status 200 (<nada>)' in resp.json['err_desc']
|
|
221 |
assert_invalid_xml(resp.json['err_desc'])
|
|
215 | 222 | |
216 | 223 |
@mock.patch('passerelle.utils.Request.get', side_effect=iph_mocked_get) |
217 | 224 |
@mock.patch('passerelle.utils.Request.post') |
... | ... | |
300 | 307 |
assert resp.json['err'] == 1 |
301 | 308 |
#assert 'zeep.exceptions.TransportError' in resp.json['err_class'] |
302 | 309 |
assert 'passerelle.utils.jsonresponse.APIError' in resp.json['err_class'] |
303 |
assert 'Server returned HTTP status 200 (<nada>)' in resp.json['err_desc']
|
|
310 |
assert_invalid_xml(resp.json['err_desc'])
|
|
304 | 311 | |
305 | 312 |
@mock.patch('passerelle.utils.Request.get', side_effect=iph_mocked_get) |
306 | 313 |
@mock.patch('passerelle.utils.Request.post') |
... | ... | |
325 | 332 |
assert resp.body == 'Test Document' |
326 | 333 | |
327 | 334 |
# KO |
328 |
soap_response = """<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><CreerDossierResponse xmlns="http://www.adullact.org/spring-ws/iparapheur/1.0" xmlns:xmime="http://www.w3.org/2005/05/xmlmime"><MessageRetour><codeRetour>KO</codeRetour><message>KOmessage</message><severite>INFO</severite></MessageRetour></CreerDossierResponse></S:Body></S:Envelope>"""
|
|
335 |
soap_response = """<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><GetDossierResponse xmlns="http://www.adullact.org/spring-ws/iparapheur/1.0" xmlns:xmime="http://www.w3.org/2005/05/xmlmime"><MessageRetour><codeRetour>KO</codeRetour><message>KOmessage</message><severite>INFO</severite></MessageRetour></GetDossierResponse></S:Body></S:Envelope>"""
|
|
329 | 336 |
response._content = soap_response |
330 | 337 |
mocked_post.return_value = response |
331 | 338 |
resp = app.get(url, status=500) |
... | ... | |
334 | 341 |
assert resp.json['err_desc'] == 'KOmessage' |
335 | 342 | |
336 | 343 |
# unknown response |
337 |
soap_response = """<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><CreerDossierResponse xmlns="http://www.adullact.org/spring-ws/iparapheur/1.0" xmlns:xmime="http://www.w3.org/2005/05/xmlmime"></CreerDossierResponse></S:Body></S:Envelope>"""
|
|
344 |
soap_response = """<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><GetDossierResponse xmlns="http://www.adullact.org/spring-ws/iparapheur/1.0" xmlns:xmime="http://www.w3.org/2005/05/xmlmime"></GetDossierResponse></S:Body></S:Envelope>"""
|
|
338 | 345 |
response._content = soap_response |
339 | 346 |
mocked_post.return_value = response |
340 | 347 |
resp = app.get(url, status=500) |
tests/test_soap.py | ||
---|---|---|
1 |
import pytest |
|
2 |
import mock |
|
1 | 3 |
import requests |
2 | 4 |
from zeep.plugins import Plugin |
5 |
from zeep.exceptions import XMLParseError |
|
3 | 6 | |
4 | 7 |
from passerelle.utils.soap import SOAPClient |
5 | 8 | |
... | ... | |
30 | 33 |
assert client.transport.session == soap_resource.requests |
31 | 34 |
assert client.transport.cache |
32 | 35 |
assert client.plugins == plugins |
36 | ||
37 |
@mock.patch('requests.sessions.Session.post') |
|
38 |
def test_disable_strict_mode(mocked_post): |
|
39 |
response = requests.Response() |
|
40 |
response.status_code = 200 |
|
41 |
response._content = '''<?xml version='1.0' encoding='utf-8'?> |
|
42 |
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/"> |
|
43 |
<soap-env:Body> |
|
44 |
<ns0:TradePrice xmlns:ns0="http://example.com/stockquote.xsd"> |
|
45 |
<price>4.20</price> |
|
46 |
</ns0:TradePrice> |
|
47 |
</soap-env:Body> |
|
48 |
</soap-env:Envelope>''' |
|
49 |
mocked_post.return_value = response |
|
50 | ||
51 |
soap_resource = SOAPResource() |
|
52 |
client = SOAPClient(soap_resource) |
|
53 |
with pytest.raises( |
|
54 |
XMLParseError, match="Unexpected element u'price', expected u'skipMe'"): |
|
55 |
client.service.GetLastTradePrice(tickerSymbol='banana') |
|
56 | ||
57 |
client = SOAPClient(soap_resource, strict=False) |
|
58 |
result = client.service.GetLastTradePrice(tickerSymbol='banana') |
|
59 |
assert len(result) == 2 |
|
60 |
assert result['skipMe'] == None |
|
61 |
assert result['price'] == 4.2 |
tox.ini | ||
---|---|---|
1 | 1 |
[tox] |
2 | 2 |
toxworkdir = {env:TMPDIR:/tmp}/tox-{env:USER}/passerelle/{env:BRANCH_NAME:} |
3 |
envlist = django111-pg |
|
3 |
envlist = django111-pg-zeep2
|
|
4 | 4 | |
5 | 5 |
[testenv] |
6 | 6 |
usedevelop = True |
... | ... | |
36 | 36 |
vobject |
37 | 37 |
django-ratelimit |
38 | 38 |
pyquery |
39 |
zeep2: zeep < 3.0 |
|
40 |
zeep3: zeep >= 3.0 |
|
39 | 41 |
commands = |
40 | 42 |
./get_wcs.sh |
41 | 43 |
django111: py.test {posargs: {env:FAST:} --junitxml=test_{envname}_results.xml --cov-report xml --cov-report html --cov=passerelle/ --cov-config .coveragerc tests/} |
42 |
- |