diff --git a/src/pretix/control/forms/waitinglist.py b/src/pretix/control/forms/waitinglist.py index 213eb2ebb2..831309aa8d 100644 --- a/src/pretix/control/forms/waitinglist.py +++ b/src/pretix/control/forms/waitinglist.py @@ -82,8 +82,9 @@ class WaitingListEntryEditForm(I18nModelForm): items = self.event.items.prefetch_related('variations').prefetch_related('quotas') for item in items: - if not item.allow_waitinglist | item.quotas.exists(): - continue + if not item.allow_waitinglist | item.quotas.exists(): # don't offer items in the selection if they don't allow waitinglists or aren't on sale at all + if not self.instance.item.pk == item.pk: # except if they are currently set in the waitinglist, this will be then caught on submit in the clean step + continue if len(item.variations.all()) > 0: for v in item.variations.all(): diff --git a/src/tests/control/test_waitinglist.py b/src/tests/control/test_waitinglist.py index 81c0fdaf16..fea9d50bbe 100644 --- a/src/tests/control/test_waitinglist.py +++ b/src/tests/control/test_waitinglist.py @@ -57,12 +57,10 @@ def env(): event.settings.set('waiting_list_names_required', False) user = User.objects.create_user('dummy@dummy.dummy', 'dummy') item1 = Item.objects.create(event=event, name="Ticket", default_price=23, - admission=True) + admission=True, allow_waitinglist=True) item2 = Item.objects.create(event=event, name="Ticket", default_price=23, admission=True) - item3 = Item.objects.create(event=event, name="Ticket", default_price=23, - admission=True, allow_waitinglist=True) - variation = ItemVariation.objects.create(item=item3) + for i in range(5): WaitingListEntry.objects.create( @@ -84,7 +82,7 @@ def env(): t = Team.objects.create(organizer=o, can_view_orders=True, can_change_orders=True) t.members.add(user) t.limit_events.add(event) - return event, user, o, item1, variation + return event, user, o, item1 @pytest.mark.django_db @@ -199,31 +197,53 @@ def test_delete_bulk(client, env): @pytest.mark.django_db def test_edit(client, env): + event = env[0] + item = Item.objects.create(event=event, name="Ticket", default_price=23, + admission=True, allow_waitinglist=True) + quota = Quota.objects.create(event=event) + quota.items.add(item) + client.login(email='dummy@dummy.dummy', password='dummy') with scopes_disabled(): - wle = WaitingListEntry.objects.first() - assert not wle.email.startswith("1_") - client.get('/control/event/dummy/dummy/waitinglist/%s/edit' % (wle.id)) - client.post('/control/event/dummy/dummy/waitinglist/%s/edit' % (wle.id), data={ - "email": f"1_{wle.email}", "itemvar": wle.item.pk - }) - wle.refresh_from_db() + wle = WaitingListEntry.objects.create( + event=event, item=item, email='foo@bar.com' + ) - assert wle.email.startswith('1_') + client.get('/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id) + response = client.post( + '/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id, + data={ + "email": f"1_{wle.email}", + "itemvar": item.pk + }, + follow=True + ) + assert response.wsgi_request.path == '/control/event/dummy/dummy/waitinglist/' @pytest.mark.django_db def test_edit_itemvariation(client, env): + event = env[0] + + item = Item.objects.create(event=event, name="Ticket", default_price=23, + admission=True, allow_waitinglist=True) + variation = ItemVariation.objects.create(item=item) + quota = Quota.objects.create(event=event) + quota.items.add(item) + quota.variations.add(variation) + client.login(email='dummy@dummy.dummy', password='dummy') with scopes_disabled(): - wle = WaitingListEntry.objects.first() - assert not wle.email.startswith("1_") - client.get('/control/event/dummy/dummy/waitinglist/%s/edit' % (wle.id)) + wle = WaitingListEntry.objects.create( + event=event, item=item, variation=variation, email='foo@bar.com' + ) - itemvar = f"{env[4].item.pk}-{env[4].pk}" + client.get('/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id) + + itemvar = f"{item.pk}-{variation.pk}" response = client.post( - '/control/event/dummy/dummy/waitinglist/%s/edit' % (wle.id), + '/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id, data={ "email": f"1_{wle.email}", "itemvar": itemvar @@ -232,19 +252,92 @@ def test_edit_itemvariation(client, env): ) assert response.wsgi_request.path == '/control/event/dummy/dummy/waitinglist/' - response = client.get('/control/event/dummy/dummy/waitinglist/%s/edit' % (wle.id)) - assert response.context['form'].initial['itemvar'] == itemvar - @pytest.mark.django_db -def test_invalid_edit(client, env): +def test_edit_voucher_send_out(client, env): + event = env[0] + + item = Item.objects.create(event=event, name="Ticket", default_price=23, + admission=True, allow_waitinglist=True) + + quota = Quota.objects.create(event=event, size=100) + quota.items.add(item) + client.login(email='dummy@dummy.dummy', password='dummy') with scopes_disabled(): - wle = WaitingListEntry.objects.first() - assert not wle.email.startswith("1_") - response = client.post('/control/event/dummy/dummy/waitinglist/%s/edit' % (wle.id), data={}) - assert response.context['form'].errors is not None + wle = WaitingListEntry.objects.create( + event=event, item=item, email='foo@bar.com' + ) + client.get('/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id) + wle.send_voucher() + response = client.post( + '/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id, + data={ + "email": f"1_{wle.email}", + "itemvar": item.pk + }, + follow=True + ) + assert response.status_code == 404 + +@pytest.mark.django_db +def test_edit_item_without_waitinglist(client, env): + event = env[0] + item = Item.objects.create(event=event, name="Ticket", default_price=23, + admission=True, allow_waitinglist=True) + item_without_waitinglist = Item.objects.create(event=event, name="Ticket", default_price=23, + admission=True, allow_waitinglist=False) + quota = Quota.objects.create(event=event) + quota.items.add(item) + quota.items.add(item_without_waitinglist) + + client.login(email='dummy@dummy.dummy', password='dummy') + with scopes_disabled(): + wle = WaitingListEntry.objects.create( + event=event, item=item, email='foo@bar.com' + ) + + client.get('/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id) + + response = client.post( + '/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id, + data={ + "email": f"1_{wle.email}", + "itemvar": item_without_waitinglist.pk + }, + follow=True + ) + assert response.context['form'].errors == {'itemvar': ["The selected product does not allow waiting list entries."]} + +@pytest.mark.django_db +def test_edit_item_without_quota(client, env): + event = env[0] + item = Item.objects.create(event=event, name="Ticket", default_price=23, + admission=True, allow_waitinglist=True) + item_without_waitinglist = Item.objects.create(event=event, name="Ticket", default_price=23, + admission=True, allow_waitinglist=True) + quota = Quota.objects.create(event=event) + quota.items.add(item) + + + client.login(email='dummy@dummy.dummy', password='dummy') + with scopes_disabled(): + wle = WaitingListEntry.objects.create( + event=event, item=item, email='foo@bar.com' + ) + + client.get('/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id) + + response = client.post( + '/control/event/dummy/dummy/waitinglist/%s/edit' % wle.id, + data={ + "email": f"1_{wle.email}", + "itemvar": item_without_waitinglist.pk + }, + follow=True + ) + assert response.context['form'].errors == {'itemvar': ["The selected product is not on sale because there is no quota configured for it."]} @pytest.mark.django_db def test_dashboard(client, env):