From ba75de7e7d2c9e5d93d2a2bb639adc1c4ed08409 Mon Sep 17 00:00:00 2001 From: Kara Engelhardt Date: Mon, 13 Apr 2026 11:43:04 +0200 Subject: [PATCH] Handle existing cart with empty session in presale views (PRETIXEU-D9Y) --- src/pretix/presale/views/__init__.py | 16 +++++++++++----- src/tests/presale/test_checkout.py | 14 +++++++++++++- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/pretix/presale/views/__init__.py b/src/pretix/presale/views/__init__.py index 3bb9426e38..46822dd46b 100644 --- a/src/pretix/presale/views/__init__.py +++ b/src/pretix/presale/views/__init__.py @@ -114,8 +114,10 @@ class CartMixin: return cached_invoice_address(self.request) def get_cart(self, answers=False, queryset=None, order=None, downloads=False, payments=None): - if not self.request.session.session_key and not order: - # The user has not even a session ID yet, so they can't have a cart and we can save a lot of work + from pretix.presale.views.cart import get_or_create_cart_id + + if not get_or_create_cart_id(self.request, create=False) and not order: + # The user has no cart, so we can save a lot of work return { 'positions': [], # Other keys are not used on non-checkout pages @@ -377,9 +379,13 @@ def cart_exists(request): from pretix.presale.views.cart import get_or_create_cart_id if not hasattr(request, '_cart_cache'): - return CartPosition.objects.filter( - cart_id=get_or_create_cart_id(request), event=request.event - ).exists() + cid = get_or_create_cart_id(request, create=False) + if cid: + return CartPosition.objects.filter( + cart_id=cid, event=request.event + ).exists() + else: + return False return bool(request._cart_cache) diff --git a/src/tests/presale/test_checkout.py b/src/tests/presale/test_checkout.py index ebeef3c5f8..5de5bcc582 100644 --- a/src/tests/presale/test_checkout.py +++ b/src/tests/presale/test_checkout.py @@ -33,7 +33,7 @@ from django.conf import settings from django.core import mail as djmail from django.core.files.uploadedfile import SimpleUploadedFile from django.core.signing import dumps -from django.test import TestCase, TransactionTestCase +from django.test import Client, TestCase, TransactionTestCase from django.utils.crypto import get_random_string from django.utils.timezone import now from django_countries.fields import Country @@ -4413,6 +4413,18 @@ class CheckoutTestCase(BaseCheckoutTestCase, TimemachineTestMixin, TestCase): assert len(djmail.outbox) == 1 assert any(["Invoice_" in a[0] for a in djmail.outbox[0].attachments]) + def test_checkout_empty_session_valid_cart(self): + client = Client() + with scopes_disabled(): + api_cid = "{}@api".format(get_random_string(48)) + CartPosition.objects.create( + event=self.event, cart_id=api_cid, item=self.ticket, + price=23, expires=now() + timedelta(minutes=10) + ) + + response = client.get('/%s/%s/w/1234567890abcdef/checkout/questions/' % (self.orga.slug, self.event.slug), query_params={"take_cart_id": api_cid}) + assert '€23.00' in response.content.decode() + class CheckoutTransactionTestCase(BaseCheckoutTestCase, TransactionTestCase): def test_order_confirmation_mail_invoice_sent_somewhere_else(self):