innercontext/backend/tests/test_health.py
Piotr Oleszczyk c09acc7c81 refactor: split table models into Base/Table/Public for proper FastAPI serialization
Add ProductBase, ProductPublic, ProductWithInventory and
SkinConditionSnapshotBase, SkinConditionSnapshotPublic. Table models now inherit
from their Base counterpart and override JSON fields with sa_column. All
field_serializer hacks removed; FastAPI response models use the non-table Public
classes so Pydantic coerces raw DB dicts → typed models cleanly. ProductCreate
and SnapshotCreate now simply inherit their respective Base classes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 15:37:46 +01:00

294 lines
8.9 KiB
Python

import uuid
# ---------------------------------------------------------------------------
# Medications
# ---------------------------------------------------------------------------
def test_create_medication_minimal(client, medication_data):
r = client.post("/health/medications", json=medication_data)
assert r.status_code == 201
data = r.json()
assert "record_id" in data
assert data["kind"] == "prescription"
assert data["product_name"] == "Epiduo"
def test_create_medication_invalid_kind(client):
r = client.post(
"/health/medications", json={"kind": "invalid_kind", "product_name": "X"}
)
assert r.status_code == 422
def test_list_medications_empty(client):
r = client.get("/health/medications")
assert r.status_code == 200
assert r.json() == []
def test_list_filter_kind(client):
client.post(
"/health/medications", json={"kind": "prescription", "product_name": "A"}
)
client.post("/health/medications", json={"kind": "supplement", "product_name": "B"})
r = client.get("/health/medications?kind=supplement")
assert r.status_code == 200
data = r.json()
assert len(data) == 1
assert data[0]["kind"] == "supplement"
def test_list_filter_product_name(client):
client.post(
"/health/medications", json={"kind": "otc", "product_name": "Epiduo Forte"}
)
client.post("/health/medications", json={"kind": "otc", "product_name": "Panoxyl"})
r = client.get("/health/medications?product_name=epid")
assert r.status_code == 200
data = r.json()
assert len(data) == 1
assert "Epiduo" in data[0]["product_name"]
def test_get_medication(client, created_medication):
mid = created_medication["record_id"]
r = client.get(f"/health/medications/{mid}")
assert r.status_code == 200
assert r.json()["record_id"] == mid
def test_get_medication_not_found(client):
r = client.get(f"/health/medications/{uuid.uuid4()}")
assert r.status_code == 404
def test_update_medication(client, created_medication):
mid = created_medication["record_id"]
r = client.patch(
f"/health/medications/{mid}", json={"notes": "Take in the evening"}
)
assert r.status_code == 200
assert r.json()["notes"] == "Take in the evening"
def test_update_medication_not_found(client):
r = client.patch(f"/health/medications/{uuid.uuid4()}", json={"notes": "x"})
assert r.status_code == 404
def test_delete_medication_no_usages(client, created_medication):
mid = created_medication["record_id"]
r = client.delete(f"/health/medications/{mid}")
assert r.status_code == 204
r2 = client.get(f"/health/medications/{mid}")
assert r2.status_code == 404
def test_delete_medication_with_usages(client, created_medication):
mid = created_medication["record_id"]
# Create a usage
client.post(
f"/health/medications/{mid}/usages",
json={"valid_from": "2026-01-01T00:00:00"},
)
# Delete medication (should also delete usages)
r = client.delete(f"/health/medications/{mid}")
assert r.status_code == 204
r2 = client.get(f"/health/medications/{mid}")
assert r2.status_code == 404
# ---------------------------------------------------------------------------
# Usages
# ---------------------------------------------------------------------------
def test_create_usage(client, created_medication):
mid = created_medication["record_id"]
r = client.post(
f"/health/medications/{mid}/usages",
json={
"valid_from": "2026-01-01T08:00:00",
"dose_value": 1.0,
"dose_unit": "pea",
},
)
assert r.status_code == 201
data = r.json()
assert "record_id" in data
assert data["medication_record_id"] == mid
assert data["dose_unit"] == "pea"
def test_create_usage_medication_not_found(client):
r = client.post(
f"/health/medications/{uuid.uuid4()}/usages",
json={"valid_from": "2026-01-01T00:00:00"},
)
assert r.status_code == 404
def test_list_usages_empty(client, created_medication):
mid = created_medication["record_id"]
r = client.get(f"/health/medications/{mid}/usages")
assert r.status_code == 200
assert r.json() == []
def test_list_usages_returns_entries(client, created_medication):
mid = created_medication["record_id"]
client.post(
f"/health/medications/{mid}/usages",
json={"valid_from": "2026-01-01T00:00:00"},
)
r = client.get(f"/health/medications/{mid}/usages")
assert r.status_code == 200
assert len(r.json()) == 1
def test_update_usage(client, created_medication):
mid = created_medication["record_id"]
r = client.post(
f"/health/medications/{mid}/usages",
json={"valid_from": "2026-01-01T00:00:00"},
)
uid = r.json()["record_id"]
r2 = client.patch(
f"/health/usages/{uid}", json={"dose_value": 2.5, "dose_unit": "mg"}
)
assert r2.status_code == 200
assert r2.json()["dose_value"] == 2.5
assert r2.json()["dose_unit"] == "mg"
def test_update_usage_not_found(client):
r = client.patch(f"/health/usages/{uuid.uuid4()}", json={"dose_value": 1.0})
assert r.status_code == 404
def test_delete_usage(client, created_medication):
mid = created_medication["record_id"]
r = client.post(
f"/health/medications/{mid}/usages",
json={"valid_from": "2026-01-01T00:00:00"},
)
uid = r.json()["record_id"]
r2 = client.delete(f"/health/usages/{uid}")
assert r2.status_code == 204
def test_delete_usage_not_found(client):
r = client.delete(f"/health/usages/{uuid.uuid4()}")
assert r.status_code == 404
# ---------------------------------------------------------------------------
# Lab results
# ---------------------------------------------------------------------------
LAB_RESULT_DATA = {
"collected_at": "2026-01-15T09:00:00",
"test_code": "718-7",
"test_name_original": "Hemoglobin",
"value_num": 14.5,
"unit_original": "g/dL",
"flag": "N",
}
def test_create_lab_result(client):
r = client.post("/health/lab-results", json=LAB_RESULT_DATA)
assert r.status_code == 201
data = r.json()
assert "record_id" in data
assert data["test_code"] == "718-7"
assert data["flag"] == "N"
def test_create_lab_result_invalid_code(client):
bad = {**LAB_RESULT_DATA, "test_code": "not-a-loinc-code"}
r = client.post("/health/lab-results", json=bad)
assert r.status_code == 422
def test_create_lab_result_invalid_flag(client):
bad = {**LAB_RESULT_DATA, "flag": "INVALID"}
r = client.post("/health/lab-results", json=bad)
assert r.status_code == 422
def test_list_lab_results_empty(client):
r = client.get("/health/lab-results")
assert r.status_code == 200
assert r.json() == []
def test_list_filter_test_code(client):
client.post("/health/lab-results", json=LAB_RESULT_DATA)
client.post("/health/lab-results", json={**LAB_RESULT_DATA, "test_code": "2951-2"})
r = client.get("/health/lab-results?test_code=718-7")
assert r.status_code == 200
data = r.json()
assert len(data) == 1
assert data[0]["test_code"] == "718-7"
def test_list_filter_flag(client):
client.post("/health/lab-results", json={**LAB_RESULT_DATA, "flag": "N"})
client.post("/health/lab-results", json={**LAB_RESULT_DATA, "flag": "H"})
r = client.get("/health/lab-results?flag=H")
assert r.status_code == 200
data = r.json()
assert len(data) == 1
assert data[0]["flag"] == "H"
def test_list_filter_date_range(client):
client.post(
"/health/lab-results",
json={**LAB_RESULT_DATA, "collected_at": "2026-01-01T00:00:00"},
)
client.post(
"/health/lab-results",
json={**LAB_RESULT_DATA, "collected_at": "2026-06-01T00:00:00"},
)
r = client.get("/health/lab-results?from_date=2026-05-01T00:00:00")
assert r.status_code == 200
data = r.json()
assert len(data) == 1
def test_get_lab_result(client):
r = client.post("/health/lab-results", json=LAB_RESULT_DATA)
rid = r.json()["record_id"]
r2 = client.get(f"/health/lab-results/{rid}")
assert r2.status_code == 200
assert r2.json()["record_id"] == rid
def test_get_lab_result_not_found(client):
r = client.get(f"/health/lab-results/{uuid.uuid4()}")
assert r.status_code == 404
def test_update_lab_result(client):
r = client.post("/health/lab-results", json=LAB_RESULT_DATA)
rid = r.json()["record_id"]
r2 = client.patch(
f"/health/lab-results/{rid}", json={"notes": "Recheck in 3 months"}
)
assert r2.status_code == 200
assert r2.json()["notes"] == "Recheck in 3 months"
def test_delete_lab_result(client):
r = client.post("/health/lab-results", json=LAB_RESULT_DATA)
rid = r.json()["record_id"]
r2 = client.delete(f"/health/lab-results/{rid}")
assert r2.status_code == 204
r3 = client.get(f"/health/lab-results/{rid}")
assert r3.status_code == 404