Systematic rename of all semantic anchors (#region, [DEF], @RELATION) across 1400+ files — backend Python, frontend Svelte/TS, specs, docs: - Flat anchors become Namespace.Module.Entity - @RELATION references updated to match new anchor paths - Zero business logic changes
131 lines
5.4 KiB
Python
131 lines
5.4 KiB
Python
# #region Test.AppModule.Spa [C:3] [TYPE Module] [SEMANTICS test,app,spa,serving,static]
|
|
# @BRIEF Tests for app.py — SPA serving, read_root, catch-all route, TestClient integration.
|
|
# @RELATION BINDS_TO -> [App.AppModule]
|
|
# @TEST_EDGE: no_frontend_build -> read_root returns API status JSON
|
|
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
|
|
|
|
import pytest
|
|
|
|
|
|
class TestSpaServing:
|
|
"""serve_spa and read_root — SPA fallback and API status."""
|
|
|
|
# #region Test.AppModule.TestReadRootResponse [C:2] [TYPE Function]
|
|
def test_read_root_response(self):
|
|
from fastapi.testclient import TestClient
|
|
from src.app import app, frontend_path
|
|
client = TestClient(app)
|
|
response = client.get("/")
|
|
assert response.status_code == 200
|
|
if frontend_path.exists():
|
|
assert "text/html" in response.headers.get("content-type", "")
|
|
else:
|
|
data = response.json()
|
|
assert "message" in data
|
|
assert "API is running" in data["message"]
|
|
# #endregion Test.AppModule.TestReadRootResponse
|
|
|
|
# #region Test.AppModule.TestSpaApiPathRejected [C:2] [TYPE Function]
|
|
def test_spa_api_path_rejected(self):
|
|
from fastapi.testclient import TestClient
|
|
from src.app import app
|
|
client = TestClient(app)
|
|
response = client.get("/api/unknown-route-test-xyz")
|
|
assert response.status_code == 404
|
|
assert response.headers.get("content-type", "").startswith("application/json")
|
|
# #endregion Test.AppModule.TestSpaApiPathRejected
|
|
|
|
|
|
class TestAppWithTestClient:
|
|
"""Integration tests using TestClient against the real app."""
|
|
|
|
# #region Test.AppModule.TestUnknownApiReturns404 [C:2] [TYPE Function]
|
|
def test_unknown_api_returns_404(self):
|
|
from fastapi.testclient import TestClient
|
|
from src.app import app
|
|
client = TestClient(app)
|
|
response = client.get("/api/nonexistent-endpoint-xyz")
|
|
assert response.status_code == 404
|
|
assert response.headers.get("content-type", "").startswith("application/json")
|
|
# #endregion Test.AppModule.TestUnknownApiReturns404
|
|
|
|
|
|
class TestServeSpaEdgeCases:
|
|
"""serve_spa — static file serving edge cases."""
|
|
|
|
# #region Test.AppModule.TestServeSpaKnownFile [C:2] [TYPE Function]
|
|
def test_serve_spa_known_file(self):
|
|
from pathlib import Path as P
|
|
root = P(__file__).resolve().parent.parent.parent
|
|
fp = root / "frontend" / "build"
|
|
if not fp.exists():
|
|
pytest.skip("Frontend build not found")
|
|
from fastapi.testclient import TestClient
|
|
from src.app import app
|
|
client = TestClient(app)
|
|
app_dir = fp / "_app"
|
|
if app_dir.exists():
|
|
assets = list(app_dir.rglob("*"))
|
|
if assets:
|
|
rel = assets[0].relative_to(fp)
|
|
resp = client.get(f"/{rel}")
|
|
assert resp.status_code == 200
|
|
# #endregion Test.AppModule.TestServeSpaKnownFile
|
|
|
|
# #region Test.AppModule.TestSpaUnknownFileReturnsIndex [C:2] [TYPE Function]
|
|
def test_spa_unknown_file_returns_index(self):
|
|
from pathlib import Path as P
|
|
root = P(__file__).resolve().parent.parent.parent
|
|
fp = root / "frontend" / "build"
|
|
if not fp.exists():
|
|
pytest.skip("Frontend build not found")
|
|
from fastapi.testclient import TestClient
|
|
from src.app import app
|
|
client = TestClient(app)
|
|
resp = client.get("/some-random-non-api-path")
|
|
assert resp.status_code == 200
|
|
assert "text/html" in resp.headers.get("content-type", "")
|
|
# #endregion Test.AppModule.TestSpaUnknownFileReturnsIndex
|
|
|
|
# #region Test.AppModule.TestSpaApiPath404 [C:2] [TYPE Function]
|
|
def test_spa_api_path_404(self):
|
|
from fastapi.testclient import TestClient
|
|
from src.app import app
|
|
client = TestClient(app)
|
|
resp = client.get("/api/does-not-exist-98765")
|
|
assert resp.status_code == 404
|
|
assert "application/json" in resp.headers.get("content-type", "")
|
|
# #endregion Test.AppModule.TestSpaApiPath404
|
|
|
|
# #region Test.AppModule.TestSpaApiPathNoLeadingSlash [C:2] [TYPE Function]
|
|
def test_spa_api_path_no_leading_slash(self):
|
|
from fastapi.testclient import TestClient
|
|
from src.app import app
|
|
client = TestClient(app)
|
|
resp = client.get("/api/another-missing-endpoint")
|
|
assert resp.status_code == 404
|
|
assert "application/json" in resp.headers.get("content-type", "")
|
|
# #endregion Test.AppModule.TestSpaApiPathNoLeadingSlash
|
|
|
|
# #region Test.AppModule.TestSpaExistingFileServed [C:2] [TYPE Function]
|
|
def test_spa_existing_file_served(self):
|
|
"""SPA catch-all serves an existing static file (covers line 910)."""
|
|
from pathlib import Path as P
|
|
root = P(__file__).resolve().parent.parent.parent
|
|
fp = root / "frontend" / "build"
|
|
if not fp.exists():
|
|
pytest.skip("Frontend build not found — SPA catch-all not registered")
|
|
from fastapi.testclient import TestClient
|
|
from src.app import app
|
|
client = TestClient(app)
|
|
# favicon.png exists at frontend/build/favicon.png
|
|
resp = client.get("/favicon.png")
|
|
assert resp.status_code == 200
|
|
assert resp.headers.get("content-type", "").startswith("image/")
|
|
# #endregion Test.AppModule.TestSpaExistingFileServed
|
|
# #endregion Test.AppModule.Spa
|