"""Mindestbestand, Laden-Kategorien und Rezeptsammlung.""" from app.kategorien import KEYS from test_haushalt import add, items, new_list, state def home(client): return state(client)["lists"][0]["id"] def amounts(data, list_id, name): return {(i["list"], i["unit"]): i["quantity"] for i in items(data, list_id) if i["name"] == name} def set_min(client, list_id, name, minimum, unit="stk"): res = client.put(f"/api/haushalt/listen/{list_id}/mindestbestand", json={"name": name, "unit": unit, "minimum": minimum}) assert res.status_code == 200, res.text return res.json() # ---------- Mindestbestand ---------- def test_mindestbestand_fuellt_einkauf_auf(login): anna = login("anna") lid = home(anna) milch = items(add(anna, lid, "Milch", area="vorrat", quantity=3).json(), lid)[0] data = set_min(anna, lid, "Milch", 2) assert amounts(data, lid, "Milch") == {("vorrat", "stk"): 3} # genug da data = anna.patch(f"/api/haushalt/items/{milch['id']}", json={"quantity": 1}).json() assert amounts(data, lid, "Milch") == {("vorrat", "stk"): 1, ("einkauf", "stk"): 1} data = anna.delete(f"/api/haushalt/items/{milch['id']}").json() # alles weg → auf 2 auffüllen assert amounts(data, lid, "Milch") == {("einkauf", "stk"): 2} assert data["minimums"] == [{"listId": lid, "key": "milch", "name": "Milch", "unit": "stk", "minimum": 2}] def test_mindestbestand_aufgebraucht_und_sofort(login): anna = login("anna") lid = home(anna) mehl = items(add(anna, lid, "Mehl", area="vorrat", quantity=1, unit="kg").json(), lid)[0] set_min(anna, lid, "Mehl", 2.5, unit="kg") # schon darunter → sofort data = state(anna) assert amounts(data, lid, "Mehl") == {("vorrat", "kg"): 1, ("einkauf", "kg"): 1.5} data = anna.post(f"/api/haushalt/items/{mehl['id']}/move").json() # aufgebraucht assert amounts(data, lid, "Mehl") == {("einkauf", "kg"): 2.5} data = set_min(anna, lid, "Mehl", 0, unit="kg") assert data["minimums"] == [] def test_mindestbestand_nur_mit_listenzugriff(login): anna, ben = login("anna"), login("ben") privat = new_list(anna, "Privat", everyone=False) res = ben.put(f"/api/haushalt/listen/{privat}/mindestbestand", json={"name": "x", "unit": "stk", "minimum": 1}) assert res.status_code == 404 # ---------- Kategorien ---------- def test_kategorie_geraten_und_aenderbar(login): anna = login("anna") lid = home(anna) data = add(anna, lid, "Vollmilch").json() assert items(data, lid)[0]["category"] == "kuehl" assert data["productCategories"]["Vollmilch"] == "kuehl" data = anna.put("/api/haushalt/produkte/kategorie", json={"name": "Vollmilch", "category": "getraenke"}).json() assert items(data, lid)[0]["category"] == "getraenke" assert anna.put("/api/haushalt/produkte/kategorie", json={"name": "Vollmilch", "category": "quatsch"}).status_code == 400 def test_kategorie_privater_produkte_nicht_aenderbar(login): anna, ben = login("anna"), login("ben") privat = new_list(anna, "Privat", everyone=False) add(anna, privat, "Geheimzutat") assert ben.put("/api/haushalt/produkte/kategorie", json={"name": "Geheimzutat", "category": "obst"}).status_code == 404 def test_laden_reihenfolge(login): anna = login("anna") lid = home(anna) assert state(anna)["lists"][0]["categoryOrder"] == KEYS order = list(reversed(KEYS)) data = anna.put(f"/api/haushalt/listen/{lid}/reihenfolge", json={"order": order}).json() assert data["lists"][0]["categoryOrder"] == order assert anna.put(f"/api/haushalt/listen/{lid}/reihenfolge", json={"order": KEYS[:3]}).status_code == 400 # ---------- Rezeptsammlung ---------- def save(client, title, lines, source=None): res = client.post("/api/haushalt/rezepte", json={"title": title, "lines": lines, "source": source, "servings": 2}) assert res.status_code == 201, res.text return res.json()["id"] def test_rezepte_nach_vorrat_sortiert(login): anna = login("anna") lid = home(anna) for name in ("Nudeln", "Tomaten"): add(anna, lid, name, area="vorrat") save(anna, "Pasta", ["250 g Nudeln", "3 Tomaten", "1 Prise Salz"]) # Salz zählt nicht save(anna, "Kuchen", ["200 g Mehl", "3 Eier", "100 g Zucker"]) res = anna.get("/api/haushalt/rezepte", params={"listId": lid}).json() assert [(r["title"], r["have"], r["total"]) for r in res] == [("Pasta", 2, 2), ("Kuchen", 0, 3)] assert res[1]["missing"] == ["Mehl", "Eier", "Zucker"] def test_rezept_gleicher_link_wird_aktualisiert(login): anna = login("anna") a = save(anna, "Alt", ["1 Ei"], source="https://example.org/r") b = save(anna, "Neu", ["2 Eier"], source="https://example.org/r") assert a == b detail = anna.get(f"/api/haushalt/rezepte/{a}").json() assert detail["title"] == "Neu" and detail["lines"] == ["2 Eier"] def test_rezept_loeschen_nur_ersteller_oder_admin(login): anna, ben, chef = login("anna"), login("ben"), login("chef", admin=True) a = save(anna, "A", ["1 Ei"]) b = save(anna, "B", ["1 Ei"]) assert ben.delete(f"/api/haushalt/rezepte/{a}").status_code == 403 assert anna.delete(f"/api/haushalt/rezepte/{a}").status_code == 200 assert chef.delete(f"/api/haushalt/rezepte/{b}").status_code == 200 def test_rezept_vorschlag_verraet_keine_privaten_produkte(login): anna, ben = login("anna"), login("ben") privat = new_list(anna, "Privat", everyone=False) add(anna, privat, "Kondome", area="vorrat") save(ben, "Test", ["2 Kondom"]) res = ben.get("/api/haushalt/rezepte", params={"listId": home(ben)}).json() assert res[0]["missing"] == ["Kondom"] # nicht Annas Schreibweise "Kondome"