diff --git a/backend/tests/test_shopping.py b/backend/tests/test_shopping.py new file mode 100644 index 0000000..c1d90b3 --- /dev/null +++ b/backend/tests/test_shopping.py @@ -0,0 +1,126 @@ +# backend/tests/test_shopping.py +import pytest +from sqlalchemy import delete +from app.models.shopping import ShoppingList, ListItem + + +@pytest.fixture(autouse=True) +async def cleanup(db_session): + yield + # Supprimer les listes de test (cascade supprime les items) + await db_session.execute( + delete(ShoppingList).where(ShoppingList.name.like("TEST_%")) + ) + # Supprimer les listes sans nom créées par les tests + await db_session.execute( + delete(ShoppingList).where(ShoppingList.name.is_(None), ShoppingList.status == "draft") + ) + await db_session.commit() + + +async def test_creer_liste(client): + resp = await client.post("/api/shopping/lists", json={"name": "TEST_semaine 1"}) + assert resp.status_code == 201 + data = resp.json() + assert data["name"] == "TEST_semaine 1" + assert data["status"] == "draft" + assert data["item_count"] == 0 + assert data["items"] == [] + + +async def test_lister_listes(client): + await client.post("/api/shopping/lists", json={"name": "TEST_liste A"}) + await client.post("/api/shopping/lists", json={"name": "TEST_liste B"}) + + resp = await client.get("/api/shopping/lists") + assert resp.status_code == 200 + noms = [l["name"] for l in resp.json()] + assert "TEST_liste A" in noms + assert "TEST_liste B" in noms + + +async def test_ajouter_article_custom(client): + liste = (await client.post("/api/shopping/lists", json={"name": "TEST_ajout"})).json() + list_id = liste["id"] + + resp = await client.post(f"/api/shopping/lists/{list_id}/items", json={ + "custom_name": "Farine T55", + "quantity": "1.5", + "unit": "kg", + }) + assert resp.status_code == 201 + data = resp.json() + assert data["display_name"] == "Farine T55" + assert data["is_checked"] is False + assert data["carried_over"] is False + + +async def test_ajouter_article_sans_nom_erreur(client): + liste = (await client.post("/api/shopping/lists", json={"name": "TEST_sans nom"})).json() + resp = await client.post(f"/api/shopping/lists/{liste['id']}/items", json={}) + assert resp.status_code == 422 + + +async def test_cocher_article(client): + liste = (await client.post("/api/shopping/lists", json={"name": "TEST_cocher"})).json() + list_id = liste["id"] + item = (await client.post(f"/api/shopping/lists/{list_id}/items", json={"custom_name": "Lait"})).json() + item_id = item["id"] + + resp = await client.patch(f"/api/shopping/lists/{list_id}/items/{item_id}", json={"is_checked": True}) + assert resp.status_code == 200 + assert resp.json()["is_checked"] is True + + +async def test_supprimer_article(client): + liste = (await client.post("/api/shopping/lists", json={"name": "TEST_suppr"})).json() + list_id = liste["id"] + item = (await client.post(f"/api/shopping/lists/{list_id}/items", json={"custom_name": "Beurre"})).json() + item_id = item["id"] + + resp = await client.delete(f"/api/shopping/lists/{list_id}/items/{item_id}") + assert resp.status_code == 204 + + detail = await client.get(f"/api/shopping/lists/{list_id}") + assert all(i["id"] != item_id for i in detail.json()["items"]) + + +async def test_terminer_courses_reporte_non_coches(client): + liste = (await client.post("/api/shopping/lists", json={"name": "TEST_finish"})).json() + list_id = liste["id"] + + await client.post(f"/api/shopping/lists/{list_id}/items", json={"custom_name": "Coché"}) + await client.post(f"/api/shopping/lists/{list_id}/items", json={"custom_name": "Non coché"}) + + # Cocher le premier article + items = (await client.get(f"/api/shopping/lists/{list_id}")).json()["items"] + coche_id = next(i["id"] for i in items if i["display_name"] == "Coché") + await client.patch(f"/api/shopping/lists/{list_id}/items/{coche_id}", json={"is_checked": True}) + + resp = await client.post(f"/api/shopping/lists/{list_id}/finish") + assert resp.status_code == 200 + assert resp.json()["status"] == "done" + + # Vérifier que la nouvelle liste draft a été créée avec l'article non coché + all_lists = (await client.get("/api/shopping/lists")).json() + new_drafts = [l for l in all_lists if l["status"] == "draft"] + assert len(new_drafts) >= 1 + + +async def test_detail_liste_404(client): + resp = await client.get("/api/shopping/lists/00000000-0000-0000-0000-000000000000") + assert resp.status_code == 404 + + +async def test_lister_stores(client): + resp = await client.get("/api/shopping/stores") + assert resp.status_code == 200 + assert isinstance(resp.json(), list) + + +async def test_rechercher_produits(client): + resp = await client.get("/api/shopping/products?q=lait&limit=5") + assert resp.status_code == 200 + data = resp.json() + assert isinstance(data, list) + assert len(data) <= 5