fixes and refactor

This commit is contained in:
HotSwapp
2025-08-14 19:16:28 -05:00
parent 5111079149
commit bfc04a6909
61 changed files with 5689 additions and 767 deletions

158
tests/test_mortality.py Normal file
View File

@@ -0,0 +1,158 @@
import os
import sys
from pathlib import Path
import pytest
from fastapi.testclient import TestClient
# Ensure required env vars for app import/config
os.environ.setdefault("SECRET_KEY", "x" * 32)
os.environ.setdefault("DATABASE_URL", "sqlite:////tmp/delphi_test.sqlite")
# Ensure repository root on sys.path for direct test runs
ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
sys.path.insert(0, str(ROOT))
from app.main import app # noqa: E402
from app.auth.security import get_current_user # noqa: E402
from tests.helpers import assert_http_error # noqa: E402
from app.database.base import SessionLocal # noqa: E402
from app.models.pensions import LifeTable, NumberTable # noqa: E402
from app.services.mortality import ( # noqa: E402
get_life_values,
get_number_value,
InvalidCodeError,
)
@pytest.fixture(scope="module")
def client():
# Override auth to bypass JWT for these tests
class _User:
def __init__(self):
self.id = "test"
self.username = "tester"
self.is_admin = True
self.is_active = True
app.dependency_overrides[get_current_user] = lambda: _User()
try:
yield TestClient(app)
finally:
app.dependency_overrides.pop(get_current_user, None)
def _seed_life_and_number():
db = SessionLocal()
try:
# Seed a life table row for age 65
db.query(LifeTable).filter(LifeTable.age == 65).delete()
lt = LifeTable(
age=65,
le_wm=14.5,
na_wm=87000.0,
le_af=20.1,
na_af=92000.0,
le_ha=18.2,
na_ha=88000.0,
)
db.add(lt)
# Seed a number table row for month 305
db.query(NumberTable).filter(NumberTable.month == 305).delete()
nt = NumberTable(
month=305,
na_wm=80000.0,
na_af=90000.0,
na_ha=85000.0,
)
db.add(nt)
db.commit()
finally:
db.close()
def test_service_helpers_success_invalid_and_not_found():
_seed_life_and_number()
db = SessionLocal()
try:
# Success cases
res = get_life_values(db, age=65, sex="M", race="W")
assert res and res["le"] == 14.5 and res["na"] == 87000.0
res = get_life_values(db, age=65, sex="F", race="A")
assert res and res["le"] == 20.1 and res["na"] == 92000.0
res = get_life_values(db, age=65, sex="A", race="H")
assert res and res["le"] == 18.2 and res["na"] == 88000.0
nres = get_number_value(db, month=305, sex="M", race="W")
assert nres and nres["na"] == 80000.0
nres = get_number_value(db, month=305, sex="F", race="A")
assert nres and nres["na"] == 90000.0
nres = get_number_value(db, month=305, sex="A", race="H")
assert nres and nres["na"] == 85000.0
# Invalid codes
with pytest.raises(InvalidCodeError):
get_life_values(db, age=65, sex="X", race="W")
with pytest.raises(InvalidCodeError):
get_number_value(db, month=305, sex="M", race="Z")
# Not found
assert get_life_values(db, age=9999, sex="M", race="W") is None
assert get_number_value(db, month=99999, sex="M", race="W") is None
finally:
db.close()
def test_api_life_valid_invalid_not_found(client: TestClient):
_seed_life_and_number()
# Valid lookups
resp = client.get("/api/mortality/life/65", params={"sex": "M", "race": "W"})
assert resp.status_code == 200
data = resp.json()
assert data["le"] == 14.5 and data["na"] == 87000.0
resp = client.get("/api/mortality/life/65", params={"sex": "F", "race": "A"})
assert resp.status_code == 200
assert resp.json()["le"] == 20.1
# Invalid code -> 400 wrapped error
resp = client.get("/api/mortality/life/65", params={"sex": "X", "race": "W"})
assert_http_error(resp, 400, "Invalid sex code")
# Not found -> 404 wrapped error
resp = client.get("/api/mortality/life/9999", params={"sex": "M", "race": "W"})
assert_http_error(resp, 404, "Age not found")
def test_api_number_valid_invalid_not_found(client: TestClient):
_seed_life_and_number()
# Valid lookup
resp = client.get("/api/mortality/number/305", params={"sex": "M", "race": "W"})
assert resp.status_code == 200
assert resp.json()["na"] == 80000.0
# Invalid code -> 400
resp = client.get("/api/mortality/number/305", params={"sex": "M", "race": "Z"})
assert_http_error(resp, 400, "Invalid race code")
# Not found -> 404
resp = client.get("/api/mortality/number/99999", params={"sex": "M", "race": "W"})
assert_http_error(resp, 404, "Month not found")
def test_api_validation_negative_inputs(client: TestClient):
# Negative age -> 422 validation envelope
resp = client.get("/api/mortality/life/-1", params={"sex": "M", "race": "W"})
from tests.helpers import assert_validation_error
assert_validation_error(resp, "age")
# Negative month -> 422 validation envelope
resp = client.get("/api/mortality/number/-5", params={"sex": "F", "race": "A"})
assert_validation_error(resp, "month")