import pytest @pytest.mark.asyncio async def test_unknown_path_serves_spa_index(client): response = await client.get("/some/client/side/route") assert response.status_code == 200 assert '
' in response.text @pytest.mark.asyncio async def test_auth_routes_still_work_alongside_spa_fallback(client): response = await client.post( "/auth/register", json={"username": "frontendcheck", "password": "spookyspooky"} ) assert response.status_code == 201 @pytest.mark.asyncio async def test_missing_frontend_build_returns_clear_error(client, monkeypatch, tmp_path): import app.main as main_module monkeypatch.setattr(main_module, "FRONTEND_DIST", tmp_path) response = await client.get("/some/route") assert response.status_code == 503 assert "npm run build" in response.json()["detail"] @pytest.mark.asyncio async def test_root_level_static_file_is_served_directly(client, monkeypatch, tmp_path): # Vite emits favicon.ico, og-image.png, etc. straight into dist/, not # dist/assets/ (the only mounted static dir) — these must be served as # themselves, not swallowed by the SPA fallback. import app.main as main_module monkeypatch.setattr(main_module, "FRONTEND_DIST", tmp_path) (tmp_path / "index.html").write_text('
') (tmp_path / "favicon.svg").write_text("fake favicon") response = await client.get("/favicon.svg") assert response.status_code == 200 assert response.text == "fake favicon" assert "html" not in response.headers["content-type"] @pytest.mark.asyncio async def test_static_file_lookup_cannot_escape_dist_directory(monkeypatch, tmp_path): # Bypasses the HTTP client, which normalizes ".." segments out of URLs # before they're ever sent — this exercises the route function's own # guard directly against a full_path value an unusual client could send. import app.main as main_module dist_dir = tmp_path / "dist" dist_dir.mkdir() (dist_dir / "index.html").write_text('
') secret = tmp_path / "secret.txt" secret.write_text("should never be served") monkeypatch.setattr(main_module, "FRONTEND_DIST", dist_dir) response = await main_module.serve_spa("../secret.txt") assert response.path == dist_dir / "index.html"