summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests/test_hub_address_seam.py
blob: ccdac7d1ae6f706884cec72e8350fe34c14cbac8 (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
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
"""
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",
           "auth-page.js", "explore-page.js", "create-group-page.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