Writable API for ticket layouts (#3004)

Co-authored-by: Richard Schreiber <schreiber@rami.io>
This commit is contained in:
Raphael Michel
2023-01-09 13:44:01 +01:00
committed by GitHub
parent 2e702b87de
commit e5528f7784
8 changed files with 770 additions and 36 deletions

View File

@@ -23,9 +23,12 @@ import copy
import json
import pytest
from django.core.files.base import ContentFile
from django.utils.timezone import now
from django_scopes import scopes_disabled
from rest_framework.test import APIClient
from pretix.base.models import Event, Item, Organizer, Team, User
from pretix.base.models import Event, Item, Organizer, Team
from pretix.plugins.ticketoutputpdf.models import TicketLayoutItem
@@ -36,14 +39,25 @@ def env():
organizer=o, name='Dummy', slug='dummy',
date_from=now(), plugins='pretix.plugins.banktransfer'
)
user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
t = Team.objects.create(organizer=event.organizer)
t.members.add(user)
t.limit_events.add(event)
item1 = Item.objects.create(event=event, name="Ticket", default_price=23)
tl = event.ticket_layouts.create(name="Foo", default=True, layout='[{"a": 2}]')
TicketLayoutItem.objects.create(layout=tl, item=item1)
return event, user, tl, item1
return event, tl, item1
@pytest.fixture
def client():
return APIClient()
@pytest.fixture
@scopes_disabled()
def token_client(client, env):
t = env[0].organizer.teams.get().tokens.create(name="Foo")
client.credentials(HTTP_AUTHORIZATION="Token " + t.token)
return client
RES_LAYOUT = {
@@ -57,32 +71,145 @@ RES_LAYOUT = {
@pytest.mark.django_db
def test_api_list(env, client):
def test_api_list(env, token_client):
res = copy.copy(RES_LAYOUT)
res['id'] = env[2].pk
res['item_assignments'][0]['item'] = env[3].pk
client.login(email='dummy@dummy.dummy', password='dummy')
r = json.loads(
client.get('/api/v1/organizers/{}/events/{}/ticketlayouts/'.format(
env[0].slug, env[0].organizer.slug)).content.decode('utf-8')
)
res['id'] = env[1].pk
res['item_assignments'][0]['item'] = env[2].pk
r = token_client.get('/api/v1/organizers/{}/events/{}/ticketlayouts/'.format(
env[0].organizer.slug, env[0].slug)).data
assert r['results'] == [res]
r = json.loads(
client.get('/api/v1/organizers/{}/events/{}/ticketlayoutitems/'.format(
env[0].slug, env[0].organizer.slug)).content.decode('utf-8')
)
assert r['results'] == [{'item': env[3].pk, 'layout': env[2].pk, 'id': env[2].item_assignments.first().pk,
r = token_client.get('/api/v1/organizers/{}/events/{}/ticketlayoutitems/'.format(
env[0].organizer.slug, env[0].slug)).data
assert r['results'] == [{'item': env[2].pk, 'layout': env[1].pk, 'id': env[1].item_assignments.first().pk,
'sales_channel': 'web'}]
@pytest.mark.django_db
def test_api_detail(env, client):
def test_api_detail(env, token_client):
res = copy.copy(RES_LAYOUT)
res['id'] = env[2].pk
res['item_assignments'][0]['item'] = env[3].pk
client.login(email='dummy@dummy.dummy', password='dummy')
r = json.loads(
client.get('/api/v1/organizers/{}/events/{}/ticketlayouts/{}/'.format(
env[0].slug, env[0].organizer.slug, env[2].pk)).content.decode('utf-8')
)
res['id'] = env[1].pk
res['item_assignments'][0]['item'] = env[2].pk
r = token_client.get('/api/v1/organizers/{}/events/{}/ticketlayouts/{}/'.format(
env[0].organizer.slug, env[0].slug, env[1].pk)).data
assert r == res
@pytest.mark.django_db
def test_api_create(env, token_client):
r = token_client.post(
'/api/v1/upload',
data={
'media_type': 'application/pdf',
'file': ContentFile('file.pdf', 'invalid pdf content')
},
format='upload',
HTTP_CONTENT_DISPOSITION='attachment; filename="file.pdf"',
)
assert r.status_code == 201
file_id_png = r.data['id']
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/ticketlayouts/'.format(env[0].slug, env[0].slug),
{
'name': 'Foo',
'default': False,
"background": file_id_png,
'layout': [],
},
format='json'
)
assert resp.status_code == 201
tl = env[0].ticket_layouts.get(pk=resp.data["id"])
assert tl.background
@pytest.mark.django_db
def test_api_create_validate_default(env, token_client):
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/ticketlayouts/'.format(env[0].slug, env[0].slug),
{
'name': 'Foo',
'default': True,
'layout': [],
},
format='json'
)
assert resp.status_code == 400
assert resp.data == {"non_field_errors": ["You cannot have two layouts with default = True"]}
@pytest.mark.django_db
def test_api_create_validate_layout(env, token_client):
resp = token_client.post(
'/api/v1/organizers/{}/events/{}/ticketlayouts/'.format(env[0].slug, env[0].slug),
{
'name': 'Foo',
'default': True,
'layout': [
{
"foo": "bar"
}
],
},
format='json'
)
assert resp.status_code == 400
assert resp.data["layout"][0].startswith("Your layout file is not a valid layout. Error message:")
@pytest.mark.django_db
def test_api_update(env, token_client):
r = token_client.post(
'/api/v1/upload',
data={
'media_type': 'application/pdf',
'file': ContentFile('file.pdf', 'invalid pdf content')
},
format='upload',
HTTP_CONTENT_DISPOSITION='attachment; filename="file.pdf"',
)
assert r.status_code == 201
file_id_png = r.data['id']
resp = token_client.patch(
'/api/v1/organizers/{}/events/{}/ticketlayouts/{}/'.format(env[0].slug, env[0].slug, env[1].pk),
{
"name": "Bar",
"background": file_id_png,
"layout": [
{"type": "barcodearea", "left": "7.00", "bottom": "11.15", "size": "45.00", "content": "secret"}
]
},
format='json'
)
assert resp.status_code == 200
env[1].refresh_from_db()
assert env[1].name == "Bar"
assert env[1].background
assert json.loads(env[1].layout) == [
{"type": "barcodearea", "left": "7.00", "bottom": "11.15", "size": "45.00", "content": "secret"}
]
@pytest.mark.django_db
def test_api_update_validate_default(env, token_client):
tl2 = env[0].ticket_layouts.create(name="Foo", default=False, layout='[{"a": 2}]')
resp = token_client.patch(
'/api/v1/organizers/{}/events/{}/ticketlayouts/{}/'.format(env[0].slug, env[0].slug, tl2.pk),
{
"default": True,
},
format='json'
)
assert resp.status_code == 400
assert resp.data == {"non_field_errors": ["You cannot have two layouts with default = True"]}
@pytest.mark.django_db
def test_api_delete(env, token_client):
resp = token_client.delete(
'/api/v1/organizers/{}/events/{}/ticketlayouts/{}/'.format(env[0].slug, env[0].slug, env[1].pk),
)
assert resp.status_code == 204
assert not env[0].ticket_layouts.exists()