solis: send files in apa-integration endpoint (#21761)

This commit is contained in:
Thomas NOËL 2018-02-09 17:16:37 +01:00
parent 8d6ec55d77
commit c21215cbcd
2 changed files with 71 additions and 9 deletions

View File

@ -14,6 +14,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import base64
import json
import re
import unicodedata
@ -100,13 +101,15 @@ class Solis(BaseResource):
class Meta:
verbose_name = _('Solis')
def request(self, endpoint, data=None):
def request(self, endpoint, data=None, files=None):
url = self.service_url + endpoint
headers = {'Accept': 'application/json'}
if data is None:
response = self.requests.get(url, headers=headers)
else:
if data is not None:
response = self.requests.post(url, json=data, headers=headers)
elif files is not None:
response = self.requests.post(url, files=files, headers=headers)
else:
response = self.requests.get(url, headers=headers)
if response.status_code // 100 != 2:
try:
@ -296,12 +299,32 @@ class Solis(BaseResource):
if not isinstance(payload, dict):
raise APIError('payload is not a JSON dict', http_status=400)
# extract files from payload, to send them before the request
files = []
for key, value in payload.items():
if (isinstance(value, dict) and 'content' in value and 'content_type' in value):
binary_content = base64.b64decode(value['content'])
files.append(('files', ('%s.pdf' % key, binary_content, value['content_type'])))
del payload[key]
# prepare request data
integration_data = {'demandeApa': unflat(payload)}
endpoint = 'asg/apa/integrationDemandeApa'
response = self.request(endpoint, data=integration_data)
return {'data': response}
# send files before request data
sendfiles = None
if files:
sendfiles = self.request('asg/apa/piecesjointes/multiple', files=files)
if not isinstance(sendfiles, dict):
raise APIError('fail to send files, response is not a dict', data=sendfiles)
if sendfiles.get('rejets') or sendfiles.get('nbFichiersAcceptes') != len(files):
raise APIError('fail to send all files', data=sendfiles)
if not sendfiles.get('id'):
raise APIError('fail to get uidPiecesJointes on sending files', data=sendfiles)
# ok, add reference id in request data
integration_data['uidPiecesJointes'] = sendfiles.get('id')
response = self.request('asg/apa/integrationDemandeApa', data=integration_data)
return {'data': response, 'sendfiles': sendfiles}
@endpoint(name='referential', perm='can_access',
pattern=r'^(?P<module>[\w-]+)/(?P<name>[\w-]+)/$',

View File

@ -466,7 +466,10 @@ def test_solis_apa_integration(app, solis):
resource_pk=solis.pk)
with mock.patch('passerelle.utils.Request.post') as requests_post:
requests_post.return_value = utils.FakedResponse(content='', status_code=204)
def integration_ok(*args, **kwargs):
return utils.FakedResponse(content='', status_code=204)
# requests_post.return_value = utils.FakedResponse(content='', status_code=204)
requests_post.side_effect = [utils.FakedResponse(content='', status_code=204)]
url = utils.generic_endpoint_url('solis', 'apa-integration', slug=solis.slug)
demande = {
@ -483,7 +486,22 @@ def test_solis_apa_integration(app, solis):
assert requests_post.call_args[1]['json']['demandeApa']['beneficiaire']['demande']['aide'] == 'APAD'
assert requests_post.call_args[1]['json']['demandeApa'] == unflat(demande)
assert resp.json['err'] == 0
assert resp.json['data'] == None
assert resp.json['data'] is None
# add a file
requests_post.reset_mock()
requests_post.side_effect = [
utils.FakedResponse(content='{"id": "foo", "nbFichiersAcceptes": 1}', status_code=200),
utils.FakedResponse(content='', status_code=204)]
demande['etat_civil_001'] = {
'content': 'Y29pbg==',
'content_type': 'application/pdf',
'filename': 'whatever.pdf',
}
resp = app.post_json(url, params=demande, status=200)
assert resp.json['err'] == 0
assert resp.json['data'] is None
assert resp.json['sendfiles'] == {'id': 'foo', 'nbFichiersAcceptes': 1}
# invalid inputs
requests_post.reset_mock()
@ -495,3 +513,24 @@ def test_solis_apa_integration(app, solis):
requests_post.assert_not_called()
assert resp.json['err'] == 1
assert resp.json['err_desc'] == 'payload is not a JSON object'
# bad file
requests_post.reset_mock()
requests_post.side_effect = [
utils.FakedResponse(content='{"id": "foo", "nbFichiersAcceptes": 0}', status_code=200),
utils.FakedResponse(content='', status_code=204)]
resp = app.post_json(url, params=demande, status=200)
requests_post.assert_called_once() # don't try to post request
assert resp.json['err'] == 1
assert resp.json['err_desc'] == 'fail to send all files'
assert resp.json['data'] == {'id': 'foo', 'nbFichiersAcceptes': 0}
# error on sending file
requests_post.reset_mock()
requests_post.side_effect = [
utils.FakedResponse(content='{"error": 1}', status_code=500),
utils.FakedResponse(content='', status_code=204)]
resp = app.post_json(url, params=demande, status=200)
requests_post.assert_called_once() # don't try to post request
assert resp.json['err'] == 1
assert resp.json['err_desc'].startswith('error status:500')