| """ |
| Tests for Nutricore FastAPI endpoints |
| """ |
|
|
| import pytest |
| from httpx import AsyncClient, ASGITransport |
| import database |
| import sys, os |
| sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) |
|
|
|
|
| @pytest.fixture |
| async def client(tmp_path): |
| db_path = str(tmp_path / "test.db") |
| database.DB_PATH = db_path |
| database.init_db() |
|
|
| from main import app |
| transport = ASGITransport(app=app) |
| async with AsyncClient(transport=transport, base_url="http://test") as ac: |
| yield ac |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_root(client): |
| r = await client.get("/") |
| assert r.status_code == 200 |
| data = r.json() |
| assert "Nutricore" in data["service"] |
| assert data["status"] == "running" |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_health(client): |
| r = await client.get("/health") |
| assert r.status_code == 200 |
| assert r.json()["status"] == "healthy" |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_get_all_products(client): |
| r = await client.get("/api/products") |
| assert r.status_code == 200 |
| data = r.json() |
| assert "products" in data |
| assert data["total"] == 12 |
| assert len(data["products"]) == 12 |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_get_products_by_category_fruit(client): |
| r = await client.get("/api/products?category=Fruit") |
| assert r.status_code == 200 |
| data = r.json() |
| assert data["total"] == 5 |
| for p in data["products"]: |
| assert "Fruit" in p["category"] |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_get_products_by_category_vegetable(client): |
| r = await client.get("/api/products?category=Vegetable") |
| assert r.status_code == 200 |
| data = r.json() |
| assert data["total"] == 4 |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_get_products_by_category_green(client): |
| r = await client.get("/api/products?category=Green") |
| assert r.status_code == 200 |
| data = r.json() |
| assert data["total"] == 3 |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_get_product_by_id(client): |
| r = await client.get("/api/products/1") |
| assert r.status_code == 200 |
| data = r.json() |
| assert data["id"] == 1 |
| assert data["name"] == "Banana Powder" |
| assert data["price"] == 850 |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_get_product_not_found(client): |
| r = await client.get("/api/products/999") |
| assert r.status_code == 404 |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_get_categories(client): |
| r = await client.get("/api/products/categories") |
| assert r.status_code == 200 |
| data = r.json() |
| assert "categories" in data |
| assert len(data["categories"]) == 3 |
| assert "Fruit Powders" in data["categories"] |
| assert "Vegetable Powders" in data["categories"] |
| assert "Green Leaf Powders" in data["categories"] |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_get_orders_empty(client): |
| r = await client.get("/api/orders") |
| assert r.status_code == 200 |
| data = r.json() |
| assert data["orders"] == [] |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_get_delivery_info(client): |
| r = await client.get("/api/delivery") |
| assert r.status_code == 200 |
| data = r.json() |
| assert "delivery" in data |
| assert "lahore" in data["delivery"] |
| assert "karachi" in data["delivery"] |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_products_have_required_fields(client): |
| r = await client.get("/api/products") |
| data = r.json() |
| required = ["id", "name", "category", "weight", "price", "description", "image"] |
| for p in data["products"]: |
| for field in required: |
| assert field in p, f"Missing field: {field} in product {p.get('name')}" |
|
|
|
|
| @pytest.mark.asyncio |
| async def test_products_prices_in_pkr(client): |
| r = await client.get("/api/products") |
| data = r.json() |
| for p in data["products"]: |
| assert p["price"] >= 400, f"Price too low for {p['name']}" |
| assert p["price"] <= 1500, f"Price too high for {p['name']}" |
|
|