diff options
Diffstat (limited to 'packages/meshbay-hub/tests/test_hub_address_seam.py')
| -rw-r--r-- | packages/meshbay-hub/tests/test_hub_address_seam.py | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/packages/meshbay-hub/tests/test_hub_address_seam.py b/packages/meshbay-hub/tests/test_hub_address_seam.py new file mode 100644 index 0000000..392a21c --- /dev/null +++ b/packages/meshbay-hub/tests/test_hub_address_seam.py @@ -0,0 +1,79 @@ +""" +One address for the hub, resolved in one place. + +`keyderive.js` carried its own `const HUB = '' // same origin`. True of a page +the hub served; false of one loaded from a package, where the origin is +`app://meshbay` — so `/v1/users/register` resolved against that and the +application's own protocol handler answered 404. **Registration and sign-in, the +first two things anybody does, failed with "Not found".** + +It was found by a person clicking Register, not by anything here, and it is the +same shape as the duplicate `MNP_VERSION` in `protocol.py`: a second copy of a +constant, harmless until something changes underneath it. + +So: no file that talks to the hub may decide for itself where the hub is. +""" + +import re +from pathlib import Path + +import pytest + +STATIC = Path(__file__).resolve().parents[1] / "src" / "meshbay_hub" / "static" + +# Files that issue hub requests. `app.js` gets its base from `platform.hubBase()` +# and the rest reach the adapter through the global it publishes. +CALLERS = ["app.js", "keyderive.js", "transport.js", "crypto.js"] + + +def _source(name: str) -> str: + return (STATIC / name).read_text(encoding="utf-8") + + +@pytest.mark.parametrize("name", CALLERS) +def test_no_file_decides_where_the_hub_is(name): + """ + A literal empty base means "same origin", which is an assumption about how + the page was loaded — and it is wrong in the application. + """ + for line in _source(name).splitlines(): + stripped = line.strip() + if stripped.startswith("*") or stripped.startswith("//"): + continue # prose about the fix, not the fix + assert not re.match(r"const HUB\s*=\s*['\"]{2}\s*;", stripped), ( + f"{name} hard-codes the hub as the current origin") + + +@pytest.mark.parametrize("name", CALLERS) +def test_hub_paths_are_never_fetched_against_the_page_origin(name): + """ + `fetch('/v1/...')` resolves against whatever served the page. In a browser + that is the hub; in the application it is the package, and the request never + leaves the machine. + """ + source = _source(name) + bad = re.findall(r"""\bfetch\(\s*['"`]/v1/""", source) + assert not bad, ( + f"{name} fetches a hub path relative to the page origin — " + f"{len(bad)} site(s)") + + +def test_the_adapter_is_reachable_from_a_classic_script(): + """ + `keyderive.js` and `transport.js` load before the module graph and cannot + import. The adapter therefore publishes a global, and they read it when a + call is made rather than when they load — by which time it exists. + """ + platform = _source("platform.js") + assert "window.MeshBayPlatform" in platform + + for name in ("keyderive.js", "transport.js"): + source = _source(name) + assert "MeshBayPlatform" in source, ( + f"{name} does not reach the adapter, so it has an answer of its own") + + +def test_the_adapter_is_the_only_thing_that_answers_where(): + """One implementation, so a second cannot drift from it.""" + platform = _source("platform.js") + assert platform.count("export function hubBase()") == 1 |