No duplicates in meal roles
This commit is contained in:
parent
37ae73ef1f
commit
c241b8dd8d
2 changed files with 87 additions and 3 deletions
36
main.py
36
main.py
|
|
@ -152,8 +152,16 @@ async def get_meal(meal_id: int, conn: sqlite3.Connection = Depends(get_db)) ->
|
|||
|
||||
return meal
|
||||
|
||||
@app.post("/meals/")
|
||||
async def create_meal(meal: meals.Meal, conn: sqlite3.Connection = Depends(get_db)) -> meals.Meal:
|
||||
def get_duplicates(items: List[meals.Person]) -> set[str]:
|
||||
seen : set[int] = set()
|
||||
duplicates : set[str] = set()
|
||||
for item in items:
|
||||
if item.id in seen:
|
||||
duplicates.add(item.name)
|
||||
seen.add(item.id)
|
||||
return duplicates
|
||||
|
||||
def validate_meal(meal : meals.Meal) -> JSONResponse | None:
|
||||
if not meal.chefs:
|
||||
return JSONResponse(status_code=400, content={'message': 'Meal must have at least one chef'})
|
||||
|
||||
|
|
@ -165,6 +173,26 @@ async def create_meal(meal: meals.Meal, conn: sqlite3.Connection = Depends(get_d
|
|||
|
||||
if len(meal.recipes) == 0 and len(meal.extra_ingredients) == 0:
|
||||
return JSONResponse(status_code=400, content={'message': 'Meal must have at least one recipe or ingredient'})
|
||||
|
||||
duplicates = get_duplicates(meal.chefs)
|
||||
if duplicates:
|
||||
return JSONResponse(status_code=400, content={'message': f'Duplicate chef: {", ".join(duplicates)}'})
|
||||
|
||||
duplicates = get_duplicates(meal.cleanup)
|
||||
if duplicates:
|
||||
return JSONResponse(status_code=400, content={'message': f'Duplicate cleanup person: {", ".join(duplicates)}'})
|
||||
|
||||
duplicates = get_duplicates(meal.consumers)
|
||||
if duplicates:
|
||||
return JSONResponse(status_code=400, content={'message': f'Duplicate consumer: {", ".join(duplicates)}'})
|
||||
|
||||
return None
|
||||
|
||||
@app.post("/meals/")
|
||||
async def create_meal(meal: meals.Meal, conn: sqlite3.Connection = Depends(get_db)) -> meals.Meal:
|
||||
validation_response = validate_meal(meal)
|
||||
if validation_response:
|
||||
return validation_response
|
||||
|
||||
await meals.insert_meal(conn, meal)
|
||||
await conn.commit()
|
||||
|
|
@ -178,6 +206,10 @@ async def update_meal(meal_id: int, meal: meals.Meal, conn: sqlite3.Connection =
|
|||
existing = await meals.find_meal_by_id(conn, meal_id)
|
||||
if not existing:
|
||||
return JSONResponse(status_code=404, content={'message': 'Meal not found'})
|
||||
|
||||
validation_response = validate_meal(meal)
|
||||
if validation_response:
|
||||
return validation_response
|
||||
|
||||
await meals.update_meal(conn, meal)
|
||||
await conn.commit()
|
||||
|
|
|
|||
54
tests.py
54
tests.py
|
|
@ -1,7 +1,13 @@
|
|||
import unittest
|
||||
import test_data
|
||||
import datetime
|
||||
|
||||
import test_data
|
||||
import importlib
|
||||
|
||||
def reload_test_data():
|
||||
global test_data
|
||||
test_data = importlib.reload(test_data)
|
||||
|
||||
import pathlib
|
||||
from db import connect, create
|
||||
|
||||
|
|
@ -20,6 +26,7 @@ class TestProducts(unittest.IsolatedAsyncioTestCase):
|
|||
async def asyncSetUp(self):
|
||||
self.conn = await connect('./testdb.db')
|
||||
await create(self.conn)
|
||||
reload_test_data()
|
||||
return await super().asyncSetUp()
|
||||
|
||||
async def asyncTearDown(self) -> None:
|
||||
|
|
@ -49,6 +56,8 @@ class TestRecipe(unittest.IsolatedAsyncioTestCase):
|
|||
self.conn = await connect('./testdb.db')
|
||||
await create(self.conn)
|
||||
await test_data.create_persons(self.conn)
|
||||
reload_test_data()
|
||||
|
||||
return await super().asyncSetUp()
|
||||
|
||||
async def asyncTearDown(self) -> None:
|
||||
|
|
@ -113,6 +122,7 @@ class TestMeals(unittest.IsolatedAsyncioTestCase):
|
|||
self.conn = await connect('./testdb.db')
|
||||
await create(self.conn)
|
||||
await test_data.create_persons(self.conn)
|
||||
reload_test_data()
|
||||
return await super().asyncSetUp()
|
||||
|
||||
async def asyncTearDown(self) -> None:
|
||||
|
|
@ -120,6 +130,48 @@ class TestMeals(unittest.IsolatedAsyncioTestCase):
|
|||
pathlib.Path('./testdb.db').unlink(missing_ok=True)
|
||||
return await super().asyncTearDown()
|
||||
|
||||
async def testMultiplePariticpants(self) -> None:
|
||||
meal = test_data.Meals.broccoli_soup_for_jacob
|
||||
recipe = meal.recipes[0]
|
||||
recipe_ingredient = recipe.ingredients[0]
|
||||
recipe_product = recipe_ingredient.product
|
||||
extra_ingredient = meal.extra_ingredients[0]
|
||||
extra_product = extra_ingredient.product
|
||||
|
||||
person = test_data.Persons.jacob
|
||||
|
||||
await products_db.insert_product(self.conn, recipe_product, {})
|
||||
await products_db.insert_product(self.conn, extra_product, {})
|
||||
|
||||
created_recipe = await main.create_recipe(recipe, self.conn, person)
|
||||
recipe.id = created_recipe.id
|
||||
|
||||
meal.chefs = [test_data.Persons.ryan, test_data.Persons.chris, test_data.Persons.ryan]
|
||||
error_response = await main.create_meal(meal, self.conn)
|
||||
self.assertIsNotNone(error_response)
|
||||
self.assertEqual(error_response.status_code, 400)
|
||||
self.assertEqual(error_response.body, b'{"message":"Duplicate chef: Ryan"}')
|
||||
|
||||
|
||||
meal.chefs = [test_data.Persons.ryan, test_data.Persons.chris]
|
||||
meal.consumers = [test_data.Persons.ryan, test_data.Persons.chris, test_data.Persons.ryan]
|
||||
error_response = await main.create_meal(meal, self.conn)
|
||||
self.assertIsNotNone(error_response)
|
||||
self.assertEqual(error_response.status_code, 400)
|
||||
self.assertEqual(error_response.body, b'{"message":"Duplicate consumer: Ryan"}')
|
||||
|
||||
meal.consumers = [test_data.Persons.ryan, test_data.Persons.chris]
|
||||
meal.cleanup = [test_data.Persons.ryan, test_data.Persons.chris, test_data.Persons.ryan]
|
||||
error_response = await main.create_meal(meal, self.conn)
|
||||
self.assertIsNotNone(error_response)
|
||||
self.assertEqual(error_response.status_code, 400)
|
||||
self.assertEqual(error_response.body, b'{"message":"Duplicate cleanup person: Ryan"}')
|
||||
|
||||
meal.cleanup = [test_data.Persons.ryan, test_data.Persons.chris]
|
||||
response = await main.create_meal(meal, self.conn)
|
||||
self.assertIsNotNone(response)
|
||||
self.assertIsInstance(response, meals.Meal, msg=response.body if hasattr(response, 'body') else response)
|
||||
|
||||
async def testCreateAndFind(self) -> None:
|
||||
meal = test_data.Meals.broccoli_soup_for_jacob
|
||||
recipe = meal.recipes[0]
|
||||
|
|
|
|||
Loading…
Reference in a new issue