Changeset View
Changeset View
Standalone View
Standalone View
swh/deposit/tests/api/test_collection_post_atom.py
# Copyright (C) 2017-2021 The Software Heritage developers | # Copyright (C) 2017-2021 The Software Heritage developers | ||||||||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||||||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||||||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||||||||
"""Tests the handling of the Atom content when doing a POST Col-IRI.""" | """Tests the handling of the Atom content when doing a POST Col-IRI.""" | ||||||||||
from io import BytesIO | from io import BytesIO | ||||||||||
import uuid | import uuid | ||||||||||
import warnings | |||||||||||
import attr | import attr | ||||||||||
from django.urls import reverse_lazy as reverse | from django.urls import reverse_lazy as reverse | ||||||||||
import pytest | import pytest | ||||||||||
from rest_framework import status | from rest_framework import status | ||||||||||
from swh.deposit.config import ( | from swh.deposit.config import ( | ||||||||||
COL_IRI, | COL_IRI, | ||||||||||
DEPOSIT_STATUS_DEPOSITED, | DEPOSIT_STATUS_DEPOSITED, | ||||||||||
DEPOSIT_STATUS_LOAD_SUCCESS, | DEPOSIT_STATUS_LOAD_SUCCESS, | ||||||||||
APIConfig, | APIConfig, | ||||||||||
) | ) | ||||||||||
from swh.deposit.models import Deposit, DepositCollection, DepositRequest | from swh.deposit.models import Deposit, DepositCollection, DepositRequest | ||||||||||
from swh.deposit.parsers import parse_xml | from swh.deposit.parsers import parse_xml | ||||||||||
from swh.deposit.tests.common import post_atom | from swh.deposit.tests.common import post_atom | ||||||||||
from swh.deposit.utils import compute_metadata_context, extended_swhid_from_qualified | from swh.deposit.utils import compute_metadata_context, extended_swhid_from_qualified | ||||||||||
from swh.model.identifiers import QualifiedSWHID | from swh.model.hypothesis_strategies import ( | ||||||||||
directories, | |||||||||||
present_contents, | |||||||||||
releases, | |||||||||||
revisions, | |||||||||||
snapshots, | |||||||||||
) | |||||||||||
from swh.model.identifiers import ObjectType, QualifiedSWHID | |||||||||||
from swh.model.model import ( | from swh.model.model import ( | ||||||||||
MetadataAuthority, | MetadataAuthority, | ||||||||||
MetadataAuthorityType, | MetadataAuthorityType, | ||||||||||
MetadataFetcher, | MetadataFetcher, | ||||||||||
Origin, | Origin, | ||||||||||
RawExtrinsicMetadata, | RawExtrinsicMetadata, | ||||||||||
) | ) | ||||||||||
from swh.storage.interface import PagedResult | from swh.storage.interface import PagedResult | ||||||||||
def _insert_object(swh_storage, swhid): | |||||||||||
"""Insert an object with the given swhid in the archive""" | |||||||||||
if swhid.object_type == ObjectType.CONTENT: | |||||||||||
with warnings.catch_warnings(): | |||||||||||
# hypothesis doesn't like us using .example(), but we know what we're doing | |||||||||||
ardumont: do we :D ? | |||||||||||
vlorentzAuthorUnsubmitted Done Inline ActionsI just want *any* object with that swhid, I don't care if the examples are reproducible vlorentz: I just want *any* object with that swhid, I don't care if the examples are reproducible | |||||||||||
ardumontUnsubmitted Not Done Inline Actionsit was a joke ;) ardumont: it was a joke ;)
sorry for misleading you. | |||||||||||
warnings.simplefilter("ignore") | |||||||||||
obj = present_contents().example() | |||||||||||
swh_storage.content_add([attr.evolve(obj, sha1_git=swhid.object_id)]) | |||||||||||
else: | |||||||||||
object_type_name = swhid.object_type.name.lower() | |||||||||||
strategy = { | |||||||||||
"directory": directories, | |||||||||||
"revision": revisions, | |||||||||||
"release": releases, | |||||||||||
"snapshot": snapshots, | |||||||||||
}[object_type_name] | |||||||||||
method = getattr(swh_storage, object_type_name + "_add") | |||||||||||
with warnings.catch_warnings(): | |||||||||||
# hypothesis doesn't like us using .example(), but we know what we're doing | |||||||||||
warnings.simplefilter("ignore") | |||||||||||
obj = strategy().example() | |||||||||||
method([attr.evolve(obj, id=swhid.object_id)]) | |||||||||||
def test_post_deposit_atom_201_even_with_decimal( | def test_post_deposit_atom_201_even_with_decimal( | ||||||||||
authenticated_client, deposit_collection, atom_dataset | authenticated_client, deposit_collection, atom_dataset | ||||||||||
): | ): | ||||||||||
"""Posting an initial atom entry should return 201 with deposit receipt | """Posting an initial atom entry should return 201 with deposit receipt | ||||||||||
""" | """ | ||||||||||
atom_error_with_decimal = atom_dataset["error-with-decimal"] | atom_error_with_decimal = atom_dataset["error-with-decimal"] | ||||||||||
▲ Show 20 Lines • Show All 428 Lines • ▼ Show 20 Lines | ): | ||||||||||
""" | """ | ||||||||||
swhid_reference = QualifiedSWHID.from_string(swhid) | swhid_reference = QualifiedSWHID.from_string(swhid) | ||||||||||
swhid_target = extended_swhid_from_qualified(swhid_reference) | swhid_target = extended_swhid_from_qualified(swhid_reference) | ||||||||||
xml_data = atom_dataset["entry-data-with-swhid"].format(swhid=swhid) | xml_data = atom_dataset["entry-data-with-swhid"].format(swhid=swhid) | ||||||||||
deposit_client = authenticated_client.deposit_client | deposit_client = authenticated_client.deposit_client | ||||||||||
_insert_object(swh_storage, swhid_reference) | |||||||||||
response = post_atom( | response = post_atom( | ||||||||||
authenticated_client, | authenticated_client, | ||||||||||
reverse(COL_IRI, args=[deposit_collection.name]), | reverse(COL_IRI, args=[deposit_collection.name]), | ||||||||||
data=xml_data, | data=xml_data, | ||||||||||
) | ) | ||||||||||
assert response.status_code == status.HTTP_201_CREATED | assert response.status_code == status.HTTP_201_CREATED, response.content.decode() | ||||||||||
ardumontUnsubmitted Not Done Inline Actions
ardumont: | |||||||||||
vlorentzAuthorUnsubmitted Done Inline ActionsIt is not necessarily the reason. It's just an assertion anyway, the code will be show next to the message vlorentz: It is not necessarily the reason. It's just an assertion anyway, the code will be show next to… | |||||||||||
ardumontUnsubmitted Not Done Inline Actionsok, but the plain extra parameter is not quite clear to me. So i'd like to have a prefix in the message the assertion to explicit it: f"Actual response: ..." may be better here. ardumont: ok, but the plain extra parameter is not quite clear to me.
So i'd like to have a prefix in… | |||||||||||
vlorentzAuthorUnsubmitted Done Inline ActionsIt's just a regular assertion... and I also don't want to add two lines on every assertion vlorentz: It's just a regular assertion...
and I also don't want to add two lines on every assertion | |||||||||||
response_content = parse_xml(BytesIO(response.content)) | response_content = parse_xml(BytesIO(response.content)) | ||||||||||
# Ensure the deposit is finalized | # Ensure the deposit is finalized | ||||||||||
deposit_id = int(response_content["swh:deposit_id"]) | deposit_id = int(response_content["swh:deposit_id"]) | ||||||||||
deposit = Deposit.objects.get(pk=deposit_id) | deposit = Deposit.objects.get(pk=deposit_id) | ||||||||||
assert deposit.swhid == str(swhid_target) | assert deposit.swhid == str(swhid_target) | ||||||||||
assert deposit.swhid_context == str(swhid_reference) | assert deposit.swhid_context == str(swhid_reference) | ||||||||||
assert deposit.complete_date == deposit.reception_date | assert deposit.complete_date == deposit.reception_date | ||||||||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | def test_deposit_metadata_origin( | ||||||||||
url, authenticated_client, deposit_collection, atom_dataset, swh_storage, | url, authenticated_client, deposit_collection, atom_dataset, swh_storage, | ||||||||||
): | ): | ||||||||||
"""Posting a swhid reference is stored on raw extrinsic metadata storage | """Posting a swhid reference is stored on raw extrinsic metadata storage | ||||||||||
""" | """ | ||||||||||
xml_data = atom_dataset["entry-data-with-origin-reference"].format(url=url) | xml_data = atom_dataset["entry-data-with-origin-reference"].format(url=url) | ||||||||||
origin_swhid = Origin(url).swhid() | origin_swhid = Origin(url).swhid() | ||||||||||
deposit_client = authenticated_client.deposit_client | deposit_client = authenticated_client.deposit_client | ||||||||||
swh_storage.origin_add([Origin(url)]) | |||||||||||
response = post_atom( | response = post_atom( | ||||||||||
authenticated_client, | authenticated_client, | ||||||||||
reverse(COL_IRI, args=[deposit_collection.name]), | reverse(COL_IRI, args=[deposit_collection.name]), | ||||||||||
data=xml_data, | data=xml_data, | ||||||||||
) | ) | ||||||||||
assert response.status_code == status.HTTP_201_CREATED | assert response.status_code == status.HTTP_201_CREATED, response.content.decode() | ||||||||||
response_content = parse_xml(BytesIO(response.content)) | response_content = parse_xml(BytesIO(response.content)) | ||||||||||
# Ensure the deposit is finalized | # Ensure the deposit is finalized | ||||||||||
deposit_id = int(response_content["swh:deposit_id"]) | deposit_id = int(response_content["swh:deposit_id"]) | ||||||||||
deposit = Deposit.objects.get(pk=deposit_id) | deposit = Deposit.objects.get(pk=deposit_id) | ||||||||||
# we got not swhid as input so we cannot have those | # we got not swhid as input so we cannot have those | ||||||||||
assert deposit.swhid is None | assert deposit.swhid is None | ||||||||||
assert deposit.swhid_context is None | assert deposit.swhid_context is None | ||||||||||
assert deposit.complete_date == deposit.reception_date | assert deposit.complete_date == deposit.reception_date | ||||||||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | assert page_results == PagedResult( | ||||||||||
fetcher=attr.evolve(metadata_fetcher, metadata=None), | fetcher=attr.evolve(metadata_fetcher, metadata=None), | ||||||||||
format="sword-v2-atom-codemeta", | format="sword-v2-atom-codemeta", | ||||||||||
metadata=xml_data.encode(), | metadata=xml_data.encode(), | ||||||||||
) | ) | ||||||||||
], | ], | ||||||||||
next_page_token=None, | next_page_token=None, | ||||||||||
) | ) | ||||||||||
assert deposit.complete_date == discovery_date | assert deposit.complete_date == discovery_date | ||||||||||
@pytest.mark.parametrize( | |||||||||||
"swhid", | |||||||||||
[ | |||||||||||
"swh:1:cnt:01b5c8cc985d190b5a7ef4878128ebfdc2358f49", | |||||||||||
"swh:1:dir:11b5c8cc985d190b5a7ef4878128ebfdc2358f49", | |||||||||||
"swh:1:rev:21b5c8cc985d190b5a7ef4878128ebfdc2358f49", | |||||||||||
"swh:1:rel:31b5c8cc985d190b5a7ef4878128ebfdc2358f49", | |||||||||||
"swh:1:snp:41b5c8cc985d190b5a7ef4878128ebfdc2358f49", | |||||||||||
"swh:1:cnt:51b5c8cc985d190b5a7ef4878128ebfdc2358f49;origin=h://g.c/o/repo", | |||||||||||
"swh:1:dir:c4993c872593e960dc84e4430dbbfbc34fd706d0;origin=https://inria.halpreprod.archives-ouvertes.fr/hal-01243573;visit=swh:1:snp:0175049fc45055a3824a1675ac06e3711619a55a;anchor=swh:1:rev:b5f505b005435fa5c4fa4c279792bd7b17167c04;path=/", # noqa | |||||||||||
"swh:1:rev:71b5c8cc985d190b5a7ef4878128ebfdc2358f49;origin=h://g.c/o/repo", | |||||||||||
"swh:1:rel:81b5c8cc985d190b5a7ef4878128ebfdc2358f49;origin=h://g.c/o/repo", | |||||||||||
"swh:1:snp:91b5c8cc985d190b5a7ef4878128ebfdc2358f49;origin=h://g.c/o/repo", | |||||||||||
], | |||||||||||
ardumontUnsubmitted Not Done Inline Actionsisn't it missing a swhid on origin in there ^ maybe not, oh well, please do tell ;) ardumont: isn't it missing a swhid on origin in there ^
maybe not, oh well, please do tell ;) | |||||||||||
vlorentzAuthorUnsubmitted Done Inline ActionsThat would be a different error msg (the one not tested as you noted) vlorentz: That would be a different error msg (the one not tested as you noted) | |||||||||||
) | |||||||||||
def test_deposit_metadata_unknown_swhid( | |||||||||||
swhid, authenticated_client, deposit_collection, atom_dataset, swh_storage, | |||||||||||
): | |||||||||||
"""Posting a swhid reference is rejected if the referenced object is unknown | |||||||||||
""" | |||||||||||
xml_data = atom_dataset["entry-data-with-swhid"].format(swhid=swhid) | |||||||||||
response = post_atom( | |||||||||||
authenticated_client, | |||||||||||
reverse(COL_IRI, args=[deposit_collection.name]), | |||||||||||
data=xml_data, | |||||||||||
) | |||||||||||
assert ( | |||||||||||
response.status_code == status.HTTP_400_BAD_REQUEST | |||||||||||
), response.content.decode() | |||||||||||
response_content = parse_xml(BytesIO(response.content)) | |||||||||||
assert "object does not exist" in response_content["sword:error"]["atom:summary"] | |||||||||||
def test_deposit_metadata_unknown_origin( | |||||||||||
authenticated_client, deposit_collection, atom_dataset, swh_storage, | |||||||||||
): | |||||||||||
"""Posting a swhid reference is stored on raw extrinsic metadata storage | |||||||||||
""" | |||||||||||
url = "https://gitlab.org/user/repo" | |||||||||||
xml_data = atom_dataset["entry-data-with-origin-reference"].format(url=url) | |||||||||||
response = post_atom( | |||||||||||
authenticated_client, | |||||||||||
reverse(COL_IRI, args=[deposit_collection.name]), | |||||||||||
data=xml_data, | |||||||||||
) | |||||||||||
assert ( | |||||||||||
response.status_code == status.HTTP_400_BAD_REQUEST | |||||||||||
), response.content.decode() | |||||||||||
response_content = parse_xml(BytesIO(response.content)) | |||||||||||
assert "known to the archive" in response_content["sword:error"]["atom:summary"] |
do we :D ?