Files
Meal-Planner/backend/tests/test_recipe_api.py
T
adminandClaude Opus 4.7 f16a2f8710 feat: recipe CRUD endpoints with canonical ingredient validation
POST/PATCH validate every ingredient_id against the ingredient table
and return 422 with the missing list when refs don't resolve. Replaces
the prior recipes.py stub. Public read routes + admin write routes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-06 06:14:37 -07:00

84 lines
2.6 KiB
Python

import pytest
pytestmark = pytest.mark.requires_postgres
def _admin_headers() -> dict:
return {"Authorization": "Bearer test-admin-token"}
def _new_ingredient(client, name: str) -> str:
r = client.post(
"/api/admin/ingredients",
json={"name": name, "aliases": [], "aisle": "pantry", "unit": "ea"},
headers=_admin_headers(),
)
assert r.status_code == 201, r.text
return r.json()["id"]
def test_create_recipe_with_canonical_ingredients(client):
chicken = _new_ingredient(client, "Test Chicken Thighs Recipe1")
olive_oil = _new_ingredient(client, "Test Olive Oil Recipe1")
body = {
"name": "Test Sheet-Pan Chicken",
"prep_time_minutes": 10,
"cook_time_minutes": 30,
"servings": 4,
"cuisine_tags": ["american"],
"dietary_tags": [],
"protein_type": "chicken",
"calories_per_serving": 520,
"ingredients": [
{"ingredient_id": chicken, "qty": 2.0, "unit": "lb"},
{"ingredient_id": olive_oil, "qty": 2.0, "unit": "tbsp"},
],
"instructions": ["Preheat oven to 425", "Roast 30 min"],
}
r = client.post("/api/admin/recipes", json=body, headers=_admin_headers())
assert r.status_code == 201, r.text
data = r.json()
assert data["id"]
assert len(data["ingredients"]) == 2
def test_create_recipe_rejects_unknown_ingredient_id(client):
body = {
"name": "Test Bogus Recipe",
"prep_time_minutes": 5,
"cook_time_minutes": 5,
"servings": 4,
"cuisine_tags": [],
"dietary_tags": [],
"protein_type": "vegetarian",
"ingredients": [
{"ingredient_id": "00000000-0000-0000-0000-000000000000", "qty": 1, "unit": "ea"}
],
"instructions": ["nope"],
}
r = client.post("/api/admin/recipes", json=body, headers=_admin_headers())
assert r.status_code == 422
def test_list_recipes_returns_seeded_data(client):
chicken = _new_ingredient(client, "Test Chicken Thighs Recipe2")
client.post(
"/api/admin/recipes",
json={
"name": "Test Listable Recipe",
"prep_time_minutes": 5,
"cook_time_minutes": 25,
"servings": 4,
"cuisine_tags": ["american"],
"dietary_tags": [],
"protein_type": "chicken",
"ingredients": [{"ingredient_id": chicken, "qty": 1, "unit": "lb"}],
"instructions": ["cook"],
},
headers=_admin_headers(),
)
r = client.get("/api/recipes")
assert r.status_code == 200
names = {row["name"] for row in r.json()}
assert "Test Listable Recipe" in names