atal_rest: accept empty files (#81518)
gitea/passerelle/pipeline/head This commit looks good Details

This commit is contained in:
Emmanuel Cazenave 2023-09-22 16:53:06 +02:00
parent ef0b518aba
commit 898a14f821
2 changed files with 102 additions and 33 deletions

View File

@ -30,29 +30,38 @@ from passerelle.base.models import BaseResource, HTTPResource
from passerelle.utils.api import endpoint
from passerelle.utils.jsonresponse import APIError
FILE_OBJECT = {
'type': 'object',
'description': 'File object',
'required': ['content'],
'properties': {
'filename': {
'type': 'string',
'description': 'Filename',
},
'content': {
'type': 'string',
'description': 'Content',
},
'content_type': {
'type': 'string',
'description': 'Content type',
},
},
}
SINGLE_ATTACHMENT_SCHEMA = {
'$schema': 'http://json-schema.org/draft-04/schema#',
'type': 'object',
'additionalProperties': False,
'properties': {
'file': {
'type': 'object',
'properties': {
'filename': {
'type': 'string',
'description': 'Filename',
},
'content': {
'type': 'string',
'description': 'Content',
},
'content_type': {
'type': 'string',
'description': 'Content type',
},
},
'required': ['content'],
},
'oneOf': [
FILE_OBJECT,
{'type': 'string', 'description': 'empty file, do not consider', 'pattern': r'^$'},
{'type': 'null', 'description': 'empty file, do not consider'},
]
}
},
'required': ['file'],
}
@ -66,22 +75,11 @@ ATTACHMENTS_SCHEMA = {
'files': {
'type': 'array',
'items': {
'type': 'object',
'properties': {
'filename': {
'type': 'string',
'description': 'Filename',
},
'content': {
'type': 'string',
'description': 'Content',
},
'content_type': {
'type': 'string',
'description': 'Content type',
},
},
'required': ['content'],
'oneOf': [
FILE_OBJECT,
{'type': 'string', 'description': 'empty file, do not consider', 'pattern': r'^$'},
{'type': 'null', 'description': 'empty file, do not consider'},
]
},
},
'worksrequests_ids': {'type': 'array', 'items': {'type': 'string'}},
@ -379,6 +377,8 @@ class AtalREST(BaseResource, HTTPResource):
},
)
def worksrequests_single_attachment(self, request, worksrequests_id, post_data):
if not post_data['file']:
return {}
try:
content = base64.b64decode(post_data['file']['content'])
except (TypeError, binascii.Error):
@ -428,6 +428,8 @@ class AtalREST(BaseResource, HTTPResource):
def worksrequests_attachments(self, request, post_data):
files = []
for file_ in post_data.get('files', []):
if not file_:
continue
try:
content = base64.b64decode(file_['content'])
except (TypeError, binascii.Error):
@ -442,6 +444,8 @@ class AtalREST(BaseResource, HTTPResource):
),
)
)
if not files:
return {}
data = {'Ids': post_data['worksrequests_ids']}
# return nothing if successful
self._call(

View File

@ -82,6 +82,51 @@ def test_worksrequests_single_attachment(app, connector):
assert json_resp['err'] == 0
def test_worksrequests_single_attachment_no_data(app, connector):
with responses.RequestsMock() as rsps:
params = {
'file': '',
}
resp = app.post_json(
'/atal-rest/test/worksrequests-single-attachment?worksrequests_id=1', params=params
)
json_resp = resp.json
assert json_resp['err'] == 0
assert len(rsps.calls) == 0
def test_worksrequests_single_attachment_string_not_empty(app, connector):
params = {
'file': 'aaa',
}
app.post_json(
'/atal-rest/test/worksrequests-single-attachment?worksrequests_id=1', params=params, status=400
)
def test_worksrequests_single_attachment_error(app, connector):
with responses.RequestsMock() as rsps:
rsps.post(
'https://atal.invalid/api/WorksRequests/1/Attachments',
status=400,
json={
'type': 'https://tools.ietf.org/html/rfc7231#section-6.5.1',
'title': 'Bad Request',
'status': 400,
'"detail': 'No content","traceId":"00-1034a23a6cfbb7c508aa7e125a8e9a52-4570fc75745b7d1d-00',
},
)
params = {
'file': {'filename': 'bla', 'content': base64.b64encode(b'bla').decode('utf-8')},
}
resp = app.post_json(
'/atal-rest/test/worksrequests-single-attachment?worksrequests_id=1', params=params
)
json_resp = resp.json
assert json_resp['err'] == 1
assert json_resp['data']['title'] == 'Bad Request'
def test_worksrequests_attachments(app, connector):
with responses.RequestsMock() as rsps:
rsps.post('https://atal.invalid/api/WorksRequests/Attachments', status=200, body=b'')
@ -97,6 +142,26 @@ def test_worksrequests_attachments(app, connector):
assert json_resp['err'] == 0
def test_worksrequests_attachments_no_data(app, connector):
with responses.RequestsMock() as rsps:
params = {
'files': ['', ''],
'worksrequests_ids': ['0', '1'],
}
resp = app.post_json('/atal-rest/test/worksrequests-attachments', params=params)
json_resp = resp.json
assert json_resp['err'] == 0
assert len(rsps.calls) == 0
def test_worksrequests_attachments_string_not_empty(app, connector):
params = {
'files': ['aa'],
'worksrequests_ids': ['0', '1'],
}
app.post_json('/atal-rest/test/worksrequests-attachments', params=params, status=400)
def test_worksrequests_attachments_error(app, connector):
with responses.RequestsMock() as rsps:
rsps.post(