diff --git a/sonar/modules/documents/cli/urn.py b/sonar/modules/documents/cli/urn.py index fb32bd4d..096fb211 100644 --- a/sonar/modules/documents/cli/urn.py +++ b/sonar/modules/documents/cli/urn.py @@ -27,7 +27,7 @@ from invenio_pidstore.models import PersistentIdentifier, PIDStatus from sonar.modules.documents.api import DocumentRecord -from sonar.modules.documents.dnb import DnbUrnService +from sonar.modules.documents.dnb import DnbServerError, DnbUrnService from sonar.modules.documents.urn import Urn from sonar.snl.ftp import SNLRepository @@ -105,6 +105,7 @@ def register(): click.secho(f'{idx} URN registered.', fg='green') + @urn.command('snl-upload-file') @click.argument('urn_code') @with_appcontext @@ -184,3 +185,23 @@ def snl_list_files(): ) snl_repository.connect() snl_repository.list() + +@urn.command() +@click.argument('urn') +@click.argument('successor_urn') +@with_appcontext +def successor(urn, successor_urn): + """Set a successor for a given run. + + :param urn: str - URN identifier + :param successor_urn: str - Sucessor URN identifier + """ + try: + DnbUrnService().set_successor(urn, successor_urn) + click.secho( + f'Added successfully a successor.', + fg='green') + except DnbServerError as err: + click.secho( + str(err), + fg='red') diff --git a/sonar/modules/documents/dnb.py b/sonar/modules/documents/dnb.py index ad60652c..adfd9882 100644 --- a/sonar/modules/documents/dnb.py +++ b/sonar/modules/documents/dnb.py @@ -148,6 +148,27 @@ def update(cls, urn_code, urls): f'when we update the information of the following ' f'urn: {urn_code}') + @classmethod + def set_successor(cls, urn_code, successor_urn): + """Set the successor of a given urn. + + :param urn_code: str - the urn code. + :param successor_urn: str - the urn code of the successor. + """ + response = requests.request( + 'PATCH', + f"{cls.base_url()}/urn/{urn_code}", + headers=cls.headers(), + data=json.dumps(dict(successor=f'{cls.base_url()}/urn/{successor_urn}')) + ) + if response.status_code != 204: + msg = response.json().get('developerMessage', '') + raise DnbServerError( + f'Bad DNB server response status {response.status_code}, ' + f'when we update the information of the following ' + f'urn: {urn_code}', + f'{msg}') + @classmethod def create(cls, data): """Register a new URN to the DBN service with a list of urls. diff --git a/tests/api/documents/test_dnb_api.py b/tests/api/documents/test_dnb_api.py index 1ba1122a..56e0d808 100644 --- a/tests/api/documents/test_dnb_api.py +++ b/tests/api/documents/test_dnb_api.py @@ -33,7 +33,6 @@ def test_dnb_rest_api_verify_exist(app): urn_code = 'urn:nbn:ch:rero-006-119656' assert DnbUrnService.exists(urn_code) - def test_dnb_rest_api_verify_not_exist(app): """Test dnb rest api verify code does not exist.""" with requests_mock.mock() as response: diff --git a/tests/ui/documents/test_dnb.py b/tests/ui/documents/test_dnb.py new file mode 100644 index 00000000..a4a673ec --- /dev/null +++ b/tests/ui/documents/test_dnb.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +# +# Swiss Open Access Repository +# Copyright (C) 2024 RERO +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +"""Test DnbUrnService API.""" + + +import requests_mock + +from sonar.modules.documents.dnb import DnbUrnService + + +def test_dnb_sucessor(app): + """Test a successor assignment.""" + with requests_mock.mock() as response: + response.patch(requests_mock.ANY, status_code=204) + DnbUrnService().set_successor( + 'urn:nbn:ch:rero-002-old', 'urn:nbn:ch:rero-002-new')