- ~60 new/extended test files across api, core, plugins, services, schemas: routes, superset clients, task_manager, lineage, git, translate, dashboard-testing, load-testing, migration, llm_analysis, scheduler, ssl - .coveragerc: enable branch coverage; exclude src/__tests__ (test files) and src/scripts (CLI/ops tools) from the denominator - bug fixes found while testing: * settings: PUT /settings/reports registered under duplicated prefix * schemas/lineage: FleetReportDTO missing run_status (route always 500) * dashboard_testing/baseline_inheritance: visual entry read wrong field * superset_client/_databases: logger extra name shadowed LogRecord attr * routes/datasets: _yaml_string_paths recursion without yield from * translate/sql_generator: restore explicit-type timestamp contract * baseline_catalog: remove unreachable dashboard_id fallback - conftest fixes: pytest_plugins to rootdir conftest (pytest 9), test filename collision, TMPDIR-safe integration fixtures
88 lines
4.1 KiB
Python
88 lines
4.1 KiB
Python
# #region Test.AppModule.EnvBranches [C:3] [TYPE Module] [SEMANTICS test,app,reload,env,cors,spa]
|
|
# @BRIEF Tests for app.py — import-time env-gated branches (CORS allow_origins, read_root)
|
|
# covered via in-process module reload. The final test restores the canonical app
|
|
# so every later test sees the standard instance.
|
|
# @RELATION BINDS_TO -> [App.AppModule]
|
|
# @TEST_EDGE: allowed_origins_set -> CORSMiddleware allow_origins populated from env
|
|
# @TEST_EDGE: frontend_missing -> read_root registered, SPA catch-all absent
|
|
# @TEST_EDGE: restore_reload -> canonical app reinstated after env experiments
|
|
# @TEST_INVARIANT: import_time_env_branches -> VERIFIED_BY: test_cors_allow_origins_reload, test_read_root_reload_when_frontend_missing
|
|
|
|
from pathlib import Path
|
|
import sys
|
|
import os
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
|
|
|
|
import pytest
|
|
from unittest.mock import patch
|
|
|
|
|
|
# #region Test.AppModule.ModuleLevelEnvBranches [C:3] [TYPE Class] [SEMANTICS test,app,reload,env,cors,spa]
|
|
# @BRIEF Verify import-time branches: ALLOWED_ORIGINS (line 364) and read_root (lines 1455-1463).
|
|
# @RELATION BINDS_TO -> [App.AppModule.AppMiddleware]
|
|
class TestModuleLevelEnvBranches:
|
|
"""Lines 356-371 (CORS) and 1455-1463 (read_root) execute only at import time."""
|
|
|
|
# #region Test.AppModule.TestCorsAllowOriginsReload [C:2] [TYPE Function]
|
|
def test_cors_allow_origins_reload(self):
|
|
"""Reload with ALLOWED_ORIGINS set -> CORSMiddleware allow_origins populated (line 364)."""
|
|
import importlib
|
|
with patch.dict(
|
|
os.environ,
|
|
{"ALLOWED_ORIGINS": "https://one.example, https://two.example, "},
|
|
clear=False,
|
|
):
|
|
import src.app as app_module
|
|
reloaded = importlib.reload(app_module)
|
|
cors = [m for m in reloaded.app.user_middleware if m.cls.__name__ == "CORSMiddleware"]
|
|
assert cors, "CORSMiddleware not registered after reload"
|
|
assert cors[0].kwargs.get("allow_origins") == ["https://one.example", "https://two.example"]
|
|
# #endregion Test.AppModule.TestCorsAllowOriginsReload
|
|
|
|
# #region Test.AppModule.TestReadRootReloadWhenFrontendMissing [C:2] [TYPE Function]
|
|
def test_read_root_reload_when_frontend_missing(self):
|
|
"""Reload with frontend/build masked -> read_root registered and serves API status JSON."""
|
|
import importlib
|
|
import pathlib
|
|
orig_exists = pathlib.Path.exists
|
|
|
|
def _fake_exists(self):
|
|
s = str(self)
|
|
if s.endswith(os.sep + "frontend" + os.sep + "build"):
|
|
return False
|
|
return orig_exists(self)
|
|
|
|
try:
|
|
pathlib.Path.exists = _fake_exists
|
|
import src.app as app_module
|
|
reloaded = importlib.reload(app_module)
|
|
finally:
|
|
pathlib.Path.exists = orig_exists
|
|
paths = [getattr(r, "path", None) for r in reloaded.app.routes]
|
|
assert "/" in paths
|
|
assert "/{file_path:path}" not in paths
|
|
from fastapi.testclient import TestClient
|
|
resp = TestClient(reloaded.app).get("/")
|
|
assert resp.status_code == 200
|
|
assert "API is running" in resp.json()["message"]
|
|
# #endregion Test.AppModule.TestReadRootReloadWhenFrontendMissing
|
|
|
|
# #region Test.AppModule.TestReloadRestoresCanonicalApp [C:2] [TYPE Function]
|
|
def test_reload_restores_canonical_app(self):
|
|
"""Third reload with default env reinstates the canonical app instance."""
|
|
import importlib
|
|
import src.app as app_module
|
|
reloaded = importlib.reload(app_module)
|
|
assert reloaded.app.title == "Superset Tools API"
|
|
names = [m.cls.__name__ for m in reloaded.app.user_middleware]
|
|
assert "CORSMiddleware" in names
|
|
assert "HSTSMiddleware" in names
|
|
assert "TraceContextMiddleware" in names
|
|
assert "SessionMiddleware" in names
|
|
paths = [getattr(r, "path", None) for r in reloaded.app.routes]
|
|
assert "/{file_path:path}" in paths # SPA catch-all restored
|
|
# #endregion Test.AppModule.TestReloadRestoresCanonicalApp
|
|
# #endregion Test.AppModule.ModuleLevelEnvBranches
|
|
# #endregion Test.AppModule.EnvBranches
|