aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-27 22:21:07 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-27 22:21:07 +0200
commitc7899e2218af26f3bab6a157c70acf5eb7871da6 (patch)
tree5ed08cfbf26cdd8d9dbf6ce1159fc259d611df2d /packages/meshbay-hub/tests
parent7422a777297347dc83e6c5b2e89c1a6fa99a36b0 (diff)
downloadmeshbay-c7899e2218af26f3bab6a157c70acf5eb7871da6.tar.gz
fix(hub): the sidebar's Node section follows the node link
Reported on a real install: after the first click on Create group, the Node section (Node, Create group) disappeared from the sidebar until a reload, although the group was created and the node ran. hasNodeKey was read once per session change and never again, so a node the wizard linked stayed out of the sidebar; and that read swallowed its errors, so a session blip (a refused renewal, then the desktop app's silent device sign-in) followed by one failed request hid the section for good. The wizard now tells the app when it has linked or started a node, the app asks again then and after a group is created, and a failed read is retried -- never applied to a session that has changed meanwhile. The wizard also starts the node on its own for a node in waiting_for_hub. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/tests')
-rw-r--r--packages/meshbay-hub/tests/test_sidebar_node_section.py55
1 files changed, 55 insertions, 0 deletions
diff --git a/packages/meshbay-hub/tests/test_sidebar_node_section.py b/packages/meshbay-hub/tests/test_sidebar_node_section.py
new file mode 100644
index 0000000..371a018
--- /dev/null
+++ b/packages/meshbay-hub/tests/test_sidebar_node_section.py
@@ -0,0 +1,55 @@
+"""
+The sidebar's Node section follows the account's node link, and must follow it
+when it changes -- not only at sign-in.
+
+Reported on a real install: after the first click on Create group, the Node
+section (Node, Create group) was gone from the sidebar until a reload, while
+the group was created and the node ran. `hasNodeKey` was read once per session
+change and never again, so a node linked by the wizard stayed out of the
+sidebar; and the one read there was swallowed its errors, so a session blip
+(a refused renewal, then the desktop app's silent device sign-in) followed by
+one failed request left the section hidden for good.
+
+Read from the source, like the rest of the SPA's wiring tests: the state lives
+inside App, and what matters is the seam between two modules.
+"""
+
+import re
+from pathlib import Path
+
+STATIC = Path(__file__).resolve().parents[1] / "src" / "meshbay_hub" / "static"
+APP = (STATIC / "app.js").read_text(encoding="utf-8")
+WIZARD = (STATIC / "create-group-page.js").read_text(encoding="utf-8")
+
+
+def _body(src: str, start: str, end: str) -> str:
+ return src.split(start, 1)[1].split(end, 1)[0]
+
+
+def test_the_create_group_page_can_tell_the_app_a_node_was_linked():
+ page = _body(APP, "<${LazyCreateGroupPage}", "/>`;")
+ assert "onNodeLinked=${refreshNodeKey}" in page
+ created = _body(page, "onCreated=${() => {", "}}")
+ assert "refreshNodeKey()" in created
+
+
+def test_the_wizard_says_so_after_each_way_it_links_one():
+ link = _body(WIZARD, "const linkNodeKey = useCallback(", "}, [")
+ assert link.index("/v1/users/me/node_key") < link.index("onNodeLinked()"), (
+ "the app must be told after the hub has the key, not before")
+ start = _body(WIZARD, "const startNode = useCallback(", "}, [")
+ assert start.index("platform.node.start(") < start.index("onNodeLinked()")
+
+
+def test_one_failed_read_does_not_hide_the_section_for_good():
+ refresh = _body(APP, "const refreshNodeKey = useCallback(", "}, [user]);")
+ assert "/pubkeys" in refresh
+ assert not re.search(r"\.catch\(\(\)\s*=>\s*\{\s*\}\)", refresh), (
+ "a swallowed failure leaves hasNodeKey false until a reload")
+ assert "setTimeout(" in refresh, "a failed read is tried again"
+ assert "nodeKeyAskedForRef.current === user" in refresh, (
+ "a late answer must not land on a session that has changed")
+
+
+def test_the_session_effect_uses_the_same_read():
+ assert APP.count("/pubkeys`") == 1, "one place decides hasNodeKey"