0005-let-requests-handle-HTTP-errors-31114.patch
passerelle/apps/api_particulier/models.py | ||
---|---|---|
73 | 73 |
url, |
74 | 74 |
headers=headers, |
75 | 75 |
**kwargs) |
76 |
except requests.HTTPError as e: |
|
77 |
msg = u'API-particulier platform "%s" request error %s' % (self.platform, e) |
|
78 |
try: |
|
79 |
data = e.response.json() |
|
80 |
if data.get('error') == 'not_found': |
|
81 |
return { |
|
82 |
'err': 1, |
|
83 |
'err_desc': data.get('message', 'not_found'), |
|
84 |
} |
|
85 |
msg += ': %s' % data |
|
86 |
except ValueError: |
|
87 |
pass |
|
88 |
raise APIError( |
|
89 |
msg, |
|
90 |
(self.platform, e), |
|
91 |
data={ |
|
92 |
'platform': self.platform, |
|
93 |
'error': six.text_type(e), |
|
94 |
}) |
|
76 | 95 |
except requests.RequestException as e: |
77 | 96 |
raise APIError( |
78 |
u'API-particulier platform "%s" connection error: %s' %
|
|
79 |
(self.platform, response.status_code),
|
|
97 |
u'API-particulier platform "%s" request error: %s' %
|
|
98 |
(self.platform, e), |
|
80 | 99 |
data={ |
81 | 100 |
'platform': self.platform, |
82 | 101 |
'error': six.text_type(e), |
... | ... | |
94 | 113 |
'platform': self.platform, |
95 | 114 |
'content': content, |
96 | 115 |
}) |
97 |
if response.status_code != 200: |
|
98 |
if data.get('error') == 'not_found': |
|
99 |
return { |
|
100 |
'err': 1, |
|
101 |
'err_desc': data.get('message', 'not-found'), |
|
102 |
} |
|
103 |
raise APIError( |
|
104 |
u'API-particulier platform "%s" returned a non 200 status %s: %s' % |
|
105 |
(self.platform, response.status_code, data), |
|
106 |
data={ |
|
107 |
'status_code': response.status_code, |
|
108 |
'platform': self.platform, |
|
109 |
'content': data, |
|
110 |
}) |
|
111 | 116 |
return { |
112 | 117 |
'err': 0, |
113 | 118 |
'data': data, |
passerelle/apps/arcgis/models.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
import urlparse |
18 | 18 | |
19 |
import requests |
|
20 | ||
19 | 21 |
from django.db import models |
20 | 22 |
from django.template import Template, Context |
21 | 23 |
from django.utils.translation import ugettext_lazy as _ |
... | ... | |
113 | 115 |
if 'distance' in params and 'units' not in params: |
114 | 116 |
params['units'] = 'esriSRUnit_Meter' |
115 | 117 | |
116 |
response = self.requests.get(url, params=params) |
|
118 |
try: |
|
119 |
response = self.requests.get(url, params=params) |
|
120 |
except requests.RequestException as e: |
|
121 |
raise ArcGISError('ArcGIS request error %s' % e) |
|
117 | 122 | |
118 | 123 |
# errors |
119 |
if response.status_code // 100 != 2: |
|
120 |
raise ArcGISError('ArcGIS returned status code %s' % response.status_code) |
|
121 | 124 |
try: |
122 | 125 |
infos = response.json() |
123 | 126 |
except (ValueError,): |
passerelle/apps/arpege_ecp/models.py | ||
---|---|---|
17 | 17 |
import json |
18 | 18 |
import urlparse |
19 | 19 | |
20 |
import requests |
|
21 | ||
20 | 22 |
from django.db import models |
21 | 23 |
from django.utils.translation import ugettext_lazy as _ |
22 | 24 |
from django.utils.dateparse import parse_date, parse_time |
... | ... | |
47 | 49 | |
48 | 50 |
def get_access_token(self, NameID): |
49 | 51 |
url = urlparse.urljoin(self.webservice_base_url, 'LoginParSubOIDC') |
50 |
response = self.requests.post(url, auth=HawkAuth(self.hawk_auth_id, self.hawk_auth_key), |
|
51 |
json={'subOIDC': NameID}) |
|
52 |
if response.status_code // 100 != 2: |
|
53 |
raise APIError(u'HTTP error: %s' % response.status_code) |
|
52 |
try: |
|
53 |
response = self.requests.post(url, auth=HawkAuth(self.hawk_auth_id, self.hawk_auth_key), |
|
54 |
json={'subOIDC': NameID}) |
|
55 |
except requests.RequestException as e: |
|
56 |
raise APIError(u'Request error: %s' % e) |
|
54 | 57 |
try: |
55 | 58 |
result = response.json() |
56 | 59 |
except ValueError: |
... | ... | |
69 | 72 |
url = urlparse.urljoin(self.webservice_base_url, 'DemandesUsager') |
70 | 73 |
params = {'scope': 'data_administratives'} |
71 | 74 |
auth = HawkAuth(self.hawk_auth_id, self.hawk_auth_key, ext=access_token) |
72 |
response = self.requests.get(url, params=params, auth=auth) |
|
75 |
try: |
|
76 |
response = self.requests.get(url, params=params, auth=auth) |
|
77 |
except requests.RequestException as e: |
|
78 |
raise APIError(u'Request error: %s' % e) |
|
73 | 79 |
data = [] |
74 |
if response.status_code // 100 != 2: |
|
75 |
raise APIError(u'HTTP error: %s' % response.status_code) |
|
76 | 80 |
try: |
77 | 81 |
result = response.json() |
78 | 82 |
except ValueError: |
passerelle/apps/base_adresse/models.py | ||
---|---|---|
5 | 5 |
import unicodedata |
6 | 6 | |
7 | 7 |
import six |
8 |
import requests |
|
8 | 9 | |
9 | 10 |
from django.db import connection, models |
10 | 11 |
from django.db.models import Q |
... | ... | |
161 | 162 |
departments.add(zipcode[:2]) |
162 | 163 | |
163 | 164 |
for department in departments: |
164 |
ban_file = self.requests.get( |
|
165 |
'http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_{}-json.bz2'.format(department)) |
|
166 |
if ban_file.status_code != 200: |
|
165 |
try: |
|
166 |
ban_file = self.requests.get( |
|
167 |
'http://bano.openstreetmap.fr/BAN_odbl/BAN_odbl_{}-json.bz2'.format(department)) |
|
168 |
except requests.HTTPError: |
|
167 | 169 |
continue |
170 |
except requests.RequestException: |
|
171 |
raise |
|
168 | 172 | |
169 | 173 |
for line in bz2.decompress(ban_file.content).splitlines(): |
170 | 174 |
street_info = json.loads(line) |
passerelle/apps/bdp/models.py | ||
---|---|---|
32 | 32 |
options = {} |
33 | 33 |
if self.keystore: |
34 | 34 |
options['cert'] = (self.keystore.path, self.keystore.path) |
35 |
if not self.verify_cert: |
|
36 |
options['verify'] = False |
|
35 |
options['verify'] = self.verify_cert |
|
37 | 36 |
if self.username: |
38 | 37 |
options['auth'] = HTTPBasicAuth(self.username, self.password) |
39 | 38 |
return options |
40 | 39 | |
41 | 40 |
def get_api(self, endpoint, **params): |
42 | 41 |
options = self.requests_options() |
43 |
return requests.get(self.service_url + '/api/' + endpoint, |
|
44 |
params=params, **options).json() |
|
42 |
return self.requests.get(self.service_url + '/api/' + endpoint, params=params, **options).json() |
|
45 | 43 | |
46 | 44 |
def post_api(self, endpoint, obj): |
47 | 45 |
data = json.dumps(obj) |
48 | 46 |
headers = {'Content-Type': 'application/json'} |
49 | 47 |
options = self.requests_options() |
50 |
request = requests.post( |
|
48 |
request = self.requests.post(
|
|
51 | 49 |
self.service_url + '/api/' + endpoint, |
52 |
data=data, headers=headers, **options) |
|
50 |
data=data, headers=headers, |
|
51 |
raise_for_status=False, |
|
52 |
raise_for_redirect=False, |
|
53 |
**options) |
|
53 | 54 |
result = { |
54 | 55 |
'status_code': request.status_code, |
55 | 56 |
'x_request_id': request.headers.get('x-request-id'), |
passerelle/apps/okina/models.py | ||
---|---|---|
16 | 16 | |
17 | 17 |
import json |
18 | 18 | |
19 |
import requests |
|
20 | ||
19 | 21 |
from django.db import models |
20 | 22 |
from django.http import HttpResponse |
21 | 23 |
from django.utils.translation import ugettext_lazy as _ |
... | ... | |
42 | 44 |
headers = {} |
43 | 45 |
if result_is_json: |
44 | 46 |
headers['Accept'] = 'application/json' |
45 |
if payload is None: |
|
46 |
result = self.requests.get(url, auth=auth, headers=headers) |
|
47 |
else: |
|
48 |
headers['Content-Type'] = 'application/json' |
|
49 |
data = json.dumps(payload) |
|
50 |
result = self.requests.post(url, data=data, auth=auth, headers=headers) |
|
51 |
if result.status_code in (401, 403): |
|
52 |
raise APIError(result.json()['message'], http_status=500) |
|
47 |
try: |
|
48 |
if payload is None: |
|
49 |
result = self.requests.get(url, auth=auth, headers=headers) |
|
50 |
else: |
|
51 |
headers['Content-Type'] = 'application/json' |
|
52 |
data = json.dumps(payload) |
|
53 |
result = self.requests.post(url, data=data, auth=auth, headers=headers) |
|
54 |
except requests.HTTPError as e: |
|
55 |
if e.response.status_code in (401, 403): |
|
56 |
raise APIError(e.response.json()['message'], http_status=500) |
|
57 |
result = e.response |
|
53 | 58 |
if result_is_json: |
54 | 59 |
return result.json() |
55 | 60 |
else: |
passerelle/apps/opengis/models.py | ||
---|---|---|
19 | 19 |
from HTMLParser import HTMLParser |
20 | 20 | |
21 | 21 |
import six |
22 |
import requests |
|
22 | 23 | |
23 | 24 |
import pyproj |
24 | 25 | |
... | ... | |
302 | 303 |
'OUTPUTFORMAT': 'json', |
303 | 304 |
'CQL_FILTER': cql_filter |
304 | 305 |
} |
305 |
response = self.requests.get(self.wfs_service_url, params=params) |
|
306 |
if not response.ok: |
|
307 |
raise APIError('Webservice returned status code %s' % response.status_code) |
|
306 |
try: |
|
307 |
response = self.requests.get(self.wfs_service_url, params=params) |
|
308 |
except requests.HTTPError as e: |
|
309 |
raise APIError('Webservice returned status code %s' % e.response.status_code) |
|
308 | 310 |
closest_feature = {} |
309 | 311 |
min_delta = None |
310 | 312 |
for feature in response.json().get('features'): |
passerelle/apps/solis/models.py | ||
---|---|---|
19 | 19 |
import re |
20 | 20 |
import unicodedata |
21 | 21 | |
22 |
import requests |
|
23 | ||
22 | 24 |
from django.db import models |
23 | 25 |
from django.template.loader import get_template |
24 | 26 |
from django.utils.translation import ugettext_lazy as _ |
... | ... | |
105 | 107 |
def request(self, endpoint, data=None, files=None): |
106 | 108 |
url = self.service_url + endpoint |
107 | 109 |
headers = {'Accept': 'application/json'} |
108 |
if data is not None:
|
|
109 |
response = self.requests.post(url, json=data, headers=headers)
|
|
110 |
elif files is not None:
|
|
111 |
response = self.requests.post(url, files=files, headers=headers)
|
|
112 |
else:
|
|
113 |
response = self.requests.get(url, headers=headers)
|
|
114 | ||
115 |
if response.status_code // 100 != 2:
|
|
110 |
try:
|
|
111 |
if data is not None:
|
|
112 |
response = self.requests.post(url, json=data, headers=headers)
|
|
113 |
elif files is not None:
|
|
114 |
response = self.requests.post(url, files=files, headers=headers)
|
|
115 |
else:
|
|
116 |
response = self.requests.get(url, headers=headers) |
|
117 |
except requests.HTTPError as e:
|
|
116 | 118 |
try: |
117 |
json_content = response.json() |
|
119 |
json_content = e.response.json()
|
|
118 | 120 |
except ValueError: |
119 | 121 |
json_content = None |
120 | 122 |
raise APIError('error status:%s %r, content:%r' % |
121 |
(response.status_code, response.reason, response.content[:1024]),
|
|
122 |
data={'status_code': response.status_code, |
|
123 |
(e.response.status_code, e.response.reason, e.response.content[:1024]),
|
|
124 |
data={'status_code': e.response.status_code,
|
|
123 | 125 |
'json_content': json_content}) |
124 | 126 | |
125 | 127 |
if response.status_code == 204: # 204 No Content |
passerelle/apps/vivaticket/models.py | ||
---|---|---|
17 | 17 |
import hashlib |
18 | 18 |
import urlparse |
19 | 19 | |
20 |
import requests |
|
21 | ||
20 | 22 |
from django.core.cache import cache |
21 | 23 |
from django.db import models |
22 | 24 |
from django.utils.translation import ugettext_lazy as _ |
... | ... | |
86 | 88 |
return cls._meta.verbose_name |
87 | 89 | |
88 | 90 |
def check_status(self): |
89 |
response = self.requests.get(urlparse.urljoin(self.url, 'Settings/GetVersion')) |
|
90 |
response.raise_for_status() |
|
91 |
self.requests.get(urlparse.urljoin(self.url, 'Settings/GetVersion')) |
|
91 | 92 | |
92 | 93 |
def get_apikey(self, renew=False): |
93 | 94 |
cache_key_name = 'vivaticket-%s-key' % self.id |
... | ... | |
95 | 96 |
return cache.get(cache_key_name) |
96 | 97 |
url = urlparse.urljoin(self.url, 'Connect/PostConnect') |
97 | 98 |
payload = {'Login': self.login, 'Password': self.password} |
98 |
response = self.requests.post(url, json=payload) |
|
99 |
if not response.ok: |
|
100 |
raise APIError(response.content) |
|
99 |
try: |
|
100 |
response = self.requests.post(url, json=payload) |
|
101 |
except requests.HTTPError as e: |
|
102 |
raise APIError(e.response.content) |
|
101 | 103 |
api_key = response.json()['Key'] |
102 | 104 |
# api key is available for 30 minutes |
103 | 105 |
cache.set(cache_key_name, api_key, 60 * 30) |
... | ... | |
107 | 109 |
url = urlparse.urljoin(self.url, endpoint) |
108 | 110 |
params = {'key': self.get_apikey()} |
109 | 111 |
params.update(kwargs) |
110 |
response = self.requests.get(url, params=params) |
|
111 |
# api key is expired |
|
112 |
if response.status_code == 401: |
|
113 |
params['key'] = self.get_apikey(True) |
|
114 |
else: |
|
115 |
return response |
|
116 |
return self.requests.get(url, params=params) |
|
112 |
try: |
|
113 |
return self.requests.get(url, params=params) |
|
114 |
except requests.HTTPError as e: |
|
115 |
# api key is expired |
|
116 |
if e.response.status_code == 401: |
|
117 |
params['key'] = self.get_apikey(True) |
|
118 |
return self.requests.get(url, params=params) |
|
119 |
return e.response |
|
117 | 120 | |
118 | 121 |
def post(self, endpoint, payload): |
119 | 122 |
url = urlparse.urljoin(self.url, endpoint) |
120 | 123 |
payload.update({'Key': self.get_apikey()}) |
121 |
response = self.requests.post(url, json=payload) |
|
122 |
# api key is expired |
|
123 |
if response.status_code == 401: |
|
124 |
payload['key'] = self.get_apikey(True) |
|
124 |
try: |
|
125 | 125 |
return self.requests.post(url, json=payload) |
126 |
return response |
|
126 |
except requests.HTTPError as e: |
|
127 |
# api key is expired |
|
128 |
if e.response.status_code == 401: |
|
129 |
payload['key'] = self.get_apikey(True) |
|
130 |
return self.requests.post(url, json=payload) |
|
131 |
raise |
|
127 | 132 | |
128 | 133 |
def get_setting(self, endpoint, **kwargs): |
129 | 134 |
response = self.get(endpoint, **kwargs) |
passerelle/contrib/gdema/models.py | ||
---|---|---|
18 | 18 |
import json |
19 | 19 |
import re |
20 | 20 | |
21 |
import requests |
|
22 | ||
21 | 23 |
from django.db import models |
22 | 24 |
from django.utils.timezone import get_fixed_timezone, utc, is_naive, make_aware |
23 | 25 |
from django.utils.dateparse import parse_date, parse_datetime |
... | ... | |
162 | 164 |
auth = None |
163 | 165 |
headers = {} |
164 | 166 |
headers['Accept'] = 'application/json' |
165 |
if payload is None: |
|
166 |
result = self.requests.get(url, auth=auth, headers=headers) |
|
167 |
else: |
|
168 |
headers['Content-Type'] = 'application/json' |
|
169 |
data = json.dumps(payload) |
|
170 |
result = self.requests.post(url, data=data, auth=auth, headers=headers) |
|
171 |
if result.status_code < 200 or result.status_code >= 300: |
|
172 |
raise APIError('GDEMA returns HTTP status %s' % result.status_code) |
|
167 |
try: |
|
168 |
if payload is None: |
|
169 |
result = self.requests.get(url, auth=auth, headers=headers) |
|
170 |
else: |
|
171 |
headers['Content-Type'] = 'application/json' |
|
172 |
data = json.dumps(payload) |
|
173 |
result = self.requests.post(url, data=data, auth=auth, headers=headers) |
|
174 |
except requests.RequestException as e: |
|
175 |
raise APIError('GDEMA request failed %s' % e) |
|
173 | 176 |
return result.json() |
174 | 177 | |
175 | 178 |
def get_services(self): |
passerelle/contrib/greco/models.py | ||
---|---|---|
23 | 23 |
from email.mime.multipart import MIMEMultipart |
24 | 24 |
from email.mime.text import MIMEText |
25 | 25 | |
26 |
import requests |
|
27 | ||
26 | 28 |
from suds.client import Client |
27 | 29 |
from suds.transport import Reply |
28 | 30 |
from suds.transport.http import HttpAuthenticated |
... | ... | |
155 | 157 |
request.headers['Authorization'] = self.instance.get_token() |
156 | 158 |
resp = self.instance.requests.post(request.url, data=request.message, |
157 | 159 |
headers=request.headers, |
158 |
verify=self.instance.verify_cert) |
|
160 |
verify=self.instance.verify_cert, |
|
161 |
raise_for_status=False, |
|
162 |
raise_for_redirect=False) |
|
159 | 163 |
if resp.status_code == 401: |
160 | 164 |
# ask for a new token, and retry |
161 | 165 |
request.headers['Authorization'] = self.instance.get_token(renew=True) |
passerelle/contrib/mdph13/models.py | ||
---|---|---|
46 | 46 | |
47 | 47 |
def url_get(self, *args, **kwargs): |
48 | 48 |
try: |
49 |
response = None |
|
50 | 49 |
response = self.requests.get(*args, **kwargs) |
51 |
response.raise_for_status() |
|
52 | 50 |
except requests.RequestException as e: |
53 | 51 |
data = {'exception': six.text_type(e)} |
52 |
response = getattr(e, 'response', None) |
|
54 | 53 |
if response is not None: |
55 | 54 |
try: |
56 | 55 |
if response.json(): |
passerelle/contrib/planitech/models.py | ||
---|---|---|
21 | 21 |
import urlparse |
22 | 22 |
import uuid |
23 | 23 | |
24 |
import requests |
|
25 | ||
24 | 26 |
from django.core.cache import cache |
25 | 27 |
from django.db import models, transaction |
26 | 28 |
from django.utils import dateformat |
27 | 29 |
from django.utils import dateparse |
28 | 30 |
from django.utils.translation import ugettext_lazy as _ |
29 | 31 |
from jsonfield import JSONField |
30 |
from requests.exceptions import RequestException |
|
31 | 32 | |
32 | 33 |
from passerelle.base.models import BaseResource |
33 | 34 |
from passerelle.contrib.planitech import mste |
... | ... | |
208 | 209 |
kwargs = {} |
209 | 210 |
if params is not None: |
210 | 211 |
kwargs['data'] = json.dumps(mste.encode(params)) |
211 |
response = session_meth(urlparse.urljoin(self.url, endpoint), **kwargs) |
|
212 |
if response.status_code != 200: |
|
213 |
error_msg = "Planitech error %s" % response.status_code |
|
212 |
try: |
|
213 |
response = session_meth(urlparse.urljoin(self.url, endpoint), **kwargs) |
|
214 |
except requests.HTTPError as e: |
|
215 |
error_msg = "Planitech error %s" % e.response.status_code |
|
214 | 216 |
try: |
215 |
data = mste.decode(response.json()) |
|
217 |
data = mste.decode(e.response.json()) |
|
218 |
except TypeError: |
|
219 |
pass |
|
220 |
else: |
|
216 | 221 |
if hasattr(data, 'get'): |
217 | 222 |
error = data.get('errors') |
218 | 223 |
if error: |
219 | 224 |
error_msg += " - %s" % error |
220 |
except TypeError: |
|
221 |
pass |
|
222 | 225 |
raise APIError(error_msg) |
223 | 226 |
return mste.decode(response.json()) |
224 | 227 | |
... | ... | |
317 | 320 |
tmp_hash = compute_hash(self.password, hardness1, salt1) |
318 | 321 |
hash_pass = compute_hash(tmp_hash, hardness2, salt2) |
319 | 322 |
response = self.requests.get(auth_url, headers={'MH-PASSWORD': hash_pass}) |
320 |
response.raise_for_status() |
|
321 | 323 |
# the last response should have set a cookie which will be used for authentication |
322 |
except RequestException as e: |
|
323 |
raise APIError("Authentication to Planitech failed: %s" % str(e))
|
|
324 |
except requests.RequestException as e:
|
|
325 |
raise APIError("Authentication to Planitech failed: %s" % e)
|
|
324 | 326 | |
325 | 327 |
@endpoint( |
326 | 328 |
perm='can_access', |
passerelle/contrib/solis_apa/models.py | ||
---|---|---|
18 | 18 |
import json |
19 | 19 |
import urlparse |
20 | 20 | |
21 |
import requests |
|
22 | ||
21 | 23 |
from django.db import models |
22 | 24 |
from django.core.cache import cache |
23 | 25 |
from django.core.urlresolvers import reverse |
... | ... | |
100 | 102 |
} |
101 | 103 |
data = json.dumps(data) |
102 | 104 | |
103 |
response = self.requests.post(url, data=data, headers=HEADERS) |
|
104 |
if response.status_code != 200: |
|
105 |
raise ValueError('referential ws: error code %d' % response.status_code) |
|
105 |
try: |
|
106 |
response = self.requests.post(url, data=data, headers=HEADERS) |
|
107 |
except requests.RequestException as e: |
|
108 |
raise ValueError('referential request failed %s' % e) |
|
106 | 109 | |
107 | 110 |
ret = self._check_requests_response(response) |
108 | 111 | |
... | ... | |
123 | 126 |
url = self.get_resource_url(uri) |
124 | 127 |
name = config['block']['name'].lower() |
125 | 128 |
data = json.dumps(conciliation.conciliation_payload(config, **data)) |
126 |
response = self.requests.post(url, data=data, headers=HEADERS) |
|
127 |
if response.status_code != 200: |
|
128 |
raise ValueError('conciliation ws: error code %d' % response.status_code) |
|
129 |
try: |
|
130 |
response = self.requests.post(url, data=data, headers=HEADERS) |
|
131 |
except requests.RequestException as e: |
|
132 |
raise ValueError('conciliation ws failed: %s' % e) |
|
129 | 133 | |
130 | 134 |
ret = self._check_requests_response(response) |
131 | 135 | |
... | ... | |
299 | 303 | |
300 | 304 |
payload = suivi.render_payload(suivi_type, datedebut, datefin) |
301 | 305 |
payload = json.dumps(payload) |
302 |
response = self.requests.post(url, data=payload, headers=HEADERS, timeout=300) |
|
303 |
if response.status_code != 200: |
|
304 |
raise ValueError('suivi %s ws: error code %d' %(suivi_type, response.status_code)) |
|
306 |
try: |
|
307 |
response = self.requests.post(url, data=payload, headers=HEADERS, timeout=300) |
|
308 |
except requests.RequestException as e: |
|
309 |
raise ValueError('suivi %s ws: error code %e' % (suivi_type, e)) |
|
305 | 310 | |
306 | 311 |
response = self._check_requests_response(response) |
307 | 312 | |
... | ... | |
315 | 320 |
data = {'ImportInputWSDemandeApa': integration.build_message(json.loads(data))} |
316 | 321 |
data = json.dumps(data) |
317 | 322 |
self.logger.debug('Demande APA: %s' % data, extra={'solis_apa_demande': data}) |
318 |
response = self.requests.post(url, data=data, headers=HEADERS) |
|
319 |
if response.status_code != 200: |
|
320 |
raise ValueError('integration ws: error code %d' %(response.status_code)) |
|
323 |
try: |
|
324 |
response = self.requests.post(url, data=data, headers=HEADERS) |
|
325 |
except requests.RequestException as e: |
|
326 |
raise ValueError('integration ws: error code %s' % e) |
|
321 | 327 | |
322 | 328 |
response = self._check_requests_response(response) |
323 | 329 |
passerelle/contrib/teamnet_axel/soap.py | ||
---|---|---|
53 | 53 |
self.addcredentials(request) |
54 | 54 |
resp = self.model.requests.post( |
55 | 55 |
request.url, data=request.message, |
56 |
headers=request.headers, **self.get_requests_kwargs()) |
|
56 |
headers=request.headers, |
|
57 |
raise_for_status=False, |
|
58 |
raise_for_redirect=False, |
|
59 |
**self.get_requests_kwargs()) |
|
57 | 60 |
result = Reply(resp.status_code, resp.headers, resp.content) |
58 | 61 |
return result |
59 | 62 |
passerelle/soap.py | ||
---|---|---|
44 | 44 | |
45 | 45 |
def send(self, request): |
46 | 46 |
resp = requests.post(request.url, data=request.message, headers=request.headers, |
47 |
raise_for_status=False, raise_for_redirect=False, |
|
47 | 48 |
**self.get_requests_kwargs(request)) |
48 | 49 |
return Reply(resp.status_code, resp.headers, resp.content) |
49 | 50 |
tests/conftest.py | ||
---|---|---|
1 |
from io import BytesIO |
|
2 |
import json as json_module |
|
3 |
import base64 |
|
4 |
from django.utils.six.moves.urllib import parse as urlparse |
|
5 | ||
1 | 6 |
import pytest |
2 | 7 |
from httmock import urlmatch, HTTMock, response |
3 | 8 | |
4 | 9 |
import django_webtest |
5 | 10 | |
11 | ||
6 | 12 |
from django.core.files import File |
7 | 13 |
from django.core.cache import cache |
8 | 14 |
from io import BytesIO |
... | ... | |
170 | 176 |
del os.environ['OPENSSL_CONF'] |
171 | 177 |
else: |
172 | 178 |
os.environ['OPENSSL_CONF'] = old_value |
179 | ||
180 | ||
181 |
@pytest.fixture |
|
182 |
def fake_http(): |
|
183 |
class MockHttp(object): |
|
184 |
def __init__(self): |
|
185 |
self.requests = [] |
|
186 |
self.responses = [] |
|
187 | ||
188 |
def reset(self): |
|
189 |
assert len(self.responses) == len(self.requests), 'all responses have not been consumed' |
|
190 |
self.requests = [] |
|
191 |
self.responses = [] |
|
192 | ||
193 |
def set_response(self, *args, **kwargs): |
|
194 |
self.reset() |
|
195 |
self.add_response(*args, **kwargs) |
|
196 | ||
197 |
def add_response(self, status_code=200, reason=None, content=None, |
|
198 |
json=None, headers=None, method=None, url=None): |
|
199 |
response = {'status_code': status_code} |
|
200 |
if not content and json: |
|
201 |
content = json_module.dumps(json) |
|
202 |
headers = headers or {} |
|
203 |
for key in headers: |
|
204 |
if key.lower() == 'content-type': |
|
205 |
break |
|
206 |
else: |
|
207 |
headers['content-type'] = 'application/json' |
|
208 |
if reason: |
|
209 |
response['reason'] = reason |
|
210 |
if content: |
|
211 |
response['content'] = content |
|
212 |
if headers: |
|
213 |
response['headers'] = headers |
|
214 |
if method: |
|
215 |
response['request_method'] = method |
|
216 |
if url: |
|
217 |
response['request_url'] = url |
|
218 |
self.responses.append(response) |
|
219 | ||
220 |
@property |
|
221 |
def last_request(self): |
|
222 |
return self.requests[-1] |
|
223 | ||
224 |
def request_handler(self, url, request): |
|
225 |
from django.http.request import QueryDict |
|
226 |
from django.http.multipartparser import MultiPartParser |
|
227 |
from django.core.files.uploadhandler import TemporaryFileUploadHandler |
|
228 | ||
229 |
idx = len(self.requests) |
|
230 | ||
231 |
url_parsed = urlparse.urlparse(request.url) |
|
232 |
request.path = url_parsed.path |
|
233 |
request.GET = QueryDict(query_string=url_parsed.query) |
|
234 | ||
235 |
if ('content-type' in request.headers |
|
236 |
and request.headers['content-type'].split(';')[0] == 'application/json'): |
|
237 |
request.json = json_module.loads(request.body) |
|
238 |
else: |
|
239 |
request.json = None |
|
240 | ||
241 |
if ('content-type' in request.headers |
|
242 |
and request.headers['content-type'].split(';')[0] == 'multipart/form-data'): |
|
243 |
data = BytesIO(request.body) |
|
244 |
META = {'CONTENT_TYPE': request.headers['content-type'], 'CONTENT_LENGTH': request.headers['content-length']} |
|
245 |
request.POST, request.FILES = MultiPartParser(META, data, [TemporaryFileUploadHandler()]).parse() |
|
246 |
else: |
|
247 |
request.POST = QueryDict() |
|
248 |
request.FILES = QueryDict() |
|
249 | ||
250 |
if ('authorization' in request.headers |
|
251 |
and request.headers['authorization'].split()[0] == 'Basic'): |
|
252 |
header = request.headers['authorization'] |
|
253 |
request.basic_auth = base64.b64decode(header.split()[1]).split(':') |
|
254 |
self.requests.append(request) |
|
255 |
assert idx < len(self.responses), ('unexpected request', request) |
|
256 |
response = self.responses[idx] |
|
257 | ||
258 |
if 'request_method' in response: |
|
259 |
assert request.method == response['request_method'] |
|
260 | ||
261 |
if 'request_url' in response: |
|
262 |
if hasattr(response['request_url'], 'match'): |
|
263 |
assert response['request_url'].match(request.url) |
|
264 |
else: |
|
265 |
assert response['request_url'] == request.url |
|
266 | ||
267 |
return response |
|
268 | ||
269 |
mock_http = MockHttp() |
|
270 |
with HTTMock(urlmatch()(mock_http.request_handler)): |
|
271 |
yield mock_http |
|
272 |
assert len(mock_http.responses) == len(mock_http.requests), 'all responses have not been consumed' |
tests/test_api_particulier.py | ||
---|---|---|
195 | 195 |
params=params) |
196 | 196 |
assert resp.status_code == 200 |
197 | 197 |
assert resp.json['err'] == 1 |
198 |
assert resp.json['data']['status_code'] == 500
|
|
198 |
assert '500 Server Error' in resp.json['err_desc']
|
|
199 | 199 |
vector = [ |
200 | 200 |
(['impots_svair', 'impots_adresse'], { |
201 | 201 |
'numero_fiscal': 12, |
tests/test_arpege_ecp.py | ||
---|---|---|
60 | 60 |
} |
61 | 61 |
}""" |
62 | 62 | |
63 | ||
63 | 64 |
@pytest.fixture |
64 | 65 |
def connector(db): |
65 |
resource = ArpegeECP.objects.create(slug='test', |
|
66 |
webservice_base_url = 'http://arpege.net', |
|
67 |
hawk_auth_id = 'id', hawk_auth_key = 'secret') |
|
66 |
resource = ArpegeECP.objects.create( |
|
67 |
slug='test', |
|
68 |
webservice_base_url='http://arpege.net', |
|
69 |
hawk_auth_id='id', |
|
70 |
hawk_auth_key='secret') |
|
68 | 71 |
return utils.setup_access_rights(resource) |
69 | 72 | |
70 |
@mock.patch('passerelle.utils.Request.get') |
|
71 |
def test_check_status(mocked_get, connector):
|
|
72 |
mocked_get.return_value = utils.FakedResponse(content=FAKE_HELLO_RESPONSE, status_code=200)
|
|
73 | ||
74 |
def test_check_status_ok(fake_http, connector):
|
|
75 |
fake_http.add_response(200, content=FAKE_HELLO_RESPONSE)
|
|
73 | 76 |
resp = connector.check_status() |
74 | 77 |
assert resp['data'] == u'InteropAPI v1 (c) Arpège 2017' |
75 | 78 | |
76 |
@mock.patch('passerelle.utils.Request.get') |
|
77 |
def test_check_status(mocked_get, connector):
|
|
79 | ||
80 |
def test_check_status_nok(fake_http, connector):
|
|
78 | 81 |
hello_response = json.loads(FAKE_HELLO_RESPONSE) |
79 | 82 |
del hello_response['Data'] |
80 |
mocked_get.return_value = utils.FakedResponse(content=json.dumps(hello_response), status_code=200)
|
|
83 |
fake_http.add_response(200, content=json.dumps(hello_response))
|
|
81 | 84 |
with pytest.raises(Exception) as error: |
82 |
resp = connector.check_status()
|
|
85 |
connector.check_status() |
|
83 | 86 |
assert str(error.value) == 'Invalid credentials' |
84 | 87 | |
85 |
@mock.patch('passerelle.utils.Request.post') |
|
86 |
def test_get_access_token(mocked_post, connector):
|
|
87 |
mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
|
|
88 | ||
89 |
def test_get_access_token(fake_http, connector):
|
|
90 |
fake_http.add_response(200, content=FAKE_LOGIN_OIDC_RESPONSE)
|
|
88 | 91 |
token = connector.get_access_token('nameid') |
89 | 92 |
assert token == '0f86353f2d87b8b78aaaacc2ecc763e287ded44f773289a5e336546a251718b3' |
90 | 93 | |
91 |
mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=404)
|
|
94 |
fake_http.add_response(404, content=FAKE_LOGIN_OIDC_RESPONSE)
|
|
92 | 95 |
with pytest.raises(APIError) as error: |
93 | 96 |
token = connector.get_access_token('nameid') |
94 | 97 | |
95 |
assert str(error.value) == 'HTTP error: 404'
|
|
98 |
assert '404' in str(error.value)
|
|
96 | 99 | |
97 |
mocked_post.return_value = utils.FakedResponse(content="content", status_code=200)
|
|
100 |
fake_http.add_response(200, content="content")
|
|
98 | 101 |
with pytest.raises(APIError) as error: |
99 | 102 |
token = connector.get_access_token('nameid') |
100 | 103 |
assert str(error.value) == 'No JSON content returned: \'content\'' |
101 | 104 | |
102 |
mocked_post.return_value = utils.FakedResponse(content="content", status_code=200)
|
|
105 |
fake_http.add_response(200, content="content")
|
|
103 | 106 |
with pytest.raises(APIError) as error: |
104 | 107 |
token = connector.get_access_token('nameid') |
105 | 108 |
assert str(error.value) == 'No JSON content returned: \'content\'' |
106 | 109 | |
107 |
mocked_post.return_value = utils.FakedResponse(content='{"IsSuccess": false, "CodErreur": "Fail", "LibErreur": "Auth FAIL"}', |
|
108 |
status_code=200) |
|
110 |
fake_http.add_response(200, content='{"IsSuccess": false, "CodErreur": "Fail", "LibErreur": "Auth FAIL"}') |
|
109 | 111 |
with pytest.raises(APIError) as error: |
110 | 112 |
token = connector.get_access_token('nameid') |
111 | 113 |
assert str(error.value) == 'Auth FAIL (Fail)' |
112 | 114 | |
113 | 115 | |
114 |
@mock.patch('passerelle.utils.Request.get') |
|
115 |
@mock.patch('passerelle.utils.Request.post') |
|
116 |
def test_get_user_forms(mocked_post, mocked_get, app, connector): |
|
116 |
def test_get_user_forms(fake_http, app, connector): |
|
117 | 117 |
endpoint = reverse('generic-endpoint', kwargs={ |
118 | 118 |
'connector': 'arpege-ecp', 'slug': connector.slug, 'endpoint': 'api', 'rest': 'users/nameid/forms'}) |
119 | 119 |
assert endpoint == '/arpege-ecp/test/api/users/nameid/forms' |
120 | 120 | |
121 |
mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
|
|
122 |
mocked_get.return_value = utils.FakedResponse(content=FAKE_USER_DEMANDS_RESPONSE, status_code=200)
|
|
121 |
fake_http.add_response(200, content=FAKE_LOGIN_OIDC_RESPONSE)
|
|
122 |
fake_http.add_response(200, content=FAKE_USER_DEMANDS_RESPONSE)
|
|
123 | 123 |
resp = app.get(endpoint) |
124 | 124 |
result = resp.json |
125 | 125 |
assert resp.json['data'] |
... | ... | |
134 | 134 |
assert item['form_status_is_endpoint'] == False |
135 | 135 | |
136 | 136 | |
137 |
@mock.patch('passerelle.utils.Request.get') |
|
138 |
@mock.patch('passerelle.utils.Request.post') |
|
139 |
def test_get_user_forms_failure(mocked_post, mocked_get, app, connector): |
|
137 |
def test_get_user_forms_failure(fake_http, app, connector): |
|
140 | 138 |
endpoint = reverse('generic-endpoint', kwargs={ |
141 | 139 |
'connector': 'arpege-ecp', 'slug': connector.slug, 'endpoint': 'api', 'rest': 'users/nameid/forms'}) |
142 | 140 | |
143 |
mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
|
|
144 |
mocked_get.return_value = utils.FakedResponse(content='{"IsSuccess": false, "CodErreur": "Fail", "LibErreur": "Failed to get demands"}',
|
|
145 |
status_code=200)
|
|
141 |
fake_http.add_response(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
|
|
142 |
fake_http.add_response(content='{"IsSuccess": false, "CodErreur": "Fail", "LibErreur": "Failed to get demands"}',
|
|
143 |
status_code=200) |
|
146 | 144 |
resp = app.get(endpoint) |
147 | 145 |
result = resp.json |
148 | 146 |
assert result['err'] == 1 |
149 | 147 |
assert result['err_desc'] == 'Failed to get demands (Fail)' |
150 | 148 | |
151 | 149 | |
152 |
@mock.patch('passerelle.utils.Request.get') |
|
153 |
@mock.patch('passerelle.utils.Request.post') |
|
154 |
def test_get_user_forms_failure_404(mocked_post, mocked_get, app, connector): |
|
150 |
def test_get_user_forms_failure_404(fake_http, app, connector): |
|
155 | 151 |
endpoint = reverse('generic-endpoint', kwargs={ |
156 | 152 |
'connector': 'arpege-ecp', 'slug': connector.slug, 'endpoint': 'api', 'rest': 'users/nameid/forms'}) |
157 | 153 | |
158 |
mocked_post.return_value = utils.FakedResponse(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
|
|
159 |
mocked_get.return_value = utils.FakedResponse(content=FAKE_USER_DEMANDS_RESPONSE, status_code=404)
|
|
154 |
fake_http.add_response(content=FAKE_LOGIN_OIDC_RESPONSE, status_code=200)
|
|
155 |
fake_http.add_response(content=FAKE_USER_DEMANDS_RESPONSE, status_code=404)
|
|
160 | 156 |
resp = app.get(endpoint) |
161 | 157 |
result = resp.json |
162 | 158 |
assert result['err'] == 1 |
163 |
assert result['err_desc'] == 'HTTP error: 404'
|
|
159 |
assert '404 Client Error' in result['err_desc']
|
|
164 | 160 | |
165 | 161 | |
166 | 162 |
@mock.patch('passerelle.utils.Request.get') |
tests/test_gdema.py | ||
---|---|---|
75 | 75 |
return gdema |
76 | 76 | |
77 | 77 | |
78 |
def test_gdema_services_and_typologies(app, gdema): |
|
78 |
def test_gdema_services_and_typologies(fake_http, app, gdema):
|
|
79 | 79 |
endpoint = utils.generic_endpoint_url('gdema', 'referentiel', slug=gdema.slug) |
80 | 80 |
assert endpoint == '/gdema/test/referentiel' |
81 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
82 |
requests_get.return_value = utils.FakedResponse(content=SERVICES, |
|
83 |
status_code=200) |
|
84 |
resp = app.get(endpoint + '/service/', status=200) |
|
85 |
assert requests_get.call_count == 1 |
|
86 |
assert requests_get.call_args[0][0] == 'https://gdema.example.net/api/referentiel/service' |
|
87 |
assert 'data' in resp.json |
|
88 |
assert resp.json['err'] == 0 |
|
89 |
assert len(resp.json['data']) == 3 |
|
90 |
assert resp.json['data'][0]['id'] == '16151' |
|
91 |
assert resp.json['data'][0]['text'] == u'DMT - Mobilité et transports' |
|
92 | ||
93 |
resp = app.get(endpoint + '/typology/', status=200) |
|
94 |
assert requests_get.call_count == 2 |
|
95 |
assert 'data' in resp.json |
|
96 |
assert resp.json['err'] == 0 |
|
97 |
assert len(resp.json['data']) == 12 |
|
98 |
assert resp.json['data'][0]['id'] == '13067' |
|
99 |
assert resp.json['data'][0]['text'] == u'Maintenance Cie' |
|
100 |
assert resp.json['data'][0]['service_id'] == '10173' |
|
101 |
assert resp.json['data'][0]['service_text'] == u'DESPU - Administration Direction environnement et services publics urbains' |
|
102 | ||
103 |
resp = app.get(endpoint + '/typology/?service_id=10426', status=200) |
|
104 |
assert requests_get.call_count == 3 |
|
105 |
assert 'data' in resp.json |
|
106 |
assert resp.json['err'] == 0 |
|
107 |
assert len(resp.json['data']) == 7 |
|
108 |
assert resp.json['data'][0]['id'] == '10804' |
|
109 |
assert resp.json['data'][0]['text'] == u'Activités périscolaires' |
|
110 |
assert resp.json['data'][0]['service_id'] == '10426' |
|
111 |
assert resp.json['data'][0]['service_text'] == u'DEE - Périscolaire et éducatif' |
|
112 | ||
113 | ||
114 |
def test_gdema_referentiel(app, gdema): |
|
81 |
fake_http.add_response(content=SERVICES, status_code=200) |
|
82 |
resp = app.get(endpoint + '/service/', status=200) |
|
83 |
assert fake_http.last_request.url == 'https://gdema.example.net/api/referentiel/service' |
|
84 |
assert 'data' in resp.json |
|
85 |
assert resp.json['err'] == 0 |
|
86 |
assert len(resp.json['data']) == 3 |
|
87 |
assert resp.json['data'][0]['id'] == '16151' |
|
88 |
assert resp.json['data'][0]['text'] == u'DMT - Mobilité et transports' |
|
89 | ||
90 |
fake_http.add_response(content=SERVICES, status_code=200) |
|
91 |
resp = app.get(endpoint + '/typology/', status=200) |
|
92 |
assert 'data' in resp.json |
|
93 |
assert resp.json['err'] == 0 |
|
94 |
assert len(resp.json['data']) == 12 |
|
95 |
assert resp.json['data'][0]['id'] == '13067' |
|
96 |
assert resp.json['data'][0]['text'] == u'Maintenance Cie' |
|
97 |
assert resp.json['data'][0]['service_id'] == '10173' |
|
98 |
assert resp.json['data'][0]['service_text'] == u'DESPU - Administration Direction environnement et services publics urbains' |
|
99 | ||
100 |
fake_http.add_response(content=SERVICES, status_code=200) |
|
101 |
resp = app.get(endpoint + '/typology/?service_id=10426', status=200) |
|
102 |
assert 'data' in resp.json |
|
103 |
assert resp.json['err'] == 0 |
|
104 |
assert len(resp.json['data']) == 7 |
|
105 |
assert resp.json['data'][0]['id'] == '10804' |
|
106 |
assert resp.json['data'][0]['text'] == u'Activités périscolaires' |
|
107 |
assert resp.json['data'][0]['service_id'] == '10426' |
|
108 |
assert resp.json['data'][0]['service_text'] == u'DEE - Périscolaire et éducatif' |
|
109 | ||
110 | ||
111 |
def test_gdema_referentiel(fake_http, app, gdema): |
|
115 | 112 |
endpoint = utils.generic_endpoint_url('gdema', 'referentiel', slug=gdema.slug) |
116 | 113 |
assert endpoint == '/gdema/test/referentiel' |
117 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
118 |
requests_get.return_value = utils.FakedResponse(content=CIVILITY, |
|
119 |
status_code=200) |
|
120 |
resp = app.get(endpoint + '/civility/', status=200) |
|
121 |
assert requests_get.call_count == 1 |
|
122 |
assert requests_get.call_args[0][0] == 'https://gdema.example.net/api/referentiel/civility' |
|
123 |
assert 'data' in resp.json |
|
124 |
assert resp.json['err'] == 0 |
|
125 |
assert len(resp.json['data']) == 3 |
|
126 |
assert resp.json['data'][0]['id'] == '1' |
|
127 |
assert resp.json['data'][0]['text'] == 'Monsieur' |
|
128 | ||
129 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
130 |
requests_get.return_value = utils.FakedResponse(content='404', status_code=404) |
|
131 |
resp = app.get(endpoint + '/nothing/', status=200) |
|
132 |
assert requests_get.call_count == 1 |
|
133 |
assert requests_get.call_args[0][0] == 'https://gdema.example.net/api/referentiel/nothing' |
|
134 |
assert 'data' in resp.json |
|
135 |
assert resp.json['err'] == 1 |
|
136 |
assert resp.json['data'] is None |
|
137 |
assert resp.json['err_class'].endswith('.APIError') |
|
138 |
assert '404' in resp.json['err_desc'] |
|
139 | ||
140 | ||
141 |
def test_gdema_get_request(app, gdema): |
|
114 |
fake_http.add_response(content=CIVILITY, status_code=200) |
|
115 |
resp = app.get(endpoint + '/civility/', status=200) |
|
116 |
assert fake_http.last_request.url == 'https://gdema.example.net/api/referentiel/civility' |
|
117 |
assert 'data' in resp.json |
|
118 |
assert resp.json['err'] == 0 |
|
119 |
assert len(resp.json['data']) == 3 |
|
120 |
assert resp.json['data'][0]['id'] == '1' |
|
121 |
assert resp.json['data'][0]['text'] == 'Monsieur' |
|
122 | ||
123 |
fake_http.add_response(content='404', status_code=404) |
|
124 |
resp = app.get(endpoint + '/nothing/', status=200) |
|
125 |
assert fake_http.last_request.url == 'https://gdema.example.net/api/referentiel/nothing' |
|
126 |
assert 'data' in resp.json |
|
127 |
assert resp.json['err'] == 1 |
|
128 |
assert resp.json['data'] is None |
|
129 |
assert resp.json['err_class'].endswith('.APIError') |
|
130 |
assert '404' in resp.json['err_desc'] |
|
131 | ||
132 | ||
133 |
def test_gdema_get_request(fake_http, app, gdema): |
|
142 | 134 |
endpoint = utils.generic_endpoint_url('gdema', 'get-request', slug=gdema.slug) |
143 | 135 |
assert endpoint == '/gdema/test/get-request' |
144 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
145 |
requests_get.return_value = utils.FakedResponse(content=REQUEST, |
|
146 |
status_code=200) |
|
147 |
resp = app.get(endpoint + '/1/', status=200) |
|
148 |
assert requests_get.call_count == 1 |
|
149 |
assert requests_get.call_args[0][0] == 'https://gdema.example.net/api/request/1' |
|
150 |
assert 'data' in resp.json |
|
151 |
assert resp.json['err'] == 0 |
|
152 |
assert resp.json['data']['Id'] == '1' |
|
153 |
assert resp.json['data']['AnswerToProvide'] is True |
|
154 |
assert resp.json['data']['Description'].startswith(u'contrôle') |
|
155 |
assert resp.json['data']['ExpectedDate'] is None |
|
156 |
assert resp.json['data']['Files'] == [] |
|
157 |
assert resp.json['data']['Handler']['CivilityId'] == '0' |
|
158 |
assert resp.json['data']['ReceptDate'] == '2006-12-13T00:00:00+01:00' |
|
136 |
fake_http.add_response(content=REQUEST, status_code=200) |
|
137 |
resp = app.get(endpoint + '/1/', status=200) |
|
138 |
assert fake_http.last_request.url == 'https://gdema.example.net/api/request/1' |
|
139 |
assert 'data' in resp.json |
|
140 |
assert resp.json['err'] == 0 |
|
141 |
assert resp.json['data']['Id'] == '1' |
|
142 |
assert resp.json['data']['AnswerToProvide'] is True |
|
143 |
assert resp.json['data']['Description'].startswith(u'contrôle') |
|
144 |
assert resp.json['data']['ExpectedDate'] is None |
|
145 |
assert resp.json['data']['Files'] == [] |
|
146 |
assert resp.json['data']['Handler']['CivilityId'] == '0' |
|
147 |
assert resp.json['data']['ReceptDate'] == '2006-12-13T00:00:00+01:00' |
|
159 | 148 | |
160 | 149 |
endpoint = utils.generic_endpoint_url('gdema', 'get-request-state', slug=gdema.slug) |
161 | 150 |
assert endpoint == '/gdema/test/get-request-state' |
162 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
163 |
requests_get.return_value = utils.FakedResponse(content=REQUEST_STATE, |
|
164 |
status_code=200) |
|
165 |
resp = app.get(endpoint + '/1/', status=200) |
|
166 |
assert requests_get.call_count == 1 |
|
167 |
assert requests_get.call_args[0][0] == 'https://gdema.example.net/api/request/1/state' |
|
168 |
assert 'data' in resp.json |
|
169 |
assert resp.json['err'] == 0 |
|
170 |
assert resp.json['data'] == {'Id': '1', 'State': '64', 'StateLabel': u'Cloturée'} |
|
171 | ||
172 | ||
173 |
def test_gdema_create_request(app, gdema): |
|
151 |
fake_http.add_response(content=REQUEST_STATE, status_code=200) |
|
152 |
resp = app.get(endpoint + '/1/', status=200) |
|
153 |
assert fake_http.last_request.url == 'https://gdema.example.net/api/request/1/state' |
|
154 |
assert 'data' in resp.json |
|
155 |
assert resp.json['err'] == 0 |
|
156 |
assert resp.json['data'] == {'Id': '1', 'State': '64', 'StateLabel': u'Cloturée'} |
|
157 | ||
158 | ||
159 |
def test_gdema_create_request(fake_http, app, gdema): |
|
174 | 160 |
endpoint = utils.generic_endpoint_url('gdema', 'create-request', slug=gdema.slug) |
175 | 161 |
assert endpoint == '/gdema/test/create-request' |
176 |
with mock.patch('passerelle.utils.Request.post') as requests_post: |
|
177 |
requests_post.return_value = utils.FakedResponse(content=REQUEST, |
|
178 |
status_code=200) |
|
179 |
resp = app.post_json(endpoint + '?raise=1', params=CREATE_INPUT, status=200) |
|
180 |
assert requests_post.call_count == 1 |
|
181 |
assert requests_post.call_args[0][0] == 'https://gdema.example.net/api/request/create' |
|
182 |
assert json.loads(requests_post.call_args[1]['data']) == CONVERTED_INPUT |
|
183 |
assert 'data' in resp.json |
|
184 |
assert resp.json['err'] == 0 |
|
185 |
assert resp.json['data']['Id'] == '1' |
|
162 |
fake_http.add_response(content=REQUEST, status_code=200) |
|
163 |
resp = app.post_json(endpoint + '?raise=1', params=CREATE_INPUT, status=200) |
|
164 |
assert fake_http.last_request.url == 'https://gdema.example.net/api/request/create' |
|
165 |
assert fake_http.last_request.json == CONVERTED_INPUT |
|
166 |
assert 'data' in resp.json |
|
167 |
assert resp.json['err'] == 0 |
|
168 |
assert resp.json['data']['Id'] == '1' |
tests/test_generic_endpoint.py | ||
---|---|---|
309 | 309 | |
310 | 310 |
@endpoint(methods=['get']) |
311 | 311 |
def httpcall(obj, request): |
312 |
response = obj.requests.get(httpbin.url + '/cookies/set?foo=bar', allow_redirects=False) |
|
312 |
response = obj.requests.get(httpbin.url + '/cookies/set?foo=bar', |
|
313 |
raise_for_redirect=False, |
|
314 |
allow_redirects=False) |
|
313 | 315 |
cookie1 = response.request.headers.get('Cookie') |
314 | 316 |
response = obj.requests.get(httpbin.url + '/get') |
315 | 317 |
cookie2 = response.request.headers.get('Cookie') |
... | ... | |
339 | 341 | |
340 | 342 |
resource = utils.make_resource(Maarch, wsdl_url='https://example.com/', slug='slug', verify_cert=True) |
341 | 343 |
with pytest.raises(SSLError): |
342 |
resource.requests.get(httpbin_secure.join('/get/'))
|
|
344 |
resource.requests.get(httpbin_secure.join('/get')) |
|
343 | 345 |
resource.verify_cert = False |
344 | 346 |
with warnings.catch_warnings(): |
345 | 347 |
warnings.simplefilter('error') |
346 |
resource.requests.get(httpbin_secure.join('/get/')) |
|
348 |
resource.requests.get(httpbin_secure.join('/get')) |
tests/test_okina.py | ||
---|---|---|
1339 | 1339 |
password='userpass') |
1340 | 1340 | |
1341 | 1341 | |
1342 |
def test_okina_cities(app, okina): |
|
1342 |
def test_okina_cities(fake_http, app, okina):
|
|
1343 | 1343 |
endpoint = utils.generic_endpoint_url('okina', 'cities', slug=okina.slug) |
1344 | 1344 |
assert endpoint == '/okina/test/cities' |
1345 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
1346 |
requests_get.return_value = utils.FakedResponse(content=CITIES, |
|
1347 |
status_code=200) |
|
1348 |
resp = app.get(endpoint, status=200) |
|
1349 |
assert requests_get.call_count == 1 |
|
1350 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/cities' |
|
1351 |
assert requests_get.call_args[1]['auth'] == ('usertest', 'userpass') |
|
1352 |
assert 'data' in resp.json |
|
1353 |
assert resp.json['err'] == 0 |
|
1354 |
assert len(resp.json['data']) == 2 |
|
1355 |
assert resp.json['data'][0]['id'] == '83355' |
|
1356 |
assert resp.json['data'][0]['insee'] == '36005' |
|
1357 |
assert resp.json['data'][0]['text'] == 'ARDENTES (36120)' |
|
1345 |
fake_http.set_response(content=CITIES, status_code=200) |
|
1346 |
resp = app.get(endpoint, status=200) |
|
1347 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/cities' |
|
1348 |
assert fake_http.last_request.basic_auth == ['usertest', 'userpass'] |
|
1349 |
assert 'data' in resp.json |
|
1350 |
assert resp.json['err'] == 0 |
|
1351 |
assert len(resp.json['data']) == 2 |
|
1352 |
assert resp.json['data'][0]['id'] == '83355' |
|
1353 |
assert resp.json['data'][0]['insee'] == '36005' |
|
1354 |
assert resp.json['data'][0]['text'] == 'ARDENTES (36120)' |
|
1355 | ||
1358 | 1356 | |
1359 |
def test_okina_classes(app, okina): |
|
1357 |
def test_okina_classes(fake_http, app, okina):
|
|
1360 | 1358 |
endpoint = utils.generic_endpoint_url('okina', 'classes', slug=okina.slug) |
1361 | 1359 |
assert endpoint == '/okina/test/classes' |
1362 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
1363 |
requests_get.return_value = utils.FakedResponse(content=CLASSES, |
|
1364 |
status_code=200) |
|
1365 |
resp = app.get(endpoint, status=200) |
|
1366 |
assert requests_get.call_count == 1 |
|
1367 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/classes' |
|
1368 |
assert resp.json['err'] == 0 |
|
1369 |
assert len(resp.json['data']) == 4 |
|
1370 |
assert resp.json['data'][0]['id'] == '1' |
|
1371 |
assert resp.json['data'][0]['text'] == u'École maternelle - Petite section' |
|
1360 |
fake_http.set_response(content=CLASSES, status_code=200) |
|
1361 |
resp = app.get(endpoint, status=200) |
|
1362 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/classes' |
|
1363 |
assert resp.json['err'] == 0 |
|
1364 |
assert len(resp.json['data']) == 4 |
|
1365 |
assert resp.json['data'][0]['id'] == '1' |
|
1366 |
assert resp.json['data'][0]['text'] == u'École maternelle - Petite section' |
|
1372 | 1367 | |
1373 |
def test_okina_institutions(app, okina): |
|
1368 | ||
1369 |
def test_okina_institutions(fake_http, app, okina): |
|
1374 | 1370 |
endpoint = utils.generic_endpoint_url('okina', 'institutions', slug=okina.slug) |
1375 | 1371 |
assert endpoint == '/okina/test/institutions' |
1376 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
1377 |
requests_get.return_value = utils.FakedResponse(content=INSTITUTIONS, |
|
1378 |
status_code=200) |
|
1379 |
resp = app.get(endpoint, status=200) |
|
1380 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/institutions' |
|
1381 |
assert resp.json['err'] == 0 |
|
1382 |
assert len(resp.json['data']) == 2 |
|
1383 |
assert resp.json['data'][0]['id'] == '277' |
|
1384 |
assert resp.json['data'][0]['text'] == u'Collège Touvent' |
|
1372 |
fake_http.set_response(content=INSTITUTIONS, status_code=200) |
|
1373 |
resp = app.get(endpoint, status=200) |
|
1374 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/institutions' |
|
1375 |
assert resp.json['err'] == 0 |
|
1376 |
assert len(resp.json['data']) == 2 |
|
1377 |
assert resp.json['data'][0]['id'] == '277' |
|
1378 |
assert resp.json['data'][0]['text'] == u'Collège Touvent' |
|
1385 | 1379 | |
1386 |
resp = app.get(endpoint + '/from-city/36005/', status=200) |
|
1387 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/institutions/subscriberCity/36005' |
|
1388 |
assert resp.json['err'] == 0 |
|
1389 |
assert len(resp.json['data']) == 2 |
|
1390 |
assert resp.json['data'][0]['id'] == '277' |
|
1391 |
assert resp.json['data'][0]['text'] == u'Collège Touvent' |
|
1380 |
fake_http.set_response(content=INSTITUTIONS, status_code=200) |
|
1381 |
resp = app.get(endpoint + '/from-city/36005/', status=200) |
|
1382 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/institutions/subscriberCity/36005' |
|
1383 |
assert resp.json['err'] == 0 |
|
1384 |
assert len(resp.json['data']) == 2 |
|
1385 |
assert resp.json['data'][0]['id'] == '277' |
|
1386 |
assert resp.json['data'][0]['text'] == u'Collège Touvent' |
|
1392 | 1387 | |
1393 |
def test_okina_stops_area(app, okina): |
|
1388 | ||
1389 |
def test_okina_stops_area(fake_http, app, okina): |
|
1394 | 1390 |
endpoint = utils.generic_endpoint_url('okina', 'stop-areas', slug=okina.slug) |
1395 | 1391 |
assert endpoint == '/okina/test/stop-areas' |
1396 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
1397 |
requests_get.return_value = utils.FakedResponse(content=STOPS, |
|
1398 |
status_code=200) |
|
1399 |
resp = app.get(endpoint + '/from-city/36005/to-institution/276/', status=200) |
|
1400 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/stop-areas/subscriberCity/36005/institution/276' |
|
1401 |
assert resp.json['err'] == 0 |
|
1402 |
assert len(resp.json['data']) == 3 |
|
1403 |
assert resp.json['data'][0]['id'] == '3281' |
|
1404 |
assert resp.json['data'][0]['text'] == u'Les Loges de Dressais' |
|
1392 |
fake_http.set_response(content=STOPS, status_code=200) |
|
1393 |
resp = app.get(endpoint + '/from-city/36005/to-institution/276/', status=200) |
|
1394 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/stop-areas/subscriberCity/36005/institution/276' |
|
1395 |
assert resp.json['err'] == 0 |
|
1396 |
assert len(resp.json['data']) == 3 |
|
1397 |
assert resp.json['data'][0]['id'] == '3281' |
|
1398 |
assert resp.json['data'][0]['text'] == u'Les Loges de Dressais' |
|
1399 | ||
1405 | 1400 | |
1406 |
def test_okina_ods(app, okina): |
|
1401 |
def test_okina_ods(fake_http, app, okina):
|
|
1407 | 1402 |
endpoint = utils.generic_endpoint_url('okina', 'origin-destinations', slug=okina.slug) |
1408 | 1403 |
assert endpoint == '/okina/test/origin-destinations' |
1409 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
1410 |
requests_get.return_value = utils.FakedResponse(content=ODS, status_code=200) |
|
1411 |
resp = app.get(endpoint, status=200) |
|
1412 |
assert requests_get.call_count == 1 |
|
1413 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods' |
|
1414 |
assert resp.json['err'] == 0 |
|
1415 |
assert len(resp.json['data']) == 2 |
|
1416 |
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84' |
|
1417 |
assert resp.json['data'][0]['text'] == 'SYNDICAT ARDENTES 4 (semaine Aller)' |
|
1418 |
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)' |
|
1419 |
assert resp.json['data'][0]['vehicle_journey_id'] == '84' |
|
1404 |
fake_http.set_response(content=ODS, status_code=200) |
|
1405 |
resp = app.get(endpoint, status=200) |
|
1406 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/ods' |
|
1407 |
assert resp.json['err'] == 0 |
|
1408 |
assert len(resp.json['data']) == 2 |
|
1409 |
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84' |
|
1410 |
assert resp.json['data'][0]['text'] == 'SYNDICAT ARDENTES 4 (semaine Aller)' |
|
1411 |
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)' |
|
1412 |
assert resp.json['data'][0]['vehicle_journey_id'] == '84' |
|
1420 | 1413 | |
1421 |
requests_get.return_value = utils.FakedResponse(content=ODS, status_code=200)
|
|
1422 |
resp = app.get(endpoint + '/to-institution/276/', status=200)
|
|
1423 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods/institution/276'
|
|
1424 |
assert resp.json['err'] == 0
|
|
1425 |
assert len(resp.json['data']) == 2
|
|
1426 |
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84'
|
|
1427 |
assert resp.json['data'][0]['text'] == 'SYNDICAT ARDENTES 4 (semaine Aller)'
|
|
1428 |
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)'
|
|
1429 |
assert resp.json['data'][0]['vehicle_journey_id'] == '84'
|
|
1414 |
fake_http.set_response(content=ODS, status_code=200)
|
|
1415 |
resp = app.get(endpoint + '/to-institution/276/', status=200) |
|
1416 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/ods/institution/276'
|
|
1417 |
assert resp.json['err'] == 0 |
|
1418 |
assert len(resp.json['data']) == 2 |
|
1419 |
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84' |
|
1420 |
assert resp.json['data'][0]['text'] == 'SYNDICAT ARDENTES 4 (semaine Aller)' |
|
1421 |
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)' |
|
1422 |
assert resp.json['data'][0]['vehicle_journey_id'] == '84' |
|
1430 | 1423 | |
1431 |
requests_get.return_value = utils.FakedResponse(content=ODS_LINES, status_code=200)
|
|
1432 |
resp = app.get(endpoint + '/from-stop-area/3282/to-institution/276/', status=200)
|
|
1433 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods/institution/276/stop-area/3282'
|
|
1434 |
assert resp.json['err'] == 0
|
|
1435 |
assert len(resp.json['data']) == 3
|
|
1436 |
assert resp.json['data'][0]['id'] == '1'
|
|
1437 |
assert resp.json['data'][0]['text'] == 'LIGNE 24'
|
|
1438 |
assert len(resp.json['data'][0]['lines']) == 1
|
|
1439 |
assert resp.json['data'][0]['lines'][0]['id'] == '24'
|
|
1440 |
assert resp.json['data'][0]['lines'][0]['text'] == 'LIGNE 24'
|
|
1441 |
assert resp.json['data'][1]['id'] == '2'
|
|
1442 |
assert resp.json['data'][1]['text'] == 'LIGNE 22'
|
|
1443 |
assert len(resp.json['data'][1]['lines']) == 1
|
|
1444 |
assert resp.json['data'][1]['lines'][0]['id'] == '22'
|
|
1445 |
assert resp.json['data'][1]['lines'][0]['text'] == 'LIGNE 22'
|
|
1446 |
assert resp.json['data'][2]['id'] == '3'
|
|
1447 |
assert resp.json['data'][2]['text'] == 'LIGNE 24 + LIGNE 23'
|
|
1448 |
assert len(resp.json['data'][2]['lines']) == 2
|
|
1449 |
assert resp.json['data'][2]['lines'][0]['id'] == '24'
|
|
1450 |
assert resp.json['data'][2]['lines'][0]['text'] == 'LIGNE 24'
|
|
1451 |
assert resp.json['data'][2]['lines'][1]['id'] == '23'
|
|
1452 |
assert resp.json['data'][2]['lines'][1]['text'] == 'LIGNE 23'
|
|
1424 |
fake_http.set_response(content=ODS_LINES, status_code=200)
|
|
1425 |
resp = app.get(endpoint + '/from-stop-area/3282/to-institution/276/', status=200) |
|
1426 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/ods/institution/276/stop-area/3282'
|
|
1427 |
assert resp.json['err'] == 0 |
|
1428 |
assert len(resp.json['data']) == 3 |
|
1429 |
assert resp.json['data'][0]['id'] == '1' |
|
1430 |
assert resp.json['data'][0]['text'] == 'LIGNE 24' |
|
1431 |
assert len(resp.json['data'][0]['lines']) == 1 |
|
1432 |
assert resp.json['data'][0]['lines'][0]['id'] == '24' |
|
1433 |
assert resp.json['data'][0]['lines'][0]['text'] == 'LIGNE 24' |
|
1434 |
assert resp.json['data'][1]['id'] == '2' |
|
1435 |
assert resp.json['data'][1]['text'] == 'LIGNE 22' |
|
1436 |
assert len(resp.json['data'][1]['lines']) == 1 |
|
1437 |
assert resp.json['data'][1]['lines'][0]['id'] == '22' |
|
1438 |
assert resp.json['data'][1]['lines'][0]['text'] == 'LIGNE 22' |
|
1439 |
assert resp.json['data'][2]['id'] == '3' |
|
1440 |
assert resp.json['data'][2]['text'] == 'LIGNE 24 + LIGNE 23' |
|
1441 |
assert len(resp.json['data'][2]['lines']) == 2 |
|
1442 |
assert resp.json['data'][2]['lines'][0]['id'] == '24' |
|
1443 |
assert resp.json['data'][2]['lines'][0]['text'] == 'LIGNE 24' |
|
1444 |
assert resp.json['data'][2]['lines'][1]['id'] == '23' |
|
1445 |
assert resp.json['data'][2]['lines'][1]['text'] == 'LIGNE 23' |
|
1453 | 1446 | |
1454 |
requests_get.return_value = utils.FakedResponse(content=ODS_FULL, status_code=200) |
|
1455 |
resp = app.get(endpoint + '/from-city/36005/to-institution/276/', status=200) |
|
1456 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods/institution/276/subscriberCity/36005' |
|
1457 |
assert resp.json['err'] == 0 |
|
1458 |
assert len(resp.json['data']) == 1 |
|
1459 |
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84' |
|
1460 |
assert resp.json['data'][0]['text'] == u'Brenne 1 vers écoles Antoine Fée, Saint Martin et Saint Vincent' |
|
1461 |
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)' |
|
1462 |
assert resp.json['data'][0]['vehicle_journey_id'] == '84' |
|
1447 |
fake_http.set_response(content=ODS_FULL, status_code=200) |
|
1448 |
resp = app.get(endpoint + '/from-city/36005/to-institution/276/', status=200) |
|
1449 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/ods/institution/276/subscriberCity/36005' |
|
1450 |
assert resp.json['err'] == 0 |
|
1451 |
assert len(resp.json['data']) == 1 |
|
1452 |
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84' |
|
1453 |
assert resp.json['data'][0]['text'] == u'Brenne 1 vers écoles Antoine Fée, Saint Martin et Saint Vincent' |
|
1454 |
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)' |
|
1455 |
assert resp.json['data'][0]['vehicle_journey_id'] == '84' |
|
1456 | ||
1457 |
fake_http.set_response(content=ODS_FULL, status_code=200) |
|
1458 |
resp = app.get(endpoint + '/from-city/36005/', status=200) |
|
1459 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/ods/subscriberCity/36005' |
|
1460 |
assert resp.json['err'] == 0 |
|
1461 |
assert len(resp.json['data']) == 1 |
|
1462 |
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84' |
|
1463 |
assert resp.json['data'][0]['text'] == u'Brenne 1 vers écoles Antoine Fée, Saint Martin et Saint Vincent' |
|
1464 |
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)' |
|
1465 |
assert resp.json['data'][0]['vehicle_journey_id'] == '84' |
|
1463 | 1466 | |
1464 |
requests_get.return_value = utils.FakedResponse(content=ODS_FULL, status_code=200) |
|
1465 |
resp = app.get(endpoint + '/from-city/36005/', status=200) |
|
1466 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/ods/subscriberCity/36005' |
|
1467 |
assert resp.json['err'] == 0 |
|
1468 |
assert len(resp.json['data']) == 1 |
|
1469 |
assert resp.json['data'][0]['id'] == 'inst:276-seq:1-6-84' |
|
1470 |
assert resp.json['data'][0]['text'] == u'Brenne 1 vers écoles Antoine Fée, Saint Martin et Saint Vincent' |
|
1471 |
assert resp.json['data'][0]['identifier'] == 'SYNDICAT ARDENTES 4 (semaine Aller)' |
|
1472 |
assert resp.json['data'][0]['vehicle_journey_id'] == '84' |
|
1473 | 1467 | |
1474 |
def test_okina_topology(app, okina): |
|
1468 |
def test_okina_topology(fake_http, app, okina):
|
|
1475 | 1469 |
endpoint = utils.generic_endpoint_url('okina', 'topology', slug=okina.slug) |
1476 | 1470 |
assert endpoint == '/okina/test/topology' |
1477 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
1478 |
requests_get.return_value = utils.FakedResponse(content=LINES, status_code=200) |
|
1479 |
resp = app.get(endpoint + '/lines/', status=200) |
|
1480 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/topology/lines' |
|
1481 |
assert resp.json['err'] == 0 |
|
1482 |
assert len(resp.json['data']) == 3 |
|
1483 |
assert resp.json['data'][0]['id'] == '45' |
|
1484 |
assert resp.json['data'][0]['text'] == '019 - 02 - VELLES LYCEES DE CHATEAUROUX' |
|
1471 |
fake_http.set_response(content=LINES, status_code=200) |
|
1472 |
resp = app.get(endpoint + '/lines/', status=200) |
|
1473 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/topology/lines' |
|
1474 |
assert resp.json['err'] == 0 |
|
1475 |
assert len(resp.json['data']) == 3 |
|
1476 |
assert resp.json['data'][0]['id'] == '45' |
|
1477 |
assert resp.json['data'][0]['text'] == '019 - 02 - VELLES LYCEES DE CHATEAUROUX' |
|
1485 | 1478 | |
1486 |
requests_get.return_value = utils.FakedResponse(content=NETWORKS, status_code=200)
|
|
1487 |
resp = app.get(endpoint + '/networks/', status=200)
|
|
1488 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/topology/networks'
|
|
1489 |
assert resp.json['err'] == 0
|
|
1490 |
assert len(resp.json['data']) == 1
|
|
1491 |
assert resp.json['data'][0]['id'] == '2'
|
|
1492 |
assert resp.json['data'][0]['text'] == u'réseau scolaire'
|
|
1479 |
fake_http.set_response(content=NETWORKS, status_code=200)
|
|
1480 |
resp = app.get(endpoint + '/networks/', status=200) |
|
1481 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/topology/networks'
|
|
1482 |
assert resp.json['err'] == 0 |
|
1483 |
assert len(resp.json['data']) == 1 |
|
1484 |
assert resp.json['data'][0]['id'] == '2' |
|
1485 |
assert resp.json['data'][0]['text'] == u'réseau scolaire' |
|
1493 | 1486 | |
1494 |
requests_get.return_value = utils.FakedResponse(content=VEHICLE_JOURNEYS, status_code=200)
|
|
1495 |
resp = app.get(endpoint + '/vehicle-journeys/', status=200)
|
|
1496 |
assert requests_get.call_args[0][0] == 'https://okina.example.net/b2b/topology/vehicle-journeys'
|
|
1497 |
assert resp.json['err'] == 0
|
|
1498 |
assert len(resp.json['data']) == 3
|
|
1499 |
assert resp.json['data'][0]['id'] == '306'
|
|
1500 |
assert resp.json['data'][0]['text'] == u'019 02 - VELLES LYCEES DE CHATEAUROUX'
|
|
1487 |
fake_http.set_response(content=VEHICLE_JOURNEYS, status_code=200)
|
|
1488 |
resp = app.get(endpoint + '/vehicle-journeys/', status=200) |
|
1489 |
assert fake_http.last_request.url == 'https://okina.example.net/b2b/topology/vehicle-journeys'
|
|
1490 |
assert resp.json['err'] == 0 |
|
1491 |
assert len(resp.json['data']) == 3 |
|
1492 |
assert resp.json['data'][0]['id'] == '306' |
|
1493 |
assert resp.json['data'][0]['text'] == u'019 02 - VELLES LYCEES DE CHATEAUROUX' |
|
1501 | 1494 | |
1502 |
def test_okina_errors(app, okina): |
|
1503 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
1504 |
for response in ((200, '{"foo": "bar"}'), # not a list |
|
1505 |
(200, '{["foo": "bar"]}'), # list of malformatted dict |
|
1506 |
(200, '<h1>Welcome</h1>'), # bad json |
|
1507 |
(403, '<h1>Bad creds</h1>'), |
|
1508 |
(404, '<h1>Not Found</h1>'), |
|
1509 |
(500, '<h1>Crash</h1>'), |
|
1510 |
): |
|
1511 |
requests_get.return_value = utils.FakedResponse(content=response[1], |
|
1512 |
status_code=response[0]) |
|
1513 |
resp = app.get('/okina/test/cities', status=500) |
|
1514 |
assert resp.json['err'] == 1 |
|
1515 |
assert resp.json['data'] == None |
|
1516 | 1495 | |
1517 |
# "normal" 401/403 response, ie problem with login/password |
|
1518 |
for status_code in (401, 403): |
|
1519 |
requests_get.return_value = utils.FakedResponse(content='''{"message": "Invalid credentials", |
|
1520 |
"code": 4, "status" : %d}''' % status_code, status_code=status_code) |
|
1521 |
resp = app.get('/okina/test/cities', status=500) |
|
1522 |
assert resp.json['err'] == 1 |
|
1523 |
assert resp.json['err_desc'] == "Invalid credentials" |
|
1524 |
assert resp.json['data'] is None |
|
1496 |
def test_okina_errors(fake_http, app, okina): |
|
1497 |
for status_code, content in ( |
|
1498 |
(200, '{"foo": "bar"}'), # not a list |
|
1499 |
(200, '{["foo": "bar"]}'), # list of malformatted dict |
|
1500 |
(200, '<h1>Welcome</h1>'), # bad json |
|
1501 |
(403, '<h1>Bad creds</h1>'), |
|
1502 |
(404, '<h1>Not Found</h1>'), |
|
1503 |
(500, '<h1>Crash</h1>')): |
|
1504 |
fake_http.set_response(status_code=status_code, content=content) |
|
1505 |
resp = app.get('/okina/test/cities', status=500) |
|
1506 |
assert resp.json['err'] == 1 |
|
1507 |
assert resp.json['data'] is None |
|
1525 | 1508 | |
1526 |
def test_okina_suscribe(app, okina): |
|
1509 |
# "normal" 401/403 response, ie problem with login/password |
|
1510 |
for status_code in (401, 403): |
|
1511 |
fake_http.set_response(content='''{"message": "Invalid credentials", "code": 4, "status" : %d}''' % status_code, |
|
1512 |
status_code=status_code) |
|
1513 |
resp = app.get('/okina/test/cities', status=500) |
|
1514 |
assert resp.json['err'] == 1 |
|
1515 |
assert resp.json['err_desc'] == "Invalid credentials" |
|
1516 |
assert resp.json['data'] is None |
|
1517 | ||
1518 | ||
1519 |
def test_okina_suscribe(fake_http, app, okina): |
|
1527 | 1520 | |
1528 | 1521 |
for service in ('subscriber', 'subscription'): |
1529 | 1522 |
endpoint = utils.generic_endpoint_url('okina', service, slug=okina.slug) |
1530 | 1523 |
assert endpoint == '/okina/test/%s' % service |
1531 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
1532 |
resp = app.post(endpoint, status=403) |
|
1533 |
assert requests_get.call_count == 0 |
|
1534 |
assert resp.json['err'] == 1 |
|
1535 |
assert resp.json['err_class'] == 'django.core.exceptions.PermissionDenied' |
|
1524 |
resp = app.post(endpoint, status=403) |
|
1525 |
assert resp.json['err'] == 1 |
|
1526 |
assert resp.json['err_class'] == 'django.core.exceptions.PermissionDenied' |
|
1527 | ||
1536 | 1528 |
# open access |
1537 | 1529 |
api = ApiUser.objects.create(username='all', keytype='', key='') |
1538 | 1530 |
obj_type = ContentType.objects.get_for_model(okina) |
... | ... | |
1541 | 1533 |
for service in ('subscriber', 'subscription'): |
1542 | 1534 |
endpoint = utils.generic_endpoint_url('okina', service, slug=okina.slug) |
1543 | 1535 |
assert endpoint == '/okina/test/%s' % service |
1544 |
with mock.patch('passerelle.utils.Request.post') as requests_get: |
|
1545 |
resp = app.post(endpoint, status=400) # no payload |
|
1546 |
assert requests_get.call_count == 0 |
|
1547 |
assert resp.json['err'] == 1 |
|
1548 |
assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError' |
|
1549 |
assert resp.json['err_desc'] == 'payload must be a JSON object' |
|
1536 |
resp = app.post(endpoint, status=400) # no payload |
|
1537 |
assert resp.json['err'] == 1 |
|
1538 |
assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError' |
|
1539 |
assert resp.json['err_desc'] == 'payload must be a JSON object' |
|
1550 | 1540 | |
1551 |
resp = app.post_json(endpoint, params=[], status=400) # bad payload |
|
1552 |
assert requests_get.call_count == 0 |
|
1553 |
assert resp.json['err'] == 1 |
|
1554 |
assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError' |
|
1555 |
assert resp.json['err_desc'] == 'payload must be a dict' |
|
1541 |
resp = app.post_json(endpoint, params=[], status=400) # bad payload |
|
1542 |
assert resp.json['err'] == 1 |
|
1543 |
assert resp.json['err_class'] == 'passerelle.utils.jsonresponse.APIError' |
|
1544 |
assert resp.json['err_desc'] == 'payload must be a dict' |
|
1556 | 1545 | |
1557 |
requests_get.return_value = utils.FakedResponse(content='{"foo":"bar"}', status_code=200) |
|
1558 |
resp = app.post_json(endpoint, params={'x':'y'}) |
|
1559 |
assert requests_get.call_count == 1 |
|
1560 |
assert resp.json['err'] == 0 |
|
1561 |
assert resp.json['data'] == {'foo': 'bar'} |
|
1546 |
fake_http.set_response(content='{"foo":"bar"}', status_code=200) |
|
1547 |
resp = app.post_json(endpoint, params={'x': 'y'}) |
|
1548 |
assert resp.json['err'] == 0 |
|
1549 |
assert resp.json['data'] == {'foo': 'bar'} |
|
1562 | 1550 | |
1563 | 1551 |
# qrcode |
1564 | 1552 |
endpoint = '/okina/test/subscriber/123/qrcode' |
1565 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
1566 |
requests_get.return_value = utils.FakedResponse(content='PNGfoo', |
|
1567 |
headers={'Content-Type': 'image/png'}, |
|
1568 |
status_code=200) |
|
1569 |
resp = app.get(endpoint) |
|
1570 |
assert requests_get.call_count == 1 |
|
1571 |
assert resp.headers['content-type'] == 'image/png' |
|
1572 |
assert resp.content == 'PNGfoo' |
|
1553 |
fake_http.set_response(content='PNGfoo', headers={'Content-Type': 'image/png'}, status_code=200) |
|
1554 |
resp = app.get(endpoint) |
|
1555 |
assert resp.headers['content-type'] == 'image/png' |
|
1556 |
assert resp.content == 'PNGfoo' |
|
1573 | 1557 | |
1574 |
requests_get.return_value = utils.FakedResponse(content=QRCODE_400, |
|
1575 |
headers={'Content-Type': 'application/json' }, |
|
1576 |
status_code=400) |
|
1577 |
resp = app.get(endpoint, status=400) |
|
1578 |
assert requests_get.call_count == 2 |
|
1579 |
assert resp.json == { |
|
1580 |
u'err': 1, |
|
1581 |
u'err_class': u'passerelle.utils.jsonresponse.APIError', |
|
1582 |
u'err_desc': u'Subscriber with ID 123 has no passcard number to generate qr code from.', |
|
1583 |
u'data': None, |
|
1584 |
} |
|
1558 |
fake_http.set_response(content=QRCODE_400, |
|
1559 |
headers={'Content-Type': 'application/json' }, |
|
1560 |
status_code=400) |
|
1561 |
resp = app.get(endpoint, status=400) |
|
1562 |
assert resp.json == { |
|
1563 |
u'err': 1, |
|
1564 |
u'err_class': u'passerelle.utils.jsonresponse.APIError', |
|
1565 |
u'err_desc': u'Subscriber with ID 123 has no passcard number to generate qr code from.', |
|
1566 |
u'data': None, |
|
1567 |
} |
|
1585 | 1568 | |
1586 |
requests_get.return_value = utils.FakedResponse(content=QRCODE_404, |
|
1587 |
headers={'Content-Type': 'application/json' }, |
|
1588 |
status_code=404) |
|
1589 |
resp = app.get(endpoint, status=404) |
|
1590 |
assert requests_get.call_count == 3 |
|
1591 |
assert resp.json == { |
|
1592 |
u'err': 1, |
|
1593 |
u'err_class': u'passerelle.utils.jsonresponse.APIError', |
|
1594 |
u'err_desc': u'Subscriber with ID 123 not found.', |
|
1595 |
u'data': None, |
|
1596 |
} |
|
1569 |
fake_http.set_response(content=QRCODE_404, |
|
1570 |
headers={'Content-Type': 'application/json' }, |
|
1571 |
status_code=404) |
|
1572 |
resp = app.get(endpoint, status=404) |
|
1573 |
assert resp.json == { |
|
1574 |
u'err': 1, |
|
1575 |
u'err_class': u'passerelle.utils.jsonresponse.APIError', |
|
1576 |
u'err_desc': u'Subscriber with ID 123 not found.', |
|
1577 |
u'data': None, |
|
1578 |
} |
tests/test_opengis.py | ||
---|---|---|
222 | 222 |
wfs_service_url='http://example.net/wfs')) |
223 | 223 | |
224 | 224 | |
225 |
def geoserver_responses(url, **kwargs): |
|
226 |
if kwargs['params'].get('request') == 'GetCapabilities': |
|
227 |
return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES) |
|
228 |
return utils.FakedResponse(status_code=200, content=FAKE_FEATURES_JSON) |
|
229 | ||
230 | ||
231 |
def geoserver_responses_errors(url, **kwargs): |
|
232 |
if kwargs['params'].get('request') == 'GetCapabilities': |
|
233 |
return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES) |
|
234 |
return utils.FakedResponse(status_code=200, content=FAKE_ERROR) |
|
235 | ||
236 | ||
237 |
def geoserver_responses_errors_unparsable(url, **kwargs): |
|
238 |
if kwargs['params'].get('request') == 'GetCapabilities': |
|
239 |
return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES) |
|
240 |
return utils.FakedResponse(status_code=200, content=FAKE_ERROR[:10]) |
|
241 | ||
242 | ||
243 |
@mock.patch('passerelle.utils.Request.get') |
|
244 |
def test_feature_info(mocked_get, app, connector): |
|
225 |
def test_feature_info(fake_http, app, connector): |
|
245 | 226 |
endpoint = utils.generic_endpoint_url('opengis', 'feature_info', slug=connector.slug) |
246 | 227 |
assert endpoint == '/opengis/test/feature_info' |
247 |
mocked_get.return_value = utils.FakedResponse(content=FAKE_FEATURE_INFO, status_code=200) |
|
228 | ||
229 |
fake_http.set_response(content=FAKE_FEATURE_INFO, status_code=200) |
|
248 | 230 |
resp = app.get(endpoint, params={'lat': '45.796890', 'lon': '4.784140'}) |
249 |
assert mocked_get.call_args[1]['params']['BBOX'] == '5747860.22776,532568.028684,5748179.56467,532790.667665'
|
|
250 |
assert mocked_get.call_args[1]['params']['CRS'] == 'EPSG:3857'
|
|
231 |
assert fake_http.last_request.GET['BBOX'] == '5747860.22776,532568.028684,5748179.56467,532790.667665'
|
|
232 |
assert fake_http.last_request.GET['CRS'] == 'EPSG:3857'
|
|
251 | 233 |
assert (resp.json['data'] |
252 | 234 |
['cad_cadastrecadparcelle_layer'] |
253 | 235 |
['cad_cadastrecadparcelle_feature'] |
... | ... | |
255 | 237 |
== 'Particulier') |
256 | 238 |
connector.projection = 'EPSG:4326' |
257 | 239 |
connector.save() |
240 | ||
241 |
fake_http.set_response(content=FAKE_FEATURE_INFO, status_code=200) |
|
258 | 242 |
resp = app.get(endpoint, params={'lat': '45.796890', 'lon': '4.784140'}) |
259 |
assert mocked_get.call_args[1]['params']['BBOX'] == '45.796890,4.784140,45.79889,4.78614'
|
|
260 |
assert mocked_get.call_args[1]['params']['CRS'] == 'EPSG:4326'
|
|
243 |
assert fake_http.last_request.GET['BBOX'] == '45.796890,4.784140,45.79889,4.78614'
|
|
244 |
assert fake_http.last_request.GET['CRS'] == 'EPSG:4326'
|
|
261 | 245 | |
262 | 246 | |
263 |
@mock.patch('passerelle.utils.Request.get') |
|
264 |
def test_tile(mocked_get, app, connector): |
|
247 |
def test_tile(fake_http, app, connector): |
|
265 | 248 |
endpoint = utils.generic_endpoint_url('opengis', 'tile', slug=connector.slug) |
266 | 249 |
assert endpoint == '/opengis/test/tile' |
267 |
mocked_get.return_value = utils.FakedResponse(content='\x89PNG\r\n\x1a\n\x00\x00...', status_code=200) |
|
250 | ||
251 |
fake_http.set_response(content='\x89PNG\r\n\x1a\n\x00\x00...', status_code=200) |
|
268 | 252 |
resp = app.get(endpoint + '/16/33650/23378.png') |
269 |
assert mocked_get.call_args[1]['params']['SRS'] == 'EPSG:3857'
|
|
270 |
assert mocked_get.call_args[1]['params']['BBOX'] == '539339.67158,5741338.06856,539951.167806,5741949.56478'
|
|
253 |
assert fake_http.last_request.GET['SRS'] == 'EPSG:3857'
|
|
254 |
assert fake_http.last_request.GET['BBOX'] == '539339.67158,5741338.06856,539951.167806,5741949.56478'
|
|
271 | 255 |
connector.projection = 'EPSG:4326' |
272 | 256 |
connector.save() |
257 | ||
258 |
fake_http.set_response(content='\x89PNG\r\n\x1a\n\x00\x00...', status_code=200) |
|
273 | 259 |
resp = app.get(endpoint + '/16/33650/23378.png') |
274 |
assert mocked_get.call_args[1]['params']['SRS'] == 'EPSG:4326'
|
|
275 |
assert mocked_get.call_args[1]['params']['BBOX'] == '4.84497070312,45.7560261559,4.85046386719,45.7598586879'
|
|
260 |
assert fake_http.last_request.GET['SRS'] == 'EPSG:4326'
|
|
261 |
assert fake_http.last_request.GET['BBOX'] == '4.84497070312,45.7560261559,4.85046386719,45.7598586879'
|
|
276 | 262 |
assert resp.content == '\x89PNG\r\n\x1a\n\x00\x00...' |
277 | 263 | |
278 | 264 | |
279 |
@mock.patch('passerelle.utils.Request.get') |
|
280 |
def test_get_feature_with_no_wfs_url(mocked_get, app, connector): |
|
265 |
def test_get_feature_with_no_wfs_url(fake_http, app, connector): |
|
281 | 266 |
connector.wfs_service_url = '' |
282 | 267 |
connector.save() |
283 | 268 |
endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug) |
284 | 269 |
assert endpoint == '/opengis/test/features' |
285 |
mocked_get.side_effect = geoserver_responses |
|
270 | ||
286 | 271 |
resp = app.get(endpoint, params={'type_names': 'ref_metro_limites_communales', 'property_name': 'nom'}) |
287 | 272 |
assert resp.json['data'] is None |
288 | 273 |
assert resp.json['err'] == 1 |
289 | 274 |
assert resp.json['err_desc'] == 'no wfs URL declared' |
290 | 275 | |
291 | 276 | |
292 |
@mock.patch('passerelle.utils.Request.get') |
|
293 |
def test_get_feature(mocked_get, app, connector): |
|
277 |
def test_get_feature(fake_http, app, connector): |
|
294 | 278 |
endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug) |
295 | 279 |
assert endpoint == '/opengis/test/features' |
296 |
mocked_get.side_effect = geoserver_responses |
|
280 | ||
281 |
fake_http.set_response(status_code=200, content=FAKE_SERVICE_CAPABILITIES, method='GET') |
|
282 |
fake_http.add_response(status_code=200, content=FAKE_FEATURES_JSON, method='GET') |
|
297 | 283 |
resp = app.get(endpoint, params={'type_names': 'ref_metro_limites_communales', 'property_name': 'nom'}) |
298 |
assert mocked_get.call_args[1]['params']['REQUEST'] == 'GetFeature'
|
|
299 |
assert mocked_get.call_args[1]['params']['PROPERTYNAME'] == 'nom'
|
|
300 |
assert mocked_get.call_args[1]['params']['TYPENAMES'] == 'ref_metro_limites_communales'
|
|
301 |
assert mocked_get.call_args[1]['params']['OUTPUTFORMAT'] == 'json'
|
|
302 |
assert mocked_get.call_args[1]['params']['SERVICE'] == 'WFS'
|
|
303 |
assert mocked_get.call_args[1]['params']['VERSION'] == connector.get_wfs_service_version()
|
|
284 |
assert fake_http.last_request.GET['REQUEST'] == 'GetFeature'
|
|
285 |
assert fake_http.last_request.GET['PROPERTYNAME'] == 'nom'
|
|
286 |
assert fake_http.last_request.GET['TYPENAMES'] == 'ref_metro_limites_communales'
|
|
287 |
assert fake_http.last_request.GET['OUTPUTFORMAT'] == 'json'
|
|
288 |
assert fake_http.last_request.GET['SERVICE'] == 'WFS'
|
|
289 |
assert fake_http.last_request.GET['VERSION'] == connector.get_wfs_service_version()
|
|
304 | 290 |
assert len(resp.json['data']) == 7 |
305 | 291 |
for item in resp.json['data']: |
306 | 292 |
assert 'text' in item |
307 | 293 | |
308 | 294 | |
309 |
@mock.patch('passerelle.utils.Request.get') |
|
310 |
def test_get_filtered_feature(mocked_get, app, connector): |
|
295 |
def test_get_filtered_feature(fake_http, app, connector): |
|
311 | 296 |
endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug) |
312 |
mocked_get.side_effect = geoserver_responses |
|
297 |
fake_http.set_response(status_code=200, content=FAKE_SERVICE_CAPABILITIES, method='GET') |
|
298 |
fake_http.add_response(status_code=200, content=FAKE_FEATURES_JSON, method='GET') |
|
313 | 299 |
app.get(endpoint, |
314 | 300 |
params={ |
315 | 301 |
'type_names': 'ref_metro_limites_communales', |
316 | 302 |
'property_name': 'nom', |
317 | 303 |
'cql_filter': 'nom=\'Fontaine\'' |
318 | 304 |
}) |
319 |
assert mocked_get.call_args[1]['params']['CQL_FILTER'] == 'nom=\'Fontaine\''
|
|
305 |
assert fake_http.last_request.GET['CQL_FILTER'] == 'nom=\'Fontaine\''
|
|
320 | 306 | |
321 | 307 | |
322 |
@mock.patch('passerelle.utils.Request.get') |
|
323 |
def test_get_filtered_by_property_feature(mocked_get, app, connector): |
|
308 |
def test_get_filtered_by_property_feature(fake_http, app, connector): |
|
324 | 309 |
endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug) |
325 |
mocked_get.side_effect = geoserver_responses |
|
310 | ||
311 |
fake_http.set_response(status_code=200, content=FAKE_SERVICE_CAPABILITIES, method='GET') |
|
312 |
fake_http.add_response(status_code=200, content=FAKE_FEATURES_JSON, method='GET') |
|
326 | 313 |
params = {'type_names': 'ref_metro_limites_communales', |
327 | 314 |
'property_name': 'nom', 'cql_filter': 'nom=\'Fontaine\'', |
328 | 315 |
'filter_property_name': 'nom'} |
329 | 316 |
app.get(endpoint, params=params) |
330 |
assert mocked_get.call_args[1]['params']['CQL_FILTER'] == 'nom=\'Fontaine\'' |
|
317 |
assert fake_http.last_request.GET['CQL_FILTER'] == 'nom=\'Fontaine\'' |
|
318 | ||
319 |
fake_http.add_response(status_code=200, content=FAKE_FEATURES_JSON, method='GET') |
|
331 | 320 |
params['q'] = 'bens' |
332 | 321 |
app.get(endpoint, params=params) |
333 |
assert mocked_get.call_args[1]['params']['CQL_FILTER'] == 'nom=\'Fontaine\' AND nom LIKE \'%bens%\'' |
|
322 |
assert fake_http.last_request.GET['CQL_FILTER'] == 'nom=\'Fontaine\' AND nom LIKE \'%bens%\'' |
|
323 | ||
324 |
fake_http.add_response(status_code=200, content=FAKE_FEATURES_JSON, method='GET') |
|
334 | 325 |
params['case-insensitive'] = True |
335 | 326 |
app.get(endpoint, params=params) |
336 |
assert mocked_get.call_args[1]['params']['CQL_FILTER'] == 'nom=\'Fontaine\' AND nom ILIKE \'%bens%\'' |
|
327 |
assert fake_http.last_request.GET['CQL_FILTER'] == 'nom=\'Fontaine\' AND nom ILIKE \'%bens%\'' |
|
328 | ||
329 |
fake_http.add_response(status_code=200, content=FAKE_FEATURES_JSON, method='GET') |
|
337 | 330 |
params.pop('cql_filter') |
338 | 331 |
app.get(endpoint, params=params) |
339 |
assert 'CQL_FILTER' not in mocked_get.call_args[1]['params']
|
|
332 |
assert 'CQL_FILTER' not in fake_http.last_request.GET
|
|
340 | 333 | |
341 | 334 | |
342 |
@mock.patch('passerelle.utils.Request.get') |
|
343 |
def test_get_feature_error(mocked_get, app, connector): |
|
335 |
def test_get_feature_error(fake_http, app, connector): |
|
344 | 336 |
endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug) |
345 | 337 |
assert endpoint == '/opengis/test/features' |
346 |
mocked_get.side_effect = geoserver_responses_errors |
|
338 | ||
339 |
fake_http.set_response(status_code=200, content=FAKE_SERVICE_CAPABILITIES) |
|
340 |
fake_http.add_response(status_code=200, content=FAKE_ERROR) |
|
347 | 341 |
resp = app.get(endpoint, params={ |
348 | 342 |
'type_names': 'ref_metro_limites_communales', |
349 | 343 |
'property_name': 'nom' |
350 | 344 |
}) |
351 |
assert mocked_get.call_args[1]['params']['REQUEST'] == 'GetFeature'
|
|
352 |
assert mocked_get.call_args[1]['params']['PROPERTYNAME'] == 'nom'
|
|
353 |
assert mocked_get.call_args[1]['params']['TYPENAMES'] == 'ref_metro_limites_communales'
|
|
354 |
assert mocked_get.call_args[1]['params']['OUTPUTFORMAT'] == 'json'
|
|
355 |
assert mocked_get.call_args[1]['params']['SERVICE'] == 'WFS'
|
|
356 |
assert mocked_get.call_args[1]['params']['VERSION'] == connector.get_wfs_service_version()
|
|
345 |
assert fake_http.last_request.GET['REQUEST'] == 'GetFeature'
|
|
346 |
assert fake_http.last_request.GET['PROPERTYNAME'] == 'nom'
|
|
347 |
assert fake_http.last_request.GET['TYPENAMES'] == 'ref_metro_limites_communales'
|
|
348 |
assert fake_http.last_request.GET['OUTPUTFORMAT'] == 'json'
|
|
349 |
assert fake_http.last_request.GET['SERVICE'] == 'WFS'
|
|
350 |
assert fake_http.last_request.GET['VERSION'] == connector.get_wfs_service_version()
|
|
357 | 351 |
result = resp.json |
358 | 352 |
assert result['err'] == 1 |
359 | 353 |
assert result['err_desc'] == 'OpenGIS Error: NoApplicableCode' |
360 | 354 |
assert 'Could not parse' in result['data']['text'] |
361 | 355 | |
362 | 356 | |
363 |
@mock.patch('passerelle.utils.Request.get') |
|
364 |
def test_get_feature_error2(mocked_get, app, connector): |
|
357 |
def test_get_feature_error2(fake_http, app, connector): |
|
365 | 358 |
endpoint = utils.generic_endpoint_url('opengis', 'features', slug=connector.slug) |
366 | 359 |
assert endpoint == '/opengis/test/features' |
367 |
mocked_get.side_effect = geoserver_responses_errors_unparsable |
|
360 | ||
361 |
fake_http.set_response(status_code=200, content=FAKE_SERVICE_CAPABILITIES) |
|
362 |
fake_http.add_response(status_code=200, content=FAKE_ERROR[:10]) |
|
368 | 363 |
resp = app.get(endpoint, params={ |
369 | 364 |
'type_names': 'ref_metro_limites_communales', |
370 | 365 |
'property_name': 'nom' |
371 | 366 |
}) |
372 |
assert mocked_get.call_args[1]['params']['REQUEST'] == 'GetFeature'
|
|
373 |
assert mocked_get.call_args[1]['params']['PROPERTYNAME'] == 'nom'
|
|
374 |
assert mocked_get.call_args[1]['params']['TYPENAMES'] == 'ref_metro_limites_communales'
|
|
375 |
assert mocked_get.call_args[1]['params']['OUTPUTFORMAT'] == 'json'
|
|
376 |
assert mocked_get.call_args[1]['params']['SERVICE'] == 'WFS'
|
|
377 |
assert mocked_get.call_args[1]['params']['VERSION'] == connector.get_wfs_service_version()
|
|
367 |
assert fake_http.last_request.GET['REQUEST'] == 'GetFeature'
|
|
368 |
assert fake_http.last_request.GET['PROPERTYNAME'] == 'nom'
|
|
369 |
assert fake_http.last_request.GET['TYPENAMES'] == 'ref_metro_limites_communales'
|
|
370 |
assert fake_http.last_request.GET['OUTPUTFORMAT'] == 'json'
|
|
371 |
assert fake_http.last_request.GET['SERVICE'] == 'WFS'
|
|
372 |
assert fake_http.last_request.GET['VERSION'] == connector.get_wfs_service_version()
|
|
378 | 373 |
result = resp.json |
379 | 374 |
assert result['err'] == 1 |
380 | 375 |
assert result['err_desc'] == 'OpenGIS Error: unparsable error' |
381 | 376 |
assert '<ows:' in result['data']['content'] |
382 | 377 | |
383 | 378 | |
384 |
@mock.patch('passerelle.utils.Request.get') |
|
385 |
def test_reverse_geocoding(mocked_get, app, connector): |
|
379 |
def test_reverse_geocoding(fake_http, app, connector): |
|
386 | 380 |
connector.search_radius = 45 |
387 | 381 |
connector.projection = 'EPSG:3945' |
388 | 382 |
connector.save() |
389 | 383 |
endpoint = utils.generic_endpoint_url('opengis', 'reverse', slug=connector.slug) |
390 | 384 |
assert endpoint == '/opengis/test/reverse' |
391 | 385 | |
392 |
def side_effect(url, **kwargs): |
|
393 |
if kwargs['params'].get('request') == 'GetCapabilities': |
|
394 |
return utils.FakedResponse(status_code=200, content=FAKE_SERVICE_CAPABILITIES) |
|
395 |
return mock.DEFAULT |
|
396 |
mocked_get.side_effect = side_effect |
|
397 |
mocked_get.return_value = utils.FakedResponse(content=FAKE_GEOLOCATED_FEATURE, status_code=200) |
|
386 |
fake_http.set_response(status_code=200, content=FAKE_SERVICE_CAPABILITIES) |
|
387 |
fake_http.add_response(content=FAKE_GEOLOCATED_FEATURE, status_code=200) |
|
388 | ||
398 | 389 |
resp = app.get(endpoint, |
399 | 390 |
params={ |
400 | 391 |
'lat': '45.1893469606986', |
401 | 392 |
'lon': '5.72462060798' |
402 | 393 |
}) |
403 |
assert (mocked_get.call_args[1]['params']['CQL_FILTER']
|
|
394 |
assert (fake_http.last_request.GET['CQL_FILTER']
|
|
404 | 395 |
== 'DWITHIN(the_geom,Point(1914061.48604 4224640.45779),45,meters)') |
405 | 396 |
assert resp.json['lon'] == '5.72407744145' |
406 | 397 |
assert resp.json['lat'] == '45.1893972656' |
... | ... | |
412 | 403 |
connector.projection = 'EPSG:4326' |
413 | 404 |
connector.search_radius = 10 |
414 | 405 |
connector.save() |
415 |
mocked_get.return_value = utils.FakedResponse(content='{"features": []}', status_code=200) |
|
406 | ||
407 |
fake_http.set_response(status_code=200, content='{"features": []}') |
|
416 | 408 |
resp = app.get( |
417 | 409 |
endpoint, |
418 | 410 |
params={ |
419 | 411 |
'lat': '45.183784', |
420 | 412 |
'lon': '5.714885' |
421 | 413 |
}) |
422 |
assert mocked_get.call_args[1]['params']['CQL_FILTER'] == 'DWITHIN(the_geom,Point(5.714885 45.183784),10,meters)'
|
|
414 |
assert fake_http.last_request.GET['CQL_FILTER'] == 'DWITHIN(the_geom,Point(5.714885 45.183784),10,meters)'
|
|
423 | 415 |
assert resp.json['err'] == 1 |
424 | 416 |
assert resp.json['err_desc'] == 'Unable to geocode' |
425 | 417 | |
426 |
mocked_get.return_value = utils.FakedResponse(status_code=404, content='{}', ok=False)
|
|
418 |
fake_http.set_response(status_code=404, content='{}')
|
|
427 | 419 |
resp = app.get(endpoint, |
428 | 420 |
params={ |
429 | 421 |
'lat': '45.183784', |
tests/test_planitech.py | ||
---|---|---|
1 |
import json |
|
1 | 2 |
from datetime import datetime |
2 | 3 | |
3 | 4 |
from django.contrib.contenttypes.models import ContentType |
... | ... | |
100 | 101 |
return mock_call_planitech |
101 | 102 | |
102 | 103 | |
103 |
def test_call_planitech(connector, monkeypatch): |
|
104 | ||
105 |
class MockResponse(object): |
|
106 | ||
107 |
status_code = 200 |
|
108 |
content = None |
|
109 | ||
110 |
def __init__(self, content=None, status_code=None): |
|
111 |
if content is not None: |
|
112 |
self.content = content |
|
113 |
if status_code is not None: |
|
114 |
self.status_code = status_code |
|
115 | ||
116 |
def session_meth(self, *args, **kwargs): |
|
117 |
return self |
|
118 | ||
119 |
def json(self): |
|
120 |
return mste.encode(self.content) |
|
121 | ||
104 |
def test_call_planitech(fake_http, connector, monkeypatch): |
|
122 | 105 |
connector._planitech_session = True |
123 | 106 | |
124 |
response = MockResponse(content='somestring') |
|
125 |
assert connector._call_planitech(response.session_meth, 'endpoint') == "somestring" |
|
107 |
def set_response(status_code, content): |
|
108 |
content = json.dumps(mste.encode(content)) |
|
109 |
fake_http.set_response(status_code=status_code, content=content) |
|
110 | ||
111 |
set_response(status_code=200, content='somestring') |
|
112 |
assert connector._call_planitech(connector.requests.get, 'endpoint') == "somestring" |
|
126 | 113 | |
127 |
response = MockResponse(content=set(), status_code=400)
|
|
114 |
set_response(status_code=400, content=[])
|
|
128 | 115 |
with pytest.raises(APIError) as excinfo: |
129 |
connector._call_planitech(response.session_meth, 'endpoint')
|
|
116 |
connector._call_planitech(connector.requests.get, 'endpoint')
|
|
130 | 117 |
assert str(excinfo.value) == 'Planitech error 400' |
131 | 118 | |
132 |
response = MockResponse(content='unexpected error format', status_code=400)
|
|
119 |
set_response(status_code=400, content='unexpected error format')
|
|
133 | 120 |
with pytest.raises(APIError) as excinfo: |
134 |
connector._call_planitech(response.session_meth, 'endpoint')
|
|
121 |
connector._call_planitech(connector.requests.get, 'endpoint')
|
|
135 | 122 |
assert str(excinfo.value) == 'Planitech error 400' |
136 | 123 | |
137 |
response = MockResponse(content={'errors': 'planitech error message'}, status_code=400)
|
|
124 |
set_response(status_code=400, content={'errors': 'planitech error message'})
|
|
138 | 125 |
with pytest.raises(APIError) as excinfo: |
139 |
connector._call_planitech(response.session_meth, 'endpoint')
|
|
126 |
connector._call_planitech(connector.requests.get, 'endpoint')
|
|
140 | 127 |
assert str(excinfo.value) == 'Planitech error 400 - planitech error message' |
141 | 128 | |
142 | 129 |
tests/test_requests.py | ||
---|---|---|
3 | 3 |
import pytest |
4 | 4 |
import mohawk |
5 | 5 |
import mock |
6 |
from httmock import urlmatch, HTTMock, response |
|
7 | 6 | |
8 | 7 |
from django.test import override_settings |
9 | 8 | |
10 | 9 |
from passerelle.utils import Request, CaseInsensitiveDict |
11 | 10 |
from passerelle.utils.http_authenticators import HawkAuth |
12 |
import utils |
|
13 | 11 |
from utils import FakedResponse |
14 | 12 | |
15 | 13 | |
... | ... | |
32 | 30 |
def log_level(request): |
33 | 31 |
return request.param |
34 | 32 | |
35 |
@urlmatch(netloc=r'(.*\.)?httpbin\.org$') |
|
36 |
def httpbin_mock(url, request): |
|
37 |
return response(200, {"message": "Are you really josh ?"}, |
|
38 |
headers={"Content-Type": "application/json"}, request=request) |
|
39 | 33 | |
40 |
@urlmatch(netloc=r'(.*\.)?httperror\.org$') |
|
41 |
def http400_mock(url, request): |
|
42 |
return response(400, {"foo": "bar"}, |
|
43 |
headers={"Content-Type": "application/json"}, request=request) |
|
44 | ||
45 | ||
46 |
def test_log_level(caplog, log_level): |
|
34 |
def test_log_level(fake_http, caplog, log_level): |
|
47 | 35 |
url = 'https://httpbin.org/post' |
48 | 36 | |
49 | 37 |
logger = logging.getLogger('requests') |
50 | 38 |
logger.setLevel(log_level) |
51 | 39 | |
52 |
with HTTMock(httpbin_mock):
|
|
53 |
requests = Request(logger=logger)
|
|
54 |
response = requests.post(url, json={'name':'josh'})
|
|
40 |
requests = Request(logger=logger)
|
|
41 |
fake_http.set_response(status_code=200, json={'message': 'Are you really josh ?'})
|
|
42 |
response = requests.post(url, json={'name': 'josh'})
|
|
55 | 43 | |
56 | 44 |
records = [record for record in caplog.records if record.name == 'requests'] |
57 | 45 | |
... | ... | |
74 | 62 |
assert not hasattr(record, 'response_content') |
75 | 63 |
assert not hasattr(record, 'response_headers') |
76 | 64 | |
77 |
def test_log_error(caplog, log_level): |
|
65 | ||
66 |
def test_log_error(fake_http, caplog, log_level): |
|
78 | 67 |
url = 'https://httperror.org/plop' |
79 | 68 | |
80 | 69 |
logger = logging.getLogger('requests') |
81 | 70 |
logger.setLevel(log_level) |
82 | 71 | |
83 |
with HTTMock(http400_mock):
|
|
84 |
requests = Request(logger=logger)
|
|
85 |
response = requests.post(url, json={'name':'josh'})
|
|
72 |
requests = Request(logger=logger)
|
|
73 |
fake_http.set_response(status_code=400, json={'foo': 'bar'})
|
|
74 |
response = requests.post(url, json={'name': 'josh'}, raise_for_status=False)
|
|
86 | 75 | |
87 | 76 |
records = [record for record in caplog.records if record.name == 'requests'] |
88 | 77 | |
89 | 78 |
records_length = len(records) |
90 | 79 | |
91 |
if logger.level > 40:
|
|
80 |
if logger.level > 20:
|
|
92 | 81 |
assert records_length == 0 |
93 | 82 |
else: |
94 | 83 |
assert records_length == 1 |
... | ... | |
105 | 94 |
assert not hasattr(record, 'response_content') |
106 | 95 |
assert not hasattr(record, 'response_headers') |
107 | 96 | |
108 |
@pytest.fixture(params=['xml', 'whatever', 'jpeg', 'pdf']) |
|
109 |
def endpoint_response(request): |
|
110 |
response_request = mock.Mock( |
|
111 |
headers={'Accept': '*/*', 'Authorization': 'Basic dG9rZW46dG9rZW4='}, body=None) |
|
112 |
xml = FakedResponse( |
|
113 |
headers={'Content-Type': 'application/xml; charset=charset=utf-8'}, status_code=200, |
|
114 |
content='<tests><test>xml test</test></tests>', request=response_request) |
|
115 | ||
116 |
whatever = FakedResponse( |
|
117 |
headers={'Content-Type': 'texto/csv'}, status_code=200, |
|
118 |
content='username;age\ntoken;10\ncartman:10', request=response_request) |
|
119 | ||
120 |
jpeg = FakedResponse( |
|
121 |
headers={'Content-Type': 'image/jpeg'}, status_code=200, |
|
122 |
content='binary content to be ignored', request=response_request) |
|
123 | ||
124 |
pdf = FakedResponse( |
|
125 |
headers={'Content-Type': 'application/pdf'}, status_code=200, |
|
126 |
content='binary content to be ignored', request=response_request) |
|
127 | 97 | |
128 |
return locals().get(request.param) |
|
129 | ||
130 | ||
131 |
@mock.patch('passerelle.utils.RequestSession.send') |
|
132 |
def test_skip_content_type(mocked_get, caplog, endpoint_response): |
|
133 |
mocked_get.return_value = endpoint_response |
|
98 |
@pytest.fixture(params=['xml', 'whatever', 'jpeg', 'pdf']) |
|
99 |
def setup_endpoint_response(request, fake_http): |
|
100 |
def do(): |
|
101 |
if request.param == 'xml': |
|
102 |
fake_http.set_response( |
|
103 |
status_code=200, |
|
104 |
headers={'Content-Type': 'application/xml; charset=charset=utf-8'}, |
|
105 |
content='<tests><test>xml test</test></tests>') |
|
106 |
elif request.param == 'whatever': |
|
107 |
fake_http.set_response( |
|
108 |
status_code=200, |
|
109 |
headers={'Content-Type': 'texto/csv'}, |
|
110 |
content='username;age\ntoken;10\ncartman:10') |
|
111 |
elif request.param == 'jpeg': |
|
112 |
fake_http.set_response( |
|
113 |
status_code=200, |
|
114 |
headers={'Content-Type': 'image/jpeg'}, |
|
115 |
content='binary content to be ignored') |
|
116 |
elif request.param == 'pdf': |
|
117 |
fake_http.set_response( |
|
118 |
status_code=200, |
|
119 |
headers={'Content-Type': 'application/pdf'}, |
|
120 |
content='binary content to be ignored') |
|
121 |
return fake_http |
|
122 |
do.param = request.param |
|
123 |
return do |
|
124 | ||
125 | ||
126 |
def test_skip_content_type(request, caplog, setup_endpoint_response): |
|
127 |
# XXX: what is tested here ? I dunno :/ |
|
134 | 128 |
logger = logging.getLogger('requests') |
135 | 129 |
logger.setLevel(logging.DEBUG) |
136 | 130 |
requests = Request(logger=logger) |
137 |
response = requests.get('http://example.net/whatever').body |
|
131 | ||
132 |
setup_endpoint_response() |
|
133 |
requests.get( |
|
134 |
'http://example.net/whatever', |
|
135 |
headers={'Accept': '*/*', 'Authorization': 'Basic dG9rZW46dG9rZW4='} |
|
136 |
) |
|
138 | 137 |
records = [record for record in caplog.records if record.name == 'requests'] |
139 | 138 | |
140 |
if 'xml' in endpoint_response.headers.get('Content-Type'):
|
|
141 |
assert len(records) == 1
|
|
139 |
assert len(records) == 1
|
|
140 |
if setup_endpoint_response.param == 'xml':
|
|
142 | 141 |
assert records[0].response_content == "'<tests><test>xml test</test></tests>'" |
143 |
else: |
|
144 |
assert len(records) == 1 |
|
145 | 142 | |
146 | 143 | |
147 | 144 |
@mock.patch('passerelle.utils.RequestSession.request') |
148 |
def test_proxies(mocked_get, caplog, endpoint_response): |
|
149 |
mocked_get.return_value = endpoint_response |
|
145 |
def test_proxies(mocked_get, caplog): |
|
150 | 146 |
logger = logging.getLogger('requests') |
147 | ||
151 | 148 |
Request(logger=logger).get('http://example.net/whatever') |
152 | 149 |
assert mocked_get.call_args[1].get('proxies') is None |
153 |
Request(logger=logger).get('http://example.net/whatever', |
|
154 |
proxies={'http': 'http://proxy'})
|
|
150 | ||
151 |
Request(logger=logger).get('http://example.net/whatever', proxies={'http': 'http://proxy'})
|
|
155 | 152 |
assert mocked_get.call_args[1].get('proxies') == {'http': 'http://proxy'} |
156 | 153 | |
157 | 154 |
with override_settings(REQUESTS_PROXIES={'http': 'http://globalproxy'}): |
158 | 155 |
Request(logger=logger).get('http://example.net/whatever') |
159 | 156 |
assert mocked_get.call_args[1].get('proxies') == {'http': 'http://globalproxy'} |
160 |
Request(logger=logger).get('http://example.net/whatever', |
|
161 |
proxies={'http': 'http://proxy'}) |
|
157 |
Request(logger=logger).get('http://example.net/whatever', proxies={'http': 'http://proxy'}) |
|
162 | 158 |
assert mocked_get.call_args[1].get('proxies') == {'http': 'http://proxy'} |
163 | 159 | |
164 | 160 |
# with a linked resource |
... | ... | |
188 | 184 | |
189 | 185 | |
190 | 186 |
@mock.patch('passerelle.utils.RequestSession.request') |
191 |
def test_resource_auth(mocked_get, caplog, endpoint_response): |
|
192 |
mocked_get.return_value = endpoint_response |
|
187 |
def test_resource_auth(mocked_get, caplog): |
|
193 | 188 |
logger = logging.getLogger('requests') |
194 | 189 |
resource = MockResource() |
195 | 190 |
request = Request(resource=resource, logger=logger) |
... | ... | |
211 | 206 |
request.get('http://example.net/whatever', auth=None) |
212 | 207 |
assert mocked_get.call_args[1].get('auth') is None |
213 | 208 | |
209 | ||
214 | 210 |
@mock.patch('passerelle.utils.RequestSession.send') |
215 |
def test_resource_hawk_auth(mocked_send, caplog, endpoint_response):
|
|
216 |
mocked_send.return_value = endpoint_response
|
|
211 |
def test_resource_hawk_auth(mocked_send): |
|
212 |
mocked_send.return_value = FakedResponse(status_code=200, headers={})
|
|
217 | 213 |
logger = logging.getLogger('requests') |
218 | 214 |
resource = MockResource() |
219 | 215 |
request = Request(resource=resource, logger=logger) |
... | ... | |
221 | 217 |
credentials = {'id': 'id', 'key': 'key', 'algorithm': 'sha256'} |
222 | 218 |
hawk_auth = HawkAuth(**credentials) |
223 | 219 | |
224 |
resp = request.get('http://httpbin.org/get', auth=hawk_auth)
|
|
220 |
request.get('http://httpbin.org/get', auth=hawk_auth) |
|
225 | 221 |
prepared_method = mocked_send.call_args[0][0] |
226 | 222 |
assert 'Authorization' in prepared_method.headers |
227 | 223 |
generated_header = prepared_method.headers['Authorization'] |
... | ... | |
236 | 232 |
assert dict(generated_parts) == dict(expected_parts) |
237 | 233 | |
238 | 234 |
hawk_auth = HawkAuth(ext='extra attribute', **credentials) |
239 |
resp = request.post('http://httpbin.org/post', auth=hawk_auth, json={'key': 'value'})
|
|
235 |
request.post('http://httpbin.org/post', auth=hawk_auth, json={'key': 'value'}) |
|
240 | 236 |
prepared_method = mocked_send.call_args[0][0] |
241 | 237 |
assert 'Authorization' in prepared_method.headers |
242 | 238 |
generated_header = prepared_method.headers['Authorization'] |
... | ... | |
252 | 248 | |
253 | 249 | |
254 | 250 |
@mock.patch('passerelle.utils.RequestSession.request') |
255 |
def test_resource_certificates(mocked_get, caplog, endpoint_response): |
|
256 |
mocked_get.return_value = endpoint_response |
|
251 |
def test_resource_certificates(mocked_get, caplog): |
|
257 | 252 |
logger = logging.getLogger('requests') |
258 | 253 |
resource = MockResource() |
259 | 254 |
request = Request(resource=resource, logger=logger) |
... | ... | |
290 | 285 | |
291 | 286 |
response_request = mock.Mock(headers={'Accept': '*/*'}, body=None) |
292 | 287 |
mocked_get.return_value = FakedResponse( |
293 |
headers={'Content-Type': 'text/plain; charset=charset=utf-8'},
|
|
294 |
request=response_request,
|
|
295 |
content='hello world', status_code=200)
|
|
288 |
headers={'Content-Type': 'text/plain; charset=charset=utf-8'}, |
|
289 |
request=response_request, |
|
290 |
content='hello world', status_code=200) |
|
296 | 291 | |
297 | 292 |
# by default there is no cache |
298 | 293 |
assert request.get('http://cache.example.org/').content == 'hello world' |
... | ... | |
308 | 303 | |
309 | 304 |
# value changed |
310 | 305 |
mocked_get.return_value = FakedResponse( |
311 |
headers={'Content-Type': 'text/plain; charset=charset=utf-8'},
|
|
312 |
request=response_request,
|
|
313 |
content='hello second world', status_code=200)
|
|
306 |
headers={'Content-Type': 'text/plain; charset=charset=utf-8'}, |
|
307 |
request=response_request, |
|
308 |
content='hello second world', status_code=200) |
|
314 | 309 |
assert request.get('http://cache.example.org/', cache_duration=15).content == 'hello world' |
315 | 310 |
assert mocked_get.call_count == 1 |
316 | 311 | |
... | ... | |
320 | 315 | |
321 | 316 |
# do not cache errors |
322 | 317 |
mocked_get.return_value = FakedResponse( |
323 |
headers={'Content-Type': 'text/plain; charset=charset=utf-8'},
|
|
324 |
request=response_request,
|
|
325 |
content='no such world', status_code=404)
|
|
318 |
headers={'Content-Type': 'text/plain; charset=charset=utf-8'}, |
|
319 |
request=response_request, |
|
320 |
content='no such world', status_code=404) |
|
326 | 321 |
mocked_get.reset_mock() |
327 | 322 |
response = request.get('http://cache.example.org/404', cache_duration=15) |
328 | 323 |
assert response.content == 'no such world' |
... | ... | |
334 | 329 |
# check response headers |
335 | 330 |
mocked_get.reset_mock() |
336 | 331 |
mocked_get.return_value = FakedResponse( |
337 |
headers=CaseInsensitiveDict({'Content-Type': 'image/png'}),
|
|
338 |
request=response_request,
|
|
339 |
content='hello world', status_code=200)
|
|
332 |
headers=CaseInsensitiveDict({'Content-Type': 'image/png'}), |
|
333 |
request=response_request, |
|
334 |
content='hello world', status_code=200) |
|
340 | 335 |
assert request.get('http://cache.example.org/img', cache_duration=15).headers.get('content-type') == 'image/png' |
341 | 336 |
assert mocked_get.call_count == 1 |
342 | 337 |
assert request.get('http://cache.example.org/img', cache_duration=15).headers.get('content-type') == 'image/png' |
343 |
assert mocked_get.call_count == 1 # got a cached response |
|
338 |
assert mocked_get.call_count == 1 # got a cached response
|
|
344 | 339 | |
345 | 340 | |
346 | 341 |
@mock.patch('passerelle.utils.RequestSession.request') |
347 |
def test_timeout(mocked_get, caplog, endpoint_response):
|
|
348 |
mocked_get.return_value = endpoint_response
|
|
342 |
def test_timeout(mocked_request, caplog):
|
|
343 |
mocked_request.return_value = FakedResponse(status_code=200, headers={})
|
|
349 | 344 |
logger = logging.getLogger('requests') |
350 | 345 | |
351 | 346 |
Request(logger=logger).get('http://example.net/whatever') |
352 |
assert mocked_get.call_args[1]['timeout'] == 25
|
|
347 |
assert mocked_request.call_args[1]['timeout'] == 25
|
|
353 | 348 | |
354 | 349 |
Request(logger=logger).get('http://example.net/whatever', timeout=42) |
355 |
assert mocked_get.call_args[1]['timeout'] == 42
|
|
350 |
assert mocked_request.call_args[1]['timeout'] == 42
|
|
356 | 351 |
Request(logger=logger).get('http://example.net/whatever', timeout=None) |
357 |
assert mocked_get.call_args[1]['timeout'] is None
|
|
352 |
assert mocked_request.call_args[1]['timeout'] is None
|
|
358 | 353 | |
359 | 354 |
with override_settings(REQUESTS_TIMEOUT=57): |
360 | 355 |
Request(logger=logger).get('http://example.net/whatever') |
361 |
assert mocked_get.call_args[1]['timeout'] == 57
|
|
356 |
assert mocked_request.call_args[1]['timeout'] == 57
|
|
362 | 357 |
Request(logger=logger).get('http://example.net/whatever', timeout=42) |
363 |
assert mocked_get.call_args[1]['timeout'] == 42
|
|
358 |
assert mocked_request.call_args[1]['timeout'] == 42
|
|
364 | 359 |
Request(logger=logger).get('http://example.net/whatever', timeout=None) |
365 |
assert mocked_get.call_args[1]['timeout'] is None |
|
360 |
assert mocked_request.call_args[1]['timeout'] is None |
tests/test_solis.py | ||
---|---|---|
127 | 127 |
'https': 'http://proxy:3128/'} |
128 | 128 | |
129 | 129 | |
130 |
def test_solis_link_infos_unlink(app, solis): |
|
130 |
def test_solis_link_infos_unlink(fake_http, app, solis):
|
|
131 | 131 |
# full opened access |
132 | 132 |
api = ApiUser.objects.create(username='all', keytype='', key='') |
133 | 133 |
obj_type = ContentType.objects.get_for_model(solis) |
... | ... | |
135 | 135 |
resource_pk=solis.pk) |
136 | 136 | |
137 | 137 |
# link |
138 |
with mock.patch('passerelle.utils.Request.post') as requests_post: # get solis token |
|
139 |
with mock.patch('passerelle.utils.Request.get') as requests_get: # get solis informations |
|
140 |
endpoint = utils.generic_endpoint_url('solis', 'apa-link', slug=solis.slug) |
|
141 |
for params in (None, '', []): |
|
142 |
resp = app.post_json(endpoint, params=params, status=200) |
|
143 |
assert requests_post.call_count == 0 |
|
144 |
assert resp.json['err'] == 1 |
|
145 |
assert 'payload is not a JSON dict' in resp.json['err_desc'] |
|
138 |
endpoint = utils.generic_endpoint_url('solis', 'apa-link', slug=solis.slug) |
|
139 |
for params in (None, '', []): |
|
140 |
resp = app.post_json(endpoint, params=params, status=200) |
|
141 |
assert resp.json['err'] == 1 |
|
142 |
assert 'payload is not a JSON dict' in resp.json['err_desc'] |
|
146 | 143 | |
147 |
for params in ({}, {'user_id': 'x'}, {'code': 'x'}, {'foo': 'bar'}): |
|
148 |
resp = app.post_json(endpoint, params=params, status=200) |
|
149 |
assert requests_post.call_count == 0 |
|
150 |
assert resp.json['err'] == 1 |
|
151 |
assert 'missing name_id' in resp.json['err_desc'] |
|
152 |
params['name_id'] = 'xx' |
|
153 |
resp = app.post_json(endpoint, params=params, status=200) |
|
154 |
assert requests_post.call_count == 0 |
|
155 |
assert resp.json['err'] == 1 |
|
156 |
assert 'missing user_id/code credentials' in resp.json['err_desc'] |
|
157 | ||
158 |
requests_post.return_value = utils.FakedResponse(content=APATOKEN_403, status_code=403) |
|
159 |
resp = app.post_json(endpoint, |
|
160 |
params={'user_id': 'x', 'code': 'x', 'name_id': NAMEID}, |
|
161 |
status=200) |
|
162 |
assert requests_post.call_count == 1 |
|
163 |
assert requests_get.call_count == 0 |
|
164 |
assert resp.json['err'] == 1 |
|
165 |
assert 'Code confidentiel non valide' in resp.json['err_desc'] |
|
166 | ||
167 |
assert SolisAPALink.objects.count() == 0 |
|
168 | ||
169 |
requests_post.return_value = utils.FakedResponse(content=APATOKEN, status_code=200) |
|
170 |
requests_get.return_value = utils.FakedResponse(content=APAINFOS['exportDonneesIndividu'], |
|
171 |
status_code=200) |
|
172 |
resp = app.post_json(endpoint, |
|
173 |
params={'name_id': NAMEID, 'user_id': '42', 'code': 'foo'}, |
|
174 |
status=200) |
|
175 |
assert requests_post.call_count == 2 |
|
176 |
assert requests_get.call_count == 1 |
|
177 |
assert resp.json['err'] == 0 |
|
178 |
assert resp.json['data']['user_id'] == '42' |
|
179 |
assert resp.json['data']['created'] |
|
180 |
assert not resp.json['data']['updated'] |
|
181 |
assert SolisAPALink.objects.count() == 1 |
|
182 |
assert SolisAPALink.objects.first().name_id == NAMEID |
|
183 |
assert SolisAPALink.objects.first().user_id == '42' |
|
184 |
assert SolisAPALink.objects.first().code == 'foo' |
|
185 |
assert SolisAPALink.objects.first().text == 'Mme Pecile PYPPENNE (NPYNEZ)' |
|
186 | ||
187 |
# change code |
|
188 |
resp = app.post_json(endpoint, |
|
189 |
params={'name_id': NAMEID, 'user_id': '42', 'code': 'bar'}, |
|
190 |
status=200) |
|
191 |
assert requests_post.call_count == 3 |
|
192 |
assert requests_get.call_count == 2 |
|
193 |
assert resp.json['err'] == 0 |
|
194 |
assert resp.json['data']['user_id'] == '42' |
|
195 |
assert not resp.json['data']['created'] |
|
196 |
assert resp.json['data']['updated'] |
|
197 |
assert SolisAPALink.objects.count() == 1 |
|
198 |
assert SolisAPALink.objects.first().name_id == NAMEID |
|
199 |
assert SolisAPALink.objects.first().user_id == '42' |
|
200 |
assert SolisAPALink.objects.first().code == 'bar' |
|
201 |
assert SolisAPALink.objects.first().text == 'Mme Pecile PYPPENNE (NPYNEZ)' |
|
202 | ||
203 |
# second link |
|
204 |
resp = app.post_json(endpoint, |
|
205 |
params={'name_id': NAMEID, 'user_id': '53', 'code': 'bar'}, |
|
206 |
status=200) |
|
207 |
assert requests_post.call_count == 4 |
|
208 |
assert requests_get.call_count == 3 |
|
209 |
assert resp.json['err'] == 0 |
|
210 |
assert resp.json['data']['user_id'] == '53' |
|
211 |
assert resp.json['data']['created'] |
|
212 |
assert not resp.json['data']['updated'] |
|
213 |
assert SolisAPALink.objects.count() == 2 |
|
144 |
for params in ({}, {'user_id': 'x'}, {'code': 'x'}, {'foo': 'bar'}): |
|
145 |
resp = app.post_json(endpoint, params=params, status=200) |
|
146 |
assert resp.json['err'] == 1 |
|
147 |
assert 'missing name_id' in resp.json['err_desc'] |
|
148 |
params['name_id'] = 'xx' |
|
149 |
resp = app.post_json(endpoint, params=params, status=200) |
|
150 |
assert resp.json['err'] == 1 |
|
151 |
assert 'missing user_id/code credentials' in resp.json['err_desc'] |
|
152 | ||
153 |
fake_http.set_response(content=APATOKEN_403, status_code=403, method='POST') |
|
154 |
resp = app.post_json(endpoint, |
|
155 |
params={'user_id': 'x', 'code': 'x', 'name_id': NAMEID}, |
|
156 |
status=200) |
|
157 |
assert resp.json['err'] == 1 |
|
158 |
assert 'Code confidentiel non valide' in resp.json['err_desc'] |
|
159 | ||
160 |
assert SolisAPALink.objects.count() == 0 |
|
161 | ||
162 |
fake_http.add_response(content=APATOKEN, status_code=200, method='POST') |
|
163 |
fake_http.add_response(content=APAINFOS['exportDonneesIndividu'], |
|
164 |
status_code=200, |
|
165 |
method='GET') |
|
166 |
resp = app.post_json(endpoint, |
|
167 |
params={'name_id': NAMEID, 'user_id': '42', 'code': 'foo'}, |
|
168 |
status=200) |
|
169 |
assert resp.json['err'] == 0 |
|
170 |
assert resp.json['data']['user_id'] == '42' |
|
171 |
assert resp.json['data']['created'] |
|
172 |
assert not resp.json['data']['updated'] |
|
173 |
assert SolisAPALink.objects.count() == 1 |
|
174 |
assert SolisAPALink.objects.first().name_id == NAMEID |
|
175 |
assert SolisAPALink.objects.first().user_id == '42' |
|
176 |
assert SolisAPALink.objects.first().code == 'foo' |
|
177 |
assert SolisAPALink.objects.first().text == 'Mme Pecile PYPPENNE (NPYNEZ)' |
|
178 | ||
179 |
# change code |
|
180 |
fake_http.add_response(content=APATOKEN, status_code=200, method='POST') |
|
181 |
fake_http.add_response(content=APAINFOS['exportDonneesIndividu'], |
|
182 |
status_code=200, |
|
183 |
method='GET') |
|
184 |
resp = app.post_json(endpoint, |
|
185 |
params={'name_id': NAMEID, 'user_id': '42', 'code': 'bar'}, |
|
186 |
status=200) |
|
187 |
assert resp.json['err'] == 0 |
|
188 |
assert resp.json['data']['user_id'] == '42' |
|
189 |
assert not resp.json['data']['created'] |
|
190 |
assert resp.json['data']['updated'] |
|
191 |
assert SolisAPALink.objects.count() == 1 |
|
192 |
assert SolisAPALink.objects.first().name_id == NAMEID |
|
193 |
assert SolisAPALink.objects.first().user_id == '42' |
|
194 |
assert SolisAPALink.objects.first().code == 'bar' |
|
195 |
assert SolisAPALink.objects.first().text == 'Mme Pecile PYPPENNE (NPYNEZ)' |
|
196 | ||
197 |
# second link |
|
198 |
fake_http.add_response(content=APATOKEN, status_code=200, method='POST') |
|
199 |
fake_http.add_response(content=APAINFOS['exportDonneesIndividu'], |
|
200 |
status_code=200, |
|
201 |
method='GET') |
|
202 |
resp = app.post_json(endpoint, |
|
203 |
params={'name_id': NAMEID, 'user_id': '53', 'code': 'bar'}, |
|
204 |
status=200) |
|
205 |
assert resp.json['err'] == 0 |
|
206 |
assert resp.json['data']['user_id'] == '53' |
|
207 |
assert resp.json['data']['created'] |
|
208 |
assert not resp.json['data']['updated'] |
|
209 |
assert SolisAPALink.objects.count() == 2 |
|
214 | 210 | |
215 | 211 |
# verify recorded names after link |
216 | 212 |
assert [x['text'] for x in SolisAPALink.objects.values('text')] == \ |
... | ... | |
227 | 223 | |
228 | 224 |
# get base informations from a linked user (exportDonneesIndividu) |
229 | 225 |
changed_name = APAINFOS['exportDonneesIndividu'].replace('PYPPENNE', 'PEPONE') |
230 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
231 |
with mock.patch('passerelle.utils.Request.post') as requests_post: |
|
232 |
requests_post.return_value = utils.FakedResponse(content=APATOKEN, status_code=200) |
|
233 |
requests_get.return_value = utils.FakedResponse(content=changed_name, status_code=200) |
|
234 |
endpoint = utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug) |
|
235 |
endpoint += '?name_id=%s&user_id=42' % NAMEID |
|
236 |
resp = app.get(endpoint, status=200) |
|
237 |
assert resp.json['err'] == 0 |
|
238 |
assert resp.json['data']['individu']['nomUsuel'] == 'PEPONE' |
|
239 |
# user "text" updated in link: |
|
240 |
assert SolisAPALink.objects.get(name_id=NAMEID, user_id='42').text == \ |
|
241 |
'Mme Pecile PEPONE (NPYNEZ)' |
|
226 |
fake_http.add_response(content=APATOKEN, status_code=200, method='POST') |
|
227 |
fake_http.add_response(content=changed_name, status_code=200, method='GET') |
|
228 |
endpoint = utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug) |
|
229 |
endpoint += '?name_id=%s&user_id=42' % NAMEID |
|
230 |
resp = app.get(endpoint, status=200) |
|
231 |
assert resp.json['err'] == 0 |
|
232 |
assert resp.json['data']['individu']['nomUsuel'] == 'PEPONE' |
|
233 |
# user "text" updated in link: |
|
234 |
assert SolisAPALink.objects.get(name_id=NAMEID, user_id='42').text == \ |
|
235 |
'Mme Pecile PEPONE (NPYNEZ)' |
|
242 | 236 | |
243 | 237 |
# get all kind of informations |
244 | 238 |
for apa_endpoint in APAINFOS: |
245 |
with mock.patch('passerelle.utils.Request.get') as requests_get:
|
|
246 |
with mock.patch('passerelle.utils.Request.post') as requests_post:
|
|
247 |
requests_post.return_value = utils.FakedResponse(content=APATOKEN, status_code=200)
|
|
239 |
endpoint_base = utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug)
|
|
240 |
resp = app.get(endpoint_base, status=400) # missing name_id
|
|
241 |
assert resp.json['err'] == 1
|
|
248 | 242 | |
249 |
endpoint_base = utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug) |
|
250 |
resp = app.get(endpoint_base, status=400) # missing name_id |
|
251 |
assert resp.json['err'] == 1 |
|
243 |
endpoint = endpoint_base + '?name_id=%s&user_id=53&information=%s' % (NAMEID, apa_endpoint) |
|
244 |
fake_http.add_response(content=APATOKEN, status_code=200, method='POST') |
|
252 | 245 | |
253 |
endpoint = endpoint_base + '?name_id=%s&user_id=53&information=%s' % (NAMEID, apa_endpoint) |
|
254 |
requests_get.return_value = utils.FakedResponse(content=APAINFOS[apa_endpoint], |
|
255 |
status_code=200) |
|
256 |
resp = app.get(endpoint, status=200) |
|
257 |
assert requests_post.call_count == 1 # get a token |
|
258 |
assert requests_get.call_count == 1 # get informations |
|
259 |
assert ('/asg/apa/%s' % apa_endpoint) in requests_get.call_args[0][0] |
|
260 |
assert resp.json['err'] == 0 |
|
261 |
assert resp.json['data'] |
|
262 | ||
263 |
# solis api crash |
|
264 |
requests_get.return_value = utils.FakedResponse(content='boum', |
|
265 |
status_code=500) |
|
266 |
resp = app.get(endpoint, status=200) |
|
267 |
assert requests_post.call_count == 2 # get a token |
|
268 |
assert requests_get.call_count == 2 # get informations |
|
269 |
assert ('/asg/apa/%s' % apa_endpoint) in requests_get.call_args[0][0] |
|
270 |
assert resp.json['err'] == 1 |
|
271 |
assert resp.json['err_desc'].startswith('error status:500') |
|
272 |
assert resp.json['data'] == {'json_content': None, 'status_code': 500} |
|
246 |
fake_http.add_response(content=APAINFOS[apa_endpoint], status_code=200, method='GET') |
|
247 |
resp = app.get(endpoint, status=200) |
|
248 |
assert ('/asg/apa/%s' % apa_endpoint) in fake_http.last_request.url |
|
249 |
assert resp.json['err'] == 0 |
|
250 |
assert resp.json['data'] |
|
273 | 251 | |
274 |
requests_get.return_value = utils.FakedResponse(content='{"error":"foobar"}', |
|
275 |
status_code=500) |
|
276 |
resp = app.get(endpoint, status=200) |
|
277 |
assert resp.json['err'] == 1 |
|
278 |
assert resp.json['err_desc'].startswith('error status:500') |
|
279 |
assert resp.json['data'] == {'json_content': {'error': 'foobar'}, 'status_code': 500} |
|
252 |
# solis api crash |
|
253 |
fake_http.add_response(content=APATOKEN, status_code=200, method='POST') |
|
280 | 254 | |
281 |
# unknown name_id or user_id |
|
282 |
for qs in ('name_id=%s&user_id=XXX' % NAMEID, 'name_id=unlinked&user_id=53'): |
|
283 |
endpoint = endpoint_base + ('?information=%s' % apa_endpoint) + '&' + qs |
|
284 |
resp = app.get(endpoint, status=200) |
|
285 |
assert resp.json['err'] == 1 |
|
286 |
assert resp.json['err_desc'] == 'unknown link' |
|
287 |
assert resp.json['data'] is None |
|
255 |
fake_http.add_response(content='boum', status_code=500, method='GET') |
|
256 |
resp = app.get(endpoint, status=200) |
|
257 |
assert ('/asg/apa/%s' % apa_endpoint) in fake_http.last_request.url |
|
258 |
assert resp.json['err'] == 1 |
|
259 |
assert resp.json['err_desc'].startswith('error status:500') |
|
260 |
assert resp.json['data'] == {'json_content': None, 'status_code': 500} |
|
288 | 261 | |
289 |
# get info about a specific request |
|
290 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
291 |
with mock.patch('passerelle.utils.Request.post') as requests_post: |
|
292 |
requests_post.return_value = utils.FakedResponse(content=APATOKEN, status_code=200) |
|
293 |
endpoint_base = utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug) |
|
262 |
fake_http.add_response(content=APATOKEN, status_code=200, method='POST') |
|
263 |
fake_http.add_response(content='{"error":"foobar"}', status_code=500, method='GET') |
|
264 |
resp = app.get(endpoint, status=200) |
|
265 |
assert resp.json['err'] == 1 |
|
266 |
assert resp.json['err_desc'].startswith('error status:500') |
|
267 |
assert resp.json['data'] == {'json_content': {'error': 'foobar'}, 'status_code': 500} |
|
294 | 268 | |
295 |
# via demandeUnitaire |
|
296 |
endpoint = endpoint_base + '?name_id=%s&user_id=53&information=demandeUnitaire&index=42' % NAMEID |
|
297 |
requests_get.return_value = utils.FakedResponse(content=APAREQUEST, status_code=200) |
|
298 |
resp = app.get(endpoint, status=200) |
|
299 |
assert requests_post.call_count == 1 # get a token |
|
300 |
assert requests_get.call_count == 1 # get demandeUnitaire |
|
301 |
url = requests_get.call_args[0][0] |
|
302 |
assert '/asg/apa/demandeUnitaire/' in url |
|
303 |
assert url.endswith('/42') |
|
304 |
assert resp.json['err'] == 0 |
|
305 |
assert resp.json['data']['demandeAsg']['demande']['indexDemande'] == 42 |
|
306 | ||
307 |
requests_post.reset_mock() |
|
308 |
requests_get.reset_mock() |
|
309 |
requests_get.return_value = utils.FakedResponse(content='nothing here', status_code=404) |
|
269 |
# unknown name_id or user_id |
|
270 |
for qs in ('name_id=%s&user_id=XXX' % NAMEID, 'name_id=unlinked&user_id=53'): |
|
271 |
endpoint = endpoint_base + ('?information=%s' % apa_endpoint) + '&' + qs |
|
310 | 272 |
resp = app.get(endpoint, status=200) |
311 |
assert requests_post.call_count == 1 # get a token |
|
312 |
assert requests_get.call_count == 1 # get demandeUnitaire |
|
313 |
url = requests_get.call_args[0][0] |
|
314 |
assert '/asg/apa/demandeUnitaire/' in url |
|
315 |
assert url.endswith('/42') |
|
316 |
assert resp.json['err'] == 1 |
|
317 |
assert resp.json['err_desc'].startswith('error status:404') |
|
318 | ||
319 |
# missing index |
|
320 |
requests_post.reset_mock() |
|
321 |
requests_get.reset_mock() |
|
322 |
endpoint = endpoint_base + '?name_id=%s&user_id=53&information=demandeUnitaire' % NAMEID |
|
323 |
resp = app.get(endpoint, status=400) |
|
324 |
requests_get.assert_not_called() |
|
325 |
requests_post.assert_not_called() |
|
326 | 273 |
assert resp.json['err'] == 1 |
274 |
assert resp.json['err_desc'] == 'unknown link' |
|
275 |
assert resp.json['data'] is None |
|
327 | 276 | |
328 |
# get indexDemande 42 in lists |
|
329 |
for information in ('consultationDeMesDroits', 'suiviDemandeHistorique', 'propositionPlanAide',): |
|
330 |
requests_post.reset_mock() |
|
331 |
requests_get.reset_mock() |
|
332 |
endpoint = endpoint_base + '?name_id=%s&user_id=53&information=%s&index=42' % (NAMEID, information) |
|
333 |
requests_get.return_value = utils.FakedResponse(content=APAINFOS[information], status_code=200) |
|
334 |
resp = app.get(endpoint, status=200) |
|
335 |
assert ('/asg/apa/%s/' % information) in requests_get.call_args[0][0] |
|
336 |
requests_post.assert_called_once() |
|
337 |
requests_get.assert_called_once() |
|
338 |
assert resp.json['err'] == 0 |
|
339 |
assert resp.json['data']['demandeAsg']['demande']['indexDemande'] == 42 |
|
340 | ||
341 |
endpoint = endpoint_base + '?name_id=%s&user_id=53&information=%s&index=57' % (NAMEID, information) |
|
342 |
resp = app.get(endpoint, status=200) |
|
343 |
assert ('/asg/apa/%s/' % information) in requests_get.call_args[0][0] |
|
344 |
assert requests_post.call_count == 2 |
|
345 |
assert requests_get.call_count == 2 |
|
346 |
assert resp.json['err'] == 1 |
|
347 |
assert resp.json['err_desc'] == 'cannot find indexDemande=57 in demandeAsg list' |
|
277 |
# get info about a specific request |
|
278 |
endpoint_base = utils.generic_endpoint_url('solis', 'apa-user-info', slug=solis.slug) |
|
279 | ||
280 |
# via demandeUnitaire |
|
281 |
endpoint = endpoint_base + '?name_id=%s&user_id=53&information=demandeUnitaire&index=42' % NAMEID |
|
282 |
fake_http.set_response(content=APATOKEN, status_code=200, method='POST') |
|
283 |
fake_http.add_response(content=APAREQUEST, status_code=200, method='GET') |
|
284 |
resp = app.get(endpoint, status=200) |
|
285 |
assert '/asg/apa/demandeUnitaire/' in fake_http.last_request.url |
|
286 |
assert fake_http.last_request.url.endswith('/42') |
|
287 |
assert resp.json['err'] == 0 |
|
288 |
assert resp.json['data']['demandeAsg']['demande']['indexDemande'] == 42 |
|
289 | ||
290 |
fake_http.set_response(content=APATOKEN, status_code=200, method='POST') |
|
291 |
fake_http.add_response(content='nothing here', status_code=404, method='GET') |
|
292 |
resp = app.get(endpoint, status=200) |
|
293 |
assert '/asg/apa/demandeUnitaire/' in fake_http.last_request.url |
|
294 |
assert fake_http.last_request.url.endswith('/42') |
|
295 |
assert resp.json['err'] == 1 |
|
296 |
assert resp.json['err_desc'].startswith('error status:404') |
|
297 | ||
298 |
# missing index |
|
299 |
fake_http.reset() |
|
300 |
endpoint = endpoint_base + '?name_id=%s&user_id=53&information=demandeUnitaire' % NAMEID |
|
301 |
resp = app.get(endpoint, status=400) |
|
302 |
assert resp.json['err'] == 1 |
|
303 | ||
304 |
# get indexDemande 42 in lists |
|
305 |
for information in ('consultationDeMesDroits', 'suiviDemandeHistorique', 'propositionPlanAide',): |
|
306 |
endpoint = endpoint_base + '?name_id=%s&user_id=53&information=%s&index=42' % (NAMEID, information) |
|
307 |
fake_http.set_response(content=APATOKEN, status_code=200, method='POST') |
|
308 |
fake_http.add_response(content=APAINFOS[information], status_code=200, method='GET') |
|
309 |
resp = app.get(endpoint, status=200) |
|
310 |
assert ('/asg/apa/%s/' % information) in fake_http.last_request.url |
|
311 |
assert resp.json['err'] == 0 |
|
312 |
assert resp.json['data']['demandeAsg']['demande']['indexDemande'] == 42 |
|
313 | ||
314 |
endpoint = endpoint_base + '?name_id=%s&user_id=53&information=%s&index=57' % (NAMEID, information) |
|
315 |
fake_http.set_response(content=APATOKEN, status_code=200, method='POST') |
|
316 |
fake_http.add_response(content=APAINFOS[information], status_code=200, method='GET') |
|
317 |
resp = app.get(endpoint, status=200) |
|
318 |
assert ('/asg/apa/%s/' % information) in fake_http.last_request.url |
|
319 |
assert resp.json['err'] == 1 |
|
320 |
assert resp.json['err_desc'] == 'cannot find indexDemande=57 in demandeAsg list' |
|
348 | 321 | |
349 | 322 |
# get informations for all users (exportDonneesIndividu) |
350 | 323 |
change_info = APAINFOS['exportDonneesIndividu'].replace('PYPPENNE', 'PEPPYNE') |
351 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
352 |
with mock.patch('passerelle.utils.Request.post') as requests_post: |
|
353 |
requests_post.return_value = utils.FakedResponse(content=APATOKEN, status_code=200) |
|
354 |
requests_get.return_value = utils.FakedResponse(content=change_info, status_code=200) |
|
355 |
endpoint = utils.generic_endpoint_url('solis', 'apa-users', slug=solis.slug) |
|
356 |
endpoint += '?name_id=%s' % NAMEID |
|
357 |
resp = app.get(endpoint, status=200) |
|
358 |
assert resp.json['err'] == 0 |
|
359 |
assert len(resp.json['data']) == 2 |
|
360 |
assert requests_post.call_count == 2 |
|
361 |
assert requests_get.call_count == 2 |
|
362 |
assert set([x['id'] for x in resp.json['data']]) == set(['42', '53']) |
|
363 |
assert resp.json['data'][0]['text'] == 'Mme Pecile PEPPYNE (NPYNEZ)' |
|
364 |
# user "text" updated in links: |
|
365 |
assert [x['text'] for x in SolisAPALink.objects.values('text')] == \ |
|
366 |
['Mme Pecile PEPPYNE (NPYNEZ)', 'Mme Pecile PEPPYNE (NPYNEZ)'] |
|
324 |
fake_http.set_response(content=APATOKEN, status_code=200, method='POST') |
|
325 |
fake_http.add_response(content=change_info, status_code=200, method='GET') |
|
326 |
fake_http.add_response(content=APATOKEN, status_code=200, method='POST') |
|
327 |
fake_http.add_response(content=change_info, status_code=200, method='GET') |
|
328 |
endpoint = utils.generic_endpoint_url('solis', 'apa-users', slug=solis.slug) |
|
329 |
endpoint += '?name_id=%s' % NAMEID |
|
330 |
resp = app.get(endpoint, status=200) |
|
331 |
assert resp.json['err'] == 0 |
|
332 |
assert len(resp.json['data']) == 2 |
|
333 |
assert set([x['id'] for x in resp.json['data']]) == set(['42', '53']) |
|
334 |
assert resp.json['data'][0]['text'] == 'Mme Pecile PEPPYNE (NPYNEZ)' |
|
335 |
# user "text" updated in links: |
|
336 |
assert [x['text'] for x in SolisAPALink.objects.values('text')] == \ |
|
337 |
['Mme Pecile PEPPYNE (NPYNEZ)', 'Mme Pecile PEPPYNE (NPYNEZ)'] |
|
338 |
fake_http.reset() |
|
367 | 339 | |
368 | 340 |
# unlink |
369 | 341 |
endpoint = utils.generic_endpoint_url('solis', 'apa-unlink', slug=solis.slug) |
... | ... | |
399 | 371 |
assert resp.json['data'] is None |
400 | 372 | |
401 | 373 | |
402 |
def test_solis_referentiels(app, solis): |
|
374 |
def test_solis_referentiels(fake_http, app, solis):
|
|
403 | 375 |
# full opened access |
404 | 376 |
api = ApiUser.objects.create(username='all', keytype='', key='') |
405 | 377 |
obj_type = ContentType.objects.get_for_model(solis) |
406 | 378 |
AccessRight.objects.create(codename='can_access', apiuser=api, resource_type=obj_type, |
407 | 379 |
resource_pk=solis.pk) |
408 | 380 | |
409 |
with mock.patch('passerelle.utils.Request.get') as requests_get: |
|
410 |
requests_get.return_value = utils.FakedResponse(content=DEPARTEMENTS, status_code=200) |
|
411 |
url = utils.generic_endpoint_url('solis', 'referential', slug=solis.slug) |
|
381 |
fake_http.set_response(content=DEPARTEMENTS, status_code=200, method='GET') |
|
382 |
url = utils.generic_endpoint_url('solis', 'referential', slug=solis.slug) |
|
412 | 383 | |
413 |
resp = app.get(url + '/trans/departement/', status=200) |
|
414 |
assert requests_get.call_count == 1 |
|
415 |
assert requests_get.call_args[0][0].endswith('/solisapi/referentiels/trans/departement') |
|
416 |
assert resp.json['err'] == 0 |
|
417 |
assert len(resp.json['data']) == 8 |
|
384 |
resp = app.get(url + '/trans/departement/', status=200) |
|
385 |
assert fake_http.last_request.url.endswith('/solisapi/referentiels/trans/departement') |
|
386 |
assert resp.json['err'] == 0 |
|
387 |
assert len(resp.json['data']) == 8 |
|
418 | 388 | |
419 |
resp = app.get(url + '/trans/departement/?q=ardeche', status=200) |
|
420 |
assert requests_get.call_args[0][0].endswith('/solisapi/referentiels/trans/departement') |
|
421 |
assert resp.json['err'] == 0 |
|
422 |
assert len(resp.json['data']) == 1 |
|
423 |
assert resp.json['data'][0]['text'] == u'Ardèche' |
|
389 |
fake_http.set_response(content=DEPARTEMENTS, status_code=200, method='GET') |
|
390 |
resp = app.get(url + '/trans/departement/?q=ardeche', status=200) |
|
391 |
assert fake_http.last_request.url.endswith('/solisapi/referentiels/trans/departement') |
|
392 |
assert resp.json['err'] == 0 |
|
393 |
assert len(resp.json['data']) == 1 |
|
394 |
assert resp.json['data'][0]['text'] == u'Ardèche' |
|
424 | 395 | |
425 |
resp = app.get(url + '/trans/departement/?q=arde', status=200) |
|
426 |
assert resp.json['err'] == 0 |
|
427 |
assert len(resp.json['data']) == 2 |
|
428 |
assert (resp.json['data'][0]['text'], resp.json['data'][1]['text']) == (u'Ardèche', 'Ardennes') |
|
396 |
fake_http.set_response(content=DEPARTEMENTS, status_code=200, method='GET') |
|
397 |
resp = app.get(url + '/trans/departement/?q=arde', status=200) |
|
398 |
assert resp.json['err'] == 0 |
|
399 |
assert len(resp.json['data']) == 2 |
|
400 |
assert (resp.json['data'][0]['text'], resp.json['data'][1]['text']) == (u'Ardèche', 'Ardennes') |
|
429 | 401 | |
430 |
resp = app.get(url + '/trans/departement/?q=arde&ignore=8', status=200) |
|
431 |
assert resp.json['err'] == 0 |
|
432 |
assert len(resp.json['data']) == 1 |
|
433 |
assert resp.json['data'][0]['text'] == u'Ardèche' |
|
402 |
fake_http.set_response(content=DEPARTEMENTS, status_code=200, method='GET') |
|
403 |
resp = app.get(url + '/trans/departement/?q=arde&ignore=8', status=200) |
|
404 |
assert resp.json['err'] == 0 |
|
405 |
assert len(resp.json['data']) == 1 |
|
406 |
assert resp.json['data'][0]['text'] == u'Ardèche' |
|
434 | 407 | |
435 |
resp = app.get(url + '/trans/departement/?q=arde&ignore=8,, 7', status=200) |
|
436 |
assert resp.json['err'] == 0 |
|
437 |
assert len(resp.json['data']) == 0 |
|
408 |
fake_http.set_response(content=DEPARTEMENTS, status_code=200, method='GET') |
|
409 |
resp = app.get(url + '/trans/departement/?q=arde&ignore=8,, 7', status=200) |
|
410 |
assert resp.json['err'] == 0 |
|
411 |
assert len(resp.json['data']) == 0 |
|
438 | 412 | |
439 |
resp = app.get(url + '/trans/departement/?codePays=79&foo=bar', status=200) |
|
440 |
assert requests_get.call_args[0][0].endswith('/solisapi/referentiels/trans/departement?codePays=79') |
|
413 |
fake_http.set_response(content=DEPARTEMENTS, status_code=200, method='GET') |
|
414 |
resp = app.get(url + '/trans/departement/?codePays=79&foo=bar', status=200) |
|
415 |
assert fake_http.last_request.url.endswith('/solisapi/referentiels/trans/departement?codePays=79') |
|
441 | 416 | |
442 |
requests_get.return_value = utils.FakedResponse(content='{"nada":0}', status_code=404, |
|
443 |
reason='Not found') |
|
444 |
resp = app.get(url + '/foo/bar/', status=200) |
|
445 |
assert requests_get.call_args[0][0].endswith('/solisapi/referentiels/foo/bar') |
|
446 |
assert resp.json['err'] == 1 |
|
447 |
assert resp.json['err_desc'] == "error status:404 'Not found', content:'{\"nada\":0}'" |
|
448 |
assert resp.json['data'] == {'json_content': {'nada': 0}, 'status_code': 404} |
|
417 |
fake_http.set_response(content='{"nada":0}', status_code=404, reason='Not found', method='GET') |
|
418 |
resp = app.get(url + '/foo/bar/', status=200) |
|
419 |
assert fake_http.last_request.url.endswith('/solisapi/referentiels/foo/bar') |
|
420 |
assert resp.json['err'] == 1 |
|
421 |
assert resp.json['err_desc'] == "error status:404 'Not found', content:'{\"nada\":0}'" |
|
422 |
assert resp.json['data'] == {'json_content': {'nada': 0}, 'status_code': 404} |
|
449 | 423 | |
450 |
requests_get.return_value = utils.FakedResponse(content='crash', status_code=500, reason='boum')
|
|
451 |
resp = app.get(url + '/foo/bar/', status=200)
|
|
452 |
assert requests_get.call_args[0][0].endswith('/solisapi/referentiels/foo/bar')
|
|
453 |
assert resp.json['err'] == 1
|
|
454 |
assert resp.json['err_desc'] == "error status:500 'boum', content:'crash'"
|
|
455 |
assert resp.json['data'] == {'json_content': None, 'status_code': 500}
|
|
424 |
fake_http.set_response(content='crash', status_code=500, reason='boum', method='GET')
|
|
425 |
resp = app.get(url + '/foo/bar/', status=200) |
|
426 |
assert fake_http.last_request.url.endswith('/solisapi/referentiels/foo/bar')
|
|
427 |
assert resp.json['err'] == 1 |
|
428 |
assert resp.json['err_desc'] == "error status:500 'boum', content:'crash'" |
|
429 |
assert resp.json['data'] == {'json_content': None, 'status_code': 500} |
|
456 | 430 | |
457 | 431 | |
458 | 432 |
def test_unflat_dict(): |
459 | 433 |
assert unflat({'foo': 'bar', 'two_foo': 'one', 'two_bar': 'two'}) == {'foo': 'bar', 'two': {'foo': 'one', 'bar': 'two'}} |
460 | 434 | |
461 | 435 | |
462 |
def test_solis_apa_integration(app, solis): |
|
436 |
def test_solis_apa_integration(fake_http, app, solis):
|
|
463 | 437 |
api = ApiUser.objects.create(username='all', keytype='', key='') |
464 | 438 |
obj_type = ContentType.objects.get_for_model(solis) |
465 | 439 |
AccessRight.objects.create(codename='can_access', apiuser=api, resource_type=obj_type, |
466 | 440 |
resource_pk=solis.pk) |
467 | 441 | |
468 |
with mock.patch('passerelle.utils.Request.post') as requests_post: |
|
469 |
def integration_ok(*args, **kwargs): |
|
470 |
return utils.FakedResponse(content='', status_code=204) |
|
471 |
requests_post.return_value = utils.FakedResponse(content='', status_code=204) |
|
472 |
# requests_post.side_effect = [utils.FakedResponse(content='', status_code=204)] |
|
473 |
url = utils.generic_endpoint_url('solis', 'apa-integration', slug=solis.slug) |
|
474 | ||
475 |
demande = { |
|
476 |
"beneficiaire_demande_aide": "APAD", |
|
477 |
"beneficiaire_demande_dateDepot": "2018-02-09", |
|
478 |
"beneficiaire_etatCivil_civilite": "M", |
|
479 |
"beneficiaire_etatCivil_contact_courriel": "benef@yopmail.com", |
|
480 |
"conjoint_nom": "Conjnom", |
|
481 |
"conjoint_prenom": "Conjprenom", |
|
482 |
} |
|
483 | ||
484 |
resp = app.post_json(url, params=demande, status=200) |
|
485 | ||
486 |
requests_post.assert_called_once() |
|
487 |
assert requests_post.call_args[0][0].endswith('/solisapi/asg/apa/integrationDemandeApa') |
|
488 |
assert requests_post.call_args[1]['json']['demandeApa']['beneficiaire']['demande']['aide'] == 'APAD' |
|
489 |
assert requests_post.call_args[1]['json']['demandeApa']['conjoint']['nom'] == 'Conjnom' |
|
490 |
assert requests_post.call_args[1]['json']['demandeApa'] == unflat(demande) |
|
491 |
assert resp.json['err'] == 0 |
|
492 |
assert resp.json['data'] is None |
|
493 | ||
494 |
# don't send "conjoint" dict to Solis |
|
495 |
requests_post.reset_mock() |
|
496 |
demande['del:conjoint'] = True |
|
497 |
resp = app.post_json(url, params=demande, status=200) |
|
498 |
requests_post.assert_called_once() |
|
499 |
assert 'conjoint' not in requests_post.call_args[1]['json']['demandeApa'] |
|
500 |
assert resp.json['err'] == 0 |
|
442 |
def integration_ok(*args, **kwargs): |
|
443 |
return utils.FakedResponse(content='', status_code=204) |
|
501 | 444 | |
502 |
# send "conjoint" dict to Solis |
|
503 |
requests_post.reset_mock() |
|
504 |
demande['del:conjoint'] = False |
|
505 |
resp = app.post_json(url, params=demande, status=200) |
|
506 |
requests_post.assert_called_once() |
|
507 |
assert requests_post.call_args[1]['json']['demandeApa']['conjoint']['nom'] == 'Conjnom' |
|
508 |
assert resp.json['err'] == 0 |
|
445 |
# requests_post.side_effect = [utils.FakedResponse(content='', status_code=204)] |
|
446 |
url = utils.generic_endpoint_url('solis', 'apa-integration', slug=solis.slug) |
|
509 | 447 | |
510 |
# add files |
|
511 |
requests_post.reset_mock() |
|
512 |
requests_post.side_effect = [ |
|
513 |
utils.FakedResponse(content='{"id": "foo", "nbFichiersAcceptes": 3}', status_code=200), |
|
514 |
utils.FakedResponse(content='', status_code=204)] |
|
515 |
demande['file:etat_civil_001.pdf'] = { |
|
516 |
'content': 'JVBERmZha2U=', |
|
517 |
'content_type': 'application/pdf', |
|
518 |
'filename': 'whatever.pdf', |
|
519 |
} |
|
520 |
demande['file:etat_civil_002.pdf'] = { |
|
521 |
# jpeg, will be converted to PDF |
|
522 |
'content': '/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCw' |
|
523 |
'kJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=', |
|
524 |
'content_type': 'image/jpeg', |
|
525 |
'filename': 'image.jpg', |
|
526 |
} |
|
527 |
demande['file:etat_civil_003.pdf'] = { |
|
528 |
# transparent png (RGBA), will be converted to RGB and then PDF |
|
529 |
'content': 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQ' |
|
530 |
'ABDQottAAAAABJRU5ErkJggg==', |
|
531 |
'content_type': 'image/png', |
|
532 |
'filename': 'image.png', |
|
533 |
} |
|
534 |
demande['file:etat_civil_004.pdf'] = { |
|
535 |
'content': 'Y29pbg==', # bad content, conversion will fail |
|
536 |
'content_type': 'image/png', |
|
537 |
'filename': 'image.png', |
|
538 |
} |
|
539 |
demande['file:etat_civil_005.pdf'] = { |
|
540 |
'content': 'Y29pbg==', |
|
541 |
'content_type': 'video/mp4', # not a image, cannot convert |
|
542 |
'filename': 'video.mp4', |
|
543 |
} |
|
544 |
demande['file:etat_civil_006.pdf'] = { |
|
545 |
'content_type': 'video/mp4', # no content, cannot convert |
|
546 |
} |
|
547 |
demande['file:etat_civil_007.pdf'] = None |
|
548 |
resp = app.post_json(url, params=demande, status=200) |
|
549 |
assert requests_post.call_count == 2 # post files + demandeApa |
|
550 |
sent_files = requests_post.call_args_list[0][1]['files'] |
|
551 |
assert len(sent_files) == 3 |
|
552 |
for file_ in sent_files: |
|
553 |
assert file_[1][1].startswith('%PDF') |
|
554 |
# file entries are removed from demandeApa JSON dict |
|
555 |
assert 'file:etat_civil_001.pdf' not in requests_post.call_args[1]['json']['demandeApa'] |
|
556 |
assert 'file:etat_civil_002.pdf' not in requests_post.call_args[1]['json']['demandeApa'] |
|
557 |
assert resp.json['err'] == 0 |
|
558 |
assert resp.json['data'] is None |
|
559 |
assert resp.json['files_sent'] == {'id': 'foo', 'nbFichiersAcceptes': 3} |
|
560 |
assert set(resp.json['files_failed_pdf_conversion']) == set(['etat_civil_004.pdf', |
|
561 |
'etat_civil_005.pdf', |
|
562 |
'etat_civil_006.pdf']) |
|
563 | ||
564 |
# invalid inputs |
|
565 |
requests_post.reset_mock() |
|
566 |
resp = app.post_json(url, params=['not', 'a', 'dict'], status=400) |
|
567 |
requests_post.assert_not_called() |
|
568 |
assert resp.json['err'] == 1 |
|
569 |
assert resp.json['err_desc'] == 'payload is not a JSON dict' |
|
570 |
resp = app.post(url, params='coin', status=400) |
|
571 |
requests_post.assert_not_called() |
|
572 |
assert resp.json['err'] == 1 |
|
573 |
assert resp.json['err_desc'] == 'payload is not a JSON object' |
|
574 | ||
575 |
# bad file |
|
576 |
requests_post.reset_mock() |
|
577 |
requests_post.side_effect = [ |
|
578 |
utils.FakedResponse(content='{"id": "foo", "nbFichiersAcceptes": 0}', status_code=200), |
|
579 |
utils.FakedResponse(content='', status_code=204)] |
|
580 |
resp = app.post_json(url, params=demande, status=200) |
|
581 |
requests_post.assert_called_once() # don't try to post request |
|
582 |
assert resp.json['err'] == 1 |
|
583 |
assert resp.json['err_desc'] == 'fail to send all files' |
|
584 |
assert resp.json['data'] == {'id': 'foo', 'nbFichiersAcceptes': 0} |
|
585 | ||
586 |
# error on sending file |
|
587 |
requests_post.reset_mock() |
|
588 |
requests_post.side_effect = [ |
|
589 |
utils.FakedResponse(content='{"error": 1}', status_code=500), |
|
590 |
utils.FakedResponse(content='', status_code=204)] |
|
591 |
resp = app.post_json(url, params=demande, status=200) |
|
592 |
requests_post.assert_called_once() # don't try to post request |
|
593 |
assert resp.json['err'] == 1 |
|
594 |
assert resp.json['err_desc'].startswith('error status:500') |
|
448 |
demande = { |
|
449 |
"beneficiaire_demande_aide": "APAD", |
|
450 |
"beneficiaire_demande_dateDepot": "2018-02-09", |
|
451 |
"beneficiaire_etatCivil_civilite": "M", |
|
452 |
"beneficiaire_etatCivil_contact_courriel": "benef@yopmail.com", |
|
453 |
"conjoint_nom": "Conjnom", |
|
454 |
"conjoint_prenom": "Conjprenom", |
|
455 |
} |
|
456 | ||
457 |
fake_http.set_response(content='', status_code=204, method='POST') |
|
458 |
resp = app.post_json(url, params=demande, status=200) |
|
459 | ||
460 |
assert fake_http.last_request.url.endswith('/solisapi/asg/apa/integrationDemandeApa') |
|
461 |
assert fake_http.last_request.json['demandeApa']['beneficiaire']['demande']['aide'] == 'APAD' |
|
462 |
assert fake_http.last_request.json['demandeApa']['conjoint']['nom'] == 'Conjnom' |
|
463 |
assert fake_http.last_request.json['demandeApa'] == unflat(demande) |
|
464 |
assert resp.json['err'] == 0 |
|
465 |
assert resp.json['data'] is None |
|
466 | ||
467 |
# don't send "conjoint" dict to Solis |
|
468 |
demande['del:conjoint'] = True |
|
469 |
fake_http.set_response(content='', status_code=204, method='POST') |
|
470 |
resp = app.post_json(url, params=demande, status=200) |
|
471 |
assert 'conjoint' not in fake_http.last_request.json['demandeApa'] |
|
472 |
assert resp.json['err'] == 0 |
|
473 | ||
474 |
# send "conjoint" dict to Solis |
|
475 |
demande['del:conjoint'] = False |
|
476 |
fake_http.set_response(content='', status_code=204, method='POST') |
|
477 |
resp = app.post_json(url, params=demande, status=200) |
|
478 |
assert fake_http.last_request.json['demandeApa']['conjoint']['nom'] == 'Conjnom' |
|
479 |
assert resp.json['err'] == 0 |
|
480 | ||
481 |
# add files |
|
482 |
demande['file:etat_civil_001.pdf'] = { |
|
483 |
'content': 'JVBERmZha2U=', |
|
484 |
'content_type': 'application/pdf', |
|
485 |
'filename': 'whatever.pdf', |
|
486 |
} |
|
487 |
demande['file:etat_civil_002.pdf'] = { |
|
488 |
# jpeg, will be converted to PDF |
|
489 |
'content': '/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCw' |
|
490 |
'kJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=', |
|
491 |
'content_type': 'image/jpeg', |
|
492 |
'filename': 'image.jpg', |
|
493 |
} |
|
494 |
demande['file:etat_civil_003.pdf'] = { |
|
495 |
# transparent png (RGBA), will be converted to RGB and then PDF |
|
496 |
'content': 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQ' |
|
497 |
'ABDQottAAAAABJRU5ErkJggg==', |
|
498 |
'content_type': 'image/png', |
|
499 |
'filename': 'image.png', |
|
500 |
} |
|
501 |
demande['file:etat_civil_004.pdf'] = { |
|
502 |
'content': 'Y29pbg==', # bad content, conversion will fail |
|
503 |
'content_type': 'image/png', |
|
504 |
'filename': 'image.png', |
|
505 |
} |
|
506 |
demande['file:etat_civil_005.pdf'] = { |
|
507 |
'content': 'Y29pbg==', |
|
508 |
'content_type': 'video/mp4', # not a image, cannot convert |
|
509 |
'filename': 'video.mp4', |
|
510 |
} |
|
511 |
demande['file:etat_civil_006.pdf'] = { |
|
512 |
'content_type': 'video/mp4', # no content, cannot convert |
|
513 |
} |
|
514 |
demande['file:etat_civil_007.pdf'] = None |
|
515 | ||
516 |
fake_http.set_response(content='{"id": "foo", "nbFichiersAcceptes": 3}', status_code=200, method='POST') |
|
517 |
fake_http.add_response(content='', status_code=204, method='POST') |
|
518 |
resp = app.post_json(url, params=demande, status=200) |
|
519 |
sent_files = fake_http.requests[0].FILES.getlist('files') |
|
520 |
assert len(sent_files) == 3 |
|
521 |
for file_ in sent_files: |
|
522 |
assert file_.read().startswith('%PDF') |
|
523 |
# file entries are removed from demandeApa JSON dict |
|
524 |
assert 'file:etat_civil_001.pdf' not in fake_http.last_request.json['demandeApa'] |
|
525 |
assert 'file:etat_civil_002.pdf' not in fake_http.last_request.json['demandeApa'] |
|
526 |
assert resp.json['err'] == 0 |
|
527 |
assert resp.json['data'] is None |
|
528 |
assert resp.json['files_sent'] == {'id': 'foo', 'nbFichiersAcceptes': 3} |
|
529 |
assert set(resp.json['files_failed_pdf_conversion']) == set(['etat_civil_004.pdf', |
|
530 |
'etat_civil_005.pdf', |
|
531 |
'etat_civil_006.pdf']) |
|
532 | ||
533 |
# invalid inputs |
|
534 |
fake_http.reset() |
|
535 |
resp = app.post_json(url, params=['not', 'a', 'dict'], status=400) |
|
536 |
assert resp.json['err'] == 1 |
|
537 |
assert resp.json['err_desc'] == 'payload is not a JSON dict' |
|
538 |
resp = app.post(url, params='coin', status=400) |
|
539 |
assert resp.json['err'] == 1 |
|
540 |
assert resp.json['err_desc'] == 'payload is not a JSON object' |
|
541 | ||
542 |
# bad file |
|
543 |
fake_http.set_response(content='{"id": "foo", "nbFichiersAcceptes": 0}', status_code=200, method='POST') |
|
544 |
resp = app.post_json(url, params=demande, status=200) |
|
545 |
assert resp.json['err'] == 1 |
|
546 |
assert resp.json['err_desc'] == 'fail to send all files' |
|
547 |
assert resp.json['data'] == {'id': 'foo', 'nbFichiersAcceptes': 0} |
|
548 | ||
549 |
# error on sending file |
|
550 |
fake_http.set_response(content='{"error": 1}', status_code=500, method='POST') |
|
551 |
resp = app.post_json(url, params=demande, status=200) |
|
552 |
assert resp.json['err'] == 1 |
|
553 |
assert resp.json['err_desc'].startswith('error status:500') |
tests/test_vivaticket.py | ||
---|---|---|
201 | 201 |
url='http://example.net/vivaticket')) |
202 | 202 | |
203 | 203 | |
204 |
@mock.patch('passerelle.utils.Request.post') |
|
205 |
def test_get_api_key(mocked_post, app, connector): |
|
204 |
def test_get_api_key(fake_http, app, connector): |
|
205 |
fake_http.set_response(content=ERROR_RESPONSE, status_code=400) |
|
206 | 206 |
with pytest.raises(APIError): |
207 |
mocked_post.return_value = utils.FakedResponse(content=ERROR_RESPONSE, ok=False) |
|
208 | 207 |
connector.get_apikey() |
209 |
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, ok=True) |
|
208 | ||
209 |
fake_http.set_response(content=KEY_RESPONSE, status_code=200) |
|
210 | 210 |
connector.get_apikey() |
211 |
assert mocked_post.call_count == 2 |
|
212 |
assert "Connect/PostConnect" in mocked_post.call_args[0][0] |
|
213 |
assert mocked_post.call_args[1]['json']['Login'] == 'foo' |
|
214 |
assert mocked_post.call_args[1]['json']['Password'] == 'bar' |
|
211 |
assert "Connect/PostConnect" in fake_http.last_request.url |
|
212 |
assert fake_http.last_request.json['Login'] == 'foo' |
|
213 |
assert fake_http.last_request.json['Password'] == 'bar' |
|
215 | 214 |
# make sure the key from cache is used |
216 | 215 |
connector.get_apikey() |
217 |
assert mocked_post.call_count == 2 |
|
216 | ||
217 |
fake_http.set_response(content=KEY_RESPONSE, status_code=200) |
|
218 | 218 |
connector.get_apikey(True) |
219 |
assert mocked_post.call_count == 3 |
|
220 | 219 | |
221 | 220 | |
222 |
@mock.patch('passerelle.utils.Request.post') |
|
223 |
@mock.patch('passerelle.utils.Request.get') |
|
224 |
def test_get_events(mocked_get, mocked_post, app, connector): |
|
225 |
mocked_get.return_value = utils.FakedResponse(content=EVENTS_RESPONSE, status_code=200) |
|
226 |
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200) |
|
221 |
def test_get_events(fake_http, app, connector): |
|
222 |
fake_http.set_response(content=KEY_RESPONSE, status_code=200) |
|
223 |
fake_http.add_response(content=EVENTS_RESPONSE, status_code=200) |
|
227 | 224 |
result = utils.endpoint_get('/vivaticket/test/events', app, connector, 'events') |
228 |
assert mocked_post.call_count == 1 |
|
229 |
assert mocked_get.call_args[1]['params']['key'] == "86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074" |
|
225 |
assert fake_http.last_request.GET['key'] == "86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074" |
|
230 | 226 |
assert 'data' in result.json |
231 | 227 |
for item in result.json['data']: |
232 | 228 |
assert 'id' in item |
233 | 229 |
assert 'text' in item |
234 | 230 | |
235 | 231 | |
236 |
@mock.patch('passerelle.utils.Request.post') |
|
237 |
@mock.patch('passerelle.utils.Request.get')
|
|
238 |
def test_get_events_with_expired_key(mocked_get, mocked_post, app, connector): |
|
239 |
mocked_get.return_value = utils.FakedResponse(content=EVENTS_RESPONSE, status_code=401)
|
|
240 |
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200)
|
|
232 |
def test_get_events_with_expired_key(fake_http, app, connector): |
|
233 |
fake_http.set_response(content=KEY_RESPONSE, status_code=200)
|
|
234 |
fake_http.add_response(content=EVENTS_RESPONSE, status_code=401) |
|
235 |
fake_http.add_response(content=KEY_RESPONSE, status_code=200)
|
|
236 |
fake_http.add_response(content=EVENTS_RESPONSE, status_code=200)
|
|
241 | 237 |
utils.endpoint_get('/vivaticket/test/events', app, connector, 'events') |
242 |
assert mocked_post.call_count == 2 |
|
243 | 238 | |
244 | 239 | |
245 |
@mock.patch('passerelle.utils.Request.post') |
|
246 |
@mock.patch('passerelle.utils.Request.get') |
|
247 |
def test_get_rooms(mocked_get, mocked_post, app, connector): |
|
248 |
mocked_get.return_value = utils.FakedResponse(content=ROOMS_RESPONSE, status_code=200) |
|
249 |
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200) |
|
240 |
def test_get_rooms(fake_http, app, connector): |
|
241 |
fake_http.set_response(content=KEY_RESPONSE, status_code=200) |
|
242 |
fake_http.add_response(content=ROOMS_RESPONSE, status_code=200) |
|
250 | 243 |
result = utils.endpoint_get('/vivaticket/test/rooms', app, connector, 'rooms') |
251 |
assert mocked_get.call_args[1]['params']['key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
|
|
244 |
assert fake_http.last_request.GET['key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
|
|
252 | 245 |
assert 'data' in result.json |
253 | 246 |
for item in result.json['data']: |
254 | 247 |
assert 'id' in item |
255 | 248 |
assert 'text' in item |
249 |
fake_http.set_response(content=ROOMS_RESPONSE, status_code=200) |
|
256 | 250 |
result = utils.endpoint_get('/vivaticket/test/rooms', app, connector, 'rooms', params={'event': '02'}) |
257 |
assert mocked_get.call_args[1]['params']['eventCategory'] == '02'
|
|
251 |
assert fake_http.last_request.GET['eventCategory'] == '02'
|
|
258 | 252 | |
259 | 253 | |
260 |
@mock.patch('passerelle.utils.Request.post') |
|
261 |
@mock.patch('passerelle.utils.Request.get') |
|
262 |
def test_get_themes(mocked_get, mocked_post, app, connector): |
|
263 |
mocked_get.return_value = utils.FakedResponse(content=ROOMS_RESPONSE, status_code=200) |
|
264 |
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200) |
|
254 |
def test_get_themes(fake_http, app, connector): |
|
255 |
fake_http.set_response(content=KEY_RESPONSE, status_code=200) |
|
256 |
fake_http.add_response(content=ROOMS_RESPONSE, status_code=200) |
|
265 | 257 |
result = utils.endpoint_get('/vivaticket/test/themes', app, connector, 'themes') |
266 |
assert mocked_get.call_args[1]['params']['key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074' |
|
258 |
assert fake_http.requests[-2].method == 'POST' |
|
259 |
assert fake_http.last_request.method == 'GET' |
|
260 |
assert fake_http.last_request.GET['key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074' |
|
267 | 261 |
assert 'data' in result.json |
268 | 262 |
for item in result.json['data']: |
269 | 263 |
assert 'id' in item |
270 | 264 |
assert 'text' in item |
265 |
fake_http.add_response(content=ROOMS_RESPONSE, status_code=200) |
|
271 | 266 |
result = utils.endpoint_get('/vivaticket/test/themes', app, connector, 'themes', params={'room': '001'}) |
272 |
assert mocked_get.call_args[1]['params']['room'] == '001'
|
|
267 |
assert fake_http.last_request.GET['room'] == '001'
|
|
273 | 268 | |
274 | 269 | |
275 |
@mock.patch('passerelle.utils.Request.post') |
|
276 |
@mock.patch('passerelle.utils.Request.get') |
|
277 |
def test_get_or_create_contact(mocked_get, mocked_post, app, connector): |
|
278 |
mocked_get.return_value = utils.FakedResponse(content=CONTACT_RESPONSE, ok=True) |
|
279 |
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200) |
|
270 |
def test_get_or_create_contact(fake_http, app, connector): |
|
271 |
fake_http.set_response(content=KEY_RESPONSE, status_code=200, method='POST') |
|
272 |
fake_http.add_response(content=CONTACT_RESPONSE, status_code=200, method='GET') |
|
280 | 273 |
assert connector.get_or_create_contact('foo@example.com') == {'InternalCode': '0000000273'} |
281 |
mocked_get.return_value = utils.FakedResponse(content=CONTACT_RESPONSE, ok=False)
|
|
282 |
mocked_post.return_value = utils.FakedResponse(
|
|
283 |
content='{"InternalCode": "0000000277", "ReturnCode": 0, "Error": null}',
|
|
284 |
status_code=200)
|
|
274 |
fake_http.add_response(content=CONTACT_RESPONSE, status_code=404, method='GET')
|
|
275 |
fake_http.add_response(content='{"InternalCode": "0000000277", "ReturnCode": 0, "Error": null}',
|
|
276 |
status_code=200,
|
|
277 |
method='POST')
|
|
285 | 278 |
connector.get_or_create_contact('foo@example.com') |
286 |
assert mocked_post.call_args[1]['json']['Key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
|
|
287 |
assert mocked_post.call_args[1]['json']['Contact']['Email'] == 'foo@example.com'
|
|
288 |
assert mocked_post.call_args[1]['json']['Contact']['ExternalCode'] == 'b48def645758b95537d4'
|
|
279 |
assert fake_http.last_request.json['Key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
|
|
280 |
assert fake_http.last_request.json['Contact']['Email'] == 'foo@example.com'
|
|
281 |
assert fake_http.last_request.json['Contact']['ExternalCode'] == 'b48def645758b95537d4'
|
|
289 | 282 | |
290 | 283 | |
291 |
@mock.patch('passerelle.utils.Request.post') |
|
292 |
@mock.patch('passerelle.utils.Request.put') |
|
293 |
@mock.patch('passerelle.utils.Request.get') |
|
294 |
def test_get_and_update_contact(mocked_get, mocked_put, mocked_post, app, connector): |
|
295 |
mocked_get.return_value = utils.FakedResponse(content=CONTACT_RESPONSE, ok=True) |
|
296 |
mocked_post.return_value = utils.FakedResponse(content=KEY_RESPONSE, status_code=200) |
|
284 |
def test_get_and_update_contact(fake_http, app, connector): |
|
285 |
fake_http.set_response(content=KEY_RESPONSE, status_code=200, method='POST') |
|
286 |
fake_http.add_response(content=CONTACT_RESPONSE, status_code=200, method='GET') |
|
297 | 287 |
assert connector.get_or_create_contact('foo@example.com') == {'InternalCode': '0000000273'} |
298 |
mocked_put.return_value = utils.FakedResponse( |
|
299 |
content='{"InternalCode": "0000000277", "ReturnCode": 0, "Error": null}', |
|
300 |
status_code=200) |
|
288 | ||
289 |
fake_http.add_response(content=CONTACT_RESPONSE, status_code=200, method='GET') |
|
290 |
fake_http.add_response(content='{"InternalCode": "0000000277", "ReturnCode": 0, "Error": null}', |
|
291 |
status_code=200, |
|
292 |
method='PUT') |
|
301 | 293 |
connector.get_or_create_contact('bar@example.com', 'bar') |
302 |
assert mocked_put.call_args[1]['params']['id'] == '0000000273' |
|
303 |
assert mocked_put.call_args[1]['json']['Key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074' |
|
304 |
assert mocked_put.call_args[1]['json']['Contact']['Email'] == 'bar@example.com' |
|
294 |
assert fake_http.last_request.method == 'PUT' |
|
295 |
assert fake_http.last_request.GET['id'] == '0000000273' |
|
296 |
assert fake_http.last_request.json['Key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074' |
|
297 |
assert fake_http.last_request.json['Contact']['Email'] == 'bar@example.com' |
|
305 | 298 | |
306 | 299 | |
307 |
@mock.patch('passerelle.utils.Request.post') |
|
308 |
@mock.patch('passerelle.utils.Request.get') |
|
309 |
def test_book(mocked_get, mocked_post, app, connector): |
|
310 |
mocked_get.return_value = utils.FakedResponse(content=CONTACT_RESPONSE, status_code=200) |
|
300 |
def test_book(fake_http, app, connector): |
|
311 | 301 |
url = utils.generic_endpoint_url('vivaticket', 'book') |
312 | 302 |
payload = {'id': 'formid', 'email': 'foo@example.com'} |
303 | ||
313 | 304 |
response = app.post_json(url, params=payload, status=400) |
305 | ||
314 | 306 |
payload['datetime'] = '2019-01-15' |
315 | 307 |
payload['event'] = '01' |
316 | 308 |
payload['theme'] = '001' |
... | ... | |
319 | 311 |
response = app.post_json(url, params=payload, status=400) |
320 | 312 |
assert "does not match '^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}$" in response.json['err_desc'] |
321 | 313 |
payload['datetime'] = '2019-01-15T10:00' |
322 |
# first return the API key, then the result of the booking creation |
|
323 |
mocked_post.side_effect = [ |
|
324 |
utils.FakedResponse(content=KEY_RESPONSE, status_code=200), |
|
325 |
utils.FakedResponse(content=BOOKING_RESPONSE), |
|
326 |
Exception(), |
|
327 |
] |
|
314 | ||
315 |
fake_http.set_response(content=KEY_RESPONSE, status_code=200, method='POST') |
|
316 |
fake_http.add_response(content=CONTACT_RESPONSE, status_code=200, method='GET') |
|
317 |
fake_http.add_response(content=BOOKING_RESPONSE, status_code=200, method='POST') |
|
328 | 318 |
response = app.post_json(url, params=payload) |
329 |
assert mocked_post.call_args[1]['json']['Key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
|
|
330 |
assert mocked_post.call_args[1]['json']['Booking']['externalCode'] == 'formid'
|
|
331 |
assert mocked_post.call_args[1]['json']['Booking']['startDateTime'] == '2019-01-15T10:00'
|
|
332 |
assert mocked_post.call_args[1]['json']['Booking']['endDateTime'] == '2019-01-15T10:00'
|
|
333 |
assert mocked_post.call_args[1]['json']['Booking']['contact'] == {'InternalCode': '0000000273'}
|
|
319 |
assert fake_http.last_request.json['Key'] == '86569D0CA1B1CBEF8D77DD5BDC9F5CBAE5C99074'
|
|
320 |
assert fake_http.last_request.json['Booking']['externalCode'] == 'formid'
|
|
321 |
assert fake_http.last_request.json['Booking']['startDateTime'] == '2019-01-15T10:00'
|
|
322 |
assert fake_http.last_request.json['Booking']['endDateTime'] == '2019-01-15T10:00'
|
|
323 |
assert fake_http.last_request.json['Booking']['contact'] == {'InternalCode': '0000000273'}
|
|
334 | 324 |
assert response.json['data']['bookingCode'] == 'II0000013' |
335 |
- |