fix(static): serve shared brand assets with CSS MIME

#9
Files changed (2) hide show
  1. serve.py +11 -0
  2. tests/test_static_brand_assets.py +33 -0
serve.py CHANGED
@@ -1800,6 +1800,17 @@ def _lambda_aggregate(axes: list[float]) -> float:
1800
  if ASSETS_DIR.exists():
1801
  app.mount("/assets", StaticFiles(directory=str(ASSETS_DIR)), name="assets")
1802
 
 
 
 
 
 
 
 
 
 
 
 
1803
 
1804
  # ---------------------------------------------------------------------------
1805
  # Health
 
1800
  if ASSETS_DIR.exists():
1801
  app.mount("/assets", StaticFiles(directory=str(ASSETS_DIR)), name="assets")
1802
 
1803
+ # The shared brand injector deliberately uses absolute ``/static/...`` URLs so
1804
+ # every HTML surface (including nested ``/elite/*`` pages) resolves the same
1805
+ # zero-CDN assets. The SPA catch-all maps a request path underneath STATIC_DIR;
1806
+ # without this mount, ``/static/brand-tokens.css`` becomes
1807
+ # ``STATIC_DIR/static/brand-tokens.css`` and falls through to HTML. Browsers
1808
+ # then reject the response under strict MIME checking. Mount the already-
1809
+ # packaged public tree before the catch-all so CSS, fonts and other explicitly
1810
+ # referenced static assets retain their real media types.
1811
+ if STATIC_DIR.exists():
1812
+ app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static")
1813
+
1814
 
1815
  # ---------------------------------------------------------------------------
1816
  # Health
tests/test_static_brand_assets.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ from fastapi import FastAPI
4
+ from fastapi.staticfiles import StaticFiles
5
+ from fastapi.testclient import TestClient
6
+
7
+
8
+ ROOT = Path(__file__).resolve().parents[1]
9
+ STATIC_DIR = ROOT / "static"
10
+
11
+
12
+ def test_brand_assets_are_packaged_and_served_as_css():
13
+ app = FastAPI()
14
+ app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static")
15
+ client = TestClient(app)
16
+
17
+ for name in ("brand-tokens.css", "brand-bridge.css"):
18
+ source = STATIC_DIR / name
19
+ assert source.is_file(), f"missing packaged brand asset: {name}"
20
+
21
+ response = client.get(f"/static/{name}")
22
+ assert response.status_code == 200
23
+ assert response.headers["content-type"].startswith("text/css")
24
+ assert response.content == source.read_bytes()
25
+
26
+
27
+ def test_static_mount_precedes_the_spa_catch_all():
28
+ source = (ROOT / "serve.py").read_text(encoding="utf-8")
29
+ mount = 'app.mount("/static", StaticFiles(directory=str(STATIC_DIR)), name="static")'
30
+ catch_all = '@app.get("/{full_path:path}")'
31
+
32
+ assert source.count(mount) == 1
33
+ assert source.index(mount) < source.index(catch_all)