aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests/test_hub_address_seam.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/tests/test_hub_address_seam.py')
-rw-r--r--packages/meshbay-hub/tests/test_hub_address_seam.py79
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