diff --git a/swh/deposit/api/deposit_update.py b/swh/deposit/api/deposit_update.py --- a/swh/deposit/api/deposit_update.py +++ b/swh/deposit/api/deposit_update.py @@ -335,12 +335,21 @@ request, headers, collection_name, deposit_id=deposit_id ) return status.HTTP_201_CREATED, EM_IRI, data - # check for final empty post - # source: http://swordapp.github.io/SWORDv2-Profile/SWORDProfile.html - # #continueddeposit_complete - if headers["content-length"] == 0 and headers["in-progress"] is False: + + content_length = headers["content-length"] or 0 + if content_length == 0 and headers["in-progress"] is False: + # check for final empty post + # source: http://swordapp.github.io/SWORDv2-Profile/SWORDProfile.html + # #continueddeposit_complete data = self._empty_post(request, headers, collection_name, deposit_id) return status.HTTP_200_OK, EDIT_SE_IRI, data + elif content_length == 0: + return make_error_dict( + BAD_REQUEST, + "Empty body request is not supported", + "Atom entry deposit is supposed to send for metadata. " + "If the body is empty, there is no metadata.", + ) data = self._atom_entry( request, headers, collection_name, deposit_id=deposit_id diff --git a/swh/deposit/tests/api/test_deposit_update.py b/swh/deposit/tests/api/test_deposit_update.py --- a/swh/deposit/tests/api/test_deposit_update.py +++ b/swh/deposit/tests/api/test_deposit_update.py @@ -9,7 +9,12 @@ from django.urls import reverse from rest_framework import status -from swh.deposit.config import EDIT_SE_IRI, EM_IRI +from swh.deposit.config import ( + DEPOSIT_STATUS_DEPOSITED, + DEPOSIT_STATUS_PARTIAL, + EDIT_SE_IRI, + EM_IRI, +) from swh.deposit.models import Deposit, DepositCollection, DepositRequest from swh.deposit.parsers import parse_xml from swh.deposit.tests.common import check_archive, create_arborescence_archive @@ -585,6 +590,66 @@ assert len(requests_archive1) == 1 + 1, "New deposit request metadata got added" +def test_post_metadata_empty_post_finalize_deposit_ok( + authenticated_client, + deposit_collection, + partial_deposit_with_metadata, + atom_dataset, +): + """Empty atom post entry with header in-progress to false can actually finish a deposit + + Response: 200 + """ + deposit = partial_deposit_with_metadata + assert deposit.status == DEPOSIT_STATUS_PARTIAL + + requests = DepositRequest.objects.filter(deposit=deposit, type="metadata") + assert len(requests) == 1 + requests_archive0 = DepositRequest.objects.filter(deposit=deposit, type="archive") + assert len(requests_archive0) == 1 + + update_uri = reverse(EDIT_SE_IRI, args=[deposit_collection.name, deposit.id]) + response = authenticated_client.post( + update_uri, + content_type="application/atom+xml;type=entry", + data="", + size=0, + HTTP_IN_PROGRESS=False, + ) + + assert response.status_code == status.HTTP_200_OK + + deposit = Deposit.objects.get(pk=deposit.id) + assert deposit.status == DEPOSIT_STATUS_DEPOSITED + + +def test_post_metadata_empty_post_refused_without_in_progress_false( + authenticated_client, + deposit_collection, + partial_deposit_with_metadata, + atom_dataset, +): + """Empty atom post entry without header in-progress to false is bad a request + + Response: 200 + """ + deposit = partial_deposit_with_metadata + assert deposit.status == DEPOSIT_STATUS_PARTIAL + + requests = DepositRequest.objects.filter(deposit=deposit, type="metadata") + assert len(requests) == 1 + requests_archive0 = DepositRequest.objects.filter(deposit=deposit, type="archive") + assert len(requests_archive0) == 1 + + update_uri = reverse(EDIT_SE_IRI, args=[deposit_collection.name, deposit.id]) + response = authenticated_client.post( + update_uri, content_type="application/atom+xml;type=entry", data="" # empty + ) + + assert response.status_code == status.HTTP_400_BAD_REQUEST + assert b"Empty body request is not supported" in response.content + + def test_add_metadata_to_unknown_deposit( deposit_collection, authenticated_client, atom_dataset ):