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 data = r.json() assert data["items"] == [] assert data["total"] == 0 assert data["limit"] == 50 assert data["offset"] == 0 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 items = r.json()["items"] assert len(items) == 1 assert items[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 items = r.json()["items"] assert len(items) == 1 assert items[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 assert len(r.json()["items"]) == 1 def test_list_lab_results_search_and_pagination(client): client.post( "/health/lab-results", json={ **LAB_RESULT_DATA, "test_code": "718-7", "test_name_original": "Hemoglobin", }, ) client.post( "/health/lab-results", json={ **LAB_RESULT_DATA, "test_code": "4548-4", "test_name_original": "Hemoglobin A1c", }, ) client.post( "/health/lab-results", json={**LAB_RESULT_DATA, "test_code": "2951-2", "test_name_original": "Sodium"}, ) r = client.get("/health/lab-results?q=hemo&limit=1&offset=1") assert r.status_code == 200 data = r.json() assert data["total"] == 2 assert data["limit"] == 1 assert data["offset"] == 1 assert len(data["items"]) == 1 assert "Hemoglobin" in data["items"][0]["test_name_original"] def test_list_lab_results_sorted_newest_first(client): client.post( "/health/lab-results", json={ **LAB_RESULT_DATA, "collected_at": "2026-01-01T00:00:00", "test_code": "1111-1", }, ) client.post( "/health/lab-results", json={ **LAB_RESULT_DATA, "collected_at": "2026-06-01T00:00:00", "test_code": "2222-2", }, ) r = client.get("/health/lab-results") assert r.status_code == 200 items = r.json()["items"] assert items[0]["collected_at"] == "2026-06-01T00:00:00" def test_list_lab_results_test_code_sorted_numerically_for_same_date(client): client.post( "/health/lab-results", json={ **LAB_RESULT_DATA, "collected_at": "2026-06-01T00:00:00", "test_code": "1111-1", }, ) client.post( "/health/lab-results", json={ **LAB_RESULT_DATA, "collected_at": "2026-06-01T00:00:00", "test_code": "99-9", }, ) client.post( "/health/lab-results", json={ **LAB_RESULT_DATA, "collected_at": "2026-06-01T00:00:00", "test_code": "718-7", }, ) r = client.get("/health/lab-results") assert r.status_code == 200 items = r.json()["items"] assert [items[0]["test_code"], items[1]["test_code"], items[2]["test_code"]] == [ "99-9", "718-7", "1111-1", ] def test_list_lab_results_latest_only_returns_one_per_test_code(client): client.post( "/health/lab-results", json={ **LAB_RESULT_DATA, "test_code": "1742-6", "test_name_original": "ALT", "collected_at": "2026-01-01T00:00:00", "value_num": 30, }, ) client.post( "/health/lab-results", json={ **LAB_RESULT_DATA, "test_code": "1742-6", "test_name_original": "ALT", "collected_at": "2026-02-01T00:00:00", "value_num": 60, }, ) client.post( "/health/lab-results", json={ **LAB_RESULT_DATA, "test_code": "2093-3", "test_name_original": "Cholesterol total", "collected_at": "2026-01-10T00:00:00", "value_num": 200, }, ) r = client.get("/health/lab-results?latest_only=true") assert r.status_code == 200 data = r.json() assert data["total"] == 2 assert len(data["items"]) == 2 alt = next(item for item in data["items"] if item["test_code"] == "1742-6") assert alt["collected_at"] == "2026-02-01T00:00:00" 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_update_lab_result_can_clear_and_switch_value_type(client): r = client.post( "/health/lab-results", json={ **LAB_RESULT_DATA, "value_num": 12.5, "unit_original": "mg/dl", "flag": "H", }, ) rid = r.json()["record_id"] r2 = client.patch( f"/health/lab-results/{rid}", json={ "value_num": None, "value_text": "not detected", "flag": None, "unit_original": None, }, ) assert r2.status_code == 200 data = r2.json() assert data["value_num"] is None assert data["value_text"] == "not detected" assert data["flag"] is None assert data["unit_original"] is None 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