Changeset View
Changeset View
Standalone View
Standalone View
swh/deposit/tests/cli/test_client.py
# Copyright (C) 2019-2020 The Software Heritage developers | # Copyright (C) 2019-2020 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 | ||||
import contextlib | import contextlib | ||||
import logging | import logging | ||||
import os | import os | ||||
import re | |||||
from unittest.mock import MagicMock | from unittest.mock import MagicMock | ||||
from click.testing import CliRunner | from click.testing import CliRunner | ||||
import pytest | import pytest | ||||
from swh.deposit.cli import deposit as cli | from swh.deposit.cli import deposit as cli | ||||
from swh.deposit.cli.client import InputError, _client, _collection, _url, generate_slug | from swh.deposit.cli.client import InputError, _client, _collection, _url, generate_slug | ||||
from swh.deposit.client import MaintenanceError, PublicApiDepositClient | from swh.deposit.client import MaintenanceError, PublicApiDepositClient | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | ): | ||||
] | ] | ||||
client_mock_api_down.service_document.assert_called_once_with() | client_mock_api_down.service_document.assert_called_once_with() | ||||
def test_single_minimal_deposit( | def test_single_minimal_deposit( | ||||
sample_archive, mocker, caplog, slug, tmp_path, requests_mock_datadir | sample_archive, mocker, caplog, slug, tmp_path, requests_mock_datadir | ||||
): | ): | ||||
""" from: | """ This ensure a single deposit upload through the cli is fine, cf. | ||||
https://docs.softwareheritage.org/devel/swh-deposit/getting-started.html#single-deposit | https://docs.softwareheritage.org/devel/swh-deposit/getting-started.html#single-deposit | ||||
""" # noqa | """ # noqa | ||||
metadata_path = os.path.join(tmp_path, "metadata.xml") | metadata_path = os.path.join(tmp_path, "metadata.xml") | ||||
mocker.patch( | mocker.patch( | ||||
"tempfile.TemporaryDirectory", | "tempfile.TemporaryDirectory", | ||||
return_value=contextlib.nullcontext(str(tmp_path)), | return_value=contextlib.nullcontext(str(tmp_path)), | ||||
) | ) | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
\t<codemeta:identifier>{slug}</codemeta:identifier> | \t<codemeta:identifier>{slug}</codemeta:identifier> | ||||
\t<codemeta:author> | \t<codemeta:author> | ||||
\t\t<codemeta:name>Jane Doe</codemeta:name> | \t\t<codemeta:name>Jane Doe</codemeta:name> | ||||
\t</codemeta:author> | \t</codemeta:author> | ||||
</entry>""" | </entry>""" | ||||
) | ) | ||||
def test_metadata_validation(sample_archive, mocker, caplog, tmp_path): | def test_metadata_validation( | ||||
""" from: | sample_archive, mocker, caplog, tmp_path, requests_mock_datadir | ||||
https://docs.softwareheritage.org/devel/swh-deposit/getting-started.html#single-deposit | ): | ||||
""" # noqa | """Multiple metadata flags scenario (missing, conflicts) properly fails the calls | ||||
""" | |||||
slug = generate_slug() | 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"}' | |||||
metadata_path = os.path.join(tmp_path, "metadata.xml") | metadata_path = os.path.join(tmp_path, "metadata.xml") | ||||
mocker.patch( | mocker.patch( | ||||
"tempfile.TemporaryDirectory", | "tempfile.TemporaryDirectory", | ||||
return_value=contextlib.nullcontext(str(tmp_path)), | return_value=contextlib.nullcontext(str(tmp_path)), | ||||
) | ) | ||||
with open(metadata_path, "a"): | with open(metadata_path, "a"): | ||||
pass # creates the file | pass # creates the file | ||||
Show All 10 Lines | result = runner.invoke( | ||||
"--username", | "--username", | ||||
TEST_USER["username"], | TEST_USER["username"], | ||||
"--password", | "--password", | ||||
TEST_USER["password"], | TEST_USER["password"], | ||||
"--name", | "--name", | ||||
"test-project", | "test-project", | ||||
"--archive", | "--archive", | ||||
sample_archive["path"], | sample_archive["path"], | ||||
"--slug", | |||||
slug, | |||||
], | ], | ||||
) | ) | ||||
assert result.exit_code == 1, result.output | assert result.exit_code == 1, result.output | ||||
assert result.output == "" | assert result.output == "" | ||||
assert len(caplog.record_tuples) == 1 | assert len(caplog.record_tuples) == 1 | ||||
(_logger, level, message) = caplog.record_tuples[0] | (_logger, level, message) = caplog.record_tuples[0] | ||||
assert level == logging.ERROR | assert level == logging.ERROR | ||||
assert " --author " in message | assert message == ( | ||||
"Problem during parsing options: Either a metadata file" | |||||
" (--metadata) or both --author and --name must be provided, " | |||||
moranegg: what's an archive only deposit?
do we have that? | |||||
Not Done Inline Actionswe do have that. He only added a test of the documentation and didn't change the documentation itself. vlorentz: we do have that. He only added a test of the documentation and didn't change the documentation… | |||||
Done Inline Actionsyep, i'm just inline the actual error message which may not be that good. To answer and clarify, the "archive-only" deposit is just an intermediary step. If it is such a case "archive-only", then the metadata part (--author and --name or --metadata are irrelevant here). Is that clearer? ardumont: yep, i'm just inline the actual error message which may not be that good.
If we want to change… | |||||
Done Inline Actions(sorry for the typos... too bad we cannot amend those comments) inlining*... ardumont: (sorry for the typos... too bad we cannot amend those comments)
inlining*...
"it" being the… | |||||
Not Done Inline ActionsOk. moranegg: Ok.
As we discussed, it might be more accurate to add deposit request on your next diff:-) | |||||
"unless this is an archive-only deposit." | |||||
) | |||||
# Clear mocking state | # Clear mocking state | ||||
caplog.clear() | caplog.clear() | ||||
mock_client.reset_mock() | |||||
# Test missing name | # Test missing name | ||||
result = runner.invoke( | result = runner.invoke( | ||||
cli, | cli, | ||||
[ | [ | ||||
"upload", | "upload", | ||||
"--url", | "--url", | ||||
"mock://deposit.swh/1", | "https://deposit.swh.test/1", | ||||
"--username", | "--username", | ||||
TEST_USER["username"], | TEST_USER["username"], | ||||
"--password", | "--password", | ||||
TEST_USER["password"], | TEST_USER["password"], | ||||
"--archive", | "--archive", | ||||
sample_archive["path"], | sample_archive["path"], | ||||
"--author", | "--author", | ||||
"Jane Doe", | "Jane Doe", | ||||
"--slug", | |||||
slug, | |||||
], | ], | ||||
) | ) | ||||
assert result.exit_code == 1, result.output | assert result.exit_code == 1, result.output | ||||
assert result.output == "" | assert result.output == "" | ||||
assert len(caplog.record_tuples) == 1 | assert len(caplog.record_tuples) == 1 | ||||
(_logger, level, message) = caplog.record_tuples[0] | (_logger, level, message) = caplog.record_tuples[0] | ||||
assert level == logging.ERROR | assert level == logging.ERROR | ||||
assert " --name " in message | assert message == ( | ||||
"Problem during parsing options: Either a metadata file" | |||||
" (--metadata) or both --author and --name must be provided, " | |||||
Not Done Inline Actionssame, what's an archive-only deposit? moranegg: same, what's an archive-only deposit? | |||||
"unless this is an archive-only deposit." | |||||
) | |||||
# Clear mocking state | # Clear mocking state | ||||
caplog.clear() | caplog.clear() | ||||
mock_client.reset_mock() | |||||
# Test both --metadata and --author | # Test both --metadata and --author | ||||
result = runner.invoke( | result = runner.invoke( | ||||
cli, | cli, | ||||
[ | [ | ||||
"upload", | "upload", | ||||
"--url", | "--url", | ||||
"mock://deposit.swh/1", | "https://deposit.swh.test/1", | ||||
"--username", | "--username", | ||||
TEST_USER["username"], | TEST_USER["username"], | ||||
"--password", | "--password", | ||||
TEST_USER["password"], | TEST_USER["password"], | ||||
"--archive", | "--archive", | ||||
sample_archive["path"], | sample_archive["path"], | ||||
"--metadata", | "--metadata", | ||||
metadata_path, | metadata_path, | ||||
"--author", | "--author", | ||||
"Jane Doe", | "Jane Doe", | ||||
"--slug", | |||||
slug, | |||||
], | ], | ||||
) | ) | ||||
assert result.exit_code == 1, result.output | assert result.exit_code == 1, result.output | ||||
assert result.output == "" | assert result.output == "" | ||||
assert len(caplog.record_tuples) == 1 | assert len(caplog.record_tuples) == 1 | ||||
(_logger, level, message) = caplog.record_tuples[0] | (_logger, level, message) = caplog.record_tuples[0] | ||||
assert level == logging.ERROR | assert level == logging.ERROR | ||||
assert re.search("--metadata.*is incompatible with", message) | assert message == ( | ||||
"Problem during parsing options: Using a metadata file " | |||||
# Clear mocking state | "(--metadata) is incompatible with --author and --name, " | ||||
caplog.clear() | "which are used to generate one." | ||||
mock_client.reset_mock() | ) | ||||
def test_single_deposit_slug_generation( | def test_single_deposit_slug_generation( | ||||
sample_archive, mocker, caplog, tmp_path, client_mock | sample_archive, mocker, caplog, tmp_path, client_mock | ||||
): | ): | ||||
""" from: | """ from: | ||||
https://docs.softwareheritage.org/devel/swh-deposit/getting-started.html#single-deposit | https://docs.softwareheritage.org/devel/swh-deposit/getting-started.html#single-deposit | ||||
""" # noqa | """ # noqa | ||||
▲ Show 20 Lines • Show All 146 Lines • Show Last 20 Lines |
what's an archive only deposit?
do we have that?