From db945d3498776d4cf85a2c00a1d645ef4ed57afa Mon Sep 17 00:00:00 2001 From: imperosol Date: Sat, 23 May 2026 11:55:01 +0200 Subject: [PATCH] test sold out items in eboutic --- counter/models.py | 4 ++- counter/tests/test_product.py | 4 ++- eboutic/tests/test_basket.py | 51 ++++++++++++++++++++++++++++------- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/counter/models.py b/counter/models.py index 2a2dcf09..10920e86 100644 --- a/counter/models.py +++ b/counter/models.py @@ -371,7 +371,9 @@ class ProductQuerySet(models.QuerySet): nb_basket_items_subquery = Subquery( BasketItem.objects.filter( product_id=OuterRef("id"), - basket__date__gt=now() - settings.SITH_EBOUTIC_BASKET_TIMEOUT, + basket__date__gt=now() + - settings.SITH_EBOUTIC_BASKET_TIMEOUT + - settings.SITH_EBOUTIC_ETRANSACTION_TIMEOUT, ) .values("product_id") .annotate(res=Sum("quantity")) diff --git a/counter/tests/test_product.py b/counter/tests/test_product.py index c856e266..d73f9513 100644 --- a/counter/tests/test_product.py +++ b/counter/tests/test_product.py @@ -276,7 +276,9 @@ class TestProductClicLimit(TestCase): item = BasketItem.objects.filter(product=self.products[1])[0] item.basket = baker.make( Basket, - date=now() - settings.SITH_EBOUTIC_BASKET_TIMEOUT - timedelta(minutes=1), + date=now() + - settings.SITH_EBOUTIC_BASKET_TIMEOUT + - settings.SITH_EBOUTIC_ETRANSACTION_TIMEOUT, ) item.save() assert list(self.qs.under_clic_limit()) == self.products[1:] diff --git a/eboutic/tests/test_basket.py b/eboutic/tests/test_basket.py index 7abb0984..5df6df6d 100644 --- a/eboutic/tests/test_basket.py +++ b/eboutic/tests/test_basket.py @@ -1,16 +1,19 @@ import re from datetime import datetime, timezone +import freezegun import pytest from bs4 import BeautifulSoup +from django.conf import settings from django.http import HttpResponse from django.test import TestCase from django.test.client import Client from django.urls import reverse -from django.utils.timezone import localdate +from django.utils.timezone import localdate, now from model_bakery import baker from pytest_django.asserts import assertRedirects +import eboutic.models from core.baker_recipes import subscriber_user from core.models import Group, User from counter.baker_recipes import ( @@ -235,17 +238,45 @@ class TestEboutic(TestCase): def test_add_forbidden_product(self): self.client.force_login(self.new_customer) - response = self.submit_basket([BasketItem(self.beer.id, 1)]) - assert response.status_code == 200 - assert Basket.objects.first() is None + for product in self.beer, self.cotiz, self.not_in_counter: + response = self.submit_basket([BasketItem(product.id, 1)]) + assert response.status_code == 200 + assert not Basket.objects.exists() - response = self.submit_basket([BasketItem(self.cotiz.id, 1)]) + def test_sold_out_product(self): + sold_out = product_recipe.make( + clic_limit=3, counters=[self.eboutic], product_type=baker.make(ProductType) + ) + price = price_recipe.make(product=sold_out, groups=[self.group_cotiz], amount=0) + sale_recipe.make( + product=sold_out, + customer=self.subscriber.customer, + unit_price=0, + quantity=1, + ) + baker.make( + eboutic.models.BasketItem, + basket=baker.make(Basket), + product=sold_out, + quantity=2, + ) + self.client.force_login(self.subscriber) + response = self.submit_basket([BasketItem(price.id, 1)]) assert response.status_code == 200 - assert Basket.objects.first() is None - - response = self.submit_basket([BasketItem(self.not_in_counter.id, 1)]) - assert response.status_code == 200 - assert Basket.objects.first() is None + assert Basket.objects.count() == 1 + with freezegun.freeze_time( + now() + + settings.SITH_EBOUTIC_BASKET_TIMEOUT + + settings.SITH_EBOUTIC_ETRANSACTION_TIMEOUT + ): + # after a while, unpaid basket items should expire and make the + # product available again. + response = self.submit_basket([BasketItem(price.id, 1)]) + assertRedirects( + response, + reverse("eboutic:checkout", kwargs={"basket_id": Basket.objects.last().id}), + ) + assert Basket.objects.count() == 2 def test_create_basket(self): self.client.force_login(self.new_customer)