Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions sonar/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,10 +379,14 @@ def _(x):
"application/json": (
"sonar.modules.documents.serializers" ":json_v1_response"
),
"application/rero+json": (
"sonar.modules.documents.serializers" ":json_doc_response"
),
"text/xml": ("sonar.modules.documents.serializers" ":dc_v1_response"),
},
record_serializers_aliases={
"json": "application/json",
"rero": "application/rero+json",
"dc": "text/xml",
},
search_serializers={
Expand Down
9 changes: 7 additions & 2 deletions sonar/modules/documents/marshmallow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@

"""Schemas for marshmallow."""

from .json import DocumentListSchemaV1, DocumentMetadataSchemaV1, DocumentSchemaV1
from .json import (
DocumentListSchemaV1,
DocumentMetadataSchemaV1,
DocumentReroSchemaV1,
DocumentSchemaV1,
)

__all__ = ("DocumentListSchemaV1", "DocumentMetadataSchemaV1", "DocumentSchemaV1")
__all__ = ("DocumentListSchemaV1", "DocumentMetadataSchemaV1", "DocumentReroSchemaV1", "DocumentSchemaV1")
31 changes: 31 additions & 0 deletions sonar/modules/documents/marshmallow/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,22 @@ class DocumentMetadataSchemaV1(DocumentListMetadataSchemaV1):

_files = Nested(FileSchemaV1, many=True)

@pre_load
def restore_ark_identifier(self, data, **kwargs):
"""Remove ark identifier if any.

:param item: Dict representing the record.
:returns: Modified dict.
"""
item = data.get("identifiedBy", [])
data["identifiedBy"] = [identifier for identifier in item if identifier.get("type") != "ark"]
from sonar.modules.documents.api import DocumentRecord

if doc := DocumentRecord.get_record_by_pid(data.get("pid")):
item = doc.get("identifiedBy", [])
data["identifiedBy"].extend([identifier for identifier in item if identifier.get("type") == "ark"])
return data


class DocumentSchemaV1(StrictKeysMixin):
"""Document schema."""
Expand All @@ -310,6 +326,21 @@ class DocumentSchemaV1(StrictKeysMixin):
explanation = fields.Raw(dump_only=True)


class DocumentReroSchemaV1(DocumentSchemaV1):
"""Document schema."""

@pre_dump
def remove_ark_identifier(self, data, **kwargs):
"""Remove ark identifier if any.

:param item: Dict representing the record.
:returns: Modified dict.
"""
item = data["metadata"].get("identifiedBy", [])
data["metadata"]["identifiedBy"] = [identifier for identifier in item if identifier.get("type") != "ark"]
return data


class DocumentListSchemaV1(StrictKeysMixin):
"""Document schema."""

Expand Down
4 changes: 3 additions & 1 deletion sonar/modules/documents/serializers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

from sonar.modules.documents.serializers.schemas.dc import DublinCoreSchema

from ..marshmallow import DocumentListSchemaV1, DocumentSchemaV1
from ..marshmallow import DocumentListSchemaV1, DocumentReroSchemaV1, DocumentSchemaV1
from .dc import DublinCoreSerializer
from .google_scholar import SonarGoogleScholarSerializer
from .json import JSONSerializer
Expand All @@ -34,6 +34,7 @@
# ===========
#: JSON serializer definition.
json_v1 = JSONSerializer(DocumentSchemaV1)
json_doc = JSONSerializer(DocumentReroSchemaV1)
json_list_v1 = JSONSerializer(DocumentListSchemaV1)
#: schema.org serializer
schemaorg_v1 = SonarSchemaOrgSerializer(SchemaOrgV1, replace_refs=True)
Expand All @@ -46,6 +47,7 @@
# ========================
#: JSON record serializer for individual records.
json_v1_response = record_responsify(json_v1, "application/json")
json_doc_response = record_responsify(json_doc, "application/rero+json")
#: JSON record serializer for search results.
json_v1_search = search_responsify(json_list_v1, "application/json")

Expand Down
66 changes: 57 additions & 9 deletions tests/api/documents/test_documents_rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,20 @@
"""Test REST endpoint for documents."""

import json
from copy import deepcopy

from flask import url_for
from invenio_accounts.testutils import login_user_via_session

from sonar.modules.documents.api import DocumentRecord


def test_get(client, document_with_file):
"""Get REST methods."""
res = client.get(url_for("invenio_records_rest.doc_list", view="global"))
assert res.status_code == 200
assert res.json["hits"]["total"]["value"] == 1

# the search results does not contains permissions
fdata = res.json["hits"]["hits"][0]["metadata"]["_files"][0]
assert list(fdata.keys()) == [
Expand All @@ -47,28 +51,72 @@ def test_get(client, document_with_file):
"read": False,
"update": False,
}
assert "ark" in [r["type"] for r in res.json["metadata"]["identifiedBy"]]

# ark identifier is removed
res = client.get(url_for("invenio_records_rest.doc_item", pid_value=document_with_file["pid"], format="rero"))
assert res.status_code == 200
assert "ark" not in [r["type"] for r in res.json["metadata"]["identifiedBy"]]


def test_put(app, client, document_with_file):
def test_post_put_delete(app, client, document_json, organisation):
"""Test putting metadata on existing file."""
# Disable configuration
app.config.update(SONAR_APP_DISABLE_PERMISSION_CHECKS=True)
headers = [("Content-Type", "application/json")]
data = deepcopy(document_json)
data["organisation"] = [{"$ref": f"https://sonar.ch/api/organisations/{organisation['code']}"}]

# Retrieve document by doing a get request.
response = client.get(
url_for("invenio_records_rest.doc_item", pid_value=document_with_file["pid"]),
headers=headers,
)
data["identifiedBy"].append({"type": "ark", "value": "ark:/99999/foo"})
response = client.post(url_for("invenio_records_rest.doc_list"), headers=headers, data=json.dumps(data))
assert response.status_code == 201
data = response.json["metadata"]
assert [r for r in data["identifiedBy"] if r["type"] == "ark"]
doc = DocumentRecord.get_record_by_pid(data["pid"])
assert doc.get_ark() != "ark:/99999/foo"

# Put data to document
response = client.put(
url_for("invenio_records_rest.doc_item", pid_value=document_with_file["pid"]),
url_for("invenio_records_rest.doc_item", pid_value=data["pid"]),
headers=headers,
data=json.dumps(response.json["metadata"]),
data=json.dumps(data),
)
assert response.status_code == 200

response = client.delete(url_for("invenio_records_rest.doc_item", pid_value=data["pid"]))
assert response.status_code == 204
response = client.get(url_for("invenio_records_rest.doc_item", pid_value=data["pid"]))

assert response.status_code == 410

# assert document_with_file.get_ark()

# # Retrieve document by doing a get request.
# response = client.get(
# url_for("invenio_records_rest.doc_item", pid_value=document_with_file["pid"]),
# headers=headers,
# )
# data = response.json["metadata"]
# # Put data to document
# response = client.put(
# url_for("invenio_records_rest.doc_item", pid_value=document_with_file["pid"]),
# headers=headers,
# data=json.dumps(data),
# )
# assert response.status_code == 200

# data["identifiedBy"].append({"type": "ark", "value": "ark:/99999/foo"})

# # Put data to document
# response = client.put(
# url_for("invenio_records_rest.doc_item", pid_value=document_with_file["pid"]),
# headers=headers,
# data=json.dumps(data),
# )
# from sonar.modules.documents.api import DocumentRecord
# doc = DocumentRecord.get_record_by_pid(document_with_file["pid"])
# assert doc.get_ark() == document_with_file.get_ark()
# assert response.status_code == 200


def test_aggregations(app, client, document, superuser, admin):
"""Test aggregations."""
Expand Down