summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_roster_pairing.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-04 02:20:57 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-04 02:20:57 +0200
commitd11e571c5b6c24b586ef5b8fb2cfcf6a6bfa6d6d (patch)
treefe3c4fbce3db02a8b84a15c413735622a51eefb0 /packages/meshbay-node/tests/test_roster_pairing.py
parent7a4b905ddb64bdc92b7f9acf2ccde9bd84d7a6f3 (diff)
downloadmeshbay-d11e571c5b6c24b586ef5b8fb2cfcf6a6bfa6d6d.tar.gz
test(node): make the suite pass on Windows
- `.read_text()` on source files now `encoding="utf-8"` — cp1252 chokes on the em dashes / box-drawing chars those files contain. - test node.toml templates embed paths via `Path.as_posix()`: a raw Windows path in a basic TOML string is a parse error (`\U`, `\a`, ... are escapes). - new `test_platform.py` covers `meshbay_node.platform` by mocking `sys.platform` / `os.environ` — runs on both OSes. - `skipif(sys.platform == "win32")`, in `conftest.needs_subprocess` and inline, for the documented gaps: ffmpeg/ffprobe via asyncio subprocess (the win32 selector loop, forced for aiortc, cannot spawn one), the systemd `reload`/`restart-daemon` delegation (Windows path is W3), the keystore `st_mode == 600` assertion (NTFS ignores mode bits), and the symlink-escape test (needs Developer Mode). Windows: 781 passed, 25 skipped. No change on Linux. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/tests/test_roster_pairing.py')
-rw-r--r--packages/meshbay-node/tests/test_roster_pairing.py20
1 files changed, 11 insertions, 9 deletions
diff --git a/packages/meshbay-node/tests/test_roster_pairing.py b/packages/meshbay-node/tests/test_roster_pairing.py
index 8bedfad..eb13c61 100644
--- a/packages/meshbay-node/tests/test_roster_pairing.py
+++ b/packages/meshbay-node/tests/test_roster_pairing.py
@@ -529,11 +529,11 @@ def test_join_policy_is_carried_from_node_config():
instead, a hub could declare any group open and be handed its key.
"""
daemon_src = (Path(__file__).parent.parent
- / "src" / "meshbay_node" / "daemon.py").read_text()
+ / "src" / "meshbay_node" / "daemon.py").read_text(encoding="utf-8")
assert '"join_policy": group_cfg.join_policy' in daemon_src
config_src = (Path(__file__).parent.parent
- / "src" / "meshbay_node" / "config.py").read_text()
+ / "src" / "meshbay_node" / "config.py").read_text(encoding="utf-8")
assert "join_policy" in config_src, "GroupConfig must carry the admission policy"
@@ -570,7 +570,7 @@ def test_challenge_carries_node_pk_in_source():
builds, whatever the surrounding handshake does.
"""
source = (Path(__file__).parent.parent
- / "src" / "meshbay_node" / "transport" / "webrtc_server.py").read_text()
+ / "src" / "meshbay_node" / "transport" / "webrtc_server.py").read_text(encoding="utf-8")
challenge = source[source.find("MNP.HANDSHAKE_CHALLENGE,"):]
challenge = challenge[:challenge.find("})")]
assert "node_pk" in challenge, (
@@ -830,11 +830,13 @@ def _run_cli(monkeypatch, tmp_path, argv, responses):
monkeypatch.setattr(_daemon, "_daemon_api", fake_api)
conf = tmp_path / "node.toml"
+ tp = tmp_path.as_posix() # a raw Windows path is a TOML escape error
conf.write_text(
- f'data_dir = "{tmp_path}"\n'
+ f'data_dir = "{tp}"\n'
'[hub]\nurl = "https://example.org"\nusername = "grenet"\n'
f'[[groups]]\nid = "{GROUP}"\nname = "demo"\n'
- f'shared_dir = "{tmp_path}"\n'
+ f'shared_dir = "{tp}"\n',
+ encoding="utf-8",
)
monkeypatch.setattr(_sys, "argv",
["meshbay-node", *argv, "--config", str(conf)])
@@ -884,7 +886,7 @@ def test_daemon_does_not_auto_pin_keystore_key():
Authority now comes from the roster, or from an explicit node.toml value.
"""
source = (Path(__file__).parent.parent
- / "src" / "meshbay_node" / "daemon.py").read_text()
+ / "src" / "meshbay_node" / "daemon.py").read_text(encoding="utf-8")
assert "Auto-pinning admin key" not in source
assert "_resolve_admin_pk" not in source, (
"the auto-pin resolver is back — node authority must be established "
@@ -898,7 +900,7 @@ def test_admin_authority_is_never_fetched_from_the_hub():
"""
src = Path(__file__).parent.parent / "src" / "meshbay_node"
- verifier = (src / "transport" / "webrtc_server.py").read_text()
+ verifier = (src / "transport" / "webrtc_server.py").read_text(encoding="utf-8")
body = verifier[verifier.index("async def _verify_admin_sig"):]
body = body[:body.index("\n def ", 1)]
assert "operator_pks" in body, "the roster is where authority comes from"
@@ -910,7 +912,7 @@ def test_admin_authority_is_never_fetched_from_the_hub():
f"_verify_admin_sig mentions {forbidden!r} — authority must come from "
"the local roster and nothing else")
- daemon = (src / "daemon.py").read_text()
+ daemon = (src / "daemon.py").read_text(encoding="utf-8")
assert "has_operator()" in daemon, "the daemon reads authority from the roster"
assert "admin_pk_ed25519" not in daemon, (
"the node.toml operator key is gone; it must not come back as a second "
@@ -940,7 +942,7 @@ async def test_group_add_appends_without_rewriting_the_file(tmp_path):
with conf.open("a") as f:
f.write(block)
- assert "# keep me" in conf.read_text(), "comments must survive"
+ assert "# keep me" in conf.read_text(encoding="utf-8"), "comments must survive"
cfg = load_config(conf)
assert [g.name for g in cfg.groups] == ["first", "second"]
assert [g.shared_dir for g in cfg.groups] == ["/tmp/a", "/tmp/b"]