Add upper limit on positions in an order (#3806)

* Add upper limit on positions in an order

* Fix form validation
This commit is contained in:
Raphael Michel
2024-01-19 18:14:45 +01:00
committed by GitHub
parent 1f465ddddb
commit 4fb49820af
10 changed files with 97 additions and 3 deletions

View File

@@ -26,6 +26,7 @@ from decimal import Decimal
from unittest import mock
import pytest
from django.conf import settings
from django.core import mail as djmail
from django.core.files.base import ContentFile
from django.utils.timezone import now
@@ -278,6 +279,31 @@ def test_order_create(token_client, organizer, event, item, quota, question):
assert o.transactions.count() == 2
@pytest.mark.django_db
def test_order_create_max_size(token_client, organizer, event, item, quota, question):
quota.size = settings.PRETIX_MAX_ORDER_SIZE * 2
quota.save()
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)
res['positions'] = [
{
"item": item.pk,
"variation": None,
"price": "23.00",
"attendee_name_parts": {"full_name": "Peter"},
"attendee_email": None,
"addon_to": None,
"subevent": None
}
] * (settings.PRETIX_MAX_ORDER_SIZE + 1)
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/'.format(
organizer.slug, event.slug
), format='json', data=res
)
assert resp.status_code == 400
assert resp.data == {"positions": [f"Orders cannot have more than {settings.PRETIX_MAX_ORDER_SIZE} positions."]}
@pytest.mark.django_db
def test_order_create_expires(token_client, organizer, event, item, quota, question):
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)

View File

@@ -25,6 +25,7 @@ from decimal import Decimal
from io import StringIO
import pytest
from django.conf import settings as django_settings
from django.core.files.base import ContentFile
from django.utils.timezone import now
from django_scopes import scopes_disabled
@@ -57,7 +58,7 @@ def user():
return User.objects.create_user('test@localhost', 'test')
def inputfile_factory():
def inputfile_factory(multiplier=1):
d = [
{
'A': 'Dieter',
@@ -103,6 +104,8 @@ def inputfile_factory():
'L': '',
},
]
if multiplier > 1:
d = d * multiplier
f = StringIO()
w = csv.DictWriter(f, ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'], dialect=csv.excel)
w.writeheader()
@@ -166,6 +169,19 @@ def test_import_as_one_order(user, event, item):
assert set(pos.positionid for pos in o.positions.all()) == {1, 2, 3}
@pytest.mark.django_db
@scopes_disabled()
def test_import_as_one_order_max_size(user, event, item):
settings = dict(DEFAULT_SETTINGS)
settings['item'] = 'static:{}'.format(item.pk)
settings['orders'] = 'one'
import_orders.apply(
args=(event.pk, inputfile_factory(multiplier=django_settings.PRETIX_MAX_ORDER_SIZE).id, settings, 'en', user.pk)
)
assert event.orders.count() == 0
@pytest.mark.django_db
@scopes_disabled()
def test_import_in_test_mode(user, event, item):

View File

@@ -26,6 +26,7 @@ from decimal import Decimal
from zoneinfo import ZoneInfo
import pytest
from django.conf import settings
from django.core import mail as djmail
from django.db.models import F, Sum
from django.test import TestCase
@@ -1829,6 +1830,13 @@ class OrderChangeManagerTests(TestCase):
with self.assertRaises(OrderError):
self.ocm.add_position(self.shirt, None, None, None)
@classscope(attr='o')
def test_add_item_limit(self):
for i in range(settings.PRETIX_MAX_ORDER_SIZE):
self.ocm.add_position(self.shirt, None, None, None)
with self.assertRaises(OrderError):
self.ocm.commit()
@classscope(attr='o')
def test_add_item_success(self):
self.ocm.add_position(self.shirt, None, None, None)

View File

@@ -38,6 +38,7 @@ from datetime import timedelta
from decimal import Decimal
from bs4 import BeautifulSoup
from django.conf import settings
from django.test import TestCase
from django.utils.timezone import now
from django_countries.fields import Country
@@ -991,6 +992,23 @@ class CartTest(CartTestMixin, TestCase):
with scopes_disabled():
self.assertEqual(CartPosition.objects.filter(cart_id=self.session_key, event=self.event).count(), 1)
def test_max_items_global(self):
with scopes_disabled():
CartPosition.objects.create(
event=self.event, cart_id=self.session_key, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
self.event.settings.max_items_per_order = settings.PRETIX_MAX_ORDER_SIZE + 100
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_%d' % self.ticket.id: str(settings.PRETIX_MAX_ORDER_SIZE + 1),
}, follow=True)
self.assertRedirects(response, '/%s/%s/?require_cookie=true' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content, "lxml")
self.assertIn('more than', doc.select('.alert-danger')[0].text)
with scopes_disabled():
self.assertEqual(CartPosition.objects.filter(cart_id=self.session_key, event=self.event).count(), 1)
def test_max_items_unlimited_sales_channel(self):
with scopes_disabled():
CartPosition.objects.create(