90 lines
3.3 KiB
Python
90 lines
3.3 KiB
Python
from typing import Callable
|
|
import importlib
|
|
import unittest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from db import connect, create
|
|
import main
|
|
import tests.test_data as test_data
|
|
|
|
|
|
def reload_test_data():
|
|
global test_data
|
|
test_data = importlib.reload(test_data)
|
|
|
|
|
|
@unittest.skip("Legacy v1 shopping API removed; see v2 household-scoped tests.")
|
|
class TestShoppingAPI(unittest.IsolatedAsyncioTestCase):
|
|
async def asyncSetUp(self):
|
|
self.conn = await connect(":memory:")
|
|
await create(self.conn)
|
|
await test_data.create_test_data(self.conn)
|
|
reload_test_data()
|
|
|
|
async def override_get_db():
|
|
try:
|
|
yield self.conn
|
|
finally:
|
|
pass
|
|
|
|
main.app.dependency_overrides[main.get_db] = override_get_db
|
|
self.client = TestClient(main.app)
|
|
return await super().asyncSetUp()
|
|
|
|
async def asyncTearDown(self) -> None:
|
|
await self.conn.close()
|
|
main.app.dependency_overrides.clear()
|
|
return await super().asyncTearDown()
|
|
|
|
def test_purchase_unauthorized_without_cookie(self):
|
|
# Do NOT override cookie_person; no cookie provided => 401
|
|
body = {"storeName": "woolworths", "items": []}
|
|
resp = self.client.post("/api/v1/shopping", json=body)
|
|
assert resp.status_code == 401
|
|
assert "application/problem+json" in resp.headers.get("content-type", "")
|
|
prob = resp.json()
|
|
assert prob.get("status") == 401
|
|
assert prob.get("title")
|
|
|
|
def test_purchase_validation_error_returns_problem(self):
|
|
# Override cookie_person to simulate authenticated user
|
|
async def override_cookie_person():
|
|
return test_data.Persons.jacob
|
|
|
|
main.app.dependency_overrides[main.cookie_person] = override_cookie_person
|
|
|
|
# Empty items triggers domain validation error => 400 with Problem Details
|
|
body = {"storeName": "woolworths", "items": []}
|
|
resp = self.client.post("/api/v1/shopping", json=body)
|
|
assert resp.status_code == 400
|
|
assert "application/problem+json" in resp.headers.get("content-type", "")
|
|
prob = resp.json()
|
|
assert prob.get("status") == 400
|
|
assert "items" in prob.get("title", "").lower() or prob.get("title")
|
|
|
|
def test_request_ingredient_scoped(
|
|
self,
|
|
household_and_user: dict,
|
|
auth_headers: dict,
|
|
ingredient_factory: Callable,
|
|
):
|
|
slug = household_and_user["household"]["slug"]
|
|
ingredient = ingredient_factory()
|
|
|
|
# Request an ingredient
|
|
response = self.client.post(
|
|
f"/households/{slug}/shopping/current/ingredients",
|
|
headers=auth_headers,
|
|
json={"ingredientId": ingredient.id},
|
|
)
|
|
assert response.status_code == 200
|
|
requested_item = response.json()
|
|
assert requested_item["ingredientId"] == ingredient.id
|
|
assert requested_item["mealId"] is None
|
|
|
|
# Check that it appears in the outstanding list
|
|
response = self.client.get(f"/households/{slug}/shopping/current", headers=auth_headers)
|
|
assert response.status_code == 200
|
|
current_list = response.json()
|
|
assert len(current_list["outstandingItems"]) == 1
|
|
assert current_list["outstandingItems"][0]["ingredientId"] == ingredient.id
|