diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-27 22:21:07 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-27 22:21:07 +0200 |
| commit | c7899e2218af26f3bab6a157c70acf5eb7871da6 (patch) | |
| tree | 5ed08cfbf26cdd8d9dbf6ce1159fc259d611df2d /packages/meshbay-hub/tests | |
| parent | 7422a777297347dc83e6c5b2e89c1a6fa99a36b0 (diff) | |
| download | meshbay-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.py | 55 |
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" |