From 0976082f20cf5be3da24d95820c20217aa53bdad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 18:28:09 +0000 Subject: [PATCH 1/2] Initial plan From 3e6282aa91051a8345f76223bd00de909e9621f0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 17 Mar 2026 18:37:22 +0000 Subject: [PATCH 2/2] Add test for search_central_via_connection with search_path=None Co-authored-by: JoeZiminski <55797454+JoeZiminski@users.noreply.github.com> --- .../tests_integration/test_search_methods.py | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tests/tests_integration/test_search_methods.py b/tests/tests_integration/test_search_methods.py index 74598c448..0be3ce5a8 100644 --- a/tests/tests_integration/test_search_methods.py +++ b/tests/tests_integration/test_search_methods.py @@ -1,3 +1,5 @@ +import json +import subprocess from pathlib import Path import pytest @@ -106,3 +108,69 @@ def mock_rclone_caller(_, func, optional=None): assert central_method_files == local_method_files, ( f"Failed files, search_str: {search_str}, search_path: {search_path}" ) + + @pytest.mark.parametrize("return_full_path", [True, False]) + def test_search_central_none_search_path( + self, project, monkeypatch, return_full_path + ): + """ + Test `search_central_via_connection` when `search_path=None`. + + When `search_path` is `None` (as is the case for Google Drive, where + `cfg["central_path"]` can be `None`), the function should search from + the root of the remote drive without error. + + Verify that: + - the function handles ``search_path=None`` without raising + - when ``return_full_path=True``, returned items are :class:`~pathlib.Path` + objects relative to the remote root (e.g. ``Path("sub-001")``) + - when ``return_full_path=False``, returned items are plain strings + """ + from datashuttle.utils import rclone + + fake_entries = [ + {"Name": "sub-001", "IsDir": True}, + {"Name": "sub-002", "IsDir": True}, + {"Name": "rawdata.md", "IsDir": False}, + ] + fake_output = subprocess.CompletedProcess( + args=[], + returncode=0, + stdout=json.dumps(fake_entries).encode(), + stderr=b"", + ) + + captured_commands = [] + + def mock_call_rclone(cfg, command, pipe_std=False): + captured_commands.append(command) + return fake_output + + monkeypatch.setattr( + rclone, + "call_rclone_for_central_connection", + mock_call_rclone, + ) + + folders, files = search_central_via_connection( + project.cfg, + None, + "*", + return_full_path=return_full_path, + ) + + assert len(folders) == 2 + assert len(files) == 1 + + if return_full_path: + assert all(isinstance(f, Path) for f in folders) + assert all(isinstance(f, Path) for f in files) + assert sorted(folders) == [Path("sub-001"), Path("sub-002")] + assert files == [Path("rawdata.md")] + else: + assert all(isinstance(f, str) for f in folders) + assert all(isinstance(f, str) for f in files) + assert sorted(folders) == ["sub-001", "sub-002"] + assert files == ["rawdata.md"] + + assert len(captured_commands) == 1, "Expected exactly one rclone call"