From 30e758ad0bce7c8d9bc69644f05adc68b11daf50 Mon Sep 17 00:00:00 2001 From: Ulysse Moreau Date: Sun, 13 Sep 2020 12:11:35 +0200 Subject: [PATCH 1/7] Add logic --- boutique/models.py | 11 ++++++++++- boutique/views.py | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/boutique/models.py b/boutique/models.py index d6c2e63a..c72bcca9 100644 --- a/boutique/models.py +++ b/boutique/models.py @@ -90,6 +90,10 @@ class Item(models.Model): return True return False + @property + def is_cotiz(self): + return self.action in ["full_cotiz", "half_cotiz"] + @property def post_payment(self) -> Callable[["OrderItem"], None]: actions_methods = { @@ -238,6 +242,10 @@ class Order(models.Model): except Payment.DoesNotExist: return False + @property + def contains_cotiz(self) -> bool: + return any([i.is_cotiz for i in self.items.all()]) + def compute_price(self) -> None: self.price = Decimal("0.00") for item in self.items.all(): @@ -339,7 +347,8 @@ class OrderItem(models.Model): def get_final_price(self) -> Decimal: is_contributor = Contributor.is_contributor(self.order.user) - if is_contributor: + # If the order contains a cotiz, we should treat it as a contributor too + if is_contributor or order.contains_cotiz: return self.get_price_contributor() else: return self.get_price() diff --git a/boutique/views.py b/boutique/views.py index c9a6fdf8..8c59d751 100644 --- a/boutique/views.py +++ b/boutique/views.py @@ -325,7 +325,7 @@ class OrderEditView(LoginRequiredMixin, UpdateView): kwargs["total_price"] = self.object.price kwargs["is_contributor"] = bde.models.Contributor.is_contributor( self.request.user - ) + ) or self.object.order.contains_cotiz return kwargs -- GitLab From 3d256abe4867acf6480f99eeb3dc09055e6d4ef1 Mon Sep 17 00:00:00 2001 From: MOREAU Ulysse Date: Thu, 26 Nov 2020 16:03:33 +0100 Subject: [PATCH 2/7] Fix logic errors --- boutique/models.py | 6 +++--- boutique/views.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/boutique/models.py b/boutique/models.py index c72bcca9..ead39429 100644 --- a/boutique/models.py +++ b/boutique/models.py @@ -91,7 +91,7 @@ class Item(models.Model): return False @property - def is_cotiz(self): + def is_cotiz(self) -> bool: return self.action in ["full_cotiz", "half_cotiz"] @property @@ -244,7 +244,7 @@ class Order(models.Model): @property def contains_cotiz(self) -> bool: - return any([i.is_cotiz for i in self.items.all()]) + return any([i.item.is_cotiz for i in self.items.all()]) def compute_price(self) -> None: self.price = Decimal("0.00") @@ -348,7 +348,7 @@ class OrderItem(models.Model): def get_final_price(self) -> Decimal: is_contributor = Contributor.is_contributor(self.order.user) # If the order contains a cotiz, we should treat it as a contributor too - if is_contributor or order.contains_cotiz: + if is_contributor or self.order.contains_cotiz: return self.get_price_contributor() else: return self.get_price() diff --git a/boutique/views.py b/boutique/views.py index 8c59d751..310374bc 100644 --- a/boutique/views.py +++ b/boutique/views.py @@ -325,7 +325,7 @@ class OrderEditView(LoginRequiredMixin, UpdateView): kwargs["total_price"] = self.object.price kwargs["is_contributor"] = bde.models.Contributor.is_contributor( self.request.user - ) or self.object.order.contains_cotiz + ) or self.object.contains_cotiz return kwargs -- GitLab From 7de91b4b24437ca96226bd158935a8dd0cafa45c Mon Sep 17 00:00:00 2001 From: Nils VAN ZUIJLEN Date: Thu, 26 Nov 2020 17:12:42 +0100 Subject: [PATCH 3/7] Optimize Item.is_cotiz Sets are faster than lists regarding the `in` operator --- boutique/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boutique/models.py b/boutique/models.py index ead39429..22e0778b 100644 --- a/boutique/models.py +++ b/boutique/models.py @@ -92,7 +92,7 @@ class Item(models.Model): @property def is_cotiz(self) -> bool: - return self.action in ["full_cotiz", "half_cotiz"] + return self.action in {"full_cotiz", "half_cotiz"} @property def post_payment(self) -> Callable[["OrderItem"], None]: -- GitLab From 9ef7a721c4d19f251b1de3b934b088abb0719fa8 Mon Sep 17 00:00:00 2001 From: Nils VAN ZUIJLEN Date: Thu, 26 Nov 2020 17:14:07 +0100 Subject: [PATCH 4/7] Add test for Item.is_cotiz --- boutique/tests/test_models.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/boutique/tests/test_models.py b/boutique/tests/test_models.py index d24b6e16..3fb28b73 100644 --- a/boutique/tests/test_models.py +++ b/boutique/tests/test_models.py @@ -31,6 +31,28 @@ class ItemTest(PaymentTestCase, OrderItemTestCase): pack = self.create_pack() self.assertTrue(pack.is_pack) + def test_is_cotiz(self) -> None: + """ + Tests that Item.is_cotiz is only true when the action is full_cotiz or half_cotiz + """ + item = self.create_item() + + for action in {"no", "event"}: + with self.subTest(action=action): + item.action = action + self.assertFalse(item.is_cotiz) + item.save() + item.refresh_from_db() + self.assertFalse(item.is_cotiz) + + for action in {"full_cotiz", "half_cotiz"}: + with self.subTest(action=action): + item.action = action + self.assertTrue(item.is_cotiz) + item.save() + item.refresh_from_db() + self.assertTrue(item.is_cotiz) + def test_single_product_is_not_pack(self) -> None: """Tests that Item.is_pack is false when Item is not a pack""" product = self.create_item() -- GitLab From 47b235a4989dbbf5feaf82eadeac8b4a68fde185 Mon Sep 17 00:00:00 2001 From: Nils VAN ZUIJLEN Date: Thu, 26 Nov 2020 17:32:28 +0100 Subject: [PATCH 5/7] Add tests and optimization to Order.contains_cotiz `any` takes an iterable, no need to create a list if it's only to use it once! --- boutique/models.py | 2 +- boutique/tests/test_models.py | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/boutique/models.py b/boutique/models.py index 22e0778b..87ae9088 100644 --- a/boutique/models.py +++ b/boutique/models.py @@ -244,7 +244,7 @@ class Order(models.Model): @property def contains_cotiz(self) -> bool: - return any([i.item.is_cotiz for i in self.items.all()]) + return any(i.item.is_cotiz for i in self.items.all()) def compute_price(self) -> None: self.price = Decimal("0.00") diff --git a/boutique/tests/test_models.py b/boutique/tests/test_models.py index 3fb28b73..6d16f3ab 100644 --- a/boutique/tests/test_models.py +++ b/boutique/tests/test_models.py @@ -646,6 +646,42 @@ class OrderTest(PaymentTestCase, OrderItemTestCase): self.assertTrue(self.order.paid) + def test_contains_cotiz_single_items(self) -> None: + """Tests that Order.contains_cotiz is able to detect single cotiz""" + item = self.create_item() + cotiz = self.create_item() + cotiz.action = "full_cotiz" + cotiz.save() + cotiz.refresh_from_db() + + self.assertFalse(self.order.contains_cotiz) + + item.add_to_order(self.order) + self.assertFalse(self.order.contains_cotiz) + + cotiz.add_to_order(self.order) + self.assertTrue(self.order.contains_cotiz) + + def test_contains_cotiz_packs(self) -> None: + """Tests that Order.contains_cotiz is able to detect cotiz in packs""" + pack = self.create_pack() + cpack = self.create_item() + cotiz = self.create_item() + cotiz.action = "full_cotiz" + cotiz.save() + cotiz.refresh_from_db() + cpack.children.add(cotiz) + cpack.save() + cpack.refresh_from_db() + + self.assertFalse(self.order.contains_cotiz) + + pack.add_to_order(self.order) + self.assertFalse(self.order.contains_cotiz) + + cpack.add_to_order(self.order) + self.assertTrue(self.order.contains_cotiz) + @patch("boutique.models.OrderItem.post_payment") def test_post_payment(self, oi_post_payment) -> None: item = self.create_item() -- GitLab From f6b38861f19093ee4330bb943eb2cb80c8ebec27 Mon Sep 17 00:00:00 2001 From: Nils VAN ZUIJLEN Date: Thu, 26 Nov 2020 17:38:48 +0100 Subject: [PATCH 6/7] Add tests for cotiz interaction with OrderItem.get_final_price --- boutique/tests/test_models.py | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/boutique/tests/test_models.py b/boutique/tests/test_models.py index 6d16f3ab..26c528bb 100644 --- a/boutique/tests/test_models.py +++ b/boutique/tests/test_models.py @@ -594,8 +594,23 @@ class OrderItemTest(OrderItemTestCase): oi.refresh_from_db() self.assertEqual(oi.get_final_price(), oi.get_price_contributor()) + cotiz = self.create_item() + cotiz.action = "half_cotiz" + cotiz.save() + + cotiz.add_to_order(self.order) + self.order.refresh_from_db() + oi.refresh_from_db() + + self.assertEqual(oi.get_final_price(), oi.get_price_contributor()) + def test_get_final_price_non_contributor(self) -> None: - """Tests OrderItem.get_final_price for a non contributor""" + """ + Tests OrderItem.get_final_price for a non contributor + + Tests with and without a cotiz in the order + With cotiz should apply contributor price + """ item = self.create_item() oi = OrderItemTest.create_orderitem(self.order, item) @@ -606,6 +621,16 @@ class OrderItemTest(OrderItemTestCase): oi.refresh_from_db() self.assertEqual(oi.get_final_price(), oi.get_price()) + cotiz = self.create_item() + cotiz.action = "half_cotiz" + cotiz.save() + + cotiz.add_to_order(self.order) + self.order.refresh_from_db() + oi.refresh_from_db() + + self.assertEqual(oi.get_final_price(), oi.get_price_contributor()) + def test_post_payment(self) -> None: item = self.create_item() oi = self.create_orderitem(self.order, item) -- GitLab From a1ffa761de1615672f2363e13e69d6811d7a6b7f Mon Sep 17 00:00:00 2001 From: Nils VAN ZUIJLEN Date: Thu, 26 Nov 2020 18:08:06 +0100 Subject: [PATCH 7/7] Add tests for OrderEditView.get_context_data And get_object --- boutique/tests/test_views.py | 107 +++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/boutique/tests/test_views.py b/boutique/tests/test_views.py index 465f8104..0dcee9c0 100644 --- a/boutique/tests/test_views.py +++ b/boutique/tests/test_views.py @@ -3,6 +3,7 @@ from datetime import timedelta from decimal import Decimal from os import path from typing import Tuple +from unittest.mock import Mock from django.urls import reverse from django.utils import timezone @@ -23,6 +24,7 @@ from ..views import DeliveryView from ..views import ItemCreateView from ..views import ItemEditView from ..views import ItemListView +from ..views import OrderEditView class ItemListViewTest(ItemTestCase, UserTestCase): @@ -394,6 +396,111 @@ class ManageCategoryViewTest(UserTestCase): self.assertTrue(len(form.errors) > 0) +class OrderEditViewTest(OrderItemTestCase): + def test_get_object(self) -> None: + view = OrderEditView() + view.request = Mock() + view.request.user = self.user + + self.assertEqual(view.get_object(), Order.objects.get_current_order(self.user)) + + @user_logged_in + def test_context_data_user(self) -> None: + url = reverse('boutique:order_edit') + + # Empty order + resp = self.client.get(url) + context = resp.context + + self.assertNotIn("form", context) + self.assertIn("formset", context) + self.assertIn("total_price", context) + self.assertIn("is_contributor", context) + + self.assertFalse(context["is_contributor"]) + + # Item in order + item = self.create_item() + item.add_to_user(self.user) + + resp = self.client.get(url) + context = resp.context + + self.assertNotIn("form", context) + self.assertIn("formset", context) + self.assertIn("total_price", context) + self.assertIn("is_contributor", context) + + self.assertEqual(context["total_price"], item.price) + self.assertFalse(context["is_contributor"]) + + # Cotiz in order + cotiz = self.create_item() + cotiz.action = "full_cotiz" + cotiz.save() + cotiz.refresh_from_db() + cotiz.add_to_user(self.user) + + resp = self.client.get(url) + context = resp.context + + self.assertNotIn("form", context) + self.assertIn("formset", context) + self.assertIn("total_price", context) + self.assertIn("is_contributor", context) + + self.assertEqual(context["total_price"], cotiz.price_contributor + item.price_contributor) + self.assertTrue(context["is_contributor"]) + + @contrib_user_logged_in + def test_context_data_contrib_user(self) -> None: + url = reverse('boutique:order_edit') + + # Empty order + resp = self.client.get(url) + context = resp.context + + self.assertNotIn("form", context) + self.assertIn("formset", context) + self.assertIn("total_price", context) + self.assertIn("is_contributor", context) + + self.assertTrue(context["is_contributor"]) + + # Item in order + item = self.create_item() + item.add_to_user(self.contributor_user) + + resp = self.client.get(url) + context = resp.context + + self.assertNotIn("form", context) + self.assertIn("formset", context) + self.assertIn("total_price", context) + self.assertIn("is_contributor", context) + + self.assertEqual(context["total_price"], item.price_contributor) + self.assertTrue(context["is_contributor"]) + + # Cotiz in order + cotiz = self.create_item() + cotiz.action = "full_cotiz" + cotiz.save() + cotiz.refresh_from_db() + cotiz.add_to_user(self.contributor_user) + + resp = self.client.get(url) + context = resp.context + + self.assertNotIn("form", context) + self.assertIn("formset", context) + self.assertIn("total_price", context) + self.assertIn("is_contributor", context) + + self.assertEqual(context["total_price"], cotiz.price_contributor + item.price_contributor) + self.assertTrue(context["is_contributor"]) + + class DeliveryViewTest(PaymentTestCase, OrderItemTestCase): """Tests for views.DeliveryView""" -- GitLab