diff --git a/service/models/shop_cart.py b/service/models/shop_cart.py index 5dc7eda..c75c05d 100644 --- a/service/models/shop_cart.py +++ b/service/models/shop_cart.py @@ -88,6 +88,18 @@ def deserialize(self, data): ) from error return self + def update_total_price(self): + """ + update the total price of a ShopCart + """ + price = 0 + for item in self.items: + if item.price is not None and item.quantity is not None: + price += item.price * item.quantity + + self.total_price = price + self.update() + ################################################## # CLASS METHODS ################################################## diff --git a/service/routes.py b/service/routes.py index 73c6139..bf8b575 100644 --- a/service/routes.py +++ b/service/routes.py @@ -190,6 +190,8 @@ def create_shopcart_item(shopcart_id): # Append item to the shopcart shopcart.items.append(item) shopcart.update() + # update the total price + shopcart.update_total_price() # Create a message to return message = item.serialize() @@ -243,6 +245,15 @@ def delete_shopcart_items(shopcart_id, item_id): if item: item.delete() + # update the total price + shopcart = ShopCart.find(shopcart_id) + if not shopcart: + abort( + status.HTTP_404_NOT_FOUND, + f"ShopCart with ID '{shopcart_id}' could not be found", + ) + shopcart.update_total_price() + return "", status.HTTP_204_NO_CONTENT @@ -274,6 +285,14 @@ def update_shopcart_item(shopcart_id, item_id): item.id = item_id item.update() + shopcart = ShopCart.find(shopcart_id) + if not shopcart: + abort( + status.HTTP_404_NOT_FOUND, + f"ShopCart with ID '{shopcart_id}' could not be found", + ) + shopcart.update_total_price() + return jsonify(item.serialize()), status.HTTP_200_OK diff --git a/tests/test_routes.py b/tests/test_routes.py index ebac58c..00ee823 100644 --- a/tests/test_routes.py +++ b/tests/test_routes.py @@ -473,3 +473,118 @@ def test_bad_request(self): """It should not Create when sending the wrong data""" resp = self.client.post(BASE_URL, json={"name": "not enough data"}) self.assertEqual(resp.status_code, status.HTTP_400_BAD_REQUEST) + + def test_shopcart_total_price_with_new_item(self): + """ + It should update the shopcart total price + once a new item is added + """ + shop_cart = self._create_shopcarts(1)[0] + item_1 = ShopCartItemFactory() + resp = self.client.post( + f"{BASE_URL}/{shop_cart.id}/items", + json=item_1.serialize(), + content_type="application/json", + ) + self.assertEqual(resp.status_code, status.HTTP_201_CREATED) + + item_2 = ShopCartItemFactory() + resp = self.client.post( + f"{BASE_URL}/{shop_cart.id}/items", + json=item_2.serialize(), + content_type="application/json", + ) + self.assertEqual(resp.status_code, status.HTTP_201_CREATED) + + resp = self.client.get( + f"{BASE_URL}/{shop_cart.id}", content_type="application/json" + ) + self.assertEqual(resp.status_code, status.HTTP_200_OK) + data = resp.get_json() + self.assertEqual( + data["total_price"], + str(item_1.price * item_1.quantity + item_2.price * item_2.quantity), + ) + + def test_shopcart_total_price_with_delete_item(self): + """ + It should update the shopcart total price + once an item is deleted + """ + shopcart = self._create_shopcarts(1)[0] + # add the first item + item = ShopCartItemFactory() + resp = self.client.post( + f"{BASE_URL}/{shopcart.id}/items", + json=item.serialize(), + content_type="application/json", + ) + self.assertEqual(resp.status_code, status.HTTP_201_CREATED) + data = resp.get_json() + item_id = data["id"] + + # add the second item + item_2 = ShopCartItemFactory() + resp = self.client.post( + f"{BASE_URL}/{shopcart.id}/items", + json=item_2.serialize(), + content_type="application/json", + ) + self.assertEqual(resp.status_code, status.HTTP_201_CREATED) + + # send delete request to delete the first item + resp = self.client.delete( + f"{BASE_URL}/{shopcart.id}/items/{item_id}", + content_type="application/json", + ) + self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT) + + resp = self.client.get( + f"{BASE_URL}/{shopcart.id}/items/{item_id}", + content_type="application/json", + ) + self.assertEqual(resp.status_code, status.HTTP_404_NOT_FOUND) + + # the total price should equal to the second item's total price + resp = self.client.get( + f"{BASE_URL}/{shopcart.id}", content_type="application/json" + ) + self.assertEqual(resp.status_code, status.HTTP_200_OK) + data = resp.get_json() + self.assertEqual(data["total_price"], str(item_2.price * item_2.quantity)) + + def test_shopcart_total_price_with_update_item(self): + """ + It should update the shopcart total price + once an item is updated + """ + # create a known item + shopcart = self._create_shopcarts(1)[0] + item = ShopCartItemFactory() + resp = self.client.post( + f"{BASE_URL}/{shopcart.id}/items", + json=item.serialize(), + content_type="application/json", + ) + self.assertEqual(resp.status_code, status.HTTP_201_CREATED) + + data = resp.get_json() + logging.debug(data) + item_id = data["id"] + data["quantity"] = 3 + + # send the update back + resp = self.client.put( + f"{BASE_URL}/{shopcart.id}/items/{item_id}", + json=data, + content_type="application/json", + ) + self.assertEqual(resp.status_code, status.HTTP_200_OK) + + # check total price + resp = self.client.get( + f"{BASE_URL}/{shopcart.id}", content_type="application/json" + ) + self.assertEqual(resp.status_code, status.HTTP_200_OK) + data = resp.get_json() + self.assertEqual(data["total_price"], str(item.price * 3))