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:
@@ -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
|
||||
Reference in New Issue
Block a user