feat: POST /api/admin/recipes/resolve-ingredient with rapidfuzz top-3

This commit is contained in:
2026-05-06 06:16:29 -07:00
parent f16a2f8710
commit 489ee03574
2 changed files with 139 additions and 1 deletions
+47
View File
@@ -0,0 +1,47 @@
import pytest
pytestmark = pytest.mark.requires_postgres
def _admin() -> dict:
return {"Authorization": "Bearer test-admin-token"}
def _seed_ingredient(client, name: str, aliases: list[str]) -> str:
r = client.post(
"/api/admin/ingredients",
json={"name": name, "aliases": aliases, "aisle": "pantry", "unit": "ea"},
headers=_admin(),
)
return r.json()["id"]
def test_resolve_ingredient_returns_top_three_candidates(client):
chicken_id = _seed_ingredient(client, "Test Resolve Chicken Thighs", ["chicken thigh resolve"])
breast_id = _seed_ingredient(client, "Test Resolve Chicken Breast", ["chicken breasts resolve"])
pork_id = _seed_ingredient(client, "Test Resolve Pork Chop", ["pork chops resolve"])
r = client.post(
"/api/admin/recipes/resolve-ingredient",
json={"text": "1 lb chicken thigh resolve"},
headers=_admin(),
)
assert r.status_code == 200, r.text
data = r.json()
assert data["parsed_qty"] == 1.0
assert data["parsed_unit"] == "lb"
candidate_ids = [c["ingredient_id"] for c in data["candidates"]]
assert chicken_id in candidate_ids
assert candidate_ids[0] == chicken_id # highest score should be exact match
def test_resolve_ingredient_handles_no_unit(client):
_seed_ingredient(client, "Test Resolve Lemon Special", ["lemons resolve"])
r = client.post(
"/api/admin/recipes/resolve-ingredient",
json={"text": "2 lemons resolve"},
headers=_admin(),
)
data = r.json()
assert data["parsed_qty"] == 2.0
assert data["parsed_unit"] is None