""" The files every website is expected to have at the root of its origin. They live in the hub's static directory, which is mounted at "/", so every hub serves them — meshbay.org included, because its Caddyfile hands the hub every path the public site does not name. """ import re from pathlib import Path import pytest from fastapi.testclient import TestClient from meshbay_hub.app import create_app CADDYFILE = Path(__file__).resolve().parents[3] / "packaging" / "caddy" / "meshbay.org.Caddyfile" @pytest.fixture(scope="module") def client(): return TestClient(create_app()) def test_robots_keeps_crawlers_out_of_the_signed_in_views(client): r = client.get("/robots.txt") assert r.status_code == 200 assert r.headers["content-type"].startswith("text/plain") rules = re.findall(r"^Disallow:\s*(\S+)", r.text, re.M) assert "/app/" in rules and "/v1/" in rules # A crawler rendering the sign-in page needs its scripts and stylesheet. assert not any(rule in ("/", "/a/", "/app") for rule in rules), rules @pytest.mark.parametrize("path, magic", [ ("/favicon.ico", b"\x00\x00\x01\x00"), ("/apple-touch-icon.png", b"\x89PNG"), ]) def test_the_icons_are_served_from_the_root(client, path, magic): """Browsers ask for both at the root whether or not a page links them.""" r = client.get(path) assert r.status_code == 200 assert r.content.startswith(magic), f"{path} is not the image it claims to be" @pytest.mark.skipif(not CADDYFILE.exists(), reason="no Caddyfile in this tree") @pytest.mark.parametrize("path", ["/robots.txt", "/favicon.ico", "/apple-touch-icon.png"]) def test_meshbay_org_sends_them_to_the_hub(path): """The public site owns only the paths its matcher names; a file claimed there would be looked for in /srv/meshbay/site and 404.""" m = re.search(r"^\s*@site path (.+)$", CADDYFILE.read_text(), re.M) assert m, "the @site matcher is gone" assert path not in m.group(1).split() def _og(html: str, prop: str) -> str | None: m = re.search(rf'', html) return m and m.group(1) def test_a_link_to_the_hub_previews_with_the_logo(): """Messengers draw a link from og:title and og:image, and resolve only an absolute image URL — so it names the hub's public name, and the file is one the hub serves.""" from meshbay_hub.config import load_config cfg = load_config() cfg.identity.id = "hub.example.org" client = TestClient(create_app(cfg)) for path in ("/", "/app"): html = client.get(path).text assert _og(html, "title") == "MeshBay" assert _og(html, "image") == "https://hub.example.org/og-image.jpg", path image = client.get("/og-image.jpg") assert image.status_code == 200 and image.content.startswith(b"\xff\xd8") assert len(image.content) < 300_000, "too heavy for some messengers to fetch" def test_the_preview_description_fits_in_a_preview(): """A preview shows a line or two and cuts the rest; a cut sentence says nothing.""" from meshbay_hub.api.webapp import PREVIEW_DESCRIPTION assert len(PREVIEW_DESCRIPTION) <= 60