summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-24 17:58:08 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-24 17:58:08 +0200
commitdf6fafa76b0eec167fa1fa18a40632c2e95181ff (patch)
treebdcc20a1a65a0564335798aeffdbefa11cad9803 /packages
parent5a180dd05046499ae0867842bfb3913796b6bd39 (diff)
downloadmeshbay-df6fafa76b0eec167fa1fa18a40632c2e95181ff.tar.gz
fix(node): Peers tab answered 500 after the webrtc split
/api/peers imported _get_remote_ip, inside the function, from webrtc_server, which no longer has it. A test now resolves every meshbay import in the node's source, function bodies included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages')
-rw-r--r--packages/meshbay-node/src/meshbay_node/ui/app.py2
-rw-r--r--packages/meshbay-node/tests/test_api_peers.py31
-rw-r--r--packages/meshbay-node/tests/test_imports_resolve.py38
3 files changed, 70 insertions, 1 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/ui/app.py b/packages/meshbay-node/src/meshbay_node/ui/app.py
index ff28e53..eabe97a 100644
--- a/packages/meshbay-node/src/meshbay_node/ui/app.py
+++ b/packages/meshbay-node/src/meshbay_node/ui/app.py
@@ -249,7 +249,7 @@ def create_ui_app(state: dict) -> FastAPI:
users, groups = await _display_names(state)
peers = []
for pid, session in list(webrtc._sessions.items()):
- from meshbay_node.transport.webrtc_server import _get_remote_ip
+ from meshbay_node.transport.webrtc.channel import _get_remote_ip
uid = session._user_id or ""
gid = session._group_id or ""
peers.append({
diff --git a/packages/meshbay-node/tests/test_api_peers.py b/packages/meshbay-node/tests/test_api_peers.py
new file mode 100644
index 0000000..420ccba
--- /dev/null
+++ b/packages/meshbay-node/tests/test_api_peers.py
@@ -0,0 +1,31 @@
+"""
+The Node page's Peers tab: one row per live session, from the loopback API.
+
+`_get_remote_ip` moved out of `webrtc_server.py` and the endpoint's import,
+inside the function, went on naming the old place. Nothing imports a function
+body until it runs, so the tab answered 500 and nothing else noticed.
+"""
+
+from types import SimpleNamespace
+
+from fastapi.testclient import TestClient
+from meshbay_node.ui.app import create_ui_app
+
+
+def test_the_peers_tab_lists_a_live_session():
+ session = SimpleNamespace(
+ _user_id="u-bob", _group_id="g" * 32, _username="bob",
+ # No address learnt at the handshake: the endpoint asks the ICE
+ # transport, which is the line that broke.
+ _remote_ip="",
+ _pc=SimpleNamespace(sctp=None, connectionState="connected"))
+ state = {"status": "running",
+ "webrtc": SimpleNamespace(_sessions={"p1": session})}
+
+ resp = TestClient(create_ui_app(state)).get("/api/peers")
+
+ assert resp.status_code == 200, resp.text
+ assert resp.json() == {"peers": [{
+ "peer_id": "p1", "user_id": "u-bob", "username": "bob",
+ "group_id": "g" * 32, "group_name": "", "remote_ip": "",
+ "state": "connected"}]}
diff --git a/packages/meshbay-node/tests/test_imports_resolve.py b/packages/meshbay-node/tests/test_imports_resolve.py
new file mode 100644
index 0000000..2d6610b
--- /dev/null
+++ b/packages/meshbay-node/tests/test_imports_resolve.py
@@ -0,0 +1,38 @@
+"""
+Every `from meshbay_… import NAME` in the node's source names something that
+exists — including the imports inside function bodies, which nothing loads
+until that function runs.
+
+When code moves between modules, an import at the top of a file breaks at
+once, and loudly. One inside a function breaks the first time somebody clicks
+the button that calls it: the Peers tab answered 500 that way after
+`_get_remote_ip` left `webrtc_server.py`.
+"""
+
+import ast
+import importlib
+from pathlib import Path
+
+SRC = Path(__file__).resolve().parents[1] / "src"
+
+
+def test_every_import_in_the_node_names_something_that_exists():
+ missing, checked = [], 0
+ for path in sorted(SRC.rglob("*.py")):
+ tree = ast.parse(path.read_text(encoding="utf-8"))
+ for node in ast.walk(tree):
+ if not (isinstance(node, ast.ImportFrom) and node.level == 0
+ and node.module and node.module.startswith("meshbay_")):
+ continue
+ module = importlib.import_module(node.module)
+ for alias in node.names:
+ checked += 1
+ if alias.name == "*" or hasattr(module, alias.name):
+ continue
+ try:
+ importlib.import_module(f"{node.module}.{alias.name}")
+ except ImportError:
+ missing.append(f"{path.relative_to(SRC)}:{node.lineno} "
+ f"{node.module}.{alias.name}")
+ assert checked > 300, "the walk found almost nothing to check"
+ assert not missing, "imports of names that do not exist:\n" + "\n".join(missing)