FastAPI backend for personal health and skincare data with MCP export. Includes SQLModel models for products, inventory, medications, lab results, routines, and skin condition snapshots. Pytest suite with 111 tests running on SQLite in-memory (no PostgreSQL required). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
132 lines
4 KiB
Python
132 lines
4 KiB
Python
import uuid
|
|
|
|
|
|
def test_create_snapshot_minimal(client):
|
|
r = client.post("/skin-snapshots/", json={"snapshot_date": "2026-02-26"})
|
|
assert r.status_code == 201
|
|
data = r.json()
|
|
assert "id" in data
|
|
assert data["snapshot_date"] == "2026-02-26"
|
|
assert data["overall_state"] is None
|
|
|
|
|
|
def test_create_snapshot_full(client):
|
|
r = client.post(
|
|
"/skin-snapshots/",
|
|
json={
|
|
"snapshot_date": "2026-02-20",
|
|
"overall_state": "good",
|
|
"trend": "improving",
|
|
"skin_type": "combination",
|
|
"hydration_level": 3,
|
|
"sebum_tzone": 4,
|
|
"sebum_cheeks": 2,
|
|
"sensitivity_level": 2,
|
|
"barrier_state": "intact",
|
|
"active_concerns": ["acne", "redness"],
|
|
"risks": ["Over-exfoliation"],
|
|
"priorities": ["Maintain barrier"],
|
|
"notes": "Looking better this week",
|
|
},
|
|
)
|
|
assert r.status_code == 201
|
|
data = r.json()
|
|
assert data["overall_state"] == "good"
|
|
assert data["trend"] == "improving"
|
|
assert "acne" in data["active_concerns"]
|
|
assert data["hydration_level"] == 3
|
|
|
|
|
|
def test_create_snapshot_invalid_state(client):
|
|
r = client.post(
|
|
"/skin-snapshots/",
|
|
json={"snapshot_date": "2026-02-26", "overall_state": "stellar"},
|
|
)
|
|
assert r.status_code == 422
|
|
|
|
|
|
def test_list_snapshots_empty(client):
|
|
r = client.get("/skin-snapshots/")
|
|
assert r.status_code == 200
|
|
assert r.json() == []
|
|
|
|
|
|
def test_list_filter_date_range(client):
|
|
client.post("/skin-snapshots/", json={"snapshot_date": "2026-01-01"})
|
|
client.post("/skin-snapshots/", json={"snapshot_date": "2026-06-01"})
|
|
r = client.get("/skin-snapshots/?from_date=2026-05-01&to_date=2026-12-31")
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert len(data) == 1
|
|
assert data[0]["snapshot_date"] == "2026-06-01"
|
|
|
|
|
|
def test_list_filter_overall_state(client):
|
|
client.post(
|
|
"/skin-snapshots/",
|
|
json={"snapshot_date": "2026-02-10", "overall_state": "good"},
|
|
)
|
|
client.post(
|
|
"/skin-snapshots/",
|
|
json={"snapshot_date": "2026-02-11", "overall_state": "poor"},
|
|
)
|
|
r = client.get("/skin-snapshots/?overall_state=poor")
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert len(data) == 1
|
|
assert data[0]["overall_state"] == "poor"
|
|
|
|
|
|
def test_get_snapshot(client):
|
|
r = client.post("/skin-snapshots/", json={"snapshot_date": "2026-02-26"})
|
|
sid = r.json()["id"]
|
|
r2 = client.get(f"/skin-snapshots/{sid}")
|
|
assert r2.status_code == 200
|
|
assert r2.json()["id"] == sid
|
|
|
|
|
|
def test_get_snapshot_not_found(client):
|
|
r = client.get(f"/skin-snapshots/{uuid.uuid4()}")
|
|
assert r.status_code == 404
|
|
|
|
|
|
def test_update_snapshot_state(client):
|
|
r = client.post("/skin-snapshots/", json={"snapshot_date": "2026-02-26"})
|
|
sid = r.json()["id"]
|
|
r2 = client.patch(f"/skin-snapshots/{sid}", json={"overall_state": "excellent"})
|
|
assert r2.status_code == 200
|
|
assert r2.json()["overall_state"] == "excellent"
|
|
|
|
|
|
def test_update_snapshot_concerns(client):
|
|
r = client.post("/skin-snapshots/", json={"snapshot_date": "2026-02-26"})
|
|
sid = r.json()["id"]
|
|
r2 = client.patch(
|
|
f"/skin-snapshots/{sid}",
|
|
json={"active_concerns": ["dehydration", "redness"]},
|
|
)
|
|
assert r2.status_code == 200
|
|
data = r2.json()
|
|
assert "dehydration" in data["active_concerns"]
|
|
assert "redness" in data["active_concerns"]
|
|
|
|
|
|
def test_update_snapshot_not_found(client):
|
|
r = client.patch(
|
|
f"/skin-snapshots/{uuid.uuid4()}", json={"overall_state": "good"}
|
|
)
|
|
assert r.status_code == 404
|
|
|
|
|
|
def test_delete_snapshot(client):
|
|
r = client.post("/skin-snapshots/", json={"snapshot_date": "2026-02-26"})
|
|
sid = r.json()["id"]
|
|
r2 = client.delete(f"/skin-snapshots/{sid}")
|
|
assert r2.status_code == 204
|
|
r3 = client.get(f"/skin-snapshots/{sid}")
|
|
assert r3.status_code == 404
|
|
|
|
|
|
def test_delete_snapshot_not_found(client):
|
|
r = client.delete(f"/skin-snapshots/{uuid.uuid4()}")
|
|
assert r.status_code == 404
|