aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_roots.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-10 17:23:40 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-10 17:23:40 +0200
commit1dcedc77083b908b7b3b431bad679a4813884355 (patch)
treedb6ae06c05e5f337aeb42dde5c7bd2a7fe9444b5 /packages/meshbay-node/tests/test_roots.py
parent6964ff112fec47498ed778a491cf2a1490392c79 (diff)
downloadmeshbay-1dcedc77083b908b7b3b431bad679a4813884355.tar.gz
refactor(mnp)!: one answer to "may this member write", and it is the root
The group-wide `member_upload` switch is gone: the message, the signed operation, the field on the handshake ack, the `upload` alias on every root in the index payload, and the client's fallback path to it. Whether a member may write has been a property of each root for a while, and that is the model that survives: a single flag over the group cannot express "this library is published read-only and that folder is a drop box", which is the ordinary arrangement. What was left of the switch was a handler that logged a deprecation and acted on nothing, and a client that read `ack.member_upload` whenever the roots carried no `writable` — a second source for one question, with whichever the code consulted first deciding it. `roots.describe()` drops `upload` for the same reason: it was `writable` under an older name, and two names for one boolean is one too many. The paperclip now says "nowhere to write" rather than picking a root, in a group that has none writable. That is the honest answer; the fallback picked whatever came first and failed at send time. Node suite 1215 passed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AsoWC3GmhNdwVFomW3QjH3
Diffstat (limited to 'packages/meshbay-node/tests/test_roots.py')
-rw-r--r--packages/meshbay-node/tests/test_roots.py17
1 files changed, 8 insertions, 9 deletions
diff --git a/packages/meshbay-node/tests/test_roots.py b/packages/meshbay-node/tests/test_roots.py
index 505091b..9233180 100644
--- a/packages/meshbay-node/tests/test_roots.py
+++ b/packages/meshbay-node/tests/test_roots.py
@@ -272,27 +272,26 @@ def test_describe_reports_what_a_member_needs(tmp_path):
described = roots.describe()
assert described == [
{"name": "Media", "kind": "generic", "available": True,
- "writable": True, "removable": False, "ejected": False,
- "upload": True},
+ "writable": True, "removable": False, "ejected": False},
{"name": "Music", "kind": "audio", "available": True,
- "writable": False, "removable": True, "ejected": False,
- "upload": False},
+ "writable": False, "removable": True, "ejected": False},
]
# Deliberately no paths: a member is told what exists and whether it is
# readable, not where on the operator's disk it lives.
assert not any("path" in d for d in described)
-def test_describe_still_carries_upload_for_mnp_1_0_clients(tmp_path):
+def test_describe_names_a_root_and_never_a_path(tmp_path):
"""
- `upload` is `writable` under its old name, kept because an MNP 1.0 client
- reads no other field and would otherwise decide the group takes no uploads
- at all. It is derived, never stored — the two can never disagree.
+ What a member is told about a root: that it exists, and whether it is
+ readable and writable. Never where on the operator's disk it lives — that
+ is the operator's own view (`with_paths`), over their own channel.
"""
(tmp_path / "Media").mkdir()
roots = RootSet.build([_spec(tmp_path / "Media", writable=True)])
described = roots.describe()[0]
- assert described["upload"] == described["writable"] is True
+ assert set(described) == {"name", "kind", "available", "writable",
+ "removable", "ejected"}
# ── SAFE_UPLOAD_NAME ────────────────────────────────────────────────────────