from datetime import datetime import importlib import unittest import tests.test_data as test_data import shopping import ingredients, products from db import connect, create def reload_test_data(): global test_data test_data = importlib.reload(test_data) def first(iterable: list, predicate: callable): for item in iterable: if predicate(item): return item return None class TestShopping(unittest.IsolatedAsyncioTestCase): async def asyncSetUp(self): self.conn = await connect(':memory:') await create(self.conn) reload_test_data() return await super().asyncSetUp() async def asyncTearDown(self) -> None: await self.conn.close() return await super().asyncTearDown() async def test_current_shopping_list(self): shopping_list = await shopping.current_shopping_list(self.conn) self.assertEqual(len(shopping_list.requests), 0) self.assertEqual(len(shopping_list.results), 0) async def test_sync_persons_requests(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) await shopping.sync_persons_requested_ingredients(self.conn, shopping_list, person, [ingredient]) 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.person_id, person.id) self.assertEqual(request.ingredient.line, ingredient.line) async def test_sync_persons_requests_multiple_add_item(self): first = test_data.Ingredients.one_apple second = test_data.Ingredients.salt person = test_data.Persons.jacob await products.insert_product(self.conn, first.product, {}) await products.insert_product(self.conn, second.product, {}) shopping_list = await shopping.current_shopping_list(self.conn) await shopping.sync_persons_requested_ingredients(self.conn, shopping_list, person, [first]) await shopping.sync_persons_requested_ingredients(self.conn, shopping_list, person, [first, second]) shopping_list = await shopping.current_shopping_list(self.conn) self.assertEqual(len(shopping_list.requests), 2) self.assertEqual(len(shopping_list.results), 0) request_by_line = {r.ingredient.line: r for r in shopping_list.requests} self.assertEqual(len(request_by_line), 2) for requested_ingredient in [first, second]: request = request_by_line[requested_ingredient.line] self.assertEqual(request.person_id, person.id) self.assertEqual(request.ingredient.line, requested_ingredient.line) async def test_mark_found(self): ingredient = test_data.Ingredients.one_apple await products.insert_product(self.conn, ingredient.product, {}) shopping_list = await shopping.current_shopping_list(self.conn) await shopping.mark_found(self.conn, ingredient, date_found=datetime.now()) shopping_list = await shopping.current_shopping_list(self.conn) self.assertEqual(len(shopping_list.results), 1) self.assertEqual(shopping_list.results[0].product_id, ingredient.product.id) self.assertEqual(shopping_list.results[0].quantity, 1) self.assertEqual(shopping_list.results[0].unit, ingredient.unit) ingredient.quantity = 2 await shopping.mark_found(self.conn, ingredient, date_found=datetime.now()) shopping_list = await shopping.current_shopping_list(self.conn) self.assertEqual(len(shopping_list.results), 1) self.assertEqual(shopping_list.results[0].product_id, ingredient.product.id) self.assertEqual(shopping_list.results[0].quantity, 2) self.assertEqual(shopping_list.results[0].unit, ingredient.unit) ingredient.unit = 'kg' await shopping.mark_found(self.conn, ingredient, date_found=datetime.now()) shopping_list = await shopping.current_shopping_list(self.conn) self.assertEqual(len(shopping_list.results), 2) results_by_unit = {r.unit: r for r in shopping_list.results} self.assertEqual(len(results_by_unit), 2) self.assertIn('kg', results_by_unit) self.assertIn('Items', results_by_unit) self.assertEqual(results_by_unit['kg'].product_id, results_by_unit['Items'].product_id)