"""Compression and caching contract for the HTTP layer.
Session history is ~1 MB of JSON and the built SPA bundle is ~0.8 MB; without
gzip both crossed the wire at full size on every session open (the measured
payloads shrink 5.1× and 3.2× respectively).
"""
from pathlib import Path
import pytest
from starlette.middleware.gzip import GZipMiddleware
def test_gzip_middleware_is_installed():
from navi.main import app
installed = [m for m in app.user_middleware if m.cls is GZipMiddleware]
assert installed, "GZipMiddleware is not registered on the app"
# Small payloads (health, tiny JSON) stay uncompressed; anything above the
# threshold — history pages, the SPA bundle — is compressed.
assert installed[0].kwargs.get("minimum_size") == 1024
# Level 6 keeps the ratio within a couple of percent of 9 on JSON while
# roughly halving the CPU spent on a 1 MB page.
assert installed[0].kwargs.get("compresslevel") == 6
def test_hashed_assets_are_cached_forever():
"""dist/assets filenames carry a Vite content hash, so the bytes never
change; without this header every cold load revalidated each asset."""
from fastapi.testclient import TestClient
from navi.main import app
assets = Path(__file__).resolve().parents[3] / "webclient" / "dist" / "assets"
built = sorted(p.name for p in assets.glob("*")) if assets.is_dir() else []
if not built:
pytest.skip("no built webclient assets")
response = TestClient(app).get(f"/assets/{built[0]}")
assert response.status_code == 200
assert response.headers["cache-control"] == "public, max-age=31536000, immutable"