chore(release): bump version to 1.3.18
Bump the package version to 1.3.18, upgrade dependencies, consolidate module exports, add a unit test suite, and document all changes. - Bump package version to 1.3.18 in pyproject.toml - Upgrade pydantic-settings to 2.14.2 and pyright to 1.1.411 - Consolidate package exports in mdrsclient/__init__.py - Add a comprehensive unit test suite in tests/test_commands.py - Document testing execution and add full history in CHANGELOG.md
This commit is contained in:
+129
@@ -0,0 +1,129 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [1.3.18] - 2026-07-02
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added a comprehensive unit test suite in `tests/test_commands.py` checking registration, parsing, and execution flow of all 16 commands.
|
||||||
|
|
||||||
|
### Refactored
|
||||||
|
- Abstracted configuration storage (introducing `ConfigInterface`, `InMemoryConfig`, and updating `ConfigFile`) to enable dependency injection.
|
||||||
|
- Modularized transfer operations (upload and download) to decouple them from the service layer.
|
||||||
|
- Decoupled commands from direct file system configurations and migrated all subcommands to use abstract config classes.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Upgraded dependencies including `pydantic-settings` to `2.14.2` and `pyright` to `1.1.411`.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed duplicate `__all__` definitions in package initialization file `mdrsclient/__init__.py` that caused `__version__` export to be overwritten.
|
||||||
|
|
||||||
|
## [1.3.17] - 2026-07-02
|
||||||
|
|
||||||
|
### Refactored
|
||||||
|
- Decoupled core logic from CLI interface and introduced `MdrsClient` service layer to improve library portability.
|
||||||
|
- Migrated all CLI commands to utilize `MdrsClient` for execution.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Abstract authentication state using `CacheInterface` and `InMemoryCache`.
|
||||||
|
|
||||||
|
## [1.3.16] - 2026-06-12
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Retrieve the full `Folder` object from `FoldersApi` instead of using the `FolderSimple` returned by `find_sub_folder` when resolving DOI subfolders. This fixes a type checker error under the upgraded pyright and avoids a potential AttributeError at runtime due to `FolderSimple` lacking the `path` attribute.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Upgraded dependencies and bumped version to 1.3.16 in pyproject.toml.
|
||||||
|
|
||||||
|
## [1.3.15] - 2026-05-01
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Bumped package version to 1.3.15.
|
||||||
|
|
||||||
|
## [1.3.14] - 2026-04-17
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Simplified `config list` command (removed `-l`/`--long` option, always display URL).
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added subcommand aliases for config commands (e.g. `ls` alias for list, `rm` alias for delete).
|
||||||
|
|
||||||
|
## [1.3.13] - 2025-07-02
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Bumped package version to 1.3.13.
|
||||||
|
|
||||||
|
## [1.3.12] - 2025-05-20
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Bumped package version to 1.3.12.
|
||||||
|
|
||||||
|
## [1.3.11] - 2025-01-21
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Bumped package version to 1.3.11.
|
||||||
|
|
||||||
|
## [1.3.10] - 2024-12-23
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Bumped package version to 1.3.10.
|
||||||
|
|
||||||
|
## [1.3.9] - 2024-10-23
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed compatibility with Python 3.10.
|
||||||
|
|
||||||
|
## [1.3.8] - 2024-09-18
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Bumped package version to 1.3.8.
|
||||||
|
|
||||||
|
## [1.3.7] - 2024-07-22
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Implemented `--exclude` argument for download subcommand.
|
||||||
|
|
||||||
|
## [1.3.6] - 2024-07-08
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Bumped package version to 1.3.6.
|
||||||
|
|
||||||
|
## [1.3.5] - 2024-07-08
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Bumped package version to 1.3.5.
|
||||||
|
|
||||||
|
## [1.3.4] - 2024-07-04
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added some aliases for config sub command.
|
||||||
|
|
||||||
|
## [1.3.3] - 2024-02-13
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Bumped package version to 1.3.3.
|
||||||
|
|
||||||
|
## [1.3.2] - 2024-02-09
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added `-u` and `-p` options to login command.
|
||||||
|
|
||||||
|
## [1.3.1] - 2023-12-20
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed bug to resolve local files for recursive file upload.
|
||||||
|
|
||||||
|
## [1.3.0] - 2023-12-18
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Removed debug comments.
|
||||||
|
|
||||||
|
## [1.2.0] - 2023-10-04
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Follow-up recent specification changes about folder access level.
|
||||||
|
|
||||||
|
## [1.1.1] - 2023-07-26
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Set destination folder name using name attribute of folder copy API.
|
||||||
@@ -236,3 +236,15 @@ client.upload("/path/to/local/data", "neurodata:/NIU/Repository/TEST/", is_recur
|
|||||||
client.download("neurodata:/NIU/Repository/TEST/data", "/path/to/local", is_recursive=True)
|
client.download("neurodata:/NIU/Repository/TEST/data", "/path/to/local", is_recursive=True)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
You can run the unit test suite using the standard library `unittest` discover runner:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
.venv/bin/python -m unittest discover tests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
See [CHANGELOG.md](./CHANGELOG.md) for the full change history.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
from mdrsclient.__version__ import __version__
|
from mdrsclient.__version__ import __version__
|
||||||
|
|
||||||
__all__ = ["__version__"]
|
|
||||||
|
|
||||||
from mdrsclient.client import MdrsClient
|
from mdrsclient.client import MdrsClient
|
||||||
|
|
||||||
__all__ = ["MdrsClient"]
|
__all__ = ["__version__", "MdrsClient"]
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "mdrs-client-python"
|
name = "mdrs-client-python"
|
||||||
version = "1.3.17"
|
version = "1.3.18"
|
||||||
description = "The mdrs-client-python is python library and a command-line client for up- and downloading files to and from MDRS based repository."
|
description = "The mdrs-client-python is python library and a command-line client for up- and downloading files to and from MDRS based repository."
|
||||||
authors = ["Yoshihiro OKUMURA <yoshihiro.okumura@riken.jp>"]
|
authors = ["Yoshihiro OKUMURA <yoshihiro.okumura@riken.jp>"]
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@@ -28,7 +28,7 @@ requests = "^2.34.2"
|
|||||||
requests-toolbelt = "^1.0.0"
|
requests-toolbelt = "^1.0.0"
|
||||||
python-dotenv = "^1.1.0"
|
python-dotenv = "^1.1.0"
|
||||||
pydantic = "^2.13.4"
|
pydantic = "^2.13.4"
|
||||||
pydantic-settings = "^2.14.1"
|
pydantic-settings = "^2.14.2"
|
||||||
PyJWT = "^2.13.0"
|
PyJWT = "^2.13.0"
|
||||||
validators = "^0.35.0"
|
validators = "^0.35.0"
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ black = "^26.5.1"
|
|||||||
flake8 = "^7.2.0"
|
flake8 = "^7.2.0"
|
||||||
Flake8-pyproject = "^1.2.3"
|
Flake8-pyproject = "^1.2.3"
|
||||||
isort = "^8.0.1"
|
isort = "^8.0.1"
|
||||||
pyright = "^1.1.401"
|
pyright = "^1.1.411"
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
[tool.poetry.scripts]
|
||||||
mdrs = 'mdrsclient.__main__:main'
|
mdrs = 'mdrsclient.__main__:main'
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
# Mark tests directory as a Python package
|
||||||
@@ -0,0 +1,418 @@
|
|||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import unittest
|
||||||
|
from io import StringIO
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
|
from mdrsclient.client import MdrsClient
|
||||||
|
from mdrsclient.commands import (
|
||||||
|
ChaclCommand,
|
||||||
|
ConfigCommand,
|
||||||
|
CpCommand,
|
||||||
|
DownloadCommand,
|
||||||
|
FileMetadataCommand,
|
||||||
|
LabsCommand,
|
||||||
|
LoginCommand,
|
||||||
|
LogoutCommand,
|
||||||
|
LsCommand,
|
||||||
|
MetadataCommand,
|
||||||
|
MkdirCommand,
|
||||||
|
MvCommand,
|
||||||
|
RmCommand,
|
||||||
|
UploadCommand,
|
||||||
|
VersionCommand,
|
||||||
|
WhoamiCommand,
|
||||||
|
)
|
||||||
|
from mdrsclient.models import Folder, Laboratory
|
||||||
|
|
||||||
|
|
||||||
|
class TestCommands(unittest.TestCase):
|
||||||
|
def parse_args(self, cmd_class, args_list):
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
subparsers = parser.add_subparsers(title="subcommands")
|
||||||
|
cmd_class.register(subparsers)
|
||||||
|
return parser.parse_args(args_list)
|
||||||
|
|
||||||
|
def test_version_command(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.return_value = mock_client
|
||||||
|
mock_client.version.return_value = "mdrs 1.3.17"
|
||||||
|
|
||||||
|
args = self.parse_args(VersionCommand, ["version"])
|
||||||
|
with patch("sys.stdout", new=StringIO()) as fake_out:
|
||||||
|
args.func(args)
|
||||||
|
self.assertEqual(fake_out.getvalue().strip(), "mdrs 1.3.17")
|
||||||
|
|
||||||
|
mock_client_class.assert_called_once_with(None)
|
||||||
|
mock_client.version.assert_called_once()
|
||||||
|
|
||||||
|
def test_login_command_with_args(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
mock_client_class.parse_remote_host.return_value = "myremote"
|
||||||
|
|
||||||
|
args = self.parse_args(LoginCommand, ["login", "-u", "myuser", "-p", "mypass", "myremote"])
|
||||||
|
with patch("sys.stdout", new=StringIO()) as fake_out:
|
||||||
|
args.func(args)
|
||||||
|
self.assertIn("Login Successful", fake_out.getvalue())
|
||||||
|
|
||||||
|
mock_client_class.parse_remote_host.assert_called_once_with("myremote")
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.login.assert_called_once_with("myuser", "mypass")
|
||||||
|
|
||||||
|
def test_login_command_interactive(self):
|
||||||
|
with (
|
||||||
|
patch("mdrsclient.client.MdrsClient") as mock_client_class,
|
||||||
|
patch("builtins.input", return_value="myuser_int") as mock_input,
|
||||||
|
patch("getpass.getpass", return_value="mypass_int") as mock_getpass,
|
||||||
|
):
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
mock_client_class.parse_remote_host.return_value = "myremote"
|
||||||
|
|
||||||
|
args = self.parse_args(LoginCommand, ["login", "myremote"])
|
||||||
|
with patch("sys.stdout", new=StringIO()) as fake_out:
|
||||||
|
args.func(args)
|
||||||
|
self.assertIn("Login Successful", fake_out.getvalue())
|
||||||
|
|
||||||
|
mock_input.assert_called_once_with("Username: ")
|
||||||
|
mock_getpass.assert_called_once_with("Password: ")
|
||||||
|
mock_client.login.assert_called_once_with("myuser_int", "mypass_int")
|
||||||
|
|
||||||
|
def test_logout_command(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
mock_client_class.parse_remote_host.return_value = "myremote"
|
||||||
|
|
||||||
|
args = self.parse_args(LogoutCommand, ["logout", "myremote"])
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.parse_remote_host.assert_called_once_with("myremote")
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.logout.assert_called_once()
|
||||||
|
|
||||||
|
def test_whoami_command_logged_in(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
mock_client_class.parse_remote_host.return_value = "myremote"
|
||||||
|
mock_client.connection.token = None
|
||||||
|
|
||||||
|
mock_user = MagicMock()
|
||||||
|
mock_user.username = "test_user"
|
||||||
|
mock_client.whoami.return_value = mock_user
|
||||||
|
|
||||||
|
args = self.parse_args(WhoamiCommand, ["whoami", "myremote"])
|
||||||
|
with patch("sys.stdout", new=StringIO()) as fake_out:
|
||||||
|
args.func(args)
|
||||||
|
self.assertEqual(fake_out.getvalue().strip(), "test_user")
|
||||||
|
|
||||||
|
mock_client_class.parse_remote_host.assert_called_once_with("myremote")
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.whoami.assert_called_once()
|
||||||
|
|
||||||
|
def test_whoami_command_anonymous(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
mock_client_class.parse_remote_host.return_value = "myremote"
|
||||||
|
mock_client.connection.token = None
|
||||||
|
mock_client.whoami.side_effect = Exception("Not logged in")
|
||||||
|
|
||||||
|
args = self.parse_args(WhoamiCommand, ["whoami", "myremote"])
|
||||||
|
with patch("sys.stdout", new=StringIO()) as fake_out:
|
||||||
|
args.func(args)
|
||||||
|
self.assertEqual(fake_out.getvalue().strip(), "(Anonymous)")
|
||||||
|
|
||||||
|
def test_labs_command(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
mock_client_class.parse_remote_host.return_value = "myremote"
|
||||||
|
|
||||||
|
mock_lab = MagicMock()
|
||||||
|
mock_lab.id = 1
|
||||||
|
mock_lab.name = "lab_name"
|
||||||
|
mock_lab.pi_name = "pi_name"
|
||||||
|
mock_lab.full_name = "full_name"
|
||||||
|
mock_client.get_laboratories.return_value = [mock_lab]
|
||||||
|
|
||||||
|
args = self.parse_args(LabsCommand, ["labs", "myremote"])
|
||||||
|
with patch("sys.stdout", new=StringIO()) as fake_out:
|
||||||
|
args.func(args)
|
||||||
|
output = fake_out.getvalue()
|
||||||
|
self.assertIn("Name", output)
|
||||||
|
self.assertIn("lab_name", output)
|
||||||
|
self.assertIn("pi_name", output)
|
||||||
|
|
||||||
|
mock_client_class.parse_remote_host.assert_called_once_with("myremote")
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.get_laboratories.assert_called_once()
|
||||||
|
|
||||||
|
def test_ls_command_plain(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock(spec=MdrsClient)
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
|
||||||
|
mock_folder = Folder(
|
||||||
|
id="folder_id",
|
||||||
|
pid=None,
|
||||||
|
name="root",
|
||||||
|
access_level=1,
|
||||||
|
lock=False,
|
||||||
|
size=0,
|
||||||
|
laboratory_id=1,
|
||||||
|
description="",
|
||||||
|
created_at="2026-07-02T00:00:00Z",
|
||||||
|
updated_at="2026-07-02T00:00:00Z",
|
||||||
|
restrict_opened_at=None,
|
||||||
|
metadata=[],
|
||||||
|
sub_folders=[],
|
||||||
|
path="/root",
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_lab = Laboratory(id=1, name="mylab", pi_name="pi_name", full_name="full_name")
|
||||||
|
|
||||||
|
mock_client.resolve_folder.return_value = (mock_folder, mock_lab)
|
||||||
|
|
||||||
|
mock_file = MagicMock()
|
||||||
|
mock_file.name = "file.txt"
|
||||||
|
mock_file.size = 100
|
||||||
|
mock_file.updated_at_name = "2026-07-02"
|
||||||
|
mock_client.find_files.return_value = [mock_file]
|
||||||
|
|
||||||
|
args = self.parse_args(LsCommand, ["ls", "myremote:/mylab/"])
|
||||||
|
with patch("sys.stdout", new=StringIO()) as fake_out:
|
||||||
|
args.func(args)
|
||||||
|
output = fake_out.getvalue()
|
||||||
|
self.assertIn("Type", output)
|
||||||
|
self.assertIn("file.txt", output)
|
||||||
|
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.resolve_folder.assert_called_once_with("myremote:/mylab/", None)
|
||||||
|
mock_client.find_files.assert_called_once_with(mock_folder.id)
|
||||||
|
|
||||||
|
def test_ls_command_json(self):
|
||||||
|
with (
|
||||||
|
patch("mdrsclient.client.MdrsClient") as mock_client_class,
|
||||||
|
patch("mdrsclient.commands.ls.FoldersApi") as mock_folders_api_class,
|
||||||
|
):
|
||||||
|
mock_folders_api = MagicMock()
|
||||||
|
mock_folders_api_class.return_value = mock_folders_api
|
||||||
|
mock_folders_api.metadata.return_value = {"folder_meta": "val"}
|
||||||
|
|
||||||
|
mock_client = MagicMock(spec=MdrsClient)
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
mock_client.connection = MagicMock()
|
||||||
|
|
||||||
|
mock_folder = Folder(
|
||||||
|
id="folder_id",
|
||||||
|
pid="parent_id",
|
||||||
|
name="root",
|
||||||
|
access_level=1,
|
||||||
|
lock=False,
|
||||||
|
size=0,
|
||||||
|
laboratory_id=1,
|
||||||
|
description="Root folder",
|
||||||
|
created_at="2026-07-02T00:00:00Z",
|
||||||
|
updated_at="2026-07-02T00:00:00Z",
|
||||||
|
restrict_opened_at=None,
|
||||||
|
metadata=[],
|
||||||
|
sub_folders=[],
|
||||||
|
path="/root",
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_lab = Laboratory(id=1, name="mylab", pi_name="pi_name", full_name="full_name")
|
||||||
|
|
||||||
|
mock_client.resolve_folder.return_value = (mock_folder, mock_lab)
|
||||||
|
mock_client.connection.laboratories.find_by_id.return_value = mock_lab
|
||||||
|
|
||||||
|
mock_file = MagicMock()
|
||||||
|
mock_file.id = "file_id"
|
||||||
|
mock_file.name = "file.txt"
|
||||||
|
mock_file.type = "text"
|
||||||
|
mock_file.size = 100
|
||||||
|
mock_file.description = "A file"
|
||||||
|
mock_file.metadata = {}
|
||||||
|
mock_file.download_url = "download/file"
|
||||||
|
mock_file.created_at = "2026-07-02T00:00:00Z"
|
||||||
|
mock_file.updated_at = "2026-07-02T00:00:00Z"
|
||||||
|
mock_client.find_files.return_value = [mock_file]
|
||||||
|
|
||||||
|
args = self.parse_args(LsCommand, ["ls", "-J", "myremote:/mylab/"])
|
||||||
|
with patch("sys.stdout", new=StringIO()) as fake_out:
|
||||||
|
args.func(args)
|
||||||
|
output = fake_out.getvalue()
|
||||||
|
parsed_json = json.loads(output)
|
||||||
|
self.assertEqual(parsed_json["name"], "root")
|
||||||
|
self.assertEqual(parsed_json["files"][0]["name"], "file.txt")
|
||||||
|
|
||||||
|
def test_mkdir_command(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
|
||||||
|
args = self.parse_args(MkdirCommand, ["mkdir", "myremote:/mylab/newfolder"])
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.mkdir.assert_called_once_with("myremote:/mylab/newfolder")
|
||||||
|
|
||||||
|
def test_rm_command_file(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
|
||||||
|
args = self.parse_args(RmCommand, ["rm", "myremote:/mylab/file.txt"])
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.rm.assert_called_once_with("myremote:/mylab/file.txt", False)
|
||||||
|
|
||||||
|
def test_rm_command_recursive(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
|
||||||
|
args = self.parse_args(RmCommand, ["rm", "-r", "myremote:/mylab/folder"])
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.rm.assert_called_once_with("myremote:/mylab/folder", True)
|
||||||
|
|
||||||
|
def test_cp_command(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
|
||||||
|
args = self.parse_args(CpCommand, ["cp", "myremote:/mylab/src", "myremote:/mylab/dest"])
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.cp.assert_called_once_with("myremote:/mylab/src", "myremote:/mylab/dest", False)
|
||||||
|
|
||||||
|
def test_mv_command(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
|
||||||
|
args = self.parse_args(MvCommand, ["mv", "myremote:/mylab/src", "myremote:/mylab/dest"])
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.mv.assert_called_once_with("myremote:/mylab/src", "myremote:/mylab/dest")
|
||||||
|
|
||||||
|
def test_chacl_command(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
|
||||||
|
args = self.parse_args(ChaclCommand, ["chacl", "-r", "-p", "secret", "private", "myremote:/mylab/"])
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.chacl.assert_called_once_with("myremote:/mylab/", 1, True, "secret")
|
||||||
|
|
||||||
|
def test_metadata_command(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
mock_client.metadata.return_value = {"meta_key": "meta_val"}
|
||||||
|
|
||||||
|
args = self.parse_args(MetadataCommand, ["metadata", "-p", "secret", "myremote:/mylab/"])
|
||||||
|
with patch("sys.stdout", new=StringIO()) as fake_out:
|
||||||
|
args.func(args)
|
||||||
|
parsed_json = json.loads(fake_out.getvalue())
|
||||||
|
self.assertEqual(parsed_json["meta_key"], "meta_val")
|
||||||
|
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.metadata.assert_called_once_with("myremote:/mylab/", "secret")
|
||||||
|
|
||||||
|
def test_file_metadata_command(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
mock_client.file_metadata.return_value = {"file_meta": "val"}
|
||||||
|
|
||||||
|
args = self.parse_args(FileMetadataCommand, ["file-metadata", "-p", "secret", "myremote:/mylab/file.txt"])
|
||||||
|
with patch("sys.stdout", new=StringIO()) as fake_out:
|
||||||
|
args.func(args)
|
||||||
|
parsed_json = json.loads(fake_out.getvalue())
|
||||||
|
self.assertEqual(parsed_json["file_meta"], "val")
|
||||||
|
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.file_metadata.assert_called_once_with("myremote:/mylab/file.txt", "secret")
|
||||||
|
|
||||||
|
def test_upload_command(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
|
||||||
|
args = self.parse_args(UploadCommand, ["upload", "-r", "-s", "local_file.txt", "myremote:/mylab/"])
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.upload.assert_called_once_with("local_file.txt", "myremote:/mylab/", True, True)
|
||||||
|
|
||||||
|
def test_download_command(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.from_remote.return_value = mock_client
|
||||||
|
|
||||||
|
args = self.parse_args(
|
||||||
|
DownloadCommand, ["download", "-r", "-s", "-p", "pass", "-e", "ex1", "myremote:/mylab/", "local_dir"]
|
||||||
|
)
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.from_remote.assert_called_once_with("myremote")
|
||||||
|
mock_client.download.assert_called_once_with("myremote:/mylab/", "local_dir", True, True, "pass", ["ex1"])
|
||||||
|
|
||||||
|
def test_config_create(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.return_value = mock_client
|
||||||
|
|
||||||
|
args = self.parse_args(ConfigCommand, ["config", "create", "myremote", "http://example.com"])
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.assert_called_once_with(None)
|
||||||
|
mock_client.config_create.assert_called_once_with("myremote", "http://example.com")
|
||||||
|
|
||||||
|
def test_config_update(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.return_value = mock_client
|
||||||
|
|
||||||
|
args = self.parse_args(ConfigCommand, ["config", "update", "myremote", "http://example.com"])
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.assert_called_once_with(None)
|
||||||
|
mock_client.config_update.assert_called_once_with("myremote", "http://example.com")
|
||||||
|
|
||||||
|
def test_config_delete(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.return_value = mock_client
|
||||||
|
|
||||||
|
args = self.parse_args(ConfigCommand, ["config", "delete", "myremote"])
|
||||||
|
args.func(args)
|
||||||
|
|
||||||
|
mock_client_class.assert_called_once_with(None)
|
||||||
|
mock_client.config_delete.assert_called_once_with("myremote")
|
||||||
|
|
||||||
|
def test_config_list(self):
|
||||||
|
with patch("mdrsclient.client.MdrsClient") as mock_client_class:
|
||||||
|
mock_client = MagicMock()
|
||||||
|
mock_client_class.return_value = mock_client
|
||||||
|
mock_client.config_list.return_value = [("remote1", "url1"), ("remote2", "url2")]
|
||||||
|
|
||||||
|
args = self.parse_args(ConfigCommand, ["config", "list"])
|
||||||
|
with patch("sys.stdout", new=StringIO()) as fake_out:
|
||||||
|
args.func(args)
|
||||||
|
self.assertEqual(fake_out.getvalue(), "remote1:\turl1\nremote2:\turl2\n")
|
||||||
|
|
||||||
|
mock_client_class.assert_called_once_with(None)
|
||||||
|
mock_client.config_list.assert_called_once()
|
||||||
Reference in New Issue
Block a user