"""SPA fallback 的 /api 守卫测试(v1.29)。 背景(实测踩坑):未注册的 ``/api/*`` 路径会掉进 StaticFiles 的 SPA fallback 返回 200 + index.html——前端 ``resp.ok`` 为 true、``resp.json()`` 抛 ``Unexpected token '<'``,把"服务是旧版本/端点不存在"伪装成前端解析 错误。守护:未知 /api 路径必须返回 JSON 404,前端路由路径仍回 index.html。 """ from __future__ import annotations from pathlib import Path import pytest fastapi_testclient = pytest.importorskip("fastapi.testclient") def _make_app_with_ui(tmp_path: Path): """带假前端 dist 的 app(index.html + 一个资产文件)。""" from easy_tdx.web.app import _create_app dist = tmp_path / "dist" dist.mkdir() (dist / "index.html").write_text("spa", encoding="utf-8") (dist / "test-asset.txt").write_text("asset", encoding="utf-8") import easy_tdx.web.app as app_mod original = app_mod._resolve_web_dist_dir app_mod._resolve_web_dist_dir = lambda: dist # type: ignore[assignment] try: return _create_app(enable_mac=False, enable_ui=True) finally: app_mod._resolve_web_dist_dir = original # type: ignore[assignment] @pytest.fixture() def client(tmp_path): app = _make_app_with_ui(tmp_path) with fastapi_testclient.TestClient(app) as c: yield c def test_unknown_api_path_returns_json_404(client): """未注册的 /api 路径:JSON 404,绝不能是 200 HTML(SPA fallback)。""" resp = client.get("/api/v1/llm/config-not-exist") assert resp.status_code == 404 assert resp.headers["content-type"].startswith("application/json") assert "