diff --git a/eboutic/models.py b/eboutic/models.py index 6bd500e6..839f8fec 100644 --- a/eboutic/models.py +++ b/eboutic/models.py @@ -48,7 +48,7 @@ def get_eboutic_products(user: User) -> list[Product]: .annotate(order=F("product_type__order")) .annotate(category=F("product_type__name")) .annotate(category_comment=F("product_type__comment")) - .annotate(price=F("selling_price")) + .annotate(price=F("selling_price")) # <-- selected price for basket validation .prefetch_related("buying_groups") # <-- used in `Product.can_be_sold_to` ) return [p for p in products if p.can_be_sold_to(user)] diff --git a/eboutic/static/bundled/eboutic/eboutic-index.ts b/eboutic/static/bundled/eboutic/eboutic-index.ts index 56597387..434d839a 100644 --- a/eboutic/static/bundled/eboutic/eboutic-index.ts +++ b/eboutic/static/bundled/eboutic/eboutic-index.ts @@ -90,7 +90,7 @@ document.addEventListener("alpine:init", () => { }, /** - * Remove all the basket from the basket & cleans the catalog CSS classes + * Remove all the items from the basket & cleans the catalog CSS classes */ clearBasket() { this.basket = []; diff --git a/eboutic/tests/test_basket.py b/eboutic/tests/test_basket.py index 3e204d16..60081102 100644 --- a/eboutic/tests/test_basket.py +++ b/eboutic/tests/test_basket.py @@ -100,7 +100,8 @@ class TestEboutic(TestCase): BasketItem(None, 1), BasketItem(self.snack.id, None), ]: - assert self.submit_basket([item]).status_code == 200 + response = self.submit_basket([item]) + assert response.status_code == 200 def test_anonymous(self): assertRedirects( @@ -118,26 +119,25 @@ class TestEboutic(TestCase): def test_add_forbidden_product(self): self.client.force_login(self.new_customer) - assert self.submit_basket([BasketItem(self.beer.id, 1)]).status_code == 200 + response = self.submit_basket([BasketItem(self.beer.id, 1)]) + assert response.status_code == 200 assert Basket.objects.first() is None - assert self.submit_basket([BasketItem(self.cotiz.id, 1)]).status_code == 200 + response = self.submit_basket([BasketItem(self.cotiz.id, 1)]) + assert response.status_code == 200 assert Basket.objects.first() is None - assert ( - self.submit_basket([BasketItem(self.not_in_counter.id, 1)]).status_code - == 200 - ) + response = self.submit_basket([BasketItem(self.not_in_counter.id, 1)]) + assert response.status_code == 200 assert Basket.objects.first() is None self.client.force_login(self.new_customer) - assert self.submit_basket([BasketItem(self.cotiz.id, 1)]).status_code == 200 + response = self.submit_basket([BasketItem(self.cotiz.id, 1)]) + assert response.status_code == 200 assert Basket.objects.first() is None - assert ( - self.submit_basket([BasketItem(self.not_in_counter.id, 1)]).status_code - == 200 - ) + response = self.submit_basket([BasketItem(self.not_in_counter.id, 1)]) + assert response.status_code == 200 assert Basket.objects.first() is None def test_create_basket(self): diff --git a/eboutic/tests/test_payment.py b/eboutic/tests/test_payment.py index 1e817cd0..61893584 100644 --- a/eboutic/tests/test_payment.py +++ b/eboutic/tests/test_payment.py @@ -30,7 +30,10 @@ class TestPaymentBase(TestCase): def setUpTestData(cls): cls.customer = subscriber_user.make() cls.basket = baker.make(Basket, user=cls.customer) - cls.refilling = Product.objects.get(code="15REFILL") + cls.refilling = product_recipe.make( + product_type_id=settings.SITH_COUNTER_PRODUCTTYPE_REFILLING, + selling_price=15, + ) product_type = baker.make(ProductType) @@ -50,35 +53,49 @@ class TestPaymentBase(TestCase): class TestPaymentSith(TestPaymentBase): def test_anonymous(self): - assert ( - self.client.post( - reverse("eboutic:pay_with_sith", kwargs={"basket_id": self.basket.id}), - ).status_code - == 403 + response = self.client.post( + reverse("eboutic:pay_with_sith", kwargs={"basket_id": self.basket.id}) + ) + assert response.status_code == 403 + assert Basket.objects.contains(self.basket), ( + "After an unsuccessful request, the basket should be kept" ) - assert Basket.objects.filter(id=self.basket.id).first() is not None def test_unauthorized(self): self.client.force_login(subscriber_user.make()) - assert ( - self.client.post( - reverse("eboutic:pay_with_sith", kwargs={"basket_id": self.basket.id}), - ).status_code - == 403 + response = self.client.post( + reverse("eboutic:pay_with_sith", kwargs={"basket_id": self.basket.id}) + ) + assert response.status_code == 403 + assert Basket.objects.contains(self.basket), ( + "After an unsuccessful request, the basket should be kept" ) - assert Basket.objects.filter(id=self.basket.id).first() is not None def test_not_found(self): self.client.force_login(self.customer) - assert ( - self.client.post( - reverse( - "eboutic:pay_with_sith", kwargs={"basket_id": self.basket.id + 1} - ), - ).status_code - == 404 + response = self.client.post( + reverse("eboutic:pay_with_sith", kwargs={"basket_id": self.basket.id + 1}) ) - assert Basket.objects.filter(id=self.basket.id).first() is not None + assert response.status_code == 404 + assert Basket.objects.contains(self.basket), ( + "After an unsuccessful request, the basket should be kept" + ) + + def test_only_post_allowed(self): + self.client.force_login(self.customer) + force_refill_user(self.customer, self.basket.total + 1) + response = self.client.get( + reverse("eboutic:pay_with_sith", kwargs={"basket_id": self.basket.id}) + ) + + assert response.status_code == 405 + + assert Basket.objects.contains(self.basket), ( + "After an unsuccessful request, the basket should be kept" + ) + + self.customer.customer.refresh_from_db() + assert self.customer.customer.amount == self.basket.total + 1 def test_buy_success(self): self.client.force_login(self.customer) @@ -112,7 +129,7 @@ class TestPaymentSith(TestPaymentBase): def test_not_enough_money(self): self.client.force_login(self.customer) response = self.client.post( - reverse("eboutic:pay_with_sith", kwargs={"basket_id": self.basket.id}), + reverse("eboutic:pay_with_sith", kwargs={"basket_id": self.basket.id}) ) assertRedirects( response, @@ -124,20 +141,23 @@ class TestPaymentSith(TestPaymentBase): assert messages[0].level == DEFAULT_LEVELS["ERROR"] assert messages[0].message == "Solde insuffisant" - assert Basket.objects.filter(id=self.basket.id).first() is not None + assert Basket.objects.contains(self.basket), ( + "After an unsuccessful request, the basket should be kept" + ) def test_refilling_in_basket(self): BasketItem.from_product(self.refilling, 1, self.basket).save() self.client.force_login(self.customer) - force_refill_user(self.customer, self.basket.total) + force_refill_user(self.customer, self.basket.total + 1) + self.customer.customer.refresh_from_db() + initial_account_balance = self.customer.customer.amount response = self.client.post( - reverse("eboutic:pay_with_sith", kwargs={"basket_id": self.basket.id}), + reverse("eboutic:pay_with_sith", kwargs={"basket_id": self.basket.id}) ) assertRedirects( response, reverse("eboutic:payment_result", kwargs={"result": "failure"}), ) - assert Basket.objects.filter(id=self.basket.id).first() is not None messages = list(get_messages(response.wsgi_request)) assert messages[0].level == DEFAULT_LEVELS["ERROR"] @@ -146,7 +166,7 @@ class TestPaymentSith(TestPaymentBase): == "Vous ne pouvez pas acheter un rechargement avec de l'argent du sith" ) self.customer.customer.refresh_from_db() - assert self.customer.customer.amount == self.basket.total + assert self.customer.customer.amount == initial_account_balance class TestPaymentCard(TestPaymentBase): @@ -197,9 +217,8 @@ class TestPaymentCard(TestPaymentBase): basket = baker.make(Basket, user=customer) BasketItem.from_product(Product.objects.get(code="2SCOTIZ"), 1, basket).save() - assert ( - self.client.get(self.generate_bank_valid_answer(basket)).status_code == 200 - ) + response = self.client.get(self.generate_bank_valid_answer(basket)) + assert response.status_code == 200 assert customer.subscriptions.count() == 2 @@ -210,17 +229,18 @@ class TestPaymentCard(TestPaymentBase): def test_buy_refilling(self): BasketItem.from_product(self.refilling, 2, self.basket).save() - assert ( - self.client.get(self.generate_bank_valid_answer(self.basket)).status_code - == 200 - ) + response = self.client.get(self.generate_bank_valid_answer(self.basket)) + assert response.status_code == 200 self.customer.customer.refresh_from_db() assert self.customer.customer.amount == self.refilling.selling_price * 2 def test_multiple_responses(self): bank_response = self.generate_bank_valid_answer(self.basket) - assert self.client.get(bank_response).status_code == 200 + + response = self.client.get(bank_response) + assert response.status_code == 200 + response = self.client.get(bank_response) assert response.status_code == 500 assert ( diff --git a/eboutic/views.py b/eboutic/views.py index 382cd507..869fe7e9 100644 --- a/eboutic/views.py +++ b/eboutic/views.py @@ -234,7 +234,6 @@ class EbouticCheckout(CanViewMixin, UseFragmentsMixin, DetailView): class EbouticPayWithSith(CanViewMixin, SingleObjectMixin, View): - http_method_names = ["post"] model = Basket pk_url_kwarg = "basket_id"