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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
|
"""
The reference application, and what it is for.
`docs/MESHBAY_DESIGN.md` §9.4 claims that adding an application costs a registry
entry and the app's own files — no op, no MNP message, no route, no edit to the
pages that render it. Every other test of that claim reads source for the
*absence* of app names, which proves nobody wrote a special case for Videos. It
cannot prove that a genuinely new app works, because there was no new app.
HelloWorld is one. It stores directories, appears as a tab, has a settings pane
and lists files, and the node has never heard its name outside one allow-list
entry. The assertions below are the claim, stated as things that must stay true
of a file that was not written for it.
It ships hidden behind `?dev=1` (apps.js's `dev: true`). Registering it
normally would put a toy app in every operator's group; not registering it
would prove nothing, since registration is exactly the thing being claimed as
sufficient.
**Two honest exceptions**, both found *by* adding it and both fixed by making
the code less app-specific rather than more:
* `group-settings.js` fell back to the whole registry when a group had no
`enabled_apps` yet, which would have turned a hidden app on for everyone. It
asks `availableApps()` now.
* `group-page.js` wrote out `videoDirectories` / `musicDirectories` /
`photoDirectories` by hand. It derives `<key>Directories` from the registry
now, which is what made the claim true rather than nearly true.
"""
import re
from pathlib import Path
import node_tree
import pytest
STATIC = Path(__file__).resolve().parents[1] / "src" / "meshbay_hub" / "static"
NODE_SRC = (Path(__file__).resolve().parents[2] / "meshbay-node" / "src"
/ "meshbay_node")
APP = STATIC / "helloworld-app.js"
SETTINGS = STATIC / "helloworld-app-settings.js"
pytestmark = pytest.mark.skipif(not APP.exists(),
reason="the reference app is not in this checkout")
def _code_only(source: str) -> str:
source = re.sub(r"/\*.*?\*/", "", source, flags=re.S)
return re.sub(r"^\s*//.*$", "", source, flags=re.M)
# ── The claim ────────────────────────────────────────────────────────────────
@pytest.mark.parametrize("name", [
"group-page.js", "group-settings.js", "files-app.js", "transport.js",
"hub-client.js", "settings-ui.js", "folder-tree.js",
])
def test_no_shared_client_file_mentions_it(name):
"""
The registry is where an app is named, and nowhere else. A branch on
`'helloworld'` in any of these would mean the architecture works for four
apps somebody wrote plumbing for.
"""
source = _code_only((STATIC / name).read_text(encoding="utf-8"))
assert "helloworld" not in source.lower(), (
f"{name} names the reference app — adding an application is supposed "
f"to touch nothing here")
@pytest.mark.parametrize("name", [
"ops.py", "roster.py", "config.py", "roots.py",
])
def test_no_shared_node_module_mentions_it(name):
"""
Its directories are stored by `ops.set_app_directories`, which keys the row
by whatever the app is called. Nothing on the node knows what it is.
"""
source = (NODE_SRC / name).read_text(encoding="utf-8")
assert "helloworld" not in source.lower(), (
f"{name} names the reference app; the generic path was supposed to "
f"cover it")
def test_the_node_names_it_once_and_only_in_the_allow_list():
"""
`ALLOWED_APPS` is server-side enforcement — a client naming an app this
node does not know is refused — so an app absent from it could not
demonstrate anything. That entry plus the client's registry line is the
whole cost.
"""
source = node_tree.webrtc_source()
code = re.sub(r"^\s*#.*$", "", source, flags=re.M)
hits = [ln for ln in code.splitlines() if "helloworld" in ln.lower()]
assert len(hits) == 1, f"expected one mention, got: {hits}"
assert "ALLOWED_APPS" in hits[0] or "helloworld" in hits[0]
assert "ALLOWED_APPS" in code[:code.index("helloworld") + 200]
def test_the_registry_entry_is_ordinary():
source = (STATIC / "apps.js").read_text(encoding="utf-8")
entry = source[source.index("key: 'helloworld'"):]
entry = entry[:entry.index("},") + 2]
for field in ("icon:", "labelKey:", "Component:", "Settings:"):
assert field in entry, f"the entry has no {field}"
assert "dev: true" in entry, "it would ship to every operator"
# ── And it is held to the same contract as the rest ──────────────────────────
def test_its_settings_pane_takes_the_shared_props_and_no_others():
m = re.search(r"function \w+Settings\(\{([^}]*)\}\)",
SETTINGS.read_text(encoding="utf-8"))
assert m
props = {p.strip() for p in m.group(1).split(",") if p.strip()}
assert props <= {"roots", "dirs", "settings", "saveDirectories",
"transport", "signFn"}
def test_it_reads_its_directories_under_its_own_key():
"""
`<key>Directories` — the shape `group-page.js` derives for every registered
app. An app reading a name spelled anywhere else would need that place
edited too.
"""
for path in (APP, SETTINGS):
assert "helloworldDirectories" in path.read_text(encoding="utf-8")
def test_it_does_not_reach_for_the_transport():
"""
It has no third-party service and no setting of its own, so it needs
neither — which is the case an app author most often starts from, and the
one the architecture has to make free.
"""
source = _code_only(SETTINGS.read_text(encoding="utf-8"))
assert "transport." not in source
assert "saveDirectories" in source
# ── Hidden, but genuinely registered ────────────────────────────────────────
def test_a_dev_app_is_filtered_out_by_default():
source = (STATIC / "apps.js").read_text(encoding="utf-8")
assert "function availableApps()" in source
body = source[source.index("function availableApps()"):]
body = body[:body.index("\n}") + 2]
assert "devAppsShown()" in body and "a.dev" in body
def test_nothing_falls_back_to_the_unfiltered_registry():
"""
A fallback of "every app in the registry" would enable a hidden one for the
whole group. This is the exception the reference app found.
"""
source = _code_only((STATIC / "group-settings.js").read_text(encoding="utf-8"))
assert "APPS.map(" not in source and "APPS.filter(" not in source, (
"group-settings.js reads the raw registry; it should ask "
"availableApps()")
|