Turns out zero is a valid id
This commit is contained in:
parent
6d7a8fb7b8
commit
e0b643bfec
10 changed files with 148 additions and 53 deletions
|
|
@ -5,7 +5,7 @@ from typing import AsyncIterator, List, ClassVar, Optional
|
||||||
|
|
||||||
class Ingredient(BaseModel):
|
class Ingredient(BaseModel):
|
||||||
KEYS: ClassVar[List[str]] = ['id', 'name', 'line', 'preparation', 'unit', 'quantity', 'product_id', 'recipe_id', 'meal_id']
|
KEYS: ClassVar[List[str]] = ['id', 'name', 'line', 'preparation', 'unit', 'quantity', 'product_id', 'recipe_id', 'meal_id']
|
||||||
id: int
|
id: int = -1
|
||||||
name: str
|
name: str
|
||||||
line: str
|
line: str
|
||||||
unit: str
|
unit: str
|
||||||
|
|
@ -34,10 +34,10 @@ async def create(conn):
|
||||||
);''')
|
);''')
|
||||||
|
|
||||||
async def insert_ingredient(conn, ingredient: Ingredient):
|
async def insert_ingredient(conn, ingredient: Ingredient):
|
||||||
if not ingredient.product_id and ingredient.product:
|
if ingredient.product:
|
||||||
ingredient.product_id = ingredient.product.id
|
ingredient.product_id = ingredient.product.id
|
||||||
|
|
||||||
if not ingredient.product_id:
|
if ingredient.product_id < 0:
|
||||||
raise ValueError('Product must be inserted before ingredient')
|
raise ValueError('Product must be inserted before ingredient')
|
||||||
|
|
||||||
async with conn.execute('''
|
async with conn.execute('''
|
||||||
|
|
|
||||||
43
main.py
43
main.py
|
|
@ -95,29 +95,29 @@ async def get_recipe(recipe_id: int, conn: sqlite3.Connection = Depends(get_db))
|
||||||
return r
|
return r
|
||||||
|
|
||||||
@app.post('/recipes/')
|
@app.post('/recipes/')
|
||||||
async def create_recipe(item: recipes.Recipe, conn: sqlite3.Connection = Depends(get_db), user: persons.Person = Depends(cookie_person)) -> recipes.Recipe:
|
async def create_recipe(recipe: recipes.Recipe, conn: sqlite3.Connection = Depends(get_db), user: persons.Person = Depends(cookie_person)) -> recipes.Recipe:
|
||||||
if not item.ingredients:
|
if not recipe.ingredients:
|
||||||
return JSONResponse(status_code=400, content={'message': 'Recipe must have at least one ingredient'})
|
return JSONResponse(status_code=400, content={'message': 'Recipe must have at least one ingredient'})
|
||||||
|
|
||||||
for ingredient in item.ingredients:
|
for ingredient in recipe.ingredients:
|
||||||
if not ingredient.product:
|
if not ingredient.product:
|
||||||
return JSONResponse(status_code=400, content={'message': 'Ingredient must have a product'})
|
return JSONResponse(status_code=400, content={'message': 'Ingredient must have a product'})
|
||||||
|
|
||||||
if item.id:
|
if recipe.id >= 0:
|
||||||
await recipes.hide_recipe(conn, item.id, user)
|
await recipes.hide_recipe(conn, recipe.id, user)
|
||||||
item.based_on_recipe = item.id
|
recipe.based_on_recipe = recipe.id
|
||||||
item.id = 0
|
recipe.id = 0
|
||||||
|
|
||||||
item.created_by_id = user.id
|
recipe.created_by_id = user.id
|
||||||
await recipes.insert_recipe(conn, item)
|
await recipes.insert_recipe(conn, recipe)
|
||||||
for ingredient in item.ingredients:
|
for ingredient in recipe.ingredients:
|
||||||
ingredient.recipe_id = item.id
|
ingredient.recipe_id = recipe.id
|
||||||
ingredient.product_id = ingredient.product.id
|
ingredient.product_id = ingredient.product.id
|
||||||
await ingredients.insert_ingredient(conn, ingredient)
|
await ingredients.insert_ingredient(conn, ingredient)
|
||||||
|
|
||||||
await conn.commit()
|
await conn.commit()
|
||||||
|
|
||||||
return item
|
return recipe
|
||||||
|
|
||||||
@app.delete('/recipes/{recipe_id}')
|
@app.delete('/recipes/{recipe_id}')
|
||||||
async def delete_recipe(recipe_id: int, conn: sqlite3.Connection = Depends(get_db), user: persons.Person = Depends(cookie_person)) -> recipes.Recipe:
|
async def delete_recipe(recipe_id: int, conn: sqlite3.Connection = Depends(get_db), user: persons.Person = Depends(cookie_person)) -> recipes.Recipe:
|
||||||
|
|
@ -224,14 +224,25 @@ async def delete_meal(meal_id: int, conn: sqlite3.Connection = Depends(get_db))
|
||||||
|
|
||||||
@app.get("/shopping/{list_id}")
|
@app.get("/shopping/{list_id}")
|
||||||
async def get_shopping_list(list_id: Union[int, str], conn: sqlite3.Connection = Depends(get_db)) -> shopping.ShoppingList:
|
async def get_shopping_list(list_id: Union[int, str], conn: sqlite3.Connection = Depends(get_db)) -> shopping.ShoppingList:
|
||||||
if isinstance(list_id, str):
|
if list_id.lower() == 'current':
|
||||||
if list_id.lower() != 'current':
|
|
||||||
return JSONResponse(status_code=400, content={'message': 'Invalid shopping list ID'})
|
|
||||||
|
|
||||||
return await shopping.current_shopping_list(conn)
|
return await shopping.current_shopping_list(conn)
|
||||||
|
|
||||||
|
try:
|
||||||
|
list_id = int(list_id)
|
||||||
|
except ValueError:
|
||||||
|
return JSONResponse(status_code=400, content={'message': 'Invalid shopping list ID'})
|
||||||
|
|
||||||
return await shopping.load_shopping_list(conn, list_id)
|
return await shopping.load_shopping_list(conn, list_id)
|
||||||
|
|
||||||
|
@app.post("/shopping/current/purchased")
|
||||||
|
async def mark_purchased(conn: sqlite3.Connection = Depends(get_db), person: persons.Person = Depends(cookie_person)) -> shopping.ShoppingList:
|
||||||
|
response = await shopping.mark_purchased(conn)
|
||||||
|
|
||||||
|
# Its easier to make the next shopping list now, while we know calling it requires commit()
|
||||||
|
await shopping.current_shopping_list(conn)
|
||||||
|
await conn.commit()
|
||||||
|
return response
|
||||||
|
|
||||||
class FoundResult(BaseModel):
|
class FoundResult(BaseModel):
|
||||||
created: List[shopping.ShoppingListResult] = []
|
created: List[shopping.ShoppingListResult] = []
|
||||||
removed: List[shopping.ShoppingListResult] = []
|
removed: List[shopping.ShoppingListResult] = []
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import datetime
|
||||||
|
|
||||||
class Meal(BaseModel):
|
class Meal(BaseModel):
|
||||||
KEYS: ClassVar[List[str]] = ['id', 'meal_date']
|
KEYS: ClassVar[List[str]] = ['id', 'meal_date']
|
||||||
id: int
|
id: int = -1
|
||||||
meal_date: datetime.datetime
|
meal_date: datetime.datetime
|
||||||
|
|
||||||
chefs: List[Person] = []
|
chefs: List[Person] = []
|
||||||
|
|
@ -60,7 +60,7 @@ async def sync_meal_participants(conn, meal_id: int, participants: List[Person],
|
||||||
await insert_meal_participant(conn, meal_id, person.id, role)
|
await insert_meal_participant(conn, meal_id, person.id, role)
|
||||||
|
|
||||||
async def insert_meal_recipe(conn, meal_id: int, recipe_id: int):
|
async def insert_meal_recipe(conn, meal_id: int, recipe_id: int):
|
||||||
if not recipe_id:
|
if recipe_id < 0:
|
||||||
raise ValueError('Recipe must be inserted before meal')
|
raise ValueError('Recipe must be inserted before meal')
|
||||||
|
|
||||||
await conn.execute('''
|
await conn.execute('''
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ from typing import AsyncIterator, ClassVar, List
|
||||||
class Person(BaseModel):
|
class Person(BaseModel):
|
||||||
KEYS: ClassVar[List[str]] = ['id', 'name']
|
KEYS: ClassVar[List[str]] = ['id', 'name']
|
||||||
|
|
||||||
id: int
|
id: int = -1
|
||||||
name: str
|
name: str
|
||||||
|
|
||||||
async def create(conn):
|
async def create(conn):
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ def get_package_size(data: dict) -> str:
|
||||||
|
|
||||||
async def create_product(link: str) -> Product:
|
async def create_product(link: str) -> Product:
|
||||||
product_id = get_product_id(link)
|
product_id = get_product_id(link)
|
||||||
if not product_id:
|
if product_id < 0:
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
product_url = get_product_details_url(product_id)
|
product_url = get_product_details_url(product_id)
|
||||||
|
|
@ -55,7 +55,7 @@ async def add_missing_tags(conn, product: Product, tags: List[str]):
|
||||||
|
|
||||||
async def get_or_create(conn, url: str, tags: List[str]) -> Product:
|
async def get_or_create(conn, url: str, tags: List[str]) -> Product:
|
||||||
product_id = get_product_id(url)
|
product_id = get_product_id(url)
|
||||||
if not product_id:
|
if product_id < 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
existing = await find_product_by_product_id(conn, product_id)
|
existing = await find_product_by_product_id(conn, product_id)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ class Product(BaseModel):
|
||||||
KEYS: ClassVar[List[str]] = ['id', 'product_id', 'link', 'name', 'quantity', 'unit', 'img_small', 'img_large']
|
KEYS: ClassVar[List[str]] = ['id', 'product_id', 'link', 'name', 'quantity', 'unit', 'img_small', 'img_large']
|
||||||
NON_INSERT_KEYS: ClassVar[List[str]] = ['id']
|
NON_INSERT_KEYS: ClassVar[List[str]] = ['id']
|
||||||
|
|
||||||
id: int
|
id: int = -1
|
||||||
product_id: str
|
product_id: str
|
||||||
link: str
|
link: str
|
||||||
name: str
|
name: str
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ class Recipe(BaseModel):
|
||||||
KEYS: ClassVar[List[str]] = ['id', 'name', 'link', 'serves', 'image_urls', 'based_on_recipe', 'created_by_id', 'date_created', 'hidden_by_id', 'date_hidden']
|
KEYS: ClassVar[List[str]] = ['id', 'name', 'link', 'serves', 'image_urls', 'based_on_recipe', 'created_by_id', 'date_created', 'hidden_by_id', 'date_hidden']
|
||||||
NON_INSERT_KEYS: ClassVar[List[str]] = ['id', 'created_date', 'hidden_by_id', 'date_hidden']
|
NON_INSERT_KEYS: ClassVar[List[str]] = ['id', 'created_date', 'hidden_by_id', 'date_hidden']
|
||||||
|
|
||||||
id: int
|
id: int = -1
|
||||||
name: str
|
name: str
|
||||||
link: str
|
link: str
|
||||||
serves: int
|
serves: int
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
from shopping.db import ShoppingList, ShoppingListRequest, ShoppingListResult, current_shopping_list, mark_found, unmark_found, sync_persons_requested_ingredients, load_shopping_list, get_persons_requests, request_meal, delete_requests
|
from shopping.db import ShoppingList, ShoppingListRequest, ShoppingListResult, current_shopping_list, mark_found, unmark_found, sync_persons_requested_ingredients, load_shopping_list, get_persons_requests, request_meal, delete_requests, mark_purchased
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ from datetime import datetime, timedelta
|
||||||
|
|
||||||
class ShoppingListRequest(BaseModel):
|
class ShoppingListRequest(BaseModel):
|
||||||
KEYS: ClassVar[List[str]] = ['id', 'ingredient_id', 'list_id', 'person_id', 'meal_id', 'created_date']
|
KEYS: ClassVar[List[str]] = ['id', 'ingredient_id', 'list_id', 'person_id', 'meal_id', 'created_date']
|
||||||
id: int = 0
|
id: int = -1
|
||||||
list_id: int
|
list_id: int
|
||||||
|
|
||||||
ingredient_id: Optional[int] = None
|
ingredient_id: Optional[int] = None
|
||||||
|
|
@ -26,7 +26,7 @@ class ShoppingListRequest(BaseModel):
|
||||||
|
|
||||||
class ShoppingListResult(BaseModel):
|
class ShoppingListResult(BaseModel):
|
||||||
KEYS: ClassVar[List[str]] = ['id', 'product_id', 'list_id', 'quantity', 'unit', 'created_date', 'found_date']
|
KEYS: ClassVar[List[str]] = ['id', 'product_id', 'list_id', 'quantity', 'unit', 'created_date', 'found_date']
|
||||||
id: int = 0
|
id: int = -1
|
||||||
list_id: int
|
list_id: int
|
||||||
product_id: int
|
product_id: int
|
||||||
product: Optional[Product] = None
|
product: Optional[Product] = None
|
||||||
|
|
@ -39,7 +39,7 @@ class ShoppingListResult(BaseModel):
|
||||||
|
|
||||||
class ShoppingList(BaseModel):
|
class ShoppingList(BaseModel):
|
||||||
KEYS: ClassVar[List[str]] = ['id', 'created_date', 'purchased_date']
|
KEYS: ClassVar[List[str]] = ['id', 'created_date', 'purchased_date']
|
||||||
id: int = 0
|
id: int = -1
|
||||||
created_date: datetime = datetime.now()
|
created_date: datetime = datetime.now()
|
||||||
purchased_date: Optional[datetime] = None
|
purchased_date: Optional[datetime] = None
|
||||||
|
|
||||||
|
|
@ -75,35 +75,64 @@ async def create(conn):
|
||||||
list_id INTEGER,
|
list_id INTEGER,
|
||||||
quantity REAL,
|
quantity REAL,
|
||||||
unit TEXT,
|
unit TEXT,
|
||||||
created_date TEXT,
|
created_date TEXT DEFAULT CURRENT_TIMESTAMP,
|
||||||
found_date TEXT,
|
found_date TEXT,
|
||||||
FOREIGN KEY(product_id) REFERENCES Product(id),
|
FOREIGN KEY(product_id) REFERENCES Product(id),
|
||||||
FOREIGN KEY(list_id) REFERENCES ShoppingList(id)
|
FOREIGN KEY(list_id) REFERENCES ShoppingList(id)
|
||||||
);''')
|
);''')
|
||||||
|
|
||||||
|
def validate_request(request: ShoppingListRequest) -> None:
|
||||||
|
# A request must always have a list id
|
||||||
|
if request.list_id < 0:
|
||||||
|
raise ValueError('Request must have a list id')
|
||||||
|
|
||||||
|
# A request must have either an ingredient or a meal, but not both
|
||||||
|
if not request.ingredient and not request.meal:
|
||||||
|
raise ValueError('Request must have either an ingredient or a meal')
|
||||||
|
|
||||||
|
if request.ingredient and request.meal:
|
||||||
|
raise ValueError('Request cannot have both an ingredient and a meal')
|
||||||
|
|
||||||
|
# If an ingredient is provided, it must have a person
|
||||||
|
if request.ingredient and not request.person:
|
||||||
|
raise ValueError('Ingredient requests must have a person')
|
||||||
|
|
||||||
async def insert_shopping_list(conn, shopping_list: ShoppingList):
|
async def insert_shopping_list(conn, shopping_list: ShoppingList):
|
||||||
async with conn.execute('''
|
async with conn.execute('''
|
||||||
INSERT INTO ShoppingList (id, created_date, purchased_date)
|
INSERT INTO ShoppingList (created_date, purchased_date)
|
||||||
VALUES (?, ?, ?)
|
VALUES (CURRENT_TIMESTAMP, NULL)
|
||||||
''', (shopping_list.id, shopping_list.created_date, shopping_list.purchased_date)) as cursor:
|
''') as cursor:
|
||||||
shopping_list.id = cursor.lastrowid
|
shopping_list.id = cursor.lastrowid
|
||||||
|
|
||||||
for request in shopping_list.requests:
|
for request in shopping_list.requests:
|
||||||
if not request.ingredient_id:
|
request.list_id = shopping_list.id
|
||||||
|
|
||||||
|
validate_request(request)
|
||||||
|
|
||||||
|
if request.ingredient and request.ingredient.id < 0:
|
||||||
await insert_ingredient(conn, request.ingredient)
|
await insert_ingredient(conn, request.ingredient)
|
||||||
|
|
||||||
request.ingredient_id = request.ingredient.id
|
if request.ingredient:
|
||||||
await conn.execute('''
|
request.ingredient_id = request.ingredient.id
|
||||||
INSERT INTO ShoppingListRequest (id, ingredient_id, list_id, person_id, meal_id, created_date)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
if request.meal:
|
||||||
''', (request.id, request.ingredient_id, shopping_list.id, request.person_id, request.meal_id, request.created_date))
|
request.meal_id = request.meal.id
|
||||||
|
|
||||||
|
async with conn.execute('''
|
||||||
|
INSERT INTO ShoppingListRequest (ingredient_id, list_id, person_id, meal_id, created_date)
|
||||||
|
VALUES (?, ?, ?, ?, ?)
|
||||||
|
''', (request.ingredient_id, shopping_list.id, request.person_id, request.meal_id, request.created_date)) as cursor:
|
||||||
|
request.id = cursor.lastrowid
|
||||||
|
|
||||||
for item in shopping_list.results:
|
for item in shopping_list.results:
|
||||||
item.product_id = item.product.id
|
item.product_id = item.product.id
|
||||||
await conn.execute('''
|
item.list_id = shopping_list.id
|
||||||
INSERT INTO ShoppingListResult (id, product_id, list_id, quantity, unit, created_date, found_date)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
async with conn.execute('''
|
||||||
''', (item.id, item.product_id, shopping_list.id, item.quantity, item.unit, item.created_date, item.found_date))
|
INSERT INTO ShoppingListResult (product_id, list_id, quantity, unit, created_date, found_date)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?)
|
||||||
|
''', (item.product_id, item.list_id, item.quantity, item.unit, item.created_date, item.found_date)) as cursor:
|
||||||
|
item.id = cursor.lastrowid
|
||||||
|
|
||||||
async def find_request(conn, id: int) -> Optional[ShoppingListRequest]:
|
async def find_request(conn, id: int) -> Optional[ShoppingListRequest]:
|
||||||
# Join Ingredient and Product to also load ingredient and product
|
# Join Ingredient and Product to also load ingredient and product
|
||||||
|
|
@ -133,7 +162,7 @@ async def find_request(conn, id: int) -> Optional[ShoppingListRequest]:
|
||||||
request_keys = {k:v for k,v in zip(ShoppingListRequest.KEYS, row[len(Product.KEYS) + len(Ingredient.KEYS):-len(Person.KEYS)])}
|
request_keys = {k:v for k,v in zip(ShoppingListRequest.KEYS, row[len(Product.KEYS) + len(Ingredient.KEYS):-len(Person.KEYS)])}
|
||||||
request = ShoppingListRequest(**request_keys, ingredient=ingredient, person=person)
|
request = ShoppingListRequest(**request_keys, ingredient=ingredient, person=person)
|
||||||
|
|
||||||
if request.meal_id:
|
if request.meal_id is not None:
|
||||||
request.meal = await find_meal_by_id(conn, request.meal_id)
|
request.meal = await find_meal_by_id(conn, request.meal_id)
|
||||||
|
|
||||||
return request
|
return request
|
||||||
|
|
@ -167,7 +196,7 @@ async def find_requests_by_list_id(conn, list_id: int) -> AsyncIterator[Shopping
|
||||||
request_keys = {k:v for k,v in zip(ShoppingListRequest.KEYS, row[len(Ingredient.KEYS) + len(Product.KEYS):-len(Person.KEYS)])}
|
request_keys = {k:v for k,v in zip(ShoppingListRequest.KEYS, row[len(Ingredient.KEYS) + len(Product.KEYS):-len(Person.KEYS)])}
|
||||||
request = ShoppingListRequest(**request_keys, ingredient=ingredient, person=person)
|
request = ShoppingListRequest(**request_keys, ingredient=ingredient, person=person)
|
||||||
|
|
||||||
if request.meal_id:
|
if request.meal_id is not None:
|
||||||
request.meal = await find_meal_by_id(conn, request.meal_id)
|
request.meal = await find_meal_by_id(conn, request.meal_id)
|
||||||
|
|
||||||
yield request
|
yield request
|
||||||
|
|
@ -235,7 +264,7 @@ async def current_shopping_list(conn) -> ShoppingList:
|
||||||
shopping_list = ShoppingList()
|
shopping_list = ShoppingList()
|
||||||
|
|
||||||
async for meal in _upcoming_meals(conn):
|
async for meal in _upcoming_meals(conn):
|
||||||
shopping_list.requests.append(ShoppingListRequest(list_id=shopping_list.id, meal_id=meal.id, created_date=datetime.now(),))
|
shopping_list.requests.append(ShoppingListRequest(list_id=shopping_list.id, meal_id=meal.id, meal=meal, created_date=datetime.now(),))
|
||||||
|
|
||||||
await insert_shopping_list(conn, shopping_list)
|
await insert_shopping_list(conn, shopping_list)
|
||||||
|
|
||||||
|
|
@ -356,4 +385,16 @@ async def unmark_found(conn, product_id: int) -> List[ShoppingListRequest]:
|
||||||
|
|
||||||
deleted = [r for r in shopping_list.results if r.product_id == product_id]
|
deleted = [r for r in shopping_list.results if r.product_id == product_id]
|
||||||
shopping_list.results = [r for r in shopping_list.results if r.product_id != product_id]
|
shopping_list.results = [r for r in shopping_list.results if r.product_id != product_id]
|
||||||
return deleted
|
return deleted
|
||||||
|
|
||||||
|
async def mark_purchased(conn) -> ShoppingList:
|
||||||
|
shopping_list = await current_shopping_list(conn)
|
||||||
|
shopping_list.purchased_date = datetime.now()
|
||||||
|
|
||||||
|
await conn.execute('''
|
||||||
|
UPDATE ShoppingList
|
||||||
|
SET purchased_date = ?
|
||||||
|
WHERE id = ?
|
||||||
|
''', (shopping_list.purchased_date, shopping_list.id))
|
||||||
|
|
||||||
|
return shopping_list
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
from datetime import datetime
|
from datetime import datetime, timedelta
|
||||||
import importlib
|
import importlib
|
||||||
import unittest
|
import unittest
|
||||||
import tests.test_data as test_data
|
import tests.test_data as test_data
|
||||||
|
|
@ -34,6 +34,28 @@ class TestShopping(unittest.IsolatedAsyncioTestCase):
|
||||||
self.assertEqual(len(shopping_list.requests), 0)
|
self.assertEqual(len(shopping_list.requests), 0)
|
||||||
self.assertEqual(len(shopping_list.results), 0)
|
self.assertEqual(len(shopping_list.results), 0)
|
||||||
|
|
||||||
|
async def test_get_current_adds_upcoming_meals(self):
|
||||||
|
import meals, recipes
|
||||||
|
|
||||||
|
meal = test_data.Meals.broccoli_soup_for_jacob
|
||||||
|
for product in [i.product for i in meal.extra_ingredients] + [i.product for r in meal.recipes for i in r.ingredients]:
|
||||||
|
if product.id < 0:
|
||||||
|
await products.insert_product(self.conn, product, {})
|
||||||
|
|
||||||
|
for recipe in meal.recipes:
|
||||||
|
await recipes.insert_recipe(self.conn, recipe)
|
||||||
|
|
||||||
|
meal.meal_date = datetime.now() + timedelta(days=1)
|
||||||
|
await meals.insert_meal(self.conn, meal)
|
||||||
|
|
||||||
|
shopping_list = await shopping.current_shopping_list(self.conn)
|
||||||
|
self.assertEqual(len(shopping_list.requests), 1)
|
||||||
|
self.assertEqual(len(shopping_list.results), 0)
|
||||||
|
|
||||||
|
request = shopping_list.requests[0]
|
||||||
|
self.assertEqual(request.meal_id, meal.id)
|
||||||
|
|
||||||
|
|
||||||
async def test_sync_persons_requests(self):
|
async def test_sync_persons_requests(self):
|
||||||
ingredient = test_data.Ingredients.one_apple
|
ingredient = test_data.Ingredients.one_apple
|
||||||
person = test_data.Persons.jacob
|
person = test_data.Persons.jacob
|
||||||
|
|
@ -41,7 +63,8 @@ class TestShopping(unittest.IsolatedAsyncioTestCase):
|
||||||
await products.insert_product(self.conn, ingredient.product, {})
|
await products.insert_product(self.conn, ingredient.product, {})
|
||||||
|
|
||||||
shopping_list = await shopping.current_shopping_list(self.conn)
|
shopping_list = await shopping.current_shopping_list(self.conn)
|
||||||
await shopping.sync_persons_requested_ingredients(self.conn, shopping_list, person, [ingredient])
|
async for _ in shopping.sync_persons_requested_ingredients(self.conn, shopping_list, person, [ingredient]):
|
||||||
|
pass
|
||||||
|
|
||||||
shopping_list = await shopping.current_shopping_list(self.conn)
|
shopping_list = await shopping.current_shopping_list(self.conn)
|
||||||
self.assertEqual(len(shopping_list.requests), 1)
|
self.assertEqual(len(shopping_list.requests), 1)
|
||||||
|
|
@ -61,8 +84,11 @@ class TestShopping(unittest.IsolatedAsyncioTestCase):
|
||||||
await products.insert_product(self.conn, second.product, {})
|
await products.insert_product(self.conn, second.product, {})
|
||||||
|
|
||||||
shopping_list = await shopping.current_shopping_list(self.conn)
|
shopping_list = await shopping.current_shopping_list(self.conn)
|
||||||
await shopping.sync_persons_requested_ingredients(self.conn, shopping_list, person, [first])
|
async for _ in shopping.sync_persons_requested_ingredients(self.conn, shopping_list, person, [first]):
|
||||||
await shopping.sync_persons_requested_ingredients(self.conn, shopping_list, person, [first, second])
|
pass
|
||||||
|
|
||||||
|
async for _ in shopping.sync_persons_requested_ingredients(self.conn, shopping_list, person, [first, second]):
|
||||||
|
pass
|
||||||
|
|
||||||
shopping_list = await shopping.current_shopping_list(self.conn)
|
shopping_list = await shopping.current_shopping_list(self.conn)
|
||||||
self.assertEqual(len(shopping_list.requests), 2)
|
self.assertEqual(len(shopping_list.requests), 2)
|
||||||
|
|
@ -109,4 +135,21 @@ class TestShopping(unittest.IsolatedAsyncioTestCase):
|
||||||
self.assertEqual(len(results_by_unit), 2)
|
self.assertEqual(len(results_by_unit), 2)
|
||||||
self.assertIn('kg', results_by_unit)
|
self.assertIn('kg', results_by_unit)
|
||||||
self.assertIn('Items', results_by_unit)
|
self.assertIn('Items', results_by_unit)
|
||||||
self.assertEqual(results_by_unit['kg'].product_id, results_by_unit['Items'].product_id)
|
self.assertEqual(results_by_unit['kg'].product_id, results_by_unit['Items'].product_id)
|
||||||
|
|
||||||
|
async def test_purchase(self):
|
||||||
|
ingredient = test_data.Ingredients.one_apple
|
||||||
|
person = test_data.Persons.jacob
|
||||||
|
|
||||||
|
await products.insert_product(self.conn, ingredient.product, {})
|
||||||
|
|
||||||
|
shopping_list = await shopping.current_shopping_list(self.conn)
|
||||||
|
self.assertIsNone(shopping_list.purchased_date)
|
||||||
|
|
||||||
|
shopping_list = await shopping.mark_purchased(self.conn)
|
||||||
|
self.assertIsNotNone(shopping_list.purchased_date)
|
||||||
|
self.assertLessEqual(shopping_list.purchased_date - datetime.now(), timedelta(seconds=1))
|
||||||
|
|
||||||
|
new_shopping_list = await shopping.current_shopping_list(self.conn)
|
||||||
|
self.assertNotEqual(shopping_list.id, new_shopping_list.id)
|
||||||
|
self.assertIsNone(new_shopping_list.purchased_date)
|
||||||
Loading…
Reference in a new issue