test(shopping): 9 tests d'intégration CRUD listes et articles

Couvre : création liste, listing, ajout article custom, validation (422),
cocher/décocher, suppression, finish avec report des non cochés, 404, stores, recherche produits.
This commit is contained in:
2026-05-24 15:37:15 +02:00
parent 3e4c209417
commit e4c3edc72b
+126
View File
@@ -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