From a3db9b1e35436fe9eee596bcab6170bfababa9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Corentin=20S=C3=A9chet?= Date: Thu, 12 Oct 2023 11:18:36 +0200 Subject: [PATCH] toulouse-foederis: use multipart/form-data to attach files & diplomas (#82291) --- .../contrib/toulouse_foederis/models.py | 4 +-- tests/test_toulouse_foederis.py | 32 +++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/passerelle/contrib/toulouse_foederis/models.py b/passerelle/contrib/toulouse_foederis/models.py index 19fe2214..d4375c5a 100644 --- a/passerelle/contrib/toulouse_foederis/models.py +++ b/passerelle/contrib/toulouse_foederis/models.py @@ -687,7 +687,7 @@ class Resource(BaseResource, HTTPResource): self.http_request( 'POST', f'data/candidature/{application_id}/fields/{attachment_name}?viewIntegrationName=api_publik', - json={ + files={ 'contentType': file['content_type'], 'value': file['content'], 'fileName': file['filename'], @@ -719,7 +719,7 @@ class Resource(BaseResource, HTTPResource): self.http_request( 'POST', f'data/diplome2/{degree_id}/fields/justificatif_diplome?viewIntegrationName=api_publik', - json={ + files={ 'contentType': file['content_type'], 'value': file['content'], 'fileName': file['filename'], diff --git a/tests/test_toulouse_foederis.py b/tests/test_toulouse_foederis.py index 007d6463..69c36d20 100644 --- a/tests/test_toulouse_foederis.py +++ b/tests/test_toulouse_foederis.py @@ -15,9 +15,11 @@ # along with this program. If not, see . import base64 +import cgi import json import os import urllib.parse +from io import BytesIO import httmock import pytest @@ -584,13 +586,18 @@ class TestEndpoints: def test_attach_file(self, resource, app): @httmock.urlmatch(path=r'^.*/data/candidature/424242/fields/cv$') def handler(url, request): - assert request.headers['content-type'] == 'application/json' + assert request.headers['content-type'].startswith('multipart/form-data') assert request.headers['api-key'] == APIKEY - payload = json.loads(request.body) + + _, headers = cgi.parse_header(request.headers['content-type']) + headers['boundary'] = bytes(headers['boundary'], 'utf-8') + headers['CONTENT-LENGTH'] = request.headers['Content-Length'] + payload = cgi.parse_multipart(BytesIO(request.body), headers) + assert payload == { - 'contentType': 'application/pdf', - 'value': 'base 64 content', - 'fileName': 'cv.pdf', + 'contentType': [b'application/pdf'], + 'value': [b'base 64 content'], + 'fileName': [b'cv.pdf'], } return httmock.response(200, json.dumps({'code': 200, 'results': ['Field updated']})) @@ -630,13 +637,18 @@ class TestEndpoints: @httmock.urlmatch(path=r'^.*/data/diplome2/DEGREE_ID/fields/justificatif_diplome$') def degree_file_handler(url, request): - assert request.headers['content-type'] == 'application/json' + assert request.headers['content-type'].startswith('multipart/form-data') assert request.headers['api-key'] == APIKEY - payload = json.loads(request.body) + + _, headers = cgi.parse_header(request.headers['content-type']) + headers['boundary'] = bytes(headers['boundary'], 'utf-8') + headers['CONTENT-LENGTH'] = request.headers['Content-Length'] + payload = cgi.parse_multipart(BytesIO(request.body), headers) + assert payload == { - 'contentType': 'application/pdf', - 'value': 'base 64 content', - 'fileName': 'cv.pdf', + 'contentType': [b'application/pdf'], + 'value': [b'base 64 content'], + 'fileName': [b'cv.pdf'], } return httmock.response(200, json.dumps({'code': 200, 'results': [{'id': 'DEGREE_ID'}]}))