diff --git a/requirements-test.txt b/requirements-test.txt --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,5 +1,6 @@ pytest pytest-django +pytest-mock swh.scheduler[testing] pytest-postgresql >= 2.1.0 requests_mock diff --git a/swh/deposit/cli/client.py b/swh/deposit/cli/client.py --- a/swh/deposit/cli/client.py +++ b/swh/deposit/cli/client.py @@ -5,6 +5,7 @@ import os import logging +import sys import tempfile import uuid @@ -335,12 +336,8 @@ metadata_deposit, collection, slug, partial, deposit_id, replace, url, name, author) except InputError as e: - msg = 'Problem during parsing options: %s' % e - r = { - 'error': msg, - } - logger.info(r) - return 1 + logger.error('Problem during parsing options: %s', e) + sys.exit(1) try: if verbose: @@ -382,12 +379,8 @@ client = _client(url, username, password) collection = _collection(client) except InputError as e: - msg = 'Problem during parsing options: %s' % e - r = { - 'error': msg, - } - logger.info(r) - return 1 + logger.error('Problem during parsing options: %s', e) + sys.exit(1) r = client.deposit_status( collection=collection, deposit_id=deposit_id) diff --git a/swh/deposit/tests/api/test_service_document.py b/swh/deposit/tests/api/test_service_document.py --- a/swh/deposit/tests/api/test_service_document.py +++ b/swh/deposit/tests/api/test_service_document.py @@ -54,19 +54,23 @@ def check_response(response, username): assert response.status_code == status.HTTP_200_OK assert response.content.decode('utf-8') == \ - ''' + get_expected_service_response('http://testserver/1', username) + + +def get_expected_service_response(base_url, username): + return f''' 2.0 - %s + {TEST_CONFIG['max_upload_size']} The Software Heritage (SWH) Archive - - %s Software Collection + + {username} Software Collection application/zip application/x-tar Collection Policy @@ -75,13 +79,9 @@ false false http://purl.org/net/sword/package/SimpleZip - http://testserver/1/%s/ - %s + {base_url}/{username}/ + {username} -''' % (TEST_CONFIG['max_upload_size'], - username, - username, - username, - username) # noqa +''' # noqa diff --git a/swh/deposit/tests/cli/test_client.py b/swh/deposit/tests/cli/test_client.py --- a/swh/deposit/tests/cli/test_client.py +++ b/swh/deposit/tests/cli/test_client.py @@ -3,12 +3,29 @@ # License: GNU General Public License version 3, or any later version # See top-level LICENSE file for more information -import pytest - +import logging +import os from unittest.mock import MagicMock +from click.testing import CliRunner +import pytest + from swh.deposit.client import PublicApiDepositClient -from swh.deposit.cli.client import _url, _client, _collection, InputError +from swh.deposit.cli.client import ( + generate_slug, _url, _client, _collection, InputError) +from swh.deposit.cli import deposit as cli +from ..conftest import TEST_USER + + +EXAMPLE_SERVICE_DOCUMENT = { + 'service': { + 'workspace': { + 'collection': { + 'sword:name': 'softcol', + } + } + } +} def test_url(): @@ -35,15 +52,149 @@ def test_collection_ok(): mock_client = MagicMock() - mock_client.service_document.return_value = { - 'service': { - 'workspace': { - 'collection': { - 'sword:name': 'softcol', - } - } - } - } + mock_client.service_document.return_value = EXAMPLE_SERVICE_DOCUMENT collection_name = _collection(mock_client) assert collection_name == 'softcol' + + +def test_single_minimal_deposit(sample_archive, mocker, caplog): + """ from: + https://docs.softwareheritage.org/devel/swh-deposit/getting-started.html#single-deposit + """ # noqa + slug = generate_slug() + mocker.patch('swh.deposit.cli.client.generate_slug', return_value=slug) + mock_client = MagicMock() + mocker.patch( + 'swh.deposit.cli.client._client', + return_value=mock_client) + mock_client.service_document.return_value = EXAMPLE_SERVICE_DOCUMENT + mock_client.deposit_create.return_value = '{"foo": "bar"}' + + runner = CliRunner() + result = runner.invoke(cli, [ + 'upload', + '--url', 'mock://deposit.swh/1', + '--username', TEST_USER['username'], + '--password', TEST_USER['password'], + '--name', 'test-project', + '--archive', sample_archive['path'], + ]) + + assert result.exit_code == 0, result.output + assert result.output == '' + assert caplog.record_tuples == [ + ('swh.deposit.cli.client', logging.INFO, '{"foo": "bar"}'), + ] + + mock_client.deposit_create.assert_called_once_with( + archive=sample_archive['path'], + collection='softcol', in_progress=False, metadata=None, + slug=slug) + + +def test_single_deposit_slug_collection(sample_archive, mocker, caplog): + """ from: + https://docs.softwareheritage.org/devel/swh-deposit/getting-started.html#single-deposit + """ # noqa + slug = 'my-slug' + collection = 'my-collection' + mock_client = MagicMock() + mocker.patch( + 'swh.deposit.cli.client._client', + return_value=mock_client) + mock_client.service_document.return_value = EXAMPLE_SERVICE_DOCUMENT + mock_client.deposit_create.return_value = '{"foo": "bar"}' + + runner = CliRunner() + result = runner.invoke(cli, [ + 'upload', + '--url', 'mock://deposit.swh/1', + '--username', TEST_USER['username'], + '--password', TEST_USER['password'], + '--name', 'test-project', + '--archive', sample_archive['path'], + '--slug', slug, + '--collection', collection, + ]) + + assert result.exit_code == 0, result.output + assert result.output == '' + assert caplog.record_tuples == [ + ('swh.deposit.cli.client', logging.INFO, '{"foo": "bar"}'), + ] + + mock_client.deposit_create.assert_called_once_with( + archive=sample_archive['path'], + collection=collection, in_progress=False, metadata=None, + slug=slug) + + +def test_multisteps_deposit( + sample_archive, atom_dataset, mocker, caplog, datadir): + """ from: + https://docs.softwareheritage.org/devel/swh-deposit/getting-started.html#multisteps-deposit + """ # noqa + slug = generate_slug() + mocker.patch('swh.deposit.cli.client.generate_slug', return_value=slug) + mock_client = MagicMock() + mocker.patch( + 'swh.deposit.cli.client._client', + return_value=mock_client) + + # https://docs.softwareheritage.org/devel/swh-deposit/getting-started.html#create-an-incomplete-deposit + mock_client.service_document.return_value = EXAMPLE_SERVICE_DOCUMENT + mock_client.deposit_create.return_value = '{"deposit_id": "42"}' + + runner = CliRunner() + result = runner.invoke(cli, [ + 'upload', + '--url', 'mock://deposit.swh/1', + '--username', TEST_USER['username'], + '--password', TEST_USER['password'], + '--archive', sample_archive['path'], + '--partial', + ]) + + assert result.exit_code == 0, result.output + assert result.output == '' + assert caplog.record_tuples == [ + ('swh.deposit.cli.client', logging.INFO, '{"deposit_id": "42"}'), + ] + + mock_client.deposit_create.assert_called_once_with( + archive=sample_archive['path'], + collection='softcol', in_progress=True, metadata=None, + slug=slug) + + # Clear mocking state + caplog.clear() + mock_client.reset_mock() + + # https://docs.softwareheritage.org/devel/swh-deposit/getting-started.html#add-content-or-metadata-to-the-deposit + + metadata_path = os.path.join( + datadir, 'atom', 'entry-data-deposit-binary.xml') + + result = runner.invoke(cli, [ + 'upload', + '--url', 'mock://deposit.swh/1', + '--username', TEST_USER['username'], + '--password', TEST_USER['password'], + '--metadata', metadata_path, + ]) + + assert result.exit_code == 0, result.output + assert result.output == '' + assert caplog.record_tuples == [ + ('swh.deposit.cli.client', logging.INFO, '{"deposit_id": "42"}'), + ] + + mock_client.deposit_create.assert_called_once_with( + archive=None, + collection='softcol', in_progress=False, metadata=metadata_path, + slug=slug) + + # Clear mocking state + caplog.clear() + mock_client.reset_mock()