aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_root_writable_policy.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/tests/test_root_writable_policy.py')
-rw-r--r--packages/meshbay-node/tests/test_root_writable_policy.py41
1 files changed, 41 insertions, 0 deletions
diff --git a/packages/meshbay-node/tests/test_root_writable_policy.py b/packages/meshbay-node/tests/test_root_writable_policy.py
index d7f2666..7eb75fd 100644
--- a/packages/meshbay-node/tests/test_root_writable_policy.py
+++ b/packages/meshbay-node/tests/test_root_writable_policy.py
@@ -108,6 +108,47 @@ async def test_read_only_binds_the_operator_too(tmp_path):
assert refusal and refusal[0].get("code") == "root_read_only"
+async def test_a_member_cannot_create_a_folder_in_a_read_only_root(tmp_path):
+ """
+ Read-only has to mean read-only for every way of writing, not just for
+ files. `_do_file_upload` gained this check with the RO/RW model and
+ `_do_dir_create` did not, so a member refused a file in a published library
+ could still leave empty directories all through it.
+
+ Creating a folder stays unprivileged — the node's own words: "a member who
+ can add a file can organise where it goes". What changed is that it now
+ requires the same root to be writable that adding the file would have.
+ """
+ session = _session(tmp_path, "member-1", writable=False)
+ session._do_dir_create({"dir": "shared", "name": "New folder"})
+
+ refusal = [m for m in session.sent if m.get("type") == "error"]
+ assert refusal and refusal[0].get("code") == "root_read_only"
+ assert not (tmp_path / "shared" / "New folder").exists()
+
+
+async def test_a_member_can_create_a_folder_in_a_writable_root(tmp_path):
+ """The counter-property: it must stay unprivileged where it is allowed."""
+ session = _session(tmp_path, "member-1", writable=True)
+ session._do_dir_create({"dir": "shared", "name": "New folder"})
+
+ assert not [m for m in session.sent if m.get("type") == "error"]
+ assert (tmp_path / "shared" / "New folder").is_dir()
+
+
+async def test_an_ejected_root_refuses_a_new_folder(tmp_path):
+ """Writing to a drive somebody has their hand on, one level up from a file."""
+ session = _session(tmp_path, "member-1", writable=True)
+ roots = session._ctx["roots"]
+ roots.roots[0].ejected = True
+ roots.roots[0].available = False
+
+ session._do_dir_create({"dir": "shared", "name": "New folder"})
+ refusal = [m for m in session.sent if m.get("type") == "error"]
+ assert refusal and refusal[0].get("code") == "root_unavailable"
+ assert not (tmp_path / "shared" / "New folder").exists()
+
+
# ── Signed, or it is a suggestion ────────────────────────────────────────────
def _capture_challenges(session) -> list[tuple[str, str]]: