aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-cli/tests/test_cli_actions.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-15 01:12:16 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-15 01:12:16 +0200
commit382fcc5f675f9942350013780335315757c245c5 (patch)
treea24ed8732c6d3971b071ed6af3c399d6142b79f4 /packages/meshbay-cli/tests/test_cli_actions.py
parent6f68bb6c1970e26de1f66c073ea5d7fecd21840d (diff)
downloadmeshbay-382fcc5f675f9942350013780335315757c245c5.tar.gz
feat(cli): rm, and Delete in the interactive mode
rm deletes files, resolved as get resolves paths and patterns, with the node's rule (design §5.4): the uploading account's devices, or the node's operator account. The whole run is checked against the index first (the entry's uploader_id, the role the join result gives this key): a file outside the rule, or a folder, refuses it before anything is asked or sent. Then one confirmation, or --yes. The node's challenge is checked against what was asked before it is signed. In the interactive mode, Delete on the right pane does the same, asked once per batch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-cli/tests/test_cli_actions.py')
-rw-r--r--packages/meshbay-cli/tests/test_cli_actions.py32
1 files changed, 32 insertions, 0 deletions
diff --git a/packages/meshbay-cli/tests/test_cli_actions.py b/packages/meshbay-cli/tests/test_cli_actions.py
index 4fffc4e..e0b5518 100644
--- a/packages/meshbay-cli/tests/test_cli_actions.py
+++ b/packages/meshbay-cli/tests/test_cli_actions.py
@@ -425,6 +425,38 @@ def test_browser_access_is_set_here_and_mirrored_never_taken_from_the_hub(
assert store.state["browser_access"] == "off"
+def test_rm_deletes_only_what_this_account_may_and_asks_first(node, monkeypatch, capsys):
+ from fake_hub import USER_ID
+ mine = node.add("share", "mine.txt", b"1", uploader_id=USER_ID)
+ node.add("share", "also-mine.txt", b"2", uploader_id=USER_ID)
+ theirs = node.add("share", "theirs.txt", b"3", uploader_id="someone-else")
+ node.dirs.add("share/sub")
+
+ # Somebody else's file, a folder: refused whole, before any question.
+ assert main("rm", "--yes", "Family/share/mine.txt", "Family/share/theirs.txt") == 8
+ assert "Family@alice-test/share/theirs.txt" in capsys.readouterr().err
+ assert main("rm", "--yes", "Family/share/sub") == 1
+ assert main("rm", "--yes", "Family/share/nothing*") == 3
+ assert mine["id"] in node.files
+
+ monkeypatch.setattr("sys.stdin.isatty", lambda: False)
+ assert main("rm", "Family/share/mine.txt") == 1 # not confirmed
+ monkeypatch.setattr("sys.stdin", _Terminal("n\n"))
+ assert main("rm", "Family/share/mine.txt") == 1
+ assert mine["id"] in node.files
+ monkeypatch.setattr("sys.stdin", _Terminal("y\n"))
+ assert main("rm", "Family/share/*mine.txt") == 0
+ assert "Deleted 2 files" in capsys.readouterr().err
+ assert set(node.files) == {theirs["id"]}
+
+ # From the node's operator key, anyone's file.
+ node.role = "operator"
+ assert main("--json", "rm", "--yes", "Family/share/theirs.txt") == 0
+ assert json.loads(capsys.readouterr().out)["deleted"] == [
+ "Family@alice-test/share/theirs.txt"]
+ assert not node.files
+
+
def test_every_action_is_run_here():
"""Runs last in this module: every action the parser knows was run above."""
assert RUN == set(cli.ACTIONS), f"never run: {set(cli.ACTIONS) - RUN}"