aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests/test_sidebar_node_section.py
blob: 371a0189ee2c6178c5938ebc9c63d537f271f7b5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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"