Add a simple test mode (#1181)

- [x] Provide data model and configuration toggle
- [x] Allow to delete individual test orders
- [x] Add tests
- [x] Add a prominent warning message to the backend if test mode orders exist (even though test mode is off), as this leads to wrong statistics
- [x] Decide if and how to generate invoices for test orders as invoice numbers cannot be repeated or should not have gaps.
- [x] Decide if and how we expose test orders through the API, since our difference pull mechanism relies on the fact that orders cannot be deleted.
- [x] Decide if and how we want to couple test modes of payment providers?
- [ ] pretix.eu: Ignore test orders for billing
- [ ] Adjust payment providers: Mollie, bitpay, cash, fakepayment, sepadebit

![download](https://user-images.githubusercontent.com/64280/53009081-fe420d80-343a-11e9-8361-b8511c988598.png)
This commit is contained in:
Raphael Michel
2019-02-20 17:51:26 +01:00
committed by GitHub
parent 8ffc96bf31
commit 67059fe323
49 changed files with 759 additions and 91 deletions

View File

@@ -181,6 +181,7 @@ TEST_REFUNDS_RES = [
TEST_ORDER_RES = {
"code": "FOO",
"status": "n",
"testmode": False,
"secret": "k24fiuwvu8kxz3y1",
"email": "dummy@dummy.test",
"locale": "en",
@@ -242,6 +243,11 @@ def test_order_list(token_client, organizer, event, order, item, taxrule, questi
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?code=BAR'.format(organizer.slug, event.slug))
assert [] == resp.data['results']
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?testmode=false'.format(organizer.slug, event.slug))
assert [res] == resp.data['results']
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?testmode=true'.format(organizer.slug, event.slug))
assert [] == resp.data['results']
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?status=n'.format(organizer.slug, event.slug))
assert [res] == resp.data['results']
resp = token_client.get('/api/v1/organizers/{}/events/{}/orders/?status=p'.format(organizer.slug, event.slug))
@@ -1352,6 +1358,7 @@ def test_order_create(token_client, organizer, event, item, quota, question):
assert o.total == Decimal('23.25')
assert o.status == Order.STATUS_PENDING
assert o.sales_channel == "web"
assert not o.testmode
p = o.payments.first()
assert p.provider == "banktransfer"
@@ -1423,6 +1430,22 @@ def test_order_create_sales_channel_invalid(token_client, organizer, event, item
assert resp.data == {'sales_channel': ['Unknown sales channel.']}
@pytest.mark.django_db
def test_order_create_in_test_mode(token_client, organizer, event, item, quota, question):
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)
res['positions'][0]['item'] = item.pk
res['positions'][0]['answers'][0]['question'] = question.pk
res['testmode'] = True
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/'.format(
organizer.slug, event.slug
), format='json', data=res
)
assert resp.status_code == 201
o = Order.objects.get(code=resp.data['code'])
assert o.testmode
@pytest.mark.django_db
def test_order_create_attendee_name_optional(token_client, organizer, event, item, quota, question):
res = copy.deepcopy(ORDER_CREATE_PAYLOAD)
@@ -2502,3 +2525,26 @@ def test_refund_create_invalid_payment(token_client, organizer, event, order):
), format='json', data=res
)
assert resp.status_code == 400
@pytest.mark.django_db
def test_order_delete(token_client, organizer, event, order):
resp = token_client.delete(
'/api/v1/organizers/{}/events/{}/orders/{}/'.format(
organizer.slug, event.slug, order.code
)
)
assert resp.status_code == 403
@pytest.mark.django_db
def test_order_delete_test_mode(token_client, organizer, event, order):
order.testmode = True
order.save()
resp = token_client.delete(
'/api/v1/organizers/{}/events/{}/orders/{}/'.format(
organizer.slug, event.slug, order.code
)
)
assert resp.status_code == 204
assert not Order.objects.filter(code=order.code).exists()