Add pytest test suite for Shopping List API\n\nTest coverage:\n- Root endpoint\n- Product CRUD\n- List CRUD\n- List items flow (add, update, delete, cascade)\n\nUse: pytest test_main.py\n\nOperation: shopping-list-api-2026-04-05\nWI3: Testing and validation
This commit is contained in:
132
test_main.py
Normal file
132
test_main.py
Normal file
@@ -0,0 +1,132 @@
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
from main import app, init_db
|
||||
import sqlite3
|
||||
import os
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
def setup_module(module):
|
||||
# Use an in-memory database for tests
|
||||
os.environ["DB_PATH"] = ":memory:"
|
||||
init_db()
|
||||
|
||||
def test_root():
|
||||
r = client.get("/")
|
||||
assert r.status_code == 200
|
||||
assert r.json() == {"message": "Shopping List API"}
|
||||
|
||||
def test_product_crud():
|
||||
# Create
|
||||
r = client.post("/products", json={"name": "Paper Plates", "sku": "PP-001"})
|
||||
assert r.status_code == 201
|
||||
product = r.json()
|
||||
assert product["name"] == "Paper Plates"
|
||||
assert product["sku"] == "PP-001"
|
||||
product_id = product["id"]
|
||||
|
||||
# List
|
||||
r = client.get("/products")
|
||||
assert r.status_code == 200
|
||||
assert len(r.json()) >= 1
|
||||
assert any(p["id"] == product_id for p in r.json())
|
||||
|
||||
# Get
|
||||
r = client.get(f"/products/{product_id}")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["id"] == product_id
|
||||
|
||||
# Delete
|
||||
r = client.delete(f"/products/{product_id}")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["deleted"] == product_id
|
||||
|
||||
# Get deleted -> 404
|
||||
r = client.get(f"/products/{product_id}")
|
||||
assert r.status_code == 404
|
||||
|
||||
def test_list_crud():
|
||||
# Create
|
||||
r = client.post("/lists", json={"name": "Picnic List"})
|
||||
assert r.status_code == 201
|
||||
lst = r.json()
|
||||
assert lst["name"] == "Picnic List"
|
||||
list_id = lst["id"]
|
||||
|
||||
# List
|
||||
r = client.get("/lists")
|
||||
assert r.status_code == 200
|
||||
assert any(l["id"] == list_id for l in r.json())
|
||||
|
||||
# Get empty items
|
||||
r = client.get(f"/lists/{list_id}")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["items"] == []
|
||||
|
||||
# Delete
|
||||
r = client.delete(f"/lists/{list_id}")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["deleted"] == list_id
|
||||
|
||||
def test_list_items_flow():
|
||||
# Create two products
|
||||
r1 = client.post("/products", json={"name": "Paper Plates"})
|
||||
r2 = client.post("/products", json={"name": "Bread"})
|
||||
p1 = r1.json()
|
||||
p2 = r2.json()
|
||||
p1_id, p2_id = p1["id"], p2["id"]
|
||||
|
||||
# Create a list
|
||||
r = client.post("/lists", json={"name": "Picnic List"})
|
||||
lst = r.json()
|
||||
list_id = lst["id"]
|
||||
|
||||
# Add items
|
||||
r = client.post(f"/lists/{list_id}/items", json={"product_id": p1_id, "quantity": 2})
|
||||
assert r.status_code == 201
|
||||
item1 = r.json()
|
||||
assert item1["product_id"] == p1_id
|
||||
assert item1["quantity"] == 2
|
||||
|
||||
r = client.post(f"/lists/{list_id}/items", json={"product_id": p2_id, "quantity": 1})
|
||||
item2 = r.json()
|
||||
assert r.status_code == 201
|
||||
assert item2["product_id"] == p2_id
|
||||
assert item2["quantity"] == 1
|
||||
|
||||
# List items
|
||||
r = client.get(f"/lists/{list_id}/items")
|
||||
assert r.status_code == 200
|
||||
items = r.json()
|
||||
assert len(items) == 2
|
||||
qty_by_prod = {i["product_id"]: i["quantity"] for i in items}
|
||||
assert qty_by_prod[p1_id] == 2
|
||||
assert qty_by_prod[p2_id] == 1
|
||||
|
||||
# Get list with items
|
||||
r = client.get(f"/lists/{list_id}")
|
||||
assert r.status_code == 200
|
||||
data = r.json()
|
||||
assert len(data["items"]) == 2
|
||||
assert any(i["product_name"] == "Paper Plates" for i in data["items"])
|
||||
|
||||
# Update quantity
|
||||
r = client.patch(f"/lists/{list_id}/items/{item1['id']}", json={"quantity": 5})
|
||||
assert r.status_code == 200
|
||||
assert r.json()["quantity"] == 5
|
||||
|
||||
# Delete item
|
||||
r = client.delete(f"/lists/{list_id}/items/{item2['id']}")
|
||||
assert r.status_code == 200
|
||||
|
||||
# Verify item2 gone
|
||||
r = client.get(f"/lists/{list_id}/items")
|
||||
assert r.status_code == 200
|
||||
assert len(r.json()) == 1
|
||||
|
||||
# Delete list cascades items
|
||||
r = client.delete(f"/lists/{list_id}")
|
||||
assert r.status_code == 200
|
||||
|
||||
r = client.get(f"/lists/{list_id}")
|
||||
assert r.status_code == 404
|
||||
Reference in New Issue
Block a user