e5d785f511
- add README live-demo badge - tighten engine validation for jump grids and detector indices - replace flaky FastAPI TestClient web tests with direct handler tests - remove unused httpx dev dependency - clean stale frontend comments - re-execute notebooks with clean sequential outputs
79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from webapp.app import SimulateRequest, app, health, simulate
|
|
|
|
|
|
def test_health_endpoint():
|
|
payload = health()
|
|
assert payload["ok"] is True
|
|
assert payload["version"] == "0.4.7"
|
|
|
|
|
|
def test_simulation_endpoint_preserves_equal_budget():
|
|
payload = simulate(
|
|
SimulateRequest(
|
|
rng_seed=3,
|
|
n_paths=5,
|
|
n_steps=100,
|
|
drop_fraction=0.05,
|
|
rise_fraction=0.08,
|
|
max_detection_lag_steps=3,
|
|
)
|
|
)
|
|
assert payload["adaptive_total_samples"] == payload["fixed_total_samples"]
|
|
assert payload["max_detection_lag_steps"] == 3
|
|
|
|
|
|
def test_webapp_imports_from_source_checkout_without_installed_package(tmp_path):
|
|
"""The documented direct uvicorn command must resolve the src-layout package."""
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
repo_root = Path(__file__).resolve().parents[1]
|
|
env = os.environ.copy()
|
|
env.pop("PYTHONPATH", None)
|
|
completed = subprocess.run(
|
|
[sys.executable, "-c", "import webapp.app; print(webapp.app.app.title)"],
|
|
cwd=repo_root,
|
|
env=env,
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
assert completed.returncode == 0, completed.stderr
|
|
assert "Adaptive Barrier Monitor" in completed.stdout
|
|
|
|
|
|
def test_simulation_endpoint_supports_fixed_cadence():
|
|
payload = simulate(
|
|
SimulateRequest(
|
|
rng_seed=3,
|
|
n_paths=5,
|
|
n_steps=200,
|
|
window_minutes=200.0,
|
|
dt_cap_minutes=2.0,
|
|
comparison_mode="fixed_cadence",
|
|
fixed_cadence_minutes=20.0,
|
|
)
|
|
)
|
|
assert payload["comparison_mode"] == "fixed_cadence"
|
|
assert payload["fixed_cadence_minutes"] == 20.0
|
|
assert payload["adaptive_total_samples"] != payload["fixed_total_samples"]
|
|
|
|
|
|
def test_simulation_endpoint_rejects_unknown_comparison_mode():
|
|
with pytest.raises(ValidationError):
|
|
SimulateRequest.model_validate({"comparison_mode": "unknown"})
|
|
|
|
|
|
def test_app_registers_expected_routes():
|
|
route_methods = {
|
|
route.path: getattr(route, "methods", set())
|
|
for route in app.routes
|
|
}
|
|
assert "GET" in route_methods["/api/health"]
|
|
assert "POST" in route_methods["/api/simulate"]
|