Files
qtalker---/backend/tests/test_frontend_serving.py
Indiana 761d6171b5 fix: actually strip stale SESSION_SECRET mentions from README
The gap-g-readme merge commit (57a8914) staged this fix but never
re-staged it after editing, so the merge landed with the pre-fix content —
the working tree had the correction but git didn't. No functional change,
just closing the gap between what was intended and what was committed.
2026-07-23 03:32:21 +00:00

62 lines
2.3 KiB
Python

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 '<div id="root">' 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('<div id="root"></div>')
(tmp_path / "favicon.svg").write_text("<svg>fake favicon</svg>")
response = await client.get("/favicon.svg")
assert response.status_code == 200
assert response.text == "<svg>fake favicon</svg>"
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('<div id="root"></div>')
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"