From 8121167d5e8a23c844d68bd2a84b9ca03eecb80b Mon Sep 17 00:00:00 2001 From: Richard Schreiber Date: Tue, 12 Oct 2021 14:46:56 +0200 Subject: [PATCH] Control: Add drag and drop to sort categories and products (#2242) * add drag and drop to categories * add drag and drop to products * add light grey background to dragged element * add missing th, add sr-only desc of columns * group up/down/move elements * improve visualizing drag-area by dimming others * change up/down-links to buttons in form-post * limit sorting to POST requests Co-authored-by: Raphael Michel --- .../pretixcontrol/items/categories.html | 12 +- .../templates/pretixcontrol/items/index.html | 19 +- src/pretix/control/urls.py | 2 + src/pretix/control/views/item.py | 72 +++++- .../pretixcontrol/js/ui/dragndroplist.js | 31 ++- .../static/pretixcontrol/scss/main.scss | 14 ++ src/tests/control/test_items.py | 4 +- src/tests/control/test_permissions.py | 207 ++++++++++-------- 8 files changed, 249 insertions(+), 112 deletions(-) diff --git a/src/pretix/control/templates/pretixcontrol/items/categories.html b/src/pretix/control/templates/pretixcontrol/items/categories.html index 237062ccf..e51de4072 100644 --- a/src/pretix/control/templates/pretixcontrol/items/categories.html +++ b/src/pretix/control/templates/pretixcontrol/items/categories.html @@ -24,6 +24,8 @@ {% trans "Create a new category" %}

+
+ {% csrf_token %}
@@ -33,15 +35,16 @@ - + {% for c in categories %} - +
{{ c.internal_name|default:c.name }} - - + + + @@ -56,6 +59,7 @@
+
{% include "pretixcontrol/pagination.html" %} {% endif %} {% endblock %} diff --git a/src/pretix/control/templates/pretixcontrol/items/index.html b/src/pretix/control/templates/pretixcontrol/items/index.html index 92847f61e..84baa4666 100644 --- a/src/pretix/control/templates/pretixcontrol/items/index.html +++ b/src/pretix/control/templates/pretixcontrol/items/index.html @@ -26,6 +26,8 @@ {% trans "Create a new product" %}

+
+ {% csrf_token %}
@@ -36,15 +38,16 @@ - - + + - {% regroup items by category as cat_list %} {% for c in cat_list %} + {% for i in c.list %} - + {% if forloop.counter0 == 0 and i.category %}{% endif %} + {% endfor %} + {% endfor %} -
{% trans "Category" %}MoveEdit
{{ i.category.name }}
{% if not i.active %}{% endif %} {{ i }} @@ -105,8 +108,9 @@ {% if i.category %}{{ i.category.name }}{% endif %} - - + + + @@ -115,10 +119,11 @@
+
{% include "pretixcontrol/pagination.html" %} {% endif %} {% endblock %} diff --git a/src/pretix/control/urls.py b/src/pretix/control/urls.py index 56d13049c..5d23f4fcb 100644 --- a/src/pretix/control/urls.py +++ b/src/pretix/control/urls.py @@ -239,6 +239,7 @@ urlpatterns = [ re_path(r'^items/(?P\d+)/$', item.ItemUpdateGeneral.as_view(), name='event.item'), re_path(r'^items/(?P\d+)/up$', item.item_move_up, name='event.items.up'), re_path(r'^items/(?P\d+)/down$', item.item_move_down, name='event.items.down'), + re_path(r'^items/reorder$', item.reorder_items, name='event.items.reorder'), re_path(r'^items/(?P\d+)/delete$', item.ItemDelete.as_view(), name='event.items.delete'), re_path(r'^items/typeahead/meta/$', typeahead.item_meta_values, name='event.items.meta.typeahead'), re_path(r'^items/select2$', typeahead.items_select2, name='event.items.select2'), @@ -250,6 +251,7 @@ urlpatterns = [ re_path(r'^categories/(?P\d+)/up$', item.category_move_up, name='event.items.categories.up'), re_path(r'^categories/(?P\d+)/down$', item.category_move_down, name='event.items.categories.down'), + re_path(r'^categories/reorder$', item.reorder_categories, name='event.items.categories.reorder'), re_path(r'^categories/(?P\d+)/$', item.CategoryUpdate.as_view(), name='event.items.categories.edit'), re_path(r'^categories/add$', item.CategoryCreate.as_view(), name='event.items.categories.add'), diff --git a/src/pretix/control/views/item.py b/src/pretix/control/views/item.py index 12a05d1f1..4e3c6c541 100644 --- a/src/pretix/control/views/item.py +++ b/src/pretix/control/views/item.py @@ -53,6 +53,7 @@ from django.urls import resolve, reverse from django.utils.functional import cached_property from django.utils.timezone import now from django.utils.translation import gettext, gettext_lazy as _ +from django.views.decorators.http import require_http_methods from django.views.generic import ListView from django.views.generic.detail import DetailView, SingleObjectMixin from django.views.generic.edit import DeleteView @@ -138,6 +139,7 @@ def item_move(request, item, up=True): @event_permission_required("can_change_items") +@require_http_methods(["POST"]) def item_move_up(request, organizer, event, item): item_move(request, item, up=True) return redirect('control:event.items', @@ -146,6 +148,7 @@ def item_move_up(request, organizer, event, item): @event_permission_required("can_change_items") +@require_http_methods(["POST"]) def item_move_down(request, organizer, event, item): item_move(request, item, up=False) return redirect('control:event.items', @@ -153,6 +156,38 @@ def item_move_down(request, organizer, event, item): event=request.event.slug) +@transaction.atomic +@event_permission_required("can_change_items") +@require_http_methods(["POST"]) +def reorder_items(request, organizer, event): + try: + ids = json.loads(request.body.decode('utf-8'))['ids'] + except (JSONDecodeError, KeyError, ValueError): + return HttpResponseBadRequest("expected JSON: {ids:[]}") + + input_items = list(request.event.items.filter(id__in=[i for i in ids if i.isdigit()])) + + if len(input_items) != len(ids): + raise Http404(_("Some of the provided item ids are invalid.")) + + item_categories = {i.category_id for i in input_items} + if len(item_categories) > 1: + raise Http404(_("You cannot reorder items spanning different categories.")) + + # get first and only category + item_category = next(iter(item_categories)) + if len(input_items) != request.event.items.filter(category=item_category).count(): + raise Http404(_("Not all items have been selected.")) + + for i in input_items: + pos = ids.index(str(i.pk)) + if pos != i.position: # Save unneccessary UPDATE queries + i.position = pos + i.save(update_fields=['position']) + + return HttpResponse() + + class CategoryDelete(EventPermissionRequiredMixin, DeleteView): model = ItemCategory form_class = CategoryForm @@ -307,6 +342,7 @@ def category_move(request, category, up=True): @event_permission_required("can_change_items") +@require_http_methods(["POST"]) def category_move_up(request, organizer, event, category): category_move(request, category, up=True) return redirect('control:event.items.categories', @@ -315,6 +351,7 @@ def category_move_up(request, organizer, event, category): @event_permission_required("can_change_items") +@require_http_methods(["POST"]) def category_move_down(request, organizer, event, category): category_move(request, category, up=False) return redirect('control:event.items.categories', @@ -322,6 +359,32 @@ def category_move_down(request, organizer, event, category): event=request.event.slug) +@transaction.atomic +@event_permission_required("can_change_items") +@require_http_methods(["POST"]) +def reorder_categories(request, organizer, event): + try: + ids = json.loads(request.body.decode('utf-8'))['ids'] + except (JSONDecodeError, KeyError, ValueError): + return HttpResponseBadRequest("expected JSON: {ids:[]}") + + input_categories = list(request.event.categories.filter(id__in=[i for i in ids if i.isdigit()])) + + if len(input_categories) != len(ids): + raise Http404(_("Some of the provided category ids are invalid.")) + + if len(input_categories) != request.event.categories.count(): + raise Http404(_("Not all categories have been selected.")) + + for c in input_categories: + pos = ids.index(str(c.pk)) + if pos != c.position: # Save unneccessary UPDATE queries + c.position = pos + c.save(update_fields=['position']) + + return HttpResponse() + + FakeQuestion = namedtuple( 'FakeQuestion', 'id question position required' ) @@ -423,18 +486,21 @@ class QuestionList(ListView): @transaction.atomic @event_permission_required("can_change_items") +@require_http_methods(["POST"]) def reorder_questions(request, organizer, event): try: ids = json.loads(request.body.decode('utf-8'))['ids'] except (JSONDecodeError, KeyError, ValueError): return HttpResponseBadRequest("expected JSON: {ids:[]}") - input_questions = request.event.questions.filter(id__in=[i for i in ids if i.isdigit()]) + # filter system_questions - normal questions are int/digit, system_questions strings + custom_question_ids = [i for i in ids if i.isdigit()] + input_questions = list(request.event.questions.filter(id__in=custom_question_ids)) - if input_questions.count() != len([i for i in ids if i.isdigit()]): + if len(input_questions) != len(custom_question_ids): raise Http404(_("Some of the provided question ids are invalid.")) - if input_questions.count() != request.event.questions.count(): + if len(input_questions) != request.event.questions.count(): raise Http404(_("Not all questions have been selected.")) for q in input_questions: diff --git a/src/pretix/static/pretixcontrol/js/ui/dragndroplist.js b/src/pretix/static/pretixcontrol/js/ui/dragndroplist.js index a9b1e9ac7..970374596 100644 --- a/src/pretix/static/pretixcontrol/js/ui/dragndroplist.js +++ b/src/pretix/static/pretixcontrol/js/ui/dragndroplist.js @@ -5,11 +5,40 @@ $(function () { url = container.data("dnd-url"), handle = $(''); - console.log(container, container.find(".dnd-container")); container.find(".dnd-container").append(handle); + if (container.find("[data-dnd-id]").length < 2) { + handle.addClass("disabled"); + return; + } Sortable.create(container.get(0), { + filter: ".sortable-disabled", handle: ".dnd-sort-handle", + onMove: function (evt) { + return evt.related.className.indexOf('sortable-disabled') === -1; + }, + onStart: function (evt) { + container.addClass("sortable-dragarea"); + container.parent().addClass("sortable-sorting"); + }, + onEnd: function (evt) { + container.removeClass("sortable-dragarea"); + container.parent().removeClass("sortable-sorting"); + + var disabledUp = container.find(".sortable-up:disabled"), + firstUp = container.find(">tr[data-dnd-id] .sortable-up").first(); + if (disabledUp.length && disabledUp.get(0) !== firstUp.get(0)) { + disabledUp.prop("disabled", false); + firstUp.prop("disabled", true); + } + + var disabledDown = container.find(".sortable-down:disabled"), + lastDown = container.find(">tr[data-dnd-id] .sortable-down").last(); + if (disabledDown.length && disabledDown.get(0) !== lastDown.get(0)) { + disabledDown.prop("disabled", false); + lastDown.prop("disabled", true); + } + }, onSort: function (evt){ var container = $(evt.to), ids = container.find("[data-dnd-id]").toArray().map(function (e) { return e.dataset.dndId; }); diff --git a/src/pretix/static/pretixcontrol/scss/main.scss b/src/pretix/static/pretixcontrol/scss/main.scss index 42db8ebee..c09f43eba 100644 --- a/src/pretix/static/pretixcontrol/scss/main.scss +++ b/src/pretix/static/pretixcontrol/scss/main.scss @@ -706,6 +706,20 @@ h1 .label { } } +.sortable-chosen { + background-color: $table-bg-hover; +} +tbody[data-dnd-url] { + transition: opacity 1s; +} +.sortable-sorting tbody:not(.sortable-dragarea) { + opacity: .4; +} +tbody th { + background: $table-bg-hover; +} + + .withoutjs { display: none !important; } diff --git a/src/tests/control/test_items.py b/src/tests/control/test_items.py index aed30f971..c44263e65 100644 --- a/src/tests/control/test_items.py +++ b/src/tests/control/test_items.py @@ -94,12 +94,12 @@ class CategoriesTest(ItemFormTest): self.assertIn("Entry tickets", doc.select("table > tbody > tr")[0].text) self.assertIn("T-Shirts", doc.select("table > tbody > tr")[1].text) - self.client.get('/control/event/%s/%s/categories/%s/down' % (self.orga1.slug, self.event1.slug, c1.id)) + self.client.post('/control/event/%s/%s/categories/%s/down' % (self.orga1.slug, self.event1.slug, c1.id)) doc = self.get_doc('/control/event/%s/%s/categories/' % (self.orga1.slug, self.event1.slug)) self.assertIn("Entry tickets", doc.select("table > tbody > tr")[1].text) self.assertIn("T-Shirts", doc.select("table > tbody > tr")[0].text) - self.client.get('/control/event/%s/%s/categories/%s/up' % (self.orga1.slug, self.event1.slug, c1.id)) + self.client.post('/control/event/%s/%s/categories/%s/up' % (self.orga1.slug, self.event1.slug, c1.id)) doc = self.get_doc('/control/event/%s/%s/categories/' % (self.orga1.slug, self.event1.slug)) self.assertIn("Entry tickets", doc.select("table > tbody > tr")[0].text) self.assertIn("T-Shirts", doc.select("table > tbody > tr")[1].text) diff --git a/src/tests/control/test_permissions.py b/src/tests/control/test_permissions.py index f3e5b71e0..7bde4dfed 100644 --- a/src/tests/control/test_permissions.py +++ b/src/tests/control/test_permissions.py @@ -272,104 +272,109 @@ def test_wrong_event(perf_patch, client, env, url): assert response.status_code == 404 +HTTP_POST = "post" +HTTP_GET = "get" + event_permission_urls = [ - ("can_change_event_settings", "live/", 200), - ("can_change_event_settings", "delete/", 200), - ("can_change_event_settings", "dangerzone/", 200), - ("can_change_event_settings", "settings/", 200), - ("can_change_event_settings", "settings/plugins", 200), - ("can_change_event_settings", "settings/payment", 200), - ("can_change_event_settings", "settings/tickets", 200), - ("can_change_event_settings", "settings/email", 200), - ("can_change_event_settings", "settings/cancel", 200), - ("can_change_event_settings", "settings/invoice", 200), - ("can_change_event_settings", "settings/widget", 200), - ("can_change_event_settings", "settings/invoice/preview", 200), - ("can_change_event_settings", "settings/tax/", 200), - ("can_change_event_settings", "settings/tax/1/", 404), - ("can_change_event_settings", "settings/tax/add", 200), - ("can_change_event_settings", "settings/tax/1/delete", 404), - ("can_change_event_settings", "comment/", 405), + ("can_change_event_settings", "live/", 200, HTTP_GET), + ("can_change_event_settings", "delete/", 200, HTTP_GET), + ("can_change_event_settings", "dangerzone/", 200, HTTP_GET), + ("can_change_event_settings", "settings/", 200, HTTP_GET), + ("can_change_event_settings", "settings/plugins", 200, HTTP_GET), + ("can_change_event_settings", "settings/payment", 200, HTTP_GET), + ("can_change_event_settings", "settings/tickets", 200, HTTP_GET), + ("can_change_event_settings", "settings/email", 200, HTTP_GET), + ("can_change_event_settings", "settings/cancel", 200, HTTP_GET), + ("can_change_event_settings", "settings/invoice", 200, HTTP_GET), + ("can_change_event_settings", "settings/widget", 200, HTTP_GET), + ("can_change_event_settings", "settings/invoice/preview", 200, HTTP_GET), + ("can_change_event_settings", "settings/tax/", 200, HTTP_GET), + ("can_change_event_settings", "settings/tax/1/", 404, HTTP_GET), + ("can_change_event_settings", "settings/tax/add", 200, HTTP_GET), + ("can_change_event_settings", "settings/tax/1/delete", 404, HTTP_GET), + ("can_change_event_settings", "comment/", 405, HTTP_GET), # Lists are currently not access-controlled # ("can_change_items", "items/", 200), - ("can_change_items", "items/add", 200), - ("can_change_items", "items/1/up", 404), - ("can_change_items", "items/1/down", 404), - ("can_change_items", "items/1/delete", 404), + ("can_change_items", "items/add", 200, HTTP_GET), + ("can_change_items", "items/1/up", 404, HTTP_POST), + ("can_change_items", "items/1/down", 404, HTTP_POST), + ("can_change_items", "items/reorder", 400, HTTP_POST), + ("can_change_items", "items/1/delete", 404, HTTP_GET), # ("can_change_items", "categories/", 200), # We don't have to create categories and similar objects # for testing this, it is enough to test that a 404 error # is returned instead of a 403 one. - ("can_change_items", "categories/2/", 404), - ("can_change_items", "categories/2/delete", 404), - ("can_change_items", "categories/2/up", 404), - ("can_change_items", "categories/2/down", 404), - ("can_change_items", "categories/add", 200), - # ("can_change_items", "questions/", 200), - ("can_change_items", "questions/2/", 404), - ("can_change_items", "questions/2/delete", 404), - ("can_change_items", "questions/reorder", 400), - ("can_change_items", "questions/add", 200), - # ("can_change_items", "quotas/", 200), - ("can_change_items", "quotas/2/change", 404), - ("can_change_items", "quotas/2/delete", 404), - ("can_change_items", "quotas/add", 200), - ("can_change_event_settings", "subevents/", 200), - ("can_change_event_settings", "subevents/2/", 404), - ("can_change_event_settings", "subevents/2/delete", 404), - ("can_change_event_settings", "subevents/add", 200), - ("can_view_orders", "orders/overview/", 200), - ("can_view_orders", "orders/export/", 200), - ("can_view_orders", "orders/", 200), - ("can_view_orders", "orders/FOO/", 200), - ("can_change_orders", "orders/FOO/extend", 200), - ("can_change_orders", "orders/FOO/reactivate", 302), - ("can_change_orders", "orders/FOO/contact", 200), - ("can_change_orders", "orders/FOO/transition", 405), - ("can_change_orders", "orders/FOO/checkvatid", 405), - ("can_change_orders", "orders/FOO/resend", 405), - ("can_change_orders", "orders/FOO/invoice", 405), - ("can_change_orders", "orders/FOO/change", 200), - ("can_change_orders", "orders/FOO/approve", 200), - ("can_change_orders", "orders/FOO/deny", 200), - ("can_change_orders", "orders/FOO/delete", 302), - ("can_change_orders", "orders/FOO/comment", 405), - ("can_change_orders", "orders/FOO/locale", 200), - ("can_change_orders", "orders/FOO/sendmail", 200), - ("can_change_orders", "orders/FOO/1/sendmail", 404), - ("can_change_orders", "orders/import/", 200), - ("can_change_orders", "orders/import/0ab7b081-92d3-4480-82de-2f8b056fd32f/", 404), - ("can_view_orders", "orders/FOO/answer/5/", 404), - ("can_change_orders", "cancel/", 200), - ("can_change_vouchers", "vouchers/add", 200), - ("can_change_vouchers", "vouchers/bulk_add", 200), - ("can_view_vouchers", "vouchers/", 200), - ("can_view_vouchers", "vouchers/tags/", 200), - ("can_change_vouchers", "vouchers/1234/", 404), - ("can_change_vouchers", "vouchers/1234/delete", 404), - ("can_view_orders", "waitinglist/", 200), - ("can_change_orders", "waitinglist/auto_assign", 405), - ("can_change_orders", "waitinglist/action", 405), - ("can_view_orders", "checkins/", 200), - ("can_view_orders", "checkinlists/", 200), - ("can_view_orders", "checkinlists/1/", 404), - ("can_change_event_settings", "checkinlists/add", 200), - ("can_change_event_settings", "checkinlists/1/change", 404), - ("can_change_event_settings", "checkinlists/1/delete", 404), + ("can_change_items", "categories/2/", 404, HTTP_GET), + ("can_change_items", "categories/2/delete", 404, HTTP_GET), + ("can_change_items", "categories/2/up", 404, HTTP_POST), + ("can_change_items", "categories/2/down", 404, HTTP_POST), + ("can_change_items", "categories/reorder", 400, HTTP_POST), + ("can_change_items", "categories/add", 200, HTTP_GET), + # ("can_change_items", "questions/", 200, HTTP_GET), + ("can_change_items", "questions/2/", 404, HTTP_GET), + ("can_change_items", "questions/2/delete", 404, HTTP_GET), + ("can_change_items", "questions/reorder", 400, HTTP_POST), + ("can_change_items", "questions/add", 200, HTTP_GET), + # ("can_change_items", "quotas/", 200, HTTP_GET), + ("can_change_items", "quotas/2/change", 404, HTTP_GET), + ("can_change_items", "quotas/2/delete", 404, HTTP_GET), + ("can_change_items", "quotas/add", 200, HTTP_GET), + ("can_change_event_settings", "subevents/", 200, HTTP_GET), + ("can_change_event_settings", "subevents/2/", 404, HTTP_GET), + ("can_change_event_settings", "subevents/2/delete", 404, HTTP_GET), + ("can_change_event_settings", "subevents/add", 200, HTTP_GET), + ("can_view_orders", "orders/overview/", 200, HTTP_GET), + ("can_view_orders", "orders/export/", 200, HTTP_GET), + ("can_view_orders", "orders/", 200, HTTP_GET), + ("can_view_orders", "orders/FOO/", 200, HTTP_GET), + ("can_change_orders", "orders/FOO/extend", 200, HTTP_GET), + ("can_change_orders", "orders/FOO/reactivate", 302, HTTP_GET), + ("can_change_orders", "orders/FOO/contact", 200, HTTP_GET), + ("can_change_orders", "orders/FOO/transition", 405, HTTP_GET), + ("can_change_orders", "orders/FOO/checkvatid", 405, HTTP_GET), + ("can_change_orders", "orders/FOO/resend", 405, HTTP_GET), + ("can_change_orders", "orders/FOO/invoice", 405, HTTP_GET), + ("can_change_orders", "orders/FOO/change", 200, HTTP_GET), + ("can_change_orders", "orders/FOO/approve", 200, HTTP_GET), + ("can_change_orders", "orders/FOO/deny", 200, HTTP_GET), + ("can_change_orders", "orders/FOO/delete", 302, HTTP_GET), + ("can_change_orders", "orders/FOO/comment", 405, HTTP_GET), + ("can_change_orders", "orders/FOO/locale", 200, HTTP_GET), + ("can_change_orders", "orders/FOO/sendmail", 200, HTTP_GET), + ("can_change_orders", "orders/FOO/1/sendmail", 404, HTTP_GET), + ("can_change_orders", "orders/import/", 200, HTTP_GET), + ("can_change_orders", "orders/import/0ab7b081-92d3-4480-82de-2f8b056fd32f/", 404, HTTP_GET), + ("can_view_orders", "orders/FOO/answer/5/", 404, HTTP_GET), + ("can_change_orders", "cancel/", 200, HTTP_GET), + ("can_change_vouchers", "vouchers/add", 200, HTTP_GET), + ("can_change_vouchers", "vouchers/bulk_add", 200, HTTP_GET), + ("can_view_vouchers", "vouchers/", 200, HTTP_GET), + ("can_view_vouchers", "vouchers/tags/", 200, HTTP_GET), + ("can_change_vouchers", "vouchers/1234/", 404, HTTP_GET), + ("can_change_vouchers", "vouchers/1234/delete", 404, HTTP_GET), + ("can_view_orders", "waitinglist/", 200, HTTP_GET), + ("can_change_orders", "waitinglist/auto_assign", 405, HTTP_GET), + ("can_change_orders", "waitinglist/action", 405, HTTP_GET), + ("can_view_orders", "checkins/", 200, HTTP_GET), + ("can_view_orders", "checkinlists/", 200, HTTP_GET), + ("can_view_orders", "checkinlists/1/", 404, HTTP_GET), + ("can_change_event_settings", "checkinlists/add", 200, HTTP_GET), + ("can_change_event_settings", "checkinlists/1/change", 404, HTTP_GET), + ("can_change_event_settings", "checkinlists/1/delete", 404, HTTP_GET), # bank transfer - ("can_change_orders", "banktransfer/import/", 200), - ("can_change_orders", "banktransfer/job/1/", 404), - ("can_change_orders", "banktransfer/action/", 200), - ("can_change_orders", "banktransfer/refunds/", 200), - ("can_change_orders", "banktransfer/export/1/", 404), - ("can_change_orders", "banktransfer/sepa-export/1/", 404), + ("can_change_orders", "banktransfer/import/", 200, HTTP_GET), + ("can_change_orders", "banktransfer/job/1/", 404, HTTP_GET), + ("can_change_orders", "banktransfer/action/", 200, HTTP_GET), + ("can_change_orders", "banktransfer/refunds/", 200, HTTP_GET), + ("can_change_orders", "banktransfer/export/1/", 404, HTTP_GET), + ("can_change_orders", "banktransfer/sepa-export/1/", 404, HTTP_GET), ] @pytest.mark.django_db -@pytest.mark.parametrize("perm,url,code", event_permission_urls) -def test_wrong_event_permission(perf_patch, client, env, perm, url, code): +@pytest.mark.parametrize("perm,url,code,http_method", event_permission_urls) +def test_wrong_event_permission(perf_patch, client, env, perm, url, code, http_method): t = Team( organizer=env[2], all_events=True ) @@ -377,13 +382,16 @@ def test_wrong_event_permission(perf_patch, client, env, perm, url, code): t.save() t.members.add(env[1]) client.login(email='dummy@dummy.dummy', password='dummy') - response = client.get('/control/event/dummy/dummy/' + url) + if http_method and http_method == HTTP_POST: + response = client.post('/control/event/dummy/dummy/' + url) + else: + response = client.get('/control/event/dummy/dummy/' + url) assert response.status_code == 403 @pytest.mark.django_db -@pytest.mark.parametrize("perm,url,code", event_permission_urls) -def test_limited_event_permission_for_other_event(perf_patch, client, env, perm, url, code): +@pytest.mark.parametrize("perm,url,code,http_method", event_permission_urls) +def test_limited_event_permission_for_other_event(perf_patch, client, env, perm, url, code, http_method): event2 = Event.objects.create( organizer=env[2], name='Dummy', slug='dummy2', date_from=now(), plugins='pretix.plugins.banktransfer' @@ -393,7 +401,10 @@ def test_limited_event_permission_for_other_event(perf_patch, client, env, perm, t.limit_events.add(event2) client.login(email='dummy@dummy.dummy', password='dummy') - response = client.get('/control/event/dummy/dummy/' + url) + if http_method and http_method == HTTP_POST: + response = client.post('/control/event/dummy/dummy/' + url) + else: + response = client.get('/control/event/dummy/dummy/' + url) assert response.status_code == 404 @@ -416,8 +427,8 @@ def test_current_permission(client, env): @pytest.mark.django_db -@pytest.mark.parametrize("perm,url,code", event_permission_urls) -def test_correct_event_permission_all_events(perf_patch, client, env, perm, url, code): +@pytest.mark.parametrize("perm,url,code,http_method", event_permission_urls) +def test_correct_event_permission_all_events(perf_patch, client, env, perm, url, code, http_method): t = Team(organizer=env[2], all_events=True) setattr(t, perm, True) t.save() @@ -426,13 +437,16 @@ def test_correct_event_permission_all_events(perf_patch, client, env, perm, url, session = client.session session['pretix_auth_login_time'] = int(time.time()) session.save() - response = client.get('/control/event/dummy/dummy/' + url) + if http_method and http_method == HTTP_POST: + response = client.post('/control/event/dummy/dummy/' + url) + else: + response = client.get('/control/event/dummy/dummy/' + url) assert response.status_code == code @pytest.mark.django_db -@pytest.mark.parametrize("perm,url,code", event_permission_urls) -def test_correct_event_permission_limited(perf_patch, client, env, perm, url, code): +@pytest.mark.parametrize("perm,url,code,http_method", event_permission_urls) +def test_correct_event_permission_limited(perf_patch, client, env, perm, url, code, http_method): t = Team(organizer=env[2]) setattr(t, perm, True) t.save() @@ -442,7 +456,10 @@ def test_correct_event_permission_limited(perf_patch, client, env, perm, url, co session = client.session session['pretix_auth_login_time'] = int(time.time()) session.save() - response = client.get('/control/event/dummy/dummy/' + url) + if http_method and http_method == HTTP_POST: + response = client.post('/control/event/dummy/dummy/' + url) + else: + response = client.get('/control/event/dummy/dummy/' + url) assert response.status_code == code