Files
TJWaterServerBinary/tests/api/test_leakage_endpoints.py
T
jiang 5966d039de refactor(backend)!: separate algorithm and data layers
Reorganize algorithm packages by business responsibility, move orchestration into services, and keep database access behind pooled repositories.

Harden analysis API validation, remove unsafe legacy simulation endpoints, and add regression and architecture boundary coverage.

BREAKING CHANGE: legacy algorithm module paths and obsolete simulation endpoints are removed.
2026-09-04 17:30:55 +08:00

91 lines
2.6 KiB
Python

from fastapi import FastAPI
from fastapi.testclient import TestClient
from app.api.v1.endpoints import leakage as leakage_endpoint
def _build_client() -> TestClient:
app = FastAPI()
app.include_router(leakage_endpoint.router, prefix="/api/v1")
app.dependency_overrides[leakage_endpoint.get_current_keycloak_username] = (
lambda: "tester"
)
return TestClient(app)
def test_identify_leakage_success(monkeypatch):
def fake_run_leakage_identification(**kwargs):
assert kwargs["network"] == "demo"
assert kwargs["username"] == "tester"
return {"rows": [], "area_count": 0}
monkeypatch.setattr(
leakage_endpoint, "run_leakage_identification", fake_run_leakage_identification
)
client = _build_client()
response = client.post(
"/api/v1/leakage-identifications",
json={
"network": "demo",
"scada_start": "2026-01-01T00:00:00+08:00",
"scada_end": "2026-01-01T01:00:00+08:00",
"scheme_name": "dma_001",
},
)
assert response.status_code == 200
assert response.json()["area_count"] == 0
def test_identify_leakage_rejects_server_file_paths():
client = _build_client()
response = client.post(
"/api/v1/leakage-identifications",
json={
"network": "demo",
"observed_pressure_data": "/etc/passwd",
"output_dir": "/tmp/leakage-results",
},
)
assert response.status_code == 422
def test_identify_leakage_rejects_unbounded_workload():
client = _build_client()
response = client.post(
"/api/v1/leakage-identifications",
json={
"network": "demo",
"observed_pressure_data": {"S1": [1.0]},
"pop_size": 1_000_000,
"max_gen": 1_000_000,
"n_workers": 10_000,
},
)
assert response.status_code == 422
def test_identify_leakage_runs_service_outside_event_loop(monkeypatch):
captured = {}
async def fake_threadpool(func, **kwargs):
captured["func"] = func
captured["kwargs"] = kwargs
return {"rows": [], "area_count": 0}
monkeypatch.setattr(leakage_endpoint, "run_in_threadpool", fake_threadpool)
client = _build_client()
response = client.post(
"/api/v1/leakage-identifications",
json={
"network": "demo",
"observed_pressure_data": {"S1": [1.0]},
},
)
assert response.status_code == 200
assert captured["func"] is leakage_endpoint.run_leakage_identification
assert captured["kwargs"]["username"] == "tester"