mirror of
https://github.com/pretix/pretix.git
synced 2026-08-28 13:34:40 +00:00
Tests
This commit is contained in:
@@ -35,8 +35,8 @@ from pretix.base.services.invoices import (
|
|||||||
)
|
)
|
||||||
from pretix.base.services.mail import SendMailException
|
from pretix.base.services.mail import SendMailException
|
||||||
from pretix.base.services.orders import (
|
from pretix.base.services.orders import (
|
||||||
OrderChangeManager, OrderError, approve_order, cancel_order, deny_order, extend_order,
|
OrderChangeManager, OrderError, approve_order, cancel_order, deny_order,
|
||||||
mark_order_expired, mark_order_refunded,
|
extend_order, mark_order_expired, mark_order_refunded,
|
||||||
)
|
)
|
||||||
from pretix.base.services.tickets import (
|
from pretix.base.services.tickets import (
|
||||||
get_cachedticket_for_order, get_cachedticket_for_position,
|
get_cachedticket_for_order, get_cachedticket_for_position,
|
||||||
|
|||||||
@@ -633,7 +633,7 @@ class ConfirmStep(CartMixin, AsyncAction, TemplateFlowStep):
|
|||||||
return eventreverse(self.request.event, 'presale:event.order', kwargs={
|
return eventreverse(self.request.event, 'presale:event.order', kwargs={
|
||||||
'order': order.code,
|
'order': order.code,
|
||||||
'secret': order.secret,
|
'secret': order.secret,
|
||||||
})
|
}) + '?thanks=1'
|
||||||
return eventreverse(self.request.event, 'presale:event.order.pay.complete', kwargs={
|
return eventreverse(self.request.event, 'presale:event.order.pay.complete', kwargs={
|
||||||
'order': order.code,
|
'order': order.code,
|
||||||
'secret': order.secret,
|
'secret': order.secret,
|
||||||
|
|||||||
@@ -14,9 +14,15 @@
|
|||||||
{% if order.status != 'p' %}
|
{% if order.status != 'p' %}
|
||||||
<p>
|
<p>
|
||||||
{% trans "Your order has been placed successfully. See below for details." %}<br>
|
{% trans "Your order has been placed successfully. See below for details." %}<br>
|
||||||
<strong>
|
{% if order.require_approval %}
|
||||||
{% trans "Please note that we still await your payment to complete the process." %}
|
<strong>
|
||||||
</strong>
|
{% trans "Please note that we still await approval by the event organizer before you can pay and complete this order." %}
|
||||||
|
</strong>
|
||||||
|
{% else %}
|
||||||
|
<strong>
|
||||||
|
{% trans "Please note that we still await your payment to complete the process." %}
|
||||||
|
</strong>
|
||||||
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
{% elif order.total == 0 %}
|
{% elif order.total == 0 %}
|
||||||
<p>{% trans "Your order has been processed successfully! See below for details." %}</p>
|
<p>{% trans "Your order has been processed successfully! See below for details." %}</p>
|
||||||
|
|||||||
@@ -1143,6 +1143,80 @@ def test_order_extend_expired_quota_left(token_client, organizer, event, order,
|
|||||||
assert order.expires.strftime("%Y-%m-%d %H:%M:%S") == newdate[:10] + " 23:59:59"
|
assert order.expires.strftime("%Y-%m-%d %H:%M:%S") == newdate[:10] + " 23:59:59"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_order_pending_approve(token_client, organizer, event, order):
|
||||||
|
order.require_approval = True
|
||||||
|
order.save()
|
||||||
|
resp = token_client.post(
|
||||||
|
'/api/v1/organizers/{}/events/{}/orders/{}/approve/'.format(
|
||||||
|
organizer.slug, event.slug, order.code
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert resp.data['status'] == Order.STATUS_PENDING
|
||||||
|
assert not resp.data['require_approval']
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_order_invalid_state_approve(token_client, organizer, event, order):
|
||||||
|
order.require_approval = True
|
||||||
|
order.status = Order.STATUS_CANCELED
|
||||||
|
order.save()
|
||||||
|
resp = token_client.post(
|
||||||
|
'/api/v1/organizers/{}/events/{}/orders/{}/approve/'.format(
|
||||||
|
organizer.slug, event.slug, order.code
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
order.require_approval = False
|
||||||
|
order.status = Order.STATUS_PENDING
|
||||||
|
order.save()
|
||||||
|
resp = token_client.post(
|
||||||
|
'/api/v1/organizers/{}/events/{}/orders/{}/approve/'.format(
|
||||||
|
organizer.slug, event.slug, order.code
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_order_pending_deny(token_client, organizer, event, order):
|
||||||
|
order.require_approval = True
|
||||||
|
order.save()
|
||||||
|
resp = token_client.post(
|
||||||
|
'/api/v1/organizers/{}/events/{}/orders/{}/deny/'.format(
|
||||||
|
organizer.slug, event.slug, order.code
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert resp.status_code == 200
|
||||||
|
assert resp.data['status'] == Order.STATUS_CANCELED
|
||||||
|
assert resp.data['require_approval']
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_order_invalid_state_deny(token_client, organizer, event, order):
|
||||||
|
order.require_approval = True
|
||||||
|
order.status = Order.STATUS_CANCELED
|
||||||
|
order.save()
|
||||||
|
resp = token_client.post(
|
||||||
|
'/api/v1/organizers/{}/events/{}/orders/{}/deny/'.format(
|
||||||
|
organizer.slug, event.slug, order.code
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
order.require_approval = False
|
||||||
|
order.status = Order.STATUS_PENDING
|
||||||
|
order.save()
|
||||||
|
resp = token_client.post(
|
||||||
|
'/api/v1/organizers/{}/events/{}/orders/{}/deny/'.format(
|
||||||
|
organizer.slug, event.slug, order.code
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
|
||||||
ORDER_CREATE_PAYLOAD = {
|
ORDER_CREATE_PAYLOAD = {
|
||||||
"email": "dummy@dummy.test",
|
"email": "dummy@dummy.test",
|
||||||
"locale": "en",
|
"locale": "en",
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ event_permission_sub_urls = [
|
|||||||
('post', 'can_change_orders', 'orders/ABC12/mark_pending/', 404),
|
('post', 'can_change_orders', 'orders/ABC12/mark_pending/', 404),
|
||||||
('post', 'can_change_orders', 'orders/ABC12/mark_expired/', 404),
|
('post', 'can_change_orders', 'orders/ABC12/mark_expired/', 404),
|
||||||
('post', 'can_change_orders', 'orders/ABC12/mark_canceled/', 404),
|
('post', 'can_change_orders', 'orders/ABC12/mark_canceled/', 404),
|
||||||
|
('post', 'can_change_orders', 'orders/ABC12/approve/', 404),
|
||||||
|
('post', 'can_change_orders', 'orders/ABC12/deny/', 404),
|
||||||
('post', 'can_change_orders', 'orders/ABC12/extend/', 400),
|
('post', 'can_change_orders', 'orders/ABC12/extend/', 400),
|
||||||
('get', 'can_view_orders', 'orders/ABC12/payments/', 404),
|
('get', 'can_view_orders', 'orders/ABC12/payments/', 404),
|
||||||
('get', 'can_view_orders', 'orders/ABC12/payments/1/', 404),
|
('get', 'can_view_orders', 'orders/ABC12/payments/1/', 404),
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ from pretix.base.payment import FreeOrderProvider
|
|||||||
from pretix.base.reldate import RelativeDate, RelativeDateWrapper
|
from pretix.base.reldate import RelativeDate, RelativeDateWrapper
|
||||||
from pretix.base.services.invoices import generate_invoice
|
from pretix.base.services.invoices import generate_invoice
|
||||||
from pretix.base.services.orders import (
|
from pretix.base.services.orders import (
|
||||||
OrderChangeManager, OrderError, _create_order, expire_orders,
|
OrderChangeManager, OrderError, _create_order, approve_order, deny_order,
|
||||||
send_download_reminders,
|
expire_orders, send_download_reminders,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -207,6 +207,88 @@ def test_expiring_auto_disabled(event):
|
|||||||
assert o2.status == Order.STATUS_PENDING
|
assert o2.status == Order.STATUS_PENDING
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_do_not_expire_if_approval_pending(event):
|
||||||
|
o1 = Order.objects.create(
|
||||||
|
code='FOO', event=event, email='dummy@dummy.test',
|
||||||
|
status=Order.STATUS_PENDING,
|
||||||
|
datetime=now(), expires=now() - timedelta(days=10),
|
||||||
|
total=0, require_approval=True
|
||||||
|
)
|
||||||
|
o2 = Order.objects.create(
|
||||||
|
code='FO2', event=event, email='dummy@dummy.test',
|
||||||
|
status=Order.STATUS_PENDING,
|
||||||
|
datetime=now(), expires=now() - timedelta(days=10),
|
||||||
|
total=0,
|
||||||
|
)
|
||||||
|
expire_orders(None)
|
||||||
|
o1 = Order.objects.get(id=o1.id)
|
||||||
|
assert o1.status == Order.STATUS_PENDING
|
||||||
|
o2 = Order.objects.get(id=o2.id)
|
||||||
|
assert o2.status == Order.STATUS_EXPIRED
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_approve(event):
|
||||||
|
djmail.outbox = []
|
||||||
|
event.settings.invoice_generate = 'True'
|
||||||
|
o1 = Order.objects.create(
|
||||||
|
code='FOO', event=event, email='dummy@dummy.test',
|
||||||
|
status=Order.STATUS_PENDING,
|
||||||
|
datetime=now(), expires=now() - timedelta(days=10),
|
||||||
|
total=10, require_approval=True, locale='de'
|
||||||
|
)
|
||||||
|
approve_order(o1)
|
||||||
|
o1.refresh_from_db()
|
||||||
|
assert o1.expires > now()
|
||||||
|
assert o1.status == Order.STATUS_PENDING
|
||||||
|
assert not o1.require_approval
|
||||||
|
assert o1.invoices.count() == 1
|
||||||
|
assert len(djmail.outbox) == 1
|
||||||
|
assert 'awaiting payment' in djmail.outbox[0].subject
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_approve_free(event):
|
||||||
|
djmail.outbox = []
|
||||||
|
event.settings.invoice_generate = 'True'
|
||||||
|
o1 = Order.objects.create(
|
||||||
|
code='FOO', event=event, email='dummy@dummy.test',
|
||||||
|
status=Order.STATUS_PENDING,
|
||||||
|
datetime=now(), expires=now() - timedelta(days=10),
|
||||||
|
total=0, require_approval=True
|
||||||
|
)
|
||||||
|
approve_order(o1)
|
||||||
|
o1.refresh_from_db()
|
||||||
|
assert o1.expires > now()
|
||||||
|
assert o1.status == Order.STATUS_PAID
|
||||||
|
assert not o1.require_approval
|
||||||
|
assert o1.invoices.count() == 0
|
||||||
|
assert len(djmail.outbox) == 1
|
||||||
|
assert 'confirmed' in djmail.outbox[0].subject
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_deny(event):
|
||||||
|
djmail.outbox = []
|
||||||
|
event.settings.invoice_generate = 'True'
|
||||||
|
o1 = Order.objects.create(
|
||||||
|
code='FOO', event=event, email='dummy@dummy.test',
|
||||||
|
status=Order.STATUS_PENDING,
|
||||||
|
datetime=now(), expires=now() - timedelta(days=10),
|
||||||
|
total=10, require_approval=True, locale='de'
|
||||||
|
)
|
||||||
|
generate_invoice(o1)
|
||||||
|
deny_order(o1)
|
||||||
|
o1.refresh_from_db()
|
||||||
|
assert o1.expires < now()
|
||||||
|
assert o1.status == Order.STATUS_CANCELED
|
||||||
|
assert o1.require_approval
|
||||||
|
assert o1.invoices.count() == 2
|
||||||
|
assert len(djmail.outbox) == 1
|
||||||
|
assert 'denied' in djmail.outbox[0].subject
|
||||||
|
|
||||||
|
|
||||||
class DownloadReminderTests(TestCase):
|
class DownloadReminderTests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|||||||
@@ -92,6 +92,13 @@ def test_order_list(client, env):
|
|||||||
response = client.get('/control/event/dummy/dummy/orders/?status=o')
|
response = client.get('/control/event/dummy/dummy/orders/?status=o')
|
||||||
assert 'FOO' in response.rendered_content
|
assert 'FOO' in response.rendered_content
|
||||||
|
|
||||||
|
response = client.get('/control/event/dummy/dummy/orders/?status=pa')
|
||||||
|
assert 'FOO' not in response.rendered_content
|
||||||
|
env[2].require_approval = True
|
||||||
|
env[2].save()
|
||||||
|
response = client.get('/control/event/dummy/dummy/orders/?status=pa')
|
||||||
|
assert 'FOO' in response.rendered_content
|
||||||
|
|
||||||
q = Question.objects.create(event=env[0], question="Q", type="N", required=True)
|
q = Question.objects.create(event=env[0], question="Q", type="N", required=True)
|
||||||
q.items.add(env[3])
|
q.items.add(env[3])
|
||||||
op = env[2].positions.first()
|
op = env[2].positions.first()
|
||||||
@@ -208,6 +215,40 @@ def test_order_transition_to_paid_expired_quota_left(client, env):
|
|||||||
assert o.status == Order.STATUS_PAID
|
assert o.status == Order.STATUS_PAID
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_order_approve(client, env):
|
||||||
|
o = Order.objects.get(id=env[2].id)
|
||||||
|
o.status = Order.STATUS_PENDING
|
||||||
|
o.require_approval = True
|
||||||
|
o.save()
|
||||||
|
q = Quota.objects.create(event=env[0], size=10)
|
||||||
|
q.items.add(env[3])
|
||||||
|
client.login(email='dummy@dummy.dummy', password='dummy')
|
||||||
|
res = client.post('/control/event/dummy/dummy/orders/FOO/approve', {
|
||||||
|
})
|
||||||
|
o = Order.objects.get(id=env[2].id)
|
||||||
|
assert res.status_code < 400
|
||||||
|
assert o.status == Order.STATUS_PENDING
|
||||||
|
assert not o.require_approval
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_order_deny(client, env):
|
||||||
|
o = Order.objects.get(id=env[2].id)
|
||||||
|
o.status = Order.STATUS_PENDING
|
||||||
|
o.require_approval = True
|
||||||
|
o.save()
|
||||||
|
q = Quota.objects.create(event=env[0], size=10)
|
||||||
|
q.items.add(env[3])
|
||||||
|
client.login(email='dummy@dummy.dummy', password='dummy')
|
||||||
|
res = client.post('/control/event/dummy/dummy/orders/FOO/deny', {
|
||||||
|
})
|
||||||
|
o = Order.objects.get(id=env[2].id)
|
||||||
|
assert res.status_code < 400
|
||||||
|
assert o.status == Order.STATUS_CANCELED
|
||||||
|
assert o.require_approval
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@pytest.mark.parametrize("process", [
|
@pytest.mark.parametrize("process", [
|
||||||
# (Old status, new status, success expected)
|
# (Old status, new status, success expected)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ from django_countries.fields import Country
|
|||||||
|
|
||||||
from pretix.base.decimal import round_decimal
|
from pretix.base.decimal import round_decimal
|
||||||
from pretix.base.models import (
|
from pretix.base.models import (
|
||||||
CartPosition, Event, InvoiceAddress, Item, ItemCategory, Order,
|
CartPosition, Event, Invoice, InvoiceAddress, Item, ItemCategory, Order,
|
||||||
OrderPosition, Organizer, Question, QuestionAnswer, Quota, Voucher,
|
OrderPosition, Organizer, Question, QuestionAnswer, Quota, Voucher,
|
||||||
)
|
)
|
||||||
from pretix.base.models.items import ItemAddOn, ItemVariation, SubEventItem
|
from pretix.base.models.items import ItemAddOn, ItemVariation, SubEventItem
|
||||||
@@ -803,6 +803,43 @@ class CheckoutTestCase(TestCase):
|
|||||||
self.assertEqual(OrderPosition.objects.count(), 1)
|
self.assertEqual(OrderPosition.objects.count(), 1)
|
||||||
self.assertEqual(OrderPosition.objects.first().subevent, se)
|
self.assertEqual(OrderPosition.objects.first().subevent, se)
|
||||||
|
|
||||||
|
def test_require_approval_no_payment_step(self):
|
||||||
|
self.event.settings.invoice_generate = 'True'
|
||||||
|
self.ticket.require_approval = True
|
||||||
|
self.ticket.save()
|
||||||
|
cr1 = CartPosition.objects.create(
|
||||||
|
event=self.event, cart_id=self.session_key, item=self.ticket,
|
||||||
|
price=42, expires=now() + timedelta(minutes=10)
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.client.post('/%s/%s/checkout/confirm/' % (self.orga.slug, self.event.slug), follow=True)
|
||||||
|
doc = BeautifulSoup(response.rendered_content, "lxml")
|
||||||
|
print(doc)
|
||||||
|
self.assertEqual(len(doc.select(".thank-you")), 1)
|
||||||
|
self.assertFalse(CartPosition.objects.filter(id=cr1.id).exists())
|
||||||
|
self.assertEqual(Order.objects.count(), 1)
|
||||||
|
self.assertEqual(Order.objects.first().status, Order.STATUS_PENDING)
|
||||||
|
self.assertTrue(Order.objects.first().require_approval)
|
||||||
|
self.assertEqual(OrderPosition.objects.count(), 1)
|
||||||
|
self.assertEqual(Invoice.objects.count(), 0)
|
||||||
|
|
||||||
|
def test_require_approval_no_payment_step_free(self):
|
||||||
|
self.ticket.require_approval = True
|
||||||
|
self.ticket.save()
|
||||||
|
cr1 = CartPosition.objects.create(
|
||||||
|
event=self.event, cart_id=self.session_key, item=self.ticket,
|
||||||
|
price=0, expires=now() + timedelta(minutes=10)
|
||||||
|
)
|
||||||
|
|
||||||
|
response = self.client.post('/%s/%s/checkout/confirm/' % (self.orga.slug, self.event.slug), follow=True)
|
||||||
|
doc = BeautifulSoup(response.rendered_content, "lxml")
|
||||||
|
self.assertEqual(len(doc.select(".thank-you")), 1)
|
||||||
|
self.assertFalse(CartPosition.objects.filter(id=cr1.id).exists())
|
||||||
|
self.assertEqual(Order.objects.count(), 1)
|
||||||
|
self.assertEqual(Order.objects.first().status, Order.STATUS_PENDING)
|
||||||
|
self.assertTrue(Order.objects.first().require_approval)
|
||||||
|
self.assertEqual(OrderPosition.objects.count(), 1)
|
||||||
|
|
||||||
def test_free_price(self):
|
def test_free_price(self):
|
||||||
self.ticket.free_price = True
|
self.ticket.free_price = True
|
||||||
self.ticket.save()
|
self.ticket.save()
|
||||||
|
|||||||
Reference in New Issue
Block a user