innercontext/backend/tests/test_routines.py
Piotr Oleszczyk 9bf94a979c fix: resolve frontend/backend integration bugs
- Rename skincare route prefix /skin-snapshots → /skincare to match API client
- Add redirect_slashes=False to FastAPI app; change collection routes from "/" to ""
  to eliminate 307 redirects on POST/GET without trailing slash
- Fix redirect() inside try/catch in products/new and routines/new server actions
  (SvelteKit redirect() throws and was being caught as a 500 error)
- Eagerly load inventory and steps relationships via explicit SELECT + model_dump(mode="json"),
  working around SQLModel 0.0.37 not serializing Relationship fields in response_model
- Add field_validator for product_effect_profile to coerce DB-returned dict → ProductEffectProfile,
  eliminating Pydantic serializer warning
- Update all tests to use routes without trailing slash

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 21:53:17 +01:00

219 lines
6.3 KiB
Python

import uuid
# ---------------------------------------------------------------------------
# Routines
# ---------------------------------------------------------------------------
def test_create_routine_minimal(client):
r = client.post(
"/routines", json={"routine_date": "2026-02-26", "part_of_day": "am"}
)
assert r.status_code == 201
data = r.json()
assert "id" in data
assert data["routine_date"] == "2026-02-26"
assert data["part_of_day"] == "am"
def test_create_routine_invalid_part_of_day(client):
r = client.post(
"/routines", json={"routine_date": "2026-02-26", "part_of_day": "noon"}
)
assert r.status_code == 422
def test_list_routines_empty(client):
r = client.get("/routines")
assert r.status_code == 200
assert r.json() == []
def test_list_filter_date_range(client):
client.post("/routines", json={"routine_date": "2026-01-01", "part_of_day": "am"})
client.post("/routines", json={"routine_date": "2026-06-01", "part_of_day": "am"})
r = client.get("/routines?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]["routine_date"] == "2026-06-01"
def test_list_filter_part_of_day(client):
client.post("/routines", json={"routine_date": "2026-02-01", "part_of_day": "am"})
client.post("/routines", json={"routine_date": "2026-02-02", "part_of_day": "pm"})
r = client.get("/routines?part_of_day=pm")
assert r.status_code == 200
data = r.json()
assert len(data) == 1
assert data[0]["part_of_day"] == "pm"
def test_get_routine(client, created_routine):
rid = created_routine["id"]
r = client.get(f"/routines/{rid}")
assert r.status_code == 200
assert r.json()["id"] == rid
def test_get_routine_not_found(client):
r = client.get(f"/routines/{uuid.uuid4()}")
assert r.status_code == 404
def test_update_routine_notes(client, created_routine):
rid = created_routine["id"]
r = client.patch(f"/routines/{rid}", json={"notes": "Felt great today"})
assert r.status_code == 200
assert r.json()["notes"] == "Felt great today"
def test_update_routine_not_found(client):
r = client.patch(f"/routines/{uuid.uuid4()}", json={"notes": "x"})
assert r.status_code == 404
def test_delete_routine(client, created_routine):
rid = created_routine["id"]
r = client.delete(f"/routines/{rid}")
assert r.status_code == 204
r2 = client.get(f"/routines/{rid}")
assert r2.status_code == 404
# ---------------------------------------------------------------------------
# RoutineStep
# ---------------------------------------------------------------------------
def test_add_step_action_only(client, created_routine):
rid = created_routine["id"]
r = client.post(
f"/routines/{rid}/steps",
json={"order_index": 0, "action_notes": "Cleanse face gently"},
)
assert r.status_code == 201
data = r.json()
assert data["order_index"] == 0
assert data["action_notes"] == "Cleanse face gently"
assert data["product_id"] is None
def test_add_step_with_product(client, created_routine, created_product):
rid = created_routine["id"]
pid = created_product["id"]
r = client.post(
f"/routines/{rid}/steps",
json={"order_index": 1, "product_id": pid},
)
assert r.status_code == 201
data = r.json()
assert data["product_id"] == pid
assert data["order_index"] == 1
def test_add_step_routine_not_found(client):
r = client.post(
f"/routines/{uuid.uuid4()}/steps",
json={"order_index": 0},
)
assert r.status_code == 404
def test_update_step(client, created_routine):
rid = created_routine["id"]
r = client.post(
f"/routines/{rid}/steps",
json={"order_index": 0, "action_notes": "Initial"},
)
step_id = r.json()["id"]
r2 = client.patch(f"/routines/steps/{step_id}", json={"action_notes": "Updated"})
assert r2.status_code == 200
assert r2.json()["action_notes"] == "Updated"
def test_update_step_not_found(client):
r = client.patch(f"/routines/steps/{uuid.uuid4()}", json={"action_notes": "x"})
assert r.status_code == 404
def test_delete_step(client, created_routine):
rid = created_routine["id"]
r = client.post(
f"/routines/{rid}/steps",
json={"order_index": 0},
)
step_id = r.json()["id"]
r2 = client.delete(f"/routines/steps/{step_id}")
assert r2.status_code == 204
def test_delete_step_not_found(client):
r = client.delete(f"/routines/steps/{uuid.uuid4()}")
assert r.status_code == 404
# ---------------------------------------------------------------------------
# GroomingSchedule
# ---------------------------------------------------------------------------
def test_list_grooming_schedule_empty(client):
r = client.get("/routines/grooming-schedule")
assert r.status_code == 200
assert r.json() == []
def test_create_grooming_schedule(client):
r = client.post(
"/routines/grooming-schedule",
json={"day_of_week": 1, "action": "shaving_razor"},
)
assert r.status_code == 201
data = r.json()
assert data["day_of_week"] == 1
assert data["action"] == "shaving_razor"
def test_list_grooming_schedule_returns_entry(client):
client.post(
"/routines/grooming-schedule",
json={"day_of_week": 3, "action": "dermarolling"},
)
r = client.get("/routines/grooming-schedule")
assert r.status_code == 200
assert len(r.json()) >= 1
def test_update_grooming_schedule(client):
r = client.post(
"/routines/grooming-schedule",
json={"day_of_week": 0, "action": "shaving_oneblade"},
)
entry_id = r.json()["id"]
r2 = client.patch(
f"/routines/grooming-schedule/{entry_id}",
json={"notes": "Use cold water"},
)
assert r2.status_code == 200
assert r2.json()["notes"] == "Use cold water"
def test_delete_grooming_schedule(client):
r = client.post(
"/routines/grooming-schedule",
json={"day_of_week": 5, "action": "shaving_razor"},
)
entry_id = r.json()["id"]
r2 = client.delete(f"/routines/grooming-schedule/{entry_id}")
assert r2.status_code == 204
def test_delete_grooming_schedule_not_found(client):
r = client.delete(f"/routines/grooming-schedule/{uuid.uuid4()}")
assert r.status_code == 404