Compare commits

...

8 Commits

Author SHA1 Message Date
Raphael Michel
2fd81a2d20 Disable scopes for a management command 2019-06-17 10:46:10 +02:00
Raphael Michel
4271245a4a Disable scopes for get_Events_with_any_permission 2019-06-17 10:16:53 +02:00
Raphael Michel
b41139a143 Fix tests after rebase 2019-06-17 10:08:42 +02:00
Raphael Michel
a68b225529 Remove unused import 2019-06-17 10:04:54 +02:00
Raphael Michel
c12ba88ad8 Fix remaining tests 2019-06-17 10:04:54 +02:00
Raphael Michel
69a80f2540 Update tasks and cronjobs 2019-06-17 10:04:54 +02:00
Raphael Michel
867667cd12 Fix tests.api 2019-06-17 10:04:54 +02:00
Raphael Michel
5c06c41a5b Install django-scopes 2019-06-17 10:04:54 +02:00
130 changed files with 6253 additions and 4509 deletions

View File

@@ -1,4 +1,5 @@
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from django_scopes import scopes_disabled
from rest_framework import exceptions from rest_framework import exceptions
from rest_framework.authentication import TokenAuthentication from rest_framework.authentication import TokenAuthentication
@@ -12,6 +13,7 @@ class DeviceTokenAuthentication(TokenAuthentication):
def authenticate_credentials(self, key): def authenticate_credentials(self, key):
model = self.get_model() model = self.get_model()
try: try:
with scopes_disabled():
device = model.objects.select_related('organizer').get(api_token=key) device = model.objects.select_related('organizer').get(api_token=key)
except model.DoesNotExist: except model.DoesNotExist:
raise exceptions.AuthenticationFailed('Invalid token.') raise exceptions.AuthenticationFailed('Invalid token.')

View File

@@ -3,7 +3,7 @@ from rest_framework.permissions import SAFE_METHODS, BasePermission
from pretix.api.models import OAuthAccessToken from pretix.api.models import OAuthAccessToken
from pretix.base.models import Device, Event, User from pretix.base.models import Device, Event, User
from pretix.base.models.auth import SuperuserPermissionSet from pretix.base.models.auth import SuperuserPermissionSet
from pretix.base.models.organizer import Organizer, TeamAPIToken from pretix.base.models.organizer import TeamAPIToken
from pretix.helpers.security import ( from pretix.helpers.security import (
SessionInvalid, SessionReauthRequired, assert_session_valid, SessionInvalid, SessionReauthRequired, assert_session_valid,
) )
@@ -50,9 +50,6 @@ class EventPermission(BasePermission):
return False return False
elif 'organizer' in request.resolver_match.kwargs: elif 'organizer' in request.resolver_match.kwargs:
request.organizer = Organizer.objects.filter(
slug=request.resolver_match.kwargs['organizer'],
).first()
if not request.organizer or not perm_holder.has_organizer_permission(request.organizer, request=request): if not request.organizer or not perm_holder.has_organizer_permission(request.organizer, request=request):
return False return False
if isinstance(perm_holder, User) and perm_holder.has_active_staff_session(request.session.session_key): if isinstance(perm_holder, User) and perm_holder.has_active_staff_session(request.session.session_key):

View File

@@ -4,10 +4,13 @@ from hashlib import sha1
from django.conf import settings from django.conf import settings
from django.db import transaction from django.db import transaction
from django.http import HttpRequest, HttpResponse, JsonResponse from django.http import HttpRequest, HttpResponse, JsonResponse
from django.urls import resolve
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scope
from rest_framework import status from rest_framework import status
from pretix.api.models import ApiCall from pretix.api.models import ApiCall
from pretix.base.models import Organizer
class IdempotencyMiddleware: class IdempotencyMiddleware:
@@ -89,3 +92,21 @@ class IdempotencyMiddleware:
for k, v in json.loads(call.response_headers).values(): for k, v in json.loads(call.response_headers).values():
r[k] = v r[k] = v
return r return r
class ApiScopeMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request: HttpRequest):
if not request.path.startswith('/api/'):
return self.get_response(request)
url = resolve(request.path_info)
if 'organizer' in url.kwargs:
request.organizer = Organizer.objects.filter(
slug=url.kwargs['organizer'],
).first()
with scope(organizer=getattr(request, 'organizer', None)):
return self.get_response(request)

View File

@@ -2,6 +2,7 @@ from datetime import timedelta
from django.dispatch import Signal, receiver from django.dispatch import Signal, receiver
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from pretix.api.models import ApiCall, WebHookCall from pretix.api.models import ApiCall, WebHookCall
from pretix.base.signals import periodic_task from pretix.base.signals import periodic_task
@@ -17,10 +18,12 @@ instances.
@receiver(periodic_task) @receiver(periodic_task)
@scopes_disabled()
def cleanup_webhook_logs(sender, **kwargs): def cleanup_webhook_logs(sender, **kwargs):
WebHookCall.objects.filter(datetime__lte=now() - timedelta(days=30)).delete() WebHookCall.objects.filter(datetime__lte=now() - timedelta(days=30)).delete()
@receiver(periodic_task) @receiver(periodic_task)
@scopes_disabled()
def cleanup_api_logs(sender, **kwargs): def cleanup_api_logs(sender, **kwargs):
ApiCall.objects.filter(created__lte=now() - timedelta(hours=24)).delete() ApiCall.objects.filter(created__lte=now() - timedelta(hours=24)).delete()

View File

@@ -6,6 +6,7 @@ from django.shortcuts import get_object_or_404
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.timezone import now from django.utils.timezone import now
from django_filters.rest_framework import DjangoFilterBackend, FilterSet from django_filters.rest_framework import DjangoFilterBackend, FilterSet
from django_scopes import scopes_disabled
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.fields import DateTimeField from rest_framework.fields import DateTimeField
@@ -24,7 +25,7 @@ from pretix.base.services.checkin import (
) )
from pretix.helpers.database import FixedOrderBy from pretix.helpers.database import FixedOrderBy
with scopes_disabled():
class CheckinListFilter(FilterSet): class CheckinListFilter(FilterSet):
class Meta: class Meta:
model = CheckinList model = CheckinList
@@ -146,6 +147,7 @@ class CheckinListViewSet(viewsets.ModelViewSet):
return Response(response) return Response(response)
with scopes_disabled():
class CheckinOrderPositionFilter(OrderPositionFilter): class CheckinOrderPositionFilter(OrderPositionFilter):
def has_checkin_qs(self, queryset, name, value): def has_checkin_qs(self, queryset, name, value):
@@ -154,7 +156,7 @@ class CheckinOrderPositionFilter(OrderPositionFilter):
class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet): class CheckinListPositionViewSet(viewsets.ReadOnlyModelViewSet):
serializer_class = CheckinListOrderPositionSerializer serializer_class = CheckinListOrderPositionSerializer
queryset = OrderPosition.objects.none() queryset = OrderPosition.all.none()
filter_backends = (DjangoFilterBackend, RichOrderingFilter) filter_backends = (DjangoFilterBackend, RichOrderingFilter)
ordering = ('attendee_name_cached', 'positionid') ordering = ('attendee_name_cached', 'positionid')
ordering_fields = ( ordering_fields = (

View File

@@ -3,6 +3,7 @@ from django.db import transaction
from django.db.models import ProtectedError, Q from django.db.models import ProtectedError, Q
from django.utils.timezone import now from django.utils.timezone import now
from django_filters.rest_framework import DjangoFilterBackend, FilterSet from django_filters.rest_framework import DjangoFilterBackend, FilterSet
from django_scopes import scopes_disabled
from rest_framework import filters, viewsets from rest_framework import filters, viewsets
from rest_framework.exceptions import PermissionDenied from rest_framework.exceptions import PermissionDenied
@@ -18,7 +19,7 @@ from pretix.base.models import (
from pretix.base.models.event import SubEvent from pretix.base.models.event import SubEvent
from pretix.helpers.dicts import merge_dicts from pretix.helpers.dicts import merge_dicts
with scopes_disabled():
class EventFilter(FilterSet): class EventFilter(FilterSet):
is_past = django_filters.rest_framework.BooleanFilter(method='is_past_qs') is_past = django_filters.rest_framework.BooleanFilter(method='is_past_qs')
is_future = django_filters.rest_framework.BooleanFilter(method='is_future_qs') is_future = django_filters.rest_framework.BooleanFilter(method='is_future_qs')
@@ -182,6 +183,7 @@ class CloneEventViewSet(viewsets.ModelViewSet):
) )
with scopes_disabled():
class SubEventFilter(FilterSet): class SubEventFilter(FilterSet):
is_past = django_filters.rest_framework.BooleanFilter(method='is_past_qs') is_past = django_filters.rest_framework.BooleanFilter(method='is_past_qs')
is_future = django_filters.rest_framework.BooleanFilter(method='is_future_qs') is_future = django_filters.rest_framework.BooleanFilter(method='is_future_qs')

View File

@@ -3,6 +3,7 @@ from django.db.models import Q
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django_filters.rest_framework import DjangoFilterBackend, FilterSet from django_filters.rest_framework import DjangoFilterBackend, FilterSet
from django_scopes import scopes_disabled
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied from rest_framework.exceptions import PermissionDenied
@@ -21,7 +22,7 @@ from pretix.base.models import (
) )
from pretix.helpers.dicts import merge_dicts from pretix.helpers.dicts import merge_dicts
with scopes_disabled():
class ItemFilter(FilterSet): class ItemFilter(FilterSet):
tax_rate = django_filters.CharFilter(method='tax_rate_qs') tax_rate = django_filters.CharFilter(method='tax_rate_qs')
@@ -319,6 +320,7 @@ class ItemCategoryViewSet(ConditionalListView, viewsets.ModelViewSet):
super().perform_destroy(instance) super().perform_destroy(instance)
with scopes_disabled():
class QuestionFilter(FilterSet): class QuestionFilter(FilterSet):
class Meta: class Meta:
model = Question model = Question
@@ -418,6 +420,7 @@ class QuestionOptionViewSet(viewsets.ModelViewSet):
super().perform_destroy(instance) super().perform_destroy(instance)
with scopes_disabled():
class QuotaFilter(FilterSet): class QuotaFilter(FilterSet):
class Meta: class Meta:
model = Quota model = Quota

View File

@@ -11,6 +11,7 @@ from django.shortcuts import get_object_or_404
from django.utils.timezone import make_aware, now from django.utils.timezone import make_aware, now
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django_filters.rest_framework import DjangoFilterBackend, FilterSet from django_filters.rest_framework import DjangoFilterBackend, FilterSet
from django_scopes import scopes_disabled
from rest_framework import mixins, serializers, status, viewsets from rest_framework import mixins, serializers, status, viewsets
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.exceptions import ( from rest_framework.exceptions import (
@@ -50,7 +51,7 @@ from pretix.base.signals import (
) )
from pretix.base.templatetags.money import money_filter from pretix.base.templatetags.money import money_filter
with scopes_disabled():
class OrderFilter(FilterSet): class OrderFilter(FilterSet):
email = django_filters.CharFilter(field_name='email', lookup_expr='iexact') email = django_filters.CharFilter(field_name='email', lookup_expr='iexact')
code = django_filters.CharFilter(field_name='code', lookup_expr='iexact') code = django_filters.CharFilter(field_name='code', lookup_expr='iexact')
@@ -531,6 +532,7 @@ class OrderViewSet(viewsets.ModelViewSet):
self.get_object().gracefully_delete(user=self.request.user if self.request.user.is_authenticated else None, auth=self.request.auth) self.get_object().gracefully_delete(user=self.request.user if self.request.user.is_authenticated else None, auth=self.request.auth)
with scopes_disabled():
class OrderPositionFilter(FilterSet): class OrderPositionFilter(FilterSet):
order = django_filters.CharFilter(field_name='order', lookup_expr='code__iexact') order = django_filters.CharFilter(field_name='order', lookup_expr='code__iexact')
has_checkin = django_filters.rest_framework.BooleanFilter(method='has_checkin_qs') has_checkin = django_filters.rest_framework.BooleanFilter(method='has_checkin_qs')
@@ -572,7 +574,7 @@ class OrderPositionFilter(FilterSet):
class OrderPositionViewSet(mixins.DestroyModelMixin, viewsets.ReadOnlyModelViewSet): class OrderPositionViewSet(mixins.DestroyModelMixin, viewsets.ReadOnlyModelViewSet):
serializer_class = OrderPositionSerializer serializer_class = OrderPositionSerializer
queryset = OrderPosition.objects.none() queryset = OrderPosition.all.none()
filter_backends = (DjangoFilterBackend, OrderingFilter) filter_backends = (DjangoFilterBackend, OrderingFilter)
ordering = ('order__datetime', 'positionid') ordering = ('order__datetime', 'positionid')
ordering_fields = ('order__code', 'order__datetime', 'positionid', 'attendee_name', 'order__status',) ordering_fields = ('order__code', 'order__datetime', 'positionid', 'attendee_name', 'order__status',)
@@ -960,6 +962,7 @@ class RefundViewSet(CreateModelMixin, viewsets.ReadOnlyModelViewSet):
serializer.save() serializer.save()
with scopes_disabled():
class InvoiceFilter(FilterSet): class InvoiceFilter(FilterSet):
refers = django_filters.CharFilter(method='refers_qs') refers = django_filters.CharFilter(method='refers_qs')
number = django_filters.CharFilter(method='nr_qs') number = django_filters.CharFilter(method='nr_qs')

View File

@@ -6,6 +6,7 @@ from django.utils.timezone import now
from django_filters.rest_framework import ( from django_filters.rest_framework import (
BooleanFilter, DjangoFilterBackend, FilterSet, BooleanFilter, DjangoFilterBackend, FilterSet,
) )
from django_scopes import scopes_disabled
from rest_framework import status, viewsets from rest_framework import status, viewsets
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied from rest_framework.exceptions import PermissionDenied
@@ -15,7 +16,7 @@ from rest_framework.response import Response
from pretix.api.serializers.voucher import VoucherSerializer from pretix.api.serializers.voucher import VoucherSerializer
from pretix.base.models import Voucher from pretix.base.models import Voucher
with scopes_disabled():
class VoucherFilter(FilterSet): class VoucherFilter(FilterSet):
active = BooleanFilter(method='filter_active') active = BooleanFilter(method='filter_active')

View File

@@ -1,5 +1,6 @@
import django_filters import django_filters
from django_filters.rest_framework import DjangoFilterBackend, FilterSet from django_filters.rest_framework import DjangoFilterBackend, FilterSet
from django_scopes import scopes_disabled
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied, ValidationError from rest_framework.exceptions import PermissionDenied, ValidationError
@@ -10,7 +11,7 @@ from pretix.api.serializers.waitinglist import WaitingListSerializer
from pretix.base.models import WaitingListEntry from pretix.base.models import WaitingListEntry
from pretix.base.models.waitinglist import WaitingListException from pretix.base.models.waitinglist import WaitingListException
with scopes_disabled():
class WaitingListFilter(FilterSet): class WaitingListFilter(FilterSet):
has_voucher = django_filters.rest_framework.BooleanFilter(method='has_voucher_qs') has_voucher = django_filters.rest_framework.BooleanFilter(method='has_voucher_qs')

View File

@@ -8,6 +8,7 @@ from celery.exceptions import MaxRetriesExceededError
from django.db.models import Exists, OuterRef, Q from django.db.models import Exists, OuterRef, Q
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django_scopes import scope, scopes_disabled
from requests import RequestException from requests import RequestException
from pretix.api.models import WebHook, WebHookCall, WebHookEventListener from pretix.api.models import WebHook, WebHookCall, WebHookEventListener
@@ -203,9 +204,10 @@ def notify_webhooks(logentry_id: int):
@app.task(base=ProfiledTask, bind=True, max_retries=9) @app.task(base=ProfiledTask, bind=True, max_retries=9)
def send_webhook(self, logentry_id: int, action_type: str, webhook_id: int): def send_webhook(self, logentry_id: int, action_type: str, webhook_id: int):
# 9 retries with 2**(2*x) timing is roughly 72 hours # 9 retries with 2**(2*x) timing is roughly 72 hours
logentry = LogEntry.all.get(id=logentry_id) with scopes_disabled():
webhook = WebHook.objects.get(id=webhook_id) webhook = WebHook.objects.get(id=webhook_id)
with scope(organizer=webhook.organizer):
logentry = LogEntry.all.get(id=logentry_id)
types = get_all_webhook_events() types = get_all_webhook_events()
event_type = types.get(action_type) event_type = types.get(action_type)
if not event_type or not webhook.enabled: if not event_type or not webhook.enabled:

View File

@@ -12,6 +12,7 @@ from django.utils.crypto import get_random_string
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django_otp.models import Device from django_otp.models import Device
from django_scopes import scopes_disabled
from pretix.base.i18n import language from pretix.base.i18n import language
from pretix.helpers.urls import build_absolute_uri from pretix.helpers.urls import build_absolute_uri
@@ -283,6 +284,7 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin):
return True return True
return False return False
@scopes_disabled()
def get_events_with_any_permission(self, request=None): def get_events_with_any_permission(self, request=None):
""" """
Returns a queryset of events the user has any permissions to. Returns a queryset of events the user has any permissions to.
@@ -300,6 +302,7 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin):
| Q(id__in=self.teams.values_list('limit_events__id', flat=True)) | Q(id__in=self.teams.values_list('limit_events__id', flat=True))
) )
@scopes_disabled()
def get_events_with_permission(self, permission, request=None): def get_events_with_permission(self, permission, request=None):
""" """
Returns a queryset of events the user has a specific permissions to. Returns a queryset of events the user has a specific permissions to.

View File

@@ -3,6 +3,7 @@ from django.db.models import Case, Count, F, OuterRef, Q, Subquery, When
from django.db.models.functions import Coalesce from django.db.models.functions import Coalesce
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import pgettext_lazy, ugettext_lazy as _ from django.utils.translation import pgettext_lazy, ugettext_lazy as _
from django_scopes import ScopedManager
from pretix.base.models import LoggedModel from pretix.base.models import LoggedModel
@@ -20,6 +21,8 @@ class CheckinList(LoggedModel):
'order have not been paid. This only works with pretixdesk ' 'order have not been paid. This only works with pretixdesk '
'0.3.0 or newer or pretixdroid 1.9 or newer.')) '0.3.0 or newer or pretixdroid 1.9 or newer.'))
objects = ScopedManager(organizer='event__organizer')
class Meta: class Meta:
ordering = ('subevent__date_from', 'name') ordering = ('subevent__date_from', 'name')
@@ -167,6 +170,8 @@ class Checkin(models.Model):
'pretixbase.CheckinList', related_name='checkins', on_delete=models.PROTECT, 'pretixbase.CheckinList', related_name='checkins', on_delete=models.PROTECT,
) )
objects = ScopedManager(organizer='position__order__event__organizer')
class Meta: class Meta:
unique_together = (('list', 'position'),) unique_together = (('list', 'position'),)

View File

@@ -4,6 +4,7 @@ from django.db import models
from django.db.models import Max from django.db.models import Max
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django_scopes import ScopedManager
from pretix.base.models import LoggedModel from pretix.base.models import LoggedModel
@@ -71,6 +72,8 @@ class Device(LoggedModel):
null=True, blank=True null=True, blank=True
) )
objects = ScopedManager(organizer='organizer')
class Meta: class Meta:
unique_together = (('organizer', 'device_id'),) unique_together = (('organizer', 'device_id'),)

View File

@@ -17,6 +17,7 @@ from django.utils.crypto import get_random_string
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.timezone import make_aware, now from django.utils.timezone import make_aware, now
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django_scopes import ScopedManager
from i18nfield.fields import I18nCharField, I18nTextField from i18nfield.fields import I18nCharField, I18nTextField
from pretix.base.models.base import LoggedModel from pretix.base.models.base import LoggedModel
@@ -336,6 +337,8 @@ class Event(EventMixin, LoggedModel):
default=False default=False
) )
objects = ScopedManager(organizer='organizer')
class Meta: class Meta:
verbose_name = _("Event") verbose_name = _("Event")
verbose_name_plural = _("Events") verbose_name_plural = _("Events")
@@ -875,6 +878,8 @@ class SubEvent(EventMixin, LoggedModel):
items = models.ManyToManyField('Item', through='SubEventItem') items = models.ManyToManyField('Item', through='SubEventItem')
variations = models.ManyToManyField('ItemVariation', through='SubEventItemVariation') variations = models.ManyToManyField('ItemVariation', through='SubEventItemVariation')
objects = ScopedManager(organizer='event__organizer')
class Meta: class Meta:
verbose_name = _("Date in event series") verbose_name = _("Date in event series")
verbose_name_plural = _("Dates in event series") verbose_name_plural = _("Dates in event series")

View File

@@ -9,6 +9,7 @@ from django.utils.crypto import get_random_string
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.translation import pgettext from django.utils.translation import pgettext
from django_countries.fields import CountryField from django_countries.fields import CountryField
from django_scopes import ScopedManager
def invoice_filename(instance, filename: str) -> str: def invoice_filename(instance, filename: str) -> str:
@@ -107,6 +108,8 @@ class Invoice(models.Model):
file = models.FileField(null=True, blank=True, upload_to=invoice_filename, max_length=255) file = models.FileField(null=True, blank=True, upload_to=invoice_filename, max_length=255)
internal_reference = models.TextField(blank=True) internal_reference = models.TextField(blank=True)
objects = ScopedManager(organizer='event__organizer')
@staticmethod @staticmethod
def _to_numeric_invoice_number(number): def _to_numeric_invoice_number(number):
return '{:05d}'.format(int(number)) return '{:05d}'.format(int(number))

View File

@@ -17,6 +17,7 @@ from django.utils.functional import cached_property
from django.utils.timezone import is_naive, make_aware, now from django.utils.timezone import is_naive, make_aware, now
from django.utils.translation import pgettext_lazy, ugettext_lazy as _ from django.utils.translation import pgettext_lazy, ugettext_lazy as _
from django_countries.fields import Country from django_countries.fields import Country
from django_scopes import ScopedManager
from i18nfield.fields import I18nCharField, I18nTextField from i18nfield.fields import I18nCharField, I18nTextField
from pretix.base.models import fields from pretix.base.models import fields
@@ -155,8 +156,7 @@ class SubEventItemVariation(models.Model):
self.subevent.event.cache.clear() self.subevent.event.cache.clear()
class ItemQuerySet(models.QuerySet): def filter_available(qs, channel='web', voucher=None, allow_addons=False):
def filter_available(self, channel='web', voucher=None, allow_addons=False):
q = ( q = (
# IMPORTANT: If this is updated, also update the ItemVariation query # IMPORTANT: If this is updated, also update the ItemVariation query
# in models/event.py: EventMixin.annotated() # in models/event.py: EventMixin.annotated()
@@ -167,7 +167,7 @@ class ItemQuerySet(models.QuerySet):
) )
if not allow_addons: if not allow_addons:
q &= Q(Q(category__isnull=True) | Q(category__is_addon=False)) q &= Q(Q(category__isnull=True) | Q(category__is_addon=False))
qs = self.filter(q) qs = qs.filter(q)
vouchq = Q(hide_without_voucher=False) vouchq = Q(hide_without_voucher=False)
if voucher: if voucher:
@@ -179,6 +179,20 @@ class ItemQuerySet(models.QuerySet):
return qs.filter(vouchq) return qs.filter(vouchq)
class ItemQuerySet(models.QuerySet):
def filter_available(self, channel='web', voucher=None, allow_addons=False):
return filter_available(self, channel, voucher, allow_addons)
class ItemQuerySetManager(ScopedManager(organizer='event__organizer').__class__):
def __init__(self):
super().__init__()
self._queryset_class = ItemQuerySet
def filter_available(self, channel='web', voucher=None, allow_addons=False):
return filter_available(self.get_queryset(), channel, voucher, allow_addons)
class Item(LoggedModel): class Item(LoggedModel):
""" """
An item is a thing which can be sold. It belongs to an event and may or may not belong to a category. An item is a thing which can be sold. It belongs to an event and may or may not belong to a category.
@@ -226,7 +240,7 @@ class Item(LoggedModel):
:type sales_channels: bool :type sales_channels: bool
""" """
objects = ItemQuerySet.as_manager() objects = ItemQuerySetManager()
event = models.ForeignKey( event = models.ForeignKey(
Event, Event,
@@ -591,6 +605,8 @@ class ItemVariation(models.Model):
'discounted one. This is just a cosmetic setting and will not actually impact pricing.') 'discounted one. This is just a cosmetic setting and will not actually impact pricing.')
) )
objects = ScopedManager(organizer='item__event__organizer')
class Meta: class Meta:
verbose_name = _("Product variation") verbose_name = _("Product variation")
verbose_name_plural = _("Product variations") verbose_name_plural = _("Product variations")
@@ -985,6 +1001,8 @@ class Question(LoggedModel):
) )
dependency_value = models.TextField(null=True, blank=True) dependency_value = models.TextField(null=True, blank=True)
objects = ScopedManager(organizer='event__organizer')
class Meta: class Meta:
verbose_name = _("Question") verbose_name = _("Question")
verbose_name_plural = _("Questions") verbose_name_plural = _("Questions")
@@ -1234,6 +1252,8 @@ class Quota(LoggedModel):
cached_availability_paid_orders = models.PositiveIntegerField(null=True, blank=True) cached_availability_paid_orders = models.PositiveIntegerField(null=True, blank=True)
cached_availability_time = models.DateTimeField(null=True, blank=True) cached_availability_time = models.DateTimeField(null=True, blank=True)
objects = ScopedManager(organizer='event__organizer')
class Meta: class Meta:
verbose_name = _("Quota") verbose_name = _("Quota")
verbose_name_plural = _("Quotas") verbose_name_plural = _("Quotas")

View File

@@ -26,6 +26,7 @@ from django.utils.functional import cached_property
from django.utils.timezone import make_aware, now from django.utils.timezone import make_aware, now
from django.utils.translation import pgettext_lazy, ugettext_lazy as _ from django.utils.translation import pgettext_lazy, ugettext_lazy as _
from django_countries.fields import Country, CountryField from django_countries.fields import Country, CountryField
from django_scopes import ScopedManager, scopes_disabled
from i18nfield.strings import LazyI18nString from i18nfield.strings import LazyI18nString
from jsonfallback.fields import FallbackJSONField from jsonfallback.fields import FallbackJSONField
@@ -186,6 +187,8 @@ class Order(LockModel, LoggedModel):
verbose_name=_('E-mail address verified') verbose_name=_('E-mail address verified')
) )
objects = ScopedManager(organizer='event__organizer')
class Meta: class Meta:
verbose_name = _("Order") verbose_name = _("Order")
verbose_name_plural = _("Orders") verbose_name_plural = _("Orders")
@@ -231,6 +234,7 @@ class Order(LockModel, LoggedModel):
return self.all_fees(manager='objects') return self.all_fees(manager='objects')
@cached_property @cached_property
@scopes_disabled()
def count_positions(self): def count_positions(self):
if hasattr(self, 'pcnt'): if hasattr(self, 'pcnt'):
return self.pcnt or 0 return self.pcnt or 0
@@ -254,6 +258,7 @@ class Order(LockModel, LoggedModel):
return None return None
@property @property
@scopes_disabled()
def payment_refund_sum(self): def payment_refund_sum(self):
payment_sum = self.payments.filter( payment_sum = self.payments.filter(
state__in=(OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED) state__in=(OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED)
@@ -265,6 +270,7 @@ class Order(LockModel, LoggedModel):
return payment_sum - refund_sum return payment_sum - refund_sum
@property @property
@scopes_disabled()
def pending_sum(self): def pending_sum(self):
total = self.total total = self.total
if self.status == Order.STATUS_CANCELED: if self.status == Order.STATUS_CANCELED:
@@ -439,6 +445,7 @@ class Order(LockModel, LoggedModel):
return round_decimal(fee, self.event.currency) return round_decimal(fee, self.event.currency)
@property @property
@scopes_disabled()
def user_cancel_allowed(self) -> bool: def user_cancel_allowed(self) -> bool:
""" """
Returns whether or not this order can be canceled by the user. Returns whether or not this order can be canceled by the user.
@@ -822,6 +829,8 @@ class QuestionAnswer(models.Model):
max_length=255 max_length=255
) )
objects = ScopedManager(organizer='question__event__organizer')
@property @property
def backend_file_url(self): def backend_file_url(self):
if self.file: if self.file:
@@ -1145,6 +1154,8 @@ class OrderPayment(models.Model):
) )
migrated = models.BooleanField(default=False) migrated = models.BooleanField(default=False)
objects = ScopedManager(organizer='order__event__organizer')
class Meta: class Meta:
ordering = ('local_id',) ordering = ('local_id',)
@@ -1501,6 +1512,8 @@ class OrderRefund(models.Model):
null=True, blank=True null=True, blank=True
) )
objects = ScopedManager(organizer='order__event__organizer')
class Meta: class Meta:
ordering = ('local_id',) ordering = ('local_id',)
@@ -1562,7 +1575,7 @@ class OrderRefund(models.Model):
super().save(*args, **kwargs) super().save(*args, **kwargs)
class ActivePositionManager(models.Manager): class ActivePositionManager(ScopedManager(organizer='order__event__organizer').__class__):
def get_queryset(self): def get_queryset(self):
return super().get_queryset().filter(canceled=False) return super().get_queryset().filter(canceled=False)
@@ -1639,7 +1652,7 @@ class OrderFee(models.Model):
) )
canceled = models.BooleanField(default=False) canceled = models.BooleanField(default=False)
all = models.Manager() all = ScopedManager(organizer='order__event__organizer')
objects = ActivePositionManager() objects = ActivePositionManager()
@property @property
@@ -1744,7 +1757,7 @@ class OrderPosition(AbstractPosition):
) )
canceled = models.BooleanField(default=False) canceled = models.BooleanField(default=False)
all = models.Manager() all = ScopedManager(organizer='order__event__organizer')
objects = ActivePositionManager() objects = ActivePositionManager()
class Meta: class Meta:
@@ -1951,6 +1964,8 @@ class CartPosition(AbstractPosition):
) )
is_bundled = models.BooleanField(default=False) is_bundled = models.BooleanField(default=False)
objects = ScopedManager(organizer='event__organizer')
class Meta: class Meta:
verbose_name = _("Cart position") verbose_name = _("Cart position")
verbose_name_plural = _("Cart positions") verbose_name_plural = _("Cart positions")
@@ -2000,6 +2015,8 @@ class InvoiceAddress(models.Model):
blank=True blank=True
) )
objects = ScopedManager(organizer='order__event__organizer')
def save(self, **kwargs): def save(self, **kwargs):
if self.order: if self.order:
self.order.touch() self.order.touch()

View File

@@ -8,6 +8,7 @@ from django.db.models import Q
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import pgettext_lazy, ugettext_lazy as _ from django.utils.translation import pgettext_lazy, ugettext_lazy as _
from django_scopes import ScopedManager
from ..decimal import round_decimal from ..decimal import round_decimal
from .base import LoggedModel from .base import LoggedModel
@@ -173,6 +174,8 @@ class Voucher(LoggedModel):
"convenience.") "convenience.")
) )
objects = ScopedManager(organizer='event__organizer')
class Meta: class Meta:
verbose_name = _("Voucher") verbose_name = _("Voucher")
verbose_name_plural = _("Vouchers") verbose_name_plural = _("Vouchers")

View File

@@ -4,6 +4,7 @@ from django.core.exceptions import ValidationError
from django.db import models, transaction from django.db import models, transaction
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import pgettext_lazy, ugettext_lazy as _ from django.utils.translation import pgettext_lazy, ugettext_lazy as _
from django_scopes import ScopedManager
from pretix.base.i18n import language from pretix.base.i18n import language
from pretix.base.models import Voucher from pretix.base.models import Voucher
@@ -67,6 +68,8 @@ class WaitingListEntry(LoggedModel):
) )
priority = models.IntegerField(default=0) priority = models.IntegerField(default=0)
objects = ScopedManager(organizer='event__organizer')
class Meta: class Meta:
verbose_name = _("Waiting list entry") verbose_name = _("Waiting list entry")
verbose_name_plural = _("Waiting list entries") verbose_name_plural = _("Waiting list entries")

View File

@@ -10,6 +10,7 @@ from django.db.models import Q
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.timezone import make_aware, now from django.utils.timezone import make_aware, now
from django.utils.translation import pgettext_lazy, ugettext as _ from django.utils.translation import pgettext_lazy, ugettext as _
from django_scopes import scopes_disabled
from pretix.base.i18n import language from pretix.base.i18n import language
from pretix.base.models import ( from pretix.base.models import (
@@ -23,7 +24,7 @@ from pretix.base.reldate import RelativeDateWrapper
from pretix.base.services.checkin import _save_answers from pretix.base.services.checkin import _save_answers
from pretix.base.services.locking import LockTimeoutException, NoLockManager from pretix.base.services.locking import LockTimeoutException, NoLockManager
from pretix.base.services.pricing import get_price from pretix.base.services.pricing import get_price
from pretix.base.services.tasks import ProfiledTask from pretix.base.services.tasks import ProfiledEventTask
from pretix.base.settings import PERSON_NAME_SCHEMES from pretix.base.settings import PERSON_NAME_SCHEMES
from pretix.base.templatetags.rich_text import rich_text from pretix.base.templatetags.rich_text import rich_text
from pretix.celery_app import app from pretix.celery_app import app
@@ -902,7 +903,7 @@ def get_fees(event, request, total, invoice_address, provider):
return fees return fees
@app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,)) @app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
def add_items_to_cart(self, event: int, items: List[dict], cart_id: str=None, locale='en', def add_items_to_cart(self, event: int, items: List[dict], cart_id: str=None, locale='en',
invoice_address: int=None, widget_data=None, sales_channel='web') -> None: invoice_address: int=None, widget_data=None, sales_channel='web') -> None:
""" """
@@ -913,11 +914,10 @@ def add_items_to_cart(self, event: int, items: List[dict], cart_id: str=None, lo
:raises CartError: On any error that occured :raises CartError: On any error that occured
""" """
with language(locale): with language(locale):
event = Event.objects.get(id=event)
ia = False ia = False
if invoice_address: if invoice_address:
try: try:
with scopes_disabled():
ia = InvoiceAddress.objects.get(pk=invoice_address) ia = InvoiceAddress.objects.get(pk=invoice_address)
except InvoiceAddress.DoesNotExist: except InvoiceAddress.DoesNotExist:
pass pass
@@ -934,8 +934,8 @@ def add_items_to_cart(self, event: int, items: List[dict], cart_id: str=None, lo
raise CartError(error_messages['busy']) raise CartError(error_messages['busy'])
@app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,)) @app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
def remove_cart_position(self, event: int, position: int, cart_id: str=None, locale='en') -> None: def remove_cart_position(self, event: Event, position: int, cart_id: str=None, locale='en') -> None:
""" """
Removes a list of items from a user's cart. Removes a list of items from a user's cart.
:param event: The event ID in question :param event: The event ID in question
@@ -943,7 +943,6 @@ def remove_cart_position(self, event: int, position: int, cart_id: str=None, loc
:param session: Session ID of a guest :param session: Session ID of a guest
""" """
with language(locale): with language(locale):
event = Event.objects.get(id=event)
try: try:
try: try:
cm = CartManager(event=event, cart_id=cart_id) cm = CartManager(event=event, cart_id=cart_id)
@@ -955,15 +954,14 @@ def remove_cart_position(self, event: int, position: int, cart_id: str=None, loc
raise CartError(error_messages['busy']) raise CartError(error_messages['busy'])
@app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,)) @app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
def clear_cart(self, event: int, cart_id: str=None, locale='en') -> None: def clear_cart(self, event: Event, cart_id: str=None, locale='en') -> None:
""" """
Removes a list of items from a user's cart. Removes a list of items from a user's cart.
:param event: The event ID in question :param event: The event ID in question
:param session: Session ID of a guest :param session: Session ID of a guest
""" """
with language(locale): with language(locale):
event = Event.objects.get(id=event)
try: try:
try: try:
cm = CartManager(event=event, cart_id=cart_id) cm = CartManager(event=event, cart_id=cart_id)
@@ -975,8 +973,8 @@ def clear_cart(self, event: int, cart_id: str=None, locale='en') -> None:
raise CartError(error_messages['busy']) raise CartError(error_messages['busy'])
@app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,)) @app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
def set_cart_addons(self, event: int, addons: List[dict], cart_id: str=None, locale='en', def set_cart_addons(self, event: Event, addons: List[dict], cart_id: str=None, locale='en',
invoice_address: int=None, sales_channel='web') -> None: invoice_address: int=None, sales_channel='web') -> None:
""" """
Removes a list of items from a user's cart. Removes a list of items from a user's cart.
@@ -985,11 +983,10 @@ def set_cart_addons(self, event: int, addons: List[dict], cart_id: str=None, loc
:param session: Session ID of a guest :param session: Session ID of a guest
""" """
with language(locale): with language(locale):
event = Event.objects.get(id=event)
ia = False ia = False
if invoice_address: if invoice_address:
try: try:
with scopes_disabled():
ia = InvoiceAddress.objects.get(pk=invoice_address) ia = InvoiceAddress.objects.get(pk=invoice_address)
except InvoiceAddress.DoesNotExist: except InvoiceAddress.DoesNotExist:
pass pass

View File

@@ -2,6 +2,7 @@ from datetime import timedelta
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from pretix.base.models import CachedCombinedTicket, CachedTicket from pretix.base.models import CachedCombinedTicket, CachedTicket
@@ -10,6 +11,7 @@ from ..signals import periodic_task
@receiver(signal=periodic_task) @receiver(signal=periodic_task)
@scopes_disabled()
def clean_cart_positions(sender, **kwargs): def clean_cart_positions(sender, **kwargs):
for cp in CartPosition.objects.filter(expires__lt=now() - timedelta(days=14), addon_to__isnull=False): for cp in CartPosition.objects.filter(expires__lt=now() - timedelta(days=14), addon_to__isnull=False):
cp.delete() cp.delete()
@@ -20,12 +22,14 @@ def clean_cart_positions(sender, **kwargs):
@receiver(signal=periodic_task) @receiver(signal=periodic_task)
@scopes_disabled()
def clean_cached_files(sender, **kwargs): def clean_cached_files(sender, **kwargs):
for cf in CachedFile.objects.filter(expires__isnull=False, expires__lt=now()): for cf in CachedFile.objects.filter(expires__isnull=False, expires__lt=now()):
cf.delete() cf.delete()
@receiver(signal=periodic_task) @receiver(signal=periodic_task)
@scopes_disabled()
def clean_cached_tickets(sender, **kwargs): def clean_cached_tickets(sender, **kwargs):
for cf in CachedTicket.objects.filter(created__lte=now() - timedelta(days=30)): for cf in CachedTicket.objects.filter(created__lte=now() - timedelta(days=30)):
cf.delete() cf.delete()

View File

@@ -6,7 +6,7 @@ from django.utils.translation import ugettext
from pretix.base.i18n import LazyLocaleException, language from pretix.base.i18n import LazyLocaleException, language
from pretix.base.models import CachedFile, Event, cachedfile_name from pretix.base.models import CachedFile, Event, cachedfile_name
from pretix.base.services.tasks import ProfiledTask from pretix.base.services.tasks import ProfiledEventTask
from pretix.base.signals import register_data_exporters from pretix.base.signals import register_data_exporters
from pretix.celery_app import app from pretix.celery_app import app
@@ -15,9 +15,8 @@ class ExportError(LazyLocaleException):
pass pass
@app.task(base=ProfiledTask, throws=(ExportError,)) @app.task(base=ProfiledEventTask, throws=(ExportError,))
def export(event: str, fileid: str, provider: str, form_data: Dict[str, Any]) -> None: def export(event: Event, fileid: str, provider: str, form_data: Dict[str, Any]) -> None:
event = Event.objects.get(id=event)
file = CachedFile.objects.get(id=fileid) file = CachedFile.objects.get(id=fileid)
with language(event.settings.locale), override(event.settings.timezone): with language(event.settings.locale), override(event.settings.timezone):
responses = register_data_exporters.send(event) responses = register_data_exporters.send(event)

View File

@@ -15,6 +15,7 @@ from django.utils import timezone
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import pgettext, ugettext as _ from django.utils.translation import pgettext, ugettext as _
from django_countries.fields import Country from django_countries.fields import Country
from django_scopes import scope, scopes_disabled
from i18nfield.strings import LazyI18nString from i18nfield.strings import LazyI18nString
from pretix.base.i18n import language from pretix.base.i18n import language
@@ -244,7 +245,9 @@ def generate_invoice(order: Order, trigger_pdf=True):
@app.task(base=TransactionAwareTask) @app.task(base=TransactionAwareTask)
def invoice_pdf_task(invoice: int): def invoice_pdf_task(invoice: int):
with scopes_disabled():
i = Invoice.objects.get(pk=invoice) i = Invoice.objects.get(pk=invoice)
with scope(organizer=i.order.event.organizer):
if i.shredded: if i.shredded:
return None return None
if i.file: if i.file:

View File

@@ -10,6 +10,7 @@ from django.conf import settings
from django.core.mail import EmailMultiAlternatives, get_connection from django.core.mail import EmailMultiAlternatives, get_connection
from django.template.loader import get_template from django.template.loader import get_template
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django_scopes import scope, scopes_disabled
from i18nfield.strings import LazyI18nString from i18nfield.strings import LazyI18nString
from pretix.base.email import ClassicMailRenderer from pretix.base.email import ClassicMailRenderer
@@ -234,11 +235,15 @@ def mail_send_task(self, *args, to: List[str], subject: str, body: str, html: st
pass pass
if event: if event:
with scopes_disabled():
event = Event.objects.get(id=event) event = Event.objects.get(id=event)
backend = event.get_mail_backend() backend = event.get_mail_backend()
cm = lambda: scope(organizer=event.organizer) # noqa
else: else:
backend = get_connection(fail_silently=False) backend = get_connection(fail_silently=False)
cm = lambda: scopes_disabled() # noqa
with cm():
if event: if event:
if order: if order:
try: try:

View File

@@ -1,5 +1,6 @@
from django.conf import settings from django.conf import settings
from django.template.loader import get_template from django.template.loader import get_template
from django_scopes import scope, scopes_disabled
from inlinestyler.utils import inline_css from inlinestyler.utils import inline_css
from pretix.base.i18n import language from pretix.base.i18n import language
@@ -12,6 +13,7 @@ from pretix.helpers.urls import build_absolute_uri
@app.task(base=TransactionAwareTask) @app.task(base=TransactionAwareTask)
@scopes_disabled()
def notify(logentry_id: int): def notify(logentry_id: int):
logentry = LogEntry.all.get(id=logentry_id) logentry = LogEntry.all.get(id=logentry_id)
if not logentry.event: if not logentry.event:
@@ -66,6 +68,11 @@ def notify(logentry_id: int):
@app.task(base=ProfiledTask) @app.task(base=ProfiledTask)
def send_notification(logentry_id: int, action_type: str, user_id: int, method: str): def send_notification(logentry_id: int, action_type: str, user_id: int, method: str):
logentry = LogEntry.all.get(id=logentry_id) logentry = LogEntry.all.get(id=logentry_id)
if logentry.event:
sm = lambda: scope(organizer=logentry.event.organizer) # noqa
else:
sm = lambda: scopes_disabled() # noqa
with sm():
user = User.objects.get(id=user_id) user = User.objects.get(id=user_id)
types = get_all_notification_types(logentry.event) types = get_all_notification_types(logentry.event)
notification_type = types.get(action_type) notification_type = types.get(action_type)

View File

@@ -16,6 +16,7 @@ from django.utils.formats import date_format
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.timezone import make_aware, now from django.utils.timezone import make_aware, now
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django_scopes import scopes_disabled
from pretix.api.models import OAuthApplication from pretix.api.models import OAuthApplication
from pretix.base.i18n import ( from pretix.base.i18n import (
@@ -42,7 +43,7 @@ from pretix.base.services.invoices import (
from pretix.base.services.locking import LockTimeoutException, NoLockManager from pretix.base.services.locking import LockTimeoutException, NoLockManager
from pretix.base.services.mail import SendMailException from pretix.base.services.mail import SendMailException
from pretix.base.services.pricing import get_price from pretix.base.services.pricing import get_price
from pretix.base.services.tasks import ProfiledTask from pretix.base.services.tasks import ProfiledEventTask, ProfiledTask
from pretix.base.settings import PERSON_NAME_SCHEMES from pretix.base.settings import PERSON_NAME_SCHEMES
from pretix.base.signals import ( from pretix.base.signals import (
allow_ticket_download, order_approved, order_canceled, order_changed, allow_ticket_download, order_approved, order_canceled, order_changed,
@@ -715,10 +716,8 @@ def _order_placed_email_attendee(event: Event, order: Order, position: OrderPosi
logger.exception('Order received email could not be sent to attendee') logger.exception('Order received email could not be sent to attendee')
def _perform_order(event: str, payment_provider: str, position_ids: List[str], def _perform_order(event: Event, payment_provider: str, position_ids: List[str],
email: str, locale: str, address: int, meta_info: dict=None, sales_channel: str='web'): email: str, locale: str, address: int, meta_info: dict=None, sales_channel: str='web'):
event = Event.objects.get(id=event)
if payment_provider: if payment_provider:
pprov = event.get_payment_providers().get(payment_provider) pprov = event.get_payment_providers().get(payment_provider)
if not pprov: if not pprov:
@@ -732,6 +731,7 @@ def _perform_order(event: str, payment_provider: str, position_ids: List[str],
addr = None addr = None
if address is not None: if address is not None:
try: try:
with scopes_disabled():
addr = InvoiceAddress.objects.get(pk=address) addr = InvoiceAddress.objects.get(pk=address)
except InvoiceAddress.DoesNotExist: except InvoiceAddress.DoesNotExist:
pass pass
@@ -804,6 +804,7 @@ def _perform_order(event: str, payment_provider: str, position_ids: List[str],
@receiver(signal=periodic_task) @receiver(signal=periodic_task)
@scopes_disabled()
def expire_orders(sender, **kwargs): def expire_orders(sender, **kwargs):
eventcache = {} eventcache = {}
@@ -818,6 +819,7 @@ def expire_orders(sender, **kwargs):
@receiver(signal=periodic_task) @receiver(signal=periodic_task)
@scopes_disabled()
def send_expiry_warnings(sender, **kwargs): def send_expiry_warnings(sender, **kwargs):
eventcache = {} eventcache = {}
today = now().replace(hour=0, minute=0, second=0) today = now().replace(hour=0, minute=0, second=0)
@@ -875,6 +877,7 @@ def send_expiry_warnings(sender, **kwargs):
@receiver(signal=periodic_task) @receiver(signal=periodic_task)
@scopes_disabled()
def send_download_reminders(sender, **kwargs): def send_download_reminders(sender, **kwargs):
today = now().replace(hour=0, minute=0, second=0, microsecond=0) today = now().replace(hour=0, minute=0, second=0, microsecond=0)
@@ -1497,8 +1500,8 @@ class OrderChangeManager:
return pprov return pprov
@app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,)) @app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,))
def perform_order(self, event: str, payment_provider: str, positions: List[str], def perform_order(self, event: Event, payment_provider: str, positions: List[str],
email: str=None, locale: str=None, address: int=None, meta_info: dict=None, email: str=None, locale: str=None, address: int=None, meta_info: dict=None,
sales_channel: str='web'): sales_channel: str='web'):
with language(locale): with language(locale):
@@ -1513,6 +1516,7 @@ def perform_order(self, event: str, payment_provider: str, positions: List[str],
@app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,)) @app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,))
@scopes_disabled()
def cancel_order(self, order: int, user: int=None, send_mail: bool=True, api_token=None, oauth_application=None, def cancel_order(self, order: int, user: int=None, send_mail: bool=True, api_token=None, oauth_application=None,
device=None, cancellation_fee=None, try_auto_refund=False): device=None, cancellation_fee=None, try_auto_refund=False):
try: try:

View File

@@ -4,6 +4,7 @@ from django.conf import settings
from django.db.models import Max, Q from django.db.models import Max, Q
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from pretix.base.models import Event, LogEntry from pretix.base.models import Event, LogEntry
from pretix.celery_app import app from pretix.celery_app import app
@@ -17,6 +18,7 @@ def build_all_quota_caches(sender, **kwargs):
@app.task @app.task
@scopes_disabled()
def refresh_quota_caches(): def refresh_quota_caches():
# Active events # Active events
active = LogEntry.objects.using(settings.DATABASE_REPLICA).filter( active = LogEntry.objects.using(settings.DATABASE_REPLICA).filter(

View File

@@ -11,14 +11,13 @@ from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from pretix.base.models import CachedFile, Event, cachedfile_name from pretix.base.models import CachedFile, Event, cachedfile_name
from pretix.base.services.tasks import ProfiledTask from pretix.base.services.tasks import ProfiledEventTask
from pretix.base.shredder import ShredError from pretix.base.shredder import ShredError
from pretix.celery_app import app from pretix.celery_app import app
@app.task(base=ProfiledTask) @app.task(base=ProfiledEventTask)
def export(event: str, shredders: List[str]) -> None: def export(event: Event, shredders: List[str]) -> None:
event = Event.objects.get(id=event)
known_shredders = event.get_data_shredders() known_shredders = event.get_data_shredders()
with NamedTemporaryFile() as rawfile: with NamedTemporaryFile() as rawfile:
@@ -63,9 +62,8 @@ def export(event: str, shredders: List[str]) -> None:
return cf.pk return cf.pk
@app.task(base=ProfiledTask, throws=(ShredError,)) @app.task(base=ProfiledEventTask, throws=(ShredError,))
def shred(event: str, fileid: str, confirm_code: str) -> None: def shred(event: Event, fileid: str, confirm_code: str) -> None:
event = Event.objects.get(id=event)
known_shredders = event.get_data_shredders() known_shredders = event.get_data_shredders()
try: try:
cf = CachedFile.objects.get(pk=fileid) cf = CachedFile.objects.get(pk=fileid)

View File

@@ -14,10 +14,12 @@ import time
from django.conf import settings from django.conf import settings
from django.db import transaction from django.db import transaction
from django_scopes import scope, scopes_disabled
from pretix.base.metrics import ( from pretix.base.metrics import (
pretix_task_duration_seconds, pretix_task_runs_total, pretix_task_duration_seconds, pretix_task_runs_total,
) )
from pretix.base.models import Event
from pretix.celery_app import app from pretix.celery_app import app
@@ -61,6 +63,35 @@ class ProfiledTask(app.Task):
return super().on_success(retval, task_id, args, kwargs) return super().on_success(retval, task_id, args, kwargs)
class EventTask(app.Task):
def __call__(self, *args, **kwargs):
if 'event_id' in kwargs:
event_id = kwargs.get('event_id')
with scopes_disabled():
event = Event.objects.select_related('organizer').get(pk=event_id)
del kwargs['event_id']
kwargs['event'] = event
elif 'event' in kwargs:
event_id = kwargs.get('event')
with scopes_disabled():
event = Event.objects.select_related('organizer').get(pk=event_id)
kwargs['event'] = event
else:
args = list(args)
event_id = args[0]
with scopes_disabled():
event = Event.objects.select_related('organizer').get(pk=event_id)
args[0] = event
with scope(organizer=event.organizer):
ret = super().__call__(*args, **kwargs)
return ret
class ProfiledEventTask(ProfiledTask, EventTask):
pass
class TransactionAwareTask(ProfiledTask): class TransactionAwareTask(ProfiledTask):
""" """
Task class which is aware of django db transactions and only executes tasks Task class which is aware of django db transactions and only executes tasks

View File

@@ -4,13 +4,14 @@ import os
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django_scopes import scopes_disabled
from pretix.base.i18n import language from pretix.base.i18n import language
from pretix.base.models import ( from pretix.base.models import (
CachedCombinedTicket, CachedTicket, Event, InvoiceAddress, Order, CachedCombinedTicket, CachedTicket, Event, InvoiceAddress, Order,
OrderPosition, OrderPosition,
) )
from pretix.base.services.tasks import ProfiledTask from pretix.base.services.tasks import EventTask, ProfiledTask
from pretix.base.settings import PERSON_NAME_SCHEMES from pretix.base.settings import PERSON_NAME_SCHEMES
from pretix.base.signals import allow_ticket_download, register_ticket_outputs from pretix.base.signals import allow_ticket_download, register_ticket_outputs
from pretix.celery_app import app from pretix.celery_app import app
@@ -57,6 +58,7 @@ def generate_order(order: int, provider: str):
@app.task(base=ProfiledTask) @app.task(base=ProfiledTask)
def generate(model: str, pk: int, provider: str): def generate(model: str, pk: int, provider: str):
with scopes_disabled():
if model == 'order': if model == 'order':
return generate_order(pk, provider) return generate_order(pk, provider)
elif model == 'orderposition': elif model == 'orderposition':
@@ -165,9 +167,8 @@ def get_tickets_for_order(order, base_position=None):
return tickets return tickets
@app.task(base=ProfiledTask) @app.task(base=EventTask)
def invalidate_cache(event: int, item: int=None, provider: str=None, order: int=None, **kwargs): def invalidate_cache(event: Event, item: int=None, provider: str=None, order: int=None, **kwargs):
event = Event.objects.get(id=event)
qs = CachedTicket.objects.filter(order_position__order__event=event) qs = CachedTicket.objects.filter(order_position__order__event=event)
qsc = CachedCombinedTicket.objects.filter(order__event=event) qsc = CachedCombinedTicket.objects.filter(order__event=event)

View File

@@ -6,6 +6,7 @@ import requests
from django.dispatch import receiver from django.dispatch import receiver
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _, ugettext_noop from django.utils.translation import ugettext_lazy as _, ugettext_noop
from django_scopes import scopes_disabled
from i18nfield.strings import LazyI18nString from i18nfield.strings import LazyI18nString
from pretix import __version__ from pretix import __version__
@@ -29,6 +30,7 @@ def run_update_check(sender, **kwargs):
@app.task @app.task
@scopes_disabled()
def update_check(): def update_check():
gs = GlobalSettingsObject() gs = GlobalSettingsObject()

View File

@@ -1,17 +1,17 @@
import sys import sys
from django.dispatch import receiver from django.dispatch import receiver
from django_scopes import scopes_disabled
from pretix.base.models import Event, User, WaitingListEntry from pretix.base.models import Event, User, WaitingListEntry
from pretix.base.models.waitinglist import WaitingListException from pretix.base.models.waitinglist import WaitingListException
from pretix.base.services.tasks import ProfiledTask from pretix.base.services.tasks import EventTask
from pretix.base.signals import periodic_task from pretix.base.signals import periodic_task
from pretix.celery_app import app from pretix.celery_app import app
@app.task(base=ProfiledTask) @app.task(base=EventTask)
def assign_automatically(event_id: int, user_id: int=None, subevent_id: int=None): def assign_automatically(event: Event, user_id: int=None, subevent_id: int=None):
event = Event.objects.get(id=event_id)
if user_id: if user_id:
user = User.objects.get(id=user_id) user = User.objects.get(id=user_id)
else: else:
@@ -69,6 +69,7 @@ def assign_automatically(event_id: int, user_id: int=None, subevent_id: int=None
@receiver(signal=periodic_task) @receiver(signal=periodic_task)
@scopes_disabled()
def process_waitinglist(sender, **kwargs): def process_waitinglist(sender, **kwargs):
qs = Event.objects.filter( qs = Event.objects.filter(
live=True live=True

View File

@@ -3,6 +3,7 @@ import hmac
from django.conf import settings from django.conf import settings
from django.http import HttpResponse from django.http import HttpResponse
from django_scopes import scopes_disabled
from .. import metrics from .. import metrics
@@ -15,6 +16,7 @@ def unauthed_response():
return response return response
@scopes_disabled()
def serve_metrics(request): def serve_metrics(request):
if not settings.METRICS_ENABLED: if not settings.METRICS_ENABLED:
return unauthed_response() return unauthed_response()

View File

@@ -5,6 +5,7 @@ from django.conf import settings
from django.db.models import Q from django.db.models import Q
from django.urls import Resolver404, get_script_prefix, resolve from django.urls import Resolver404, get_script_prefix, resolve
from django.utils.translation import get_language from django.utils.translation import get_language
from django_scopes import scope
from pretix.base.models.auth import StaffSession from pretix.base.models.auth import StaffSession
from pretix.base.settings import GlobalSettingsObject from pretix.base.settings import GlobalSettingsObject
@@ -53,6 +54,7 @@ def contextprocessor(request):
ctx['has_domain'] = request.event.organizer.domains.exists() ctx['has_domain'] = request.event.organizer.domains.exists()
if not request.event.testmode: if not request.event.testmode:
with scope(organizer=request.organizer):
complain_testmode_orders = request.event.cache.get('complain_testmode_orders') complain_testmode_orders = request.event.cache.get('complain_testmode_orders')
if complain_testmode_orders is None: if complain_testmode_orders is None:
complain_testmode_orders = request.event.orders.filter(testmode=True).exists() complain_testmode_orders = request.event.orders.filter(testmode=True).exists()

View File

@@ -1,6 +1,9 @@
from django import forms from django import forms
from django.urls import reverse from django.urls import reverse
from django.utils.translation import pgettext_lazy from django.utils.translation import pgettext_lazy
from django_scopes.forms import (
SafeModelChoiceField, SafeModelMultipleChoiceField,
)
from pretix.base.models.checkin import CheckinList from pretix.base.models.checkin import CheckinList
from pretix.control.forms.widgets import Select2 from pretix.control.forms.widgets import Select2
@@ -44,3 +47,7 @@ class CheckinListForm(forms.ModelForm):
'data-inverse-dependency': '<[name$=all_products]' 'data-inverse-dependency': '<[name$=all_products]'
}), }),
} }
field_classes = {
'limit_products': SafeModelMultipleChoiceField,
'subevent': SafeModelChoiceField,
}

View File

@@ -6,6 +6,9 @@ from django.urls import reverse
from django.utils.translation import ( from django.utils.translation import (
pgettext_lazy, ugettext as __, ugettext_lazy as _, pgettext_lazy, ugettext as __, ugettext_lazy as _,
) )
from django_scopes.forms import (
SafeModelChoiceField, SafeModelMultipleChoiceField,
)
from i18nfield.forms import I18nFormField, I18nTextarea from i18nfield.forms import I18nFormField, I18nTextarea
from pretix.base.channels import get_all_sales_channels from pretix.base.channels import get_all_sales_channels
@@ -94,6 +97,10 @@ class QuestionForm(I18nModelForm):
), ),
'dependency_value': forms.Select, 'dependency_value': forms.Select,
} }
field_classes = {
'items': SafeModelMultipleChoiceField,
'dependency_question': SafeModelChoiceField,
}
class QuestionOptionForm(I18nModelForm): class QuestionOptionForm(I18nModelForm):
@@ -159,6 +166,9 @@ class QuotaForm(I18nModelForm):
'size', 'size',
'subevent' 'subevent'
] ]
field_classes = {
'subevent': SafeModelChoiceField,
}
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
creating = not self.instance.pk creating = not self.instance.pk

View File

@@ -192,7 +192,7 @@ class OrderPositionAddForm(forms.Form):
label=_('Product') label=_('Product')
) )
addon_to = forms.ModelChoiceField( addon_to = forms.ModelChoiceField(
OrderPosition.objects.none(), OrderPosition.all.none(),
required=False, required=False,
label=_('Add-on to'), label=_('Add-on to'),
) )

View File

@@ -6,6 +6,7 @@ from django.core.exceptions import ValidationError
from django.core.validators import RegexValidator from django.core.validators import RegexValidator
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import pgettext_lazy, ugettext_lazy as _ from django.utils.translation import pgettext_lazy, ugettext_lazy as _
from django_scopes.forms import SafeModelMultipleChoiceField
from i18nfield.forms import I18nFormField, I18nTextarea from i18nfield.forms import I18nFormField, I18nTextarea
from pretix.api.models import WebHook from pretix.api.models import WebHook
@@ -149,6 +150,9 @@ class TeamForm(forms.ModelForm):
'data-inverse-dependency': '#id_all_events' 'data-inverse-dependency': '#id_all_events'
}), }),
} }
field_classes = {
'limit_events': SafeModelMultipleChoiceField
}
def clean(self): def clean(self):
data = super().clean() data = super().clean()
@@ -177,6 +181,9 @@ class DeviceForm(forms.ModelForm):
'data-inverse-dependency': '#id_all_events' 'data-inverse-dependency': '#id_all_events'
}), }),
} }
field_classes = {
'limit_events': SafeModelMultipleChoiceField
}
class OrganizerSettingsForm(SettingsForm): class OrganizerSettingsForm(SettingsForm):
@@ -307,3 +314,6 @@ class WebHookForm(forms.ModelForm):
'data-inverse-dependency': '#id_all_events' 'data-inverse-dependency': '#id_all_events'
}), }),
} }
field_classes = {
'limit_events': SafeModelMultipleChoiceField
}

View File

@@ -3,6 +3,7 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.db.models.functions import Lower from django.db.models.functions import Lower
from django.urls import reverse from django.urls import reverse
from django.utils.translation import pgettext_lazy, ugettext_lazy as _ from django.utils.translation import pgettext_lazy, ugettext_lazy as _
from django_scopes.forms import SafeModelChoiceField
from pretix.base.forms import I18nModelForm from pretix.base.forms import I18nModelForm
from pretix.base.models import Item, Voucher from pretix.base.models import Item, Voucher
@@ -35,6 +36,7 @@ class VoucherForm(I18nModelForm):
] ]
field_classes = { field_classes = {
'valid_until': SplitDateTimeField, 'valid_until': SplitDateTimeField,
'subevent': SafeModelChoiceField,
} }
widgets = { widgets = {
'valid_until': SplitDateTimePickerWidget(), 'valid_until': SplitDateTimePickerWidget(),
@@ -199,6 +201,7 @@ class VoucherBulkForm(VoucherForm):
] ]
field_classes = { field_classes = {
'valid_until': SplitDateTimeField, 'valid_until': SplitDateTimeField,
'subevent': SafeModelChoiceField,
} }
widgets = { widgets = {
'valid_until': SplitDateTimePickerWidget(), 'valid_until': SplitDateTimePickerWidget(),

View File

@@ -4,10 +4,11 @@ from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME, logout from django.contrib.auth import REDIRECT_FIELD_NAME, logout
from django.http import Http404 from django.http import Http404
from django.shortcuts import get_object_or_404, redirect, resolve_url from django.shortcuts import get_object_or_404, redirect, resolve_url
from django.template.response import TemplateResponse
from django.urls import get_script_prefix, resolve, reverse from django.urls import get_script_prefix, resolve, reverse
from django.utils.deprecation import MiddlewareMixin
from django.utils.encoding import force_str from django.utils.encoding import force_str
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django_scopes import scope
from hijack.templatetags.hijack_tags import is_hijacked from hijack.templatetags.hijack_tags import is_hijacked
from pretix.base.models import Event, Organizer from pretix.base.models import Event, Organizer
@@ -17,7 +18,7 @@ from pretix.helpers.security import (
) )
class PermissionMiddleware(MiddlewareMixin): class PermissionMiddleware:
""" """
This middleware enforces all requests to the control app to require login. This middleware enforces all requests to the control app to require login.
Additionally, it enforces all requests to "control:event." URLs Additionally, it enforces all requests to "control:event." URLs
@@ -34,6 +35,10 @@ class PermissionMiddleware(MiddlewareMixin):
"user.settings.notifications.off", "user.settings.notifications.off",
) )
def __init__(self, get_response=None):
self.get_response = get_response
super().__init__()
def _login_redirect(self, request): def _login_redirect(self, request):
# Taken from django/contrib/auth/decorators.py # Taken from django/contrib/auth/decorators.py
path = request.build_absolute_uri() path = request.build_absolute_uri()
@@ -52,19 +57,19 @@ class PermissionMiddleware(MiddlewareMixin):
return redirect_to_login( return redirect_to_login(
path, resolved_login_url, REDIRECT_FIELD_NAME) path, resolved_login_url, REDIRECT_FIELD_NAME)
def process_request(self, request): def __call__(self, request):
url = resolve(request.path_info) url = resolve(request.path_info)
url_name = url.url_name url_name = url.url_name
if not request.path.startswith(get_script_prefix() + 'control'): if not request.path.startswith(get_script_prefix() + 'control'):
# This middleware should only touch the /control subpath # This middleware should only touch the /control subpath
return return self.get_response(request)
if hasattr(request, 'organizer'): if hasattr(request, 'organizer'):
# If the user is on a organizer's subdomain, he should be redirected to pretix # If the user is on a organizer's subdomain, he should be redirected to pretix
return redirect(urljoin(settings.SITE_URL, request.get_full_path())) return redirect(urljoin(settings.SITE_URL, request.get_full_path()))
if url_name in self.EXCEPTIONS: if url_name in self.EXCEPTIONS:
return return self.get_response(request)
if not request.user.is_authenticated: if not request.user.is_authenticated:
return self._login_redirect(request) return self._login_redirect(request)
@@ -79,6 +84,7 @@ class PermissionMiddleware(MiddlewareMixin):
return redirect(reverse('control:user.reauth') + '?next=' + quote(request.get_full_path())) return redirect(reverse('control:user.reauth') + '?next=' + quote(request.get_full_path()))
if 'event' in url.kwargs and 'organizer' in url.kwargs: if 'event' in url.kwargs and 'organizer' in url.kwargs:
with scope(organizer=None):
request.event = Event.objects.filter( request.event = Event.objects.filter(
slug=url.kwargs['event'], slug=url.kwargs['event'],
organizer__slug=url.kwargs['organizer'], organizer__slug=url.kwargs['organizer'],
@@ -104,6 +110,12 @@ class PermissionMiddleware(MiddlewareMixin):
else: else:
request.orgapermset = request.user.get_organizer_permission_set(request.organizer) request.orgapermset = request.user.get_organizer_permission_set(request.organizer)
with scope(organizer=getattr(request, 'organizer', None)):
r = self.get_response(request)
if isinstance(r, TemplateResponse):
r = r.render()
return r
class AuditLogMiddleware: class AuditLogMiddleware:

View File

@@ -7,6 +7,7 @@ from pretix.base.models import (
CachedFile, Event, OrderPosition, cachedfile_name, CachedFile, Event, OrderPosition, cachedfile_name,
) )
from pretix.base.services.orders import OrderError from pretix.base.services.orders import OrderError
from pretix.base.services.tasks import EventTask
from pretix.celery_app import app from pretix.celery_app import app
from .exporters import render_pdf from .exporters import render_pdf
@@ -14,8 +15,8 @@ from .exporters import render_pdf
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@app.task(throws=(OrderError,)) @app.task(base=EventTask, throws=(OrderError,))
def badges_create_pdf(fileid: int, event: int, positions: List[int]) -> int: def badges_create_pdf(event: int, fileid: int, positions: List[int]) -> int:
file = CachedFile.objects.get(id=fileid) file = CachedFile.objects.get(id=fileid)
event = Event.objects.get(id=event) event = Event.objects.get(id=event)

View File

@@ -223,7 +223,7 @@ class OrderPrintDo(EventPermissionRequiredMixin, AsyncAction, View):
else: else:
positions = [p.pk for p in order.positions.all()] positions = [p.pk for p in order.positions.all()]
return self.do( return self.do(
str(cf.id),
self.request.event.pk, self.request.event.pk,
str(cf.id),
positions, positions,
) )

View File

@@ -9,6 +9,7 @@ from django.db import transaction
from django.db.models import Q from django.db.models import Q
from django.utils.formats import date_format from django.utils.formats import date_format
from django.utils.translation import ugettext, ugettext_noop from django.utils.translation import ugettext, ugettext_noop
from django_scopes import scope, scopes_disabled
from pretix.base.i18n import language from pretix.base.i18n import language
from pretix.base.models import ( from pretix.base.models import (
@@ -194,7 +195,9 @@ def _get_unknown_transactions(job: BankImportJob, data: list, event: Event=None,
@app.task(base=TransactionAwareTask, bind=True, max_retries=5, default_retry_delay=1) @app.task(base=TransactionAwareTask, bind=True, max_retries=5, default_retry_delay=1)
def process_banktransfers(self, job: int, data: list) -> None: def process_banktransfers(self, job: int, data: list) -> None:
with language("en"): # We'll translate error messages at display time with language("en"): # We'll translate error messages at display time
with scopes_disabled():
job = BankImportJob.objects.get(pk=job) job = BankImportJob.objects.get(pk=job)
with scope(organizer=job.organizer or job.event.organizer):
job.state = BankImportJob.STATE_RUNNING job.state = BankImportJob.STATE_RUNNING
job.save() job.save()
prefixes = [] prefixes = []

View File

@@ -13,6 +13,7 @@ from django.utils.translation import ugettext_lazy as _
from django.views.decorators.clickjacking import xframe_options_exempt from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from django_scopes import scopes_disabled
from paypalrestsdk.openid_connect import Tokeninfo from paypalrestsdk.openid_connect import Tokeninfo
from pretix.base.models import Event, Order, OrderPayment, OrderRefund, Quota from pretix.base.models import Event, Order, OrderPayment, OrderRefund, Quota
@@ -133,6 +134,7 @@ def abort(request, *args, **kwargs):
@csrf_exempt @csrf_exempt
@require_POST @require_POST
@scopes_disabled()
def webhook(request, *args, **kwargs): def webhook(request, *args, **kwargs):
event_body = request.body.decode('utf-8').strip() event_body = request.body.decode('utf-8').strip()
event_json = json.loads(event_body) event_json = json.loads(event_body)

View File

@@ -1,6 +1,9 @@
from django import forms from django import forms
from django.urls import reverse from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django_scopes.forms import (
SafeModelChoiceField, SafeModelMultipleChoiceField,
)
from pretix.control.forms.widgets import Select2 from pretix.control.forms.widgets import Select2
from pretix.plugins.pretixdroid.models import AppConfiguration from pretix.plugins.pretixdroid.models import AppConfiguration
@@ -16,6 +19,10 @@ class AppConfigurationForm(forms.ModelForm):
}), }),
'app': forms.RadioSelect 'app': forms.RadioSelect
} }
field_classes = {
'items': SafeModelMultipleChoiceField,
'list': SafeModelChoiceField,
}
def __init__(self, **kwargs): def __init__(self, **kwargs):
self.event = kwargs.pop('event') self.event = kwargs.pop('event')

View File

@@ -17,6 +17,7 @@ from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.views.generic import TemplateView, View from django.views.generic import TemplateView, View
from django_scopes import scope, scopes_disabled
from pretix.base.models import Checkin, Event, Order, OrderPosition from pretix.base.models import Checkin, Event, Order, OrderPosition
from pretix.base.models.event import SubEvent from pretix.base.models.event import SubEvent
@@ -124,6 +125,7 @@ class ConfigView(EventPermissionRequiredMixin, TemplateView):
class ApiView(View): class ApiView(View):
@method_decorator(csrf_exempt) @method_decorator(csrf_exempt)
def dispatch(self, request, **kwargs): def dispatch(self, request, **kwargs):
with scopes_disabled():
try: try:
self.event = Event.objects.get( self.event = Event.objects.get(
slug=self.kwargs['event'], slug=self.kwargs['event'],
@@ -131,7 +133,7 @@ class ApiView(View):
) )
except Event.DoesNotExist: except Event.DoesNotExist:
return HttpResponseNotFound('Unknown event') return HttpResponseNotFound('Unknown event')
with scope(organizer=self.event.organizer):
try: try:
self.config = self.event.appconfiguration_set.get(key=request.GET.get("key", "-unset-")) self.config = self.event.appconfiguration_set.get(key=request.GET.get("key", "-unset-"))
except AppConfiguration.DoesNotExist: except AppConfiguration.DoesNotExist:

View File

@@ -5,15 +5,14 @@ from i18nfield.strings import LazyI18nString
from pretix.base.i18n import language from pretix.base.i18n import language
from pretix.base.models import Event, InvoiceAddress, Order, User from pretix.base.models import Event, InvoiceAddress, Order, User
from pretix.base.services.mail import SendMailException, mail from pretix.base.services.mail import SendMailException, mail
from pretix.base.services.tasks import ProfiledTask from pretix.base.services.tasks import ProfiledEventTask
from pretix.celery_app import app from pretix.celery_app import app
from pretix.multidomain.urlreverse import build_absolute_uri from pretix.multidomain.urlreverse import build_absolute_uri
@app.task(base=ProfiledTask) @app.task(base=ProfiledEventTask)
def send_mails(event: int, user: int, subject: dict, message: dict, orders: list, items: list, recipients: str) -> None: def send_mails(event: Event, user: int, subject: dict, message: dict, orders: list, items: list, recipients: str) -> None:
failures = [] failures = []
event = Event.objects.get(pk=event)
user = User.objects.get(pk=user) if user else None user = User.objects.get(pk=user) if user else None
orders = Order.objects.filter(pk__in=orders, event=event) orders = Order.objects.filter(pk__in=orders, event=event)
subject = LazyI18nString(subject) subject = LazyI18nString(subject)

View File

@@ -1,5 +1,6 @@
import stripe import stripe
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django_scopes import scopes_disabled
from pretix.base.models import Event from pretix.base.models import Event
from pretix.base.settings import GlobalSettingsObject from pretix.base.settings import GlobalSettingsObject
@@ -8,6 +9,7 @@ from pretix.base.settings import GlobalSettingsObject
class Command(BaseCommand): class Command(BaseCommand):
help = "Detect country for Stripe Connect accounts connected with pretix 2.0 (required for payment request buttons)" help = "Detect country for Stripe Connect accounts connected with pretix 2.0 (required for payment request buttons)"
@scopes_disabled()
def handle(self, *args, **options): def handle(self, *args, **options):
cache = {} cache = {}
gs = GlobalSettingsObject() gs = GlobalSettingsObject()

View File

@@ -5,6 +5,7 @@ import stripe
from django.conf import settings from django.conf import settings
from pretix.base.models import Event from pretix.base.models import Event
from pretix.base.services.tasks import EventTask
from pretix.celery_app import app from pretix.celery_app import app
from pretix.multidomain.urlreverse import get_domain from pretix.multidomain.urlreverse import get_domain
from pretix.plugins.stripe.models import RegisteredApplePayDomain from pretix.plugins.stripe.models import RegisteredApplePayDomain
@@ -27,7 +28,7 @@ def get_stripe_account_key(prov):
return prov.settings.publishable_key return prov.settings.publishable_key
@app.task(max_retries=5, default_retry_delay=1) @app.task(base=EventTask, max_retries=5, default_retry_delay=1)
def stripe_verify_domain(event_id, domain): def stripe_verify_domain(event_id, domain):
from pretix.plugins.stripe.payment import StripeCC from pretix.plugins.stripe.payment import StripeCC
event = Event.objects.get(pk=event_id) event = Event.objects.get(pk=event_id)

View File

@@ -17,6 +17,7 @@ from django.views import View
from django.views.decorators.clickjacking import xframe_options_exempt from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from django_scopes import scopes_disabled
from pretix.base.models import Event, Order, OrderPayment, Quota from pretix.base.models import Event, Order, OrderPayment, Quota
from pretix.base.payment import PaymentException from pretix.base.payment import PaymentException
@@ -140,6 +141,7 @@ def oauth_return(request, *args, **kwargs):
@csrf_exempt @csrf_exempt
@require_POST @require_POST
@scopes_disabled()
def webhook(request, *args, **kwargs): def webhook(request, *args, **kwargs):
event_json = json.loads(request.body.decode('utf-8')) event_json = json.loads(request.body.decode('utf-8'))

View File

@@ -12,6 +12,7 @@ from django.utils.translation import (
get_language, pgettext_lazy, ugettext_lazy as _, get_language, pgettext_lazy, ugettext_lazy as _,
) )
from django.views.generic.base import TemplateResponseMixin from django.views.generic.base import TemplateResponseMixin
from django_scopes import scopes_disabled
from pretix.base.models import Order from pretix.base.models import Order
from pretix.base.models.orders import InvoiceAddress, OrderPayment from pretix.base.models.orders import InvoiceAddress, OrderPayment
@@ -114,7 +115,10 @@ class BaseCheckoutFlowStep:
self.request._checkout_flow_invoice_address = InvoiceAddress() self.request._checkout_flow_invoice_address = InvoiceAddress()
else: else:
try: try:
self.request._checkout_flow_invoice_address = InvoiceAddress.objects.get(pk=iapk, order__isnull=True) with scopes_disabled():
self.request._checkout_flow_invoice_address = InvoiceAddress.objects.get(
pk=iapk, order__isnull=True
)
except InvoiceAddress.DoesNotExist: except InvoiceAddress.DoesNotExist:
self.request._checkout_flow_invoice_address = InvoiceAddress() self.request._checkout_flow_invoice_address = InvoiceAddress()
return self.request._checkout_flow_invoice_address return self.request._checkout_flow_invoice_address

View File

@@ -4,6 +4,7 @@ from django.conf import settings
from django.core.files.base import ContentFile, File from django.core.files.base import ContentFile, File
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django_scopes import scopes_disabled
from pretix.base.models import Event_SettingsStore, Organizer_SettingsStore from pretix.base.models import Event_SettingsStore, Organizer_SettingsStore
from pretix.base.settings import GlobalSettingsObject from pretix.base.settings import GlobalSettingsObject
@@ -15,6 +16,7 @@ from ...style import regenerate_css, regenerate_organizer_css
class Command(BaseCommand): class Command(BaseCommand):
help = "Re-generate all custom stylesheets and scripts" help = "Re-generate all custom stylesheets and scripts"
@scopes_disabled()
def handle(self, *args, **options): def handle(self, *args, **options):
for es in Organizer_SettingsStore.objects.filter(key="presale_css_file"): for es in Organizer_SettingsStore.objects.filter(key="presale_css_file"):
regenerate_organizer_css.apply_async(args=(es.object_id,)) regenerate_organizer_css.apply_async(args=(es.object_id,))

View File

@@ -1,25 +1,32 @@
from django.urls import resolve from django.urls import resolve
from django.utils.deprecation import MiddlewareMixin from django_scopes import scope
from pretix.presale.signals import process_response from pretix.presale.signals import process_response
from .utils import _detect_event from .utils import _detect_event
class EventMiddleware(MiddlewareMixin): class EventMiddleware:
def process_request(self, request): def __init__(self, get_response=None):
self.get_response = get_response
super().__init__()
def __call__(self, request):
url = resolve(request.path_info) url = resolve(request.path_info)
request._namespace = url.namespace request._namespace = url.namespace
if url.namespace != 'presale': if url.namespace != 'presale':
return return self.get_response(request)
if 'organizer' in url.kwargs or 'event' in url.kwargs: if 'organizer' in url.kwargs or 'event' in url.kwargs:
redirect = _detect_event(request, require_live=url.url_name != 'event.widget.productlist') redirect = _detect_event(request, require_live=url.url_name != 'event.widget.productlist')
if redirect: if redirect:
return redirect return redirect
def process_response(self, request, response): with scope(organizer=getattr(request, 'organizer', None)):
response = self.get_response(request)
if hasattr(request, '_namespace') and request._namespace == 'presale' and hasattr(request, 'event'): if hasattr(request, '_namespace') and request._namespace == 'presale' and hasattr(request, 'event'):
for receiver, r in process_response.send(request.event, request=request, response=response): for receiver, r in process_response.send(request.event, request=request, response=response):
response = r response = r
return response return response

View File

@@ -11,9 +11,10 @@ from django.core.files.base import ContentFile
from django.core.files.storage import default_storage from django.core.files.storage import default_storage
from django.dispatch import Signal from django.dispatch import Signal
from django.templatetags.static import static as _static from django.templatetags.static import static as _static
from django_scopes import scope
from pretix.base.models import Event, Event_SettingsStore, Organizer from pretix.base.models import Event, Event_SettingsStore, Organizer
from pretix.base.services.tasks import ProfiledTask from pretix.base.services.tasks import ProfiledEventTask, ProfiledTask
from pretix.celery_app import app from pretix.celery_app import app
from pretix.multidomain.urlreverse import get_domain from pretix.multidomain.urlreverse import get_domain
from pretix.presale.signals import sass_postamble, sass_preamble from pretix.presale.signals import sass_postamble, sass_preamble
@@ -78,10 +79,8 @@ def compile_scss(object, file="main.scss", fonts=True):
return css, checksum return css, checksum
@app.task(base=ProfiledTask) @app.task(base=ProfiledEventTask)
def regenerate_css(event_id: int): def regenerate_css(event):
event = Event.objects.select_related('organizer').get(pk=event_id)
# main.scss # main.scss
css, checksum = compile_scss(event) css, checksum = compile_scss(event)
fname = 'pub/{}/{}/presale.{}.css'.format(event.organizer.slug, event.slug, checksum[:16]) fname = 'pub/{}/{}/presale.{}.css'.format(event.organizer.slug, event.slug, checksum[:16])
@@ -105,6 +104,7 @@ def regenerate_css(event_id: int):
def regenerate_organizer_css(organizer_id: int): def regenerate_organizer_css(organizer_id: int):
organizer = Organizer.objects.get(pk=organizer_id) organizer = Organizer.objects.get(pk=organizer_id)
with scope(organizer=organizer):
# main.scss # main.scss
css, checksum = compile_scss(organizer) css, checksum = compile_scss(organizer)
fname = 'pub/{}/presale.{}.css'.format(organizer.slug, checksum[:16]) fname = 'pub/{}/presale.{}.css'.format(organizer.slug, checksum[:16])

View File

@@ -8,6 +8,7 @@ from django.http import Http404
from django.shortcuts import redirect from django.shortcuts import redirect
from django.urls import resolve from django.urls import resolve
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django_scopes import scope
from pretix.base.middleware import LocaleMiddleware from pretix.base.middleware import LocaleMiddleware
from pretix.base.models import Event, Organizer from pretix.base.models import Event, Organizer
@@ -17,6 +18,7 @@ from pretix.presale.signals import process_request, process_response
SessionStore = import_module(settings.SESSION_ENGINE).SessionStore SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
@scope(organizer=None)
def _detect_event(request, require_live=True, require_plugin=None): def _detect_event(request, require_live=True, require_plugin=None):
if hasattr(request, '_event_detected'): if hasattr(request, '_event_detected'):
return return
@@ -151,6 +153,7 @@ def _event_view(function=None, require_live=True, require_plugin=None):
if ret: if ret:
return ret return ret
else: else:
with scope(organizer=getattr(request, 'organizer', None)):
response = func(request=request, *args, **kwargs) response = func(request=request, *args, **kwargs)
for receiver, r in process_response.send(request.event, request=request, response=response): for receiver, r in process_response.send(request.event, request=request, response=response):
response = r response = r

View File

@@ -9,6 +9,7 @@ from django.db.models import Prefetch, Sum
from django.utils.decorators import available_attrs from django.utils.decorators import available_attrs
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from pretix.base.i18n import language from pretix.base.i18n import language
from pretix.base.models import ( from pretix.base.models import (
@@ -40,7 +41,10 @@ class CartMixin:
self.request._checkout_flow_invoice_address = InvoiceAddress() self.request._checkout_flow_invoice_address = InvoiceAddress()
else: else:
try: try:
self.request._checkout_flow_invoice_address = InvoiceAddress.objects.get(pk=iapk, order__isnull=True) with scopes_disabled():
self.request._checkout_flow_invoice_address = InvoiceAddress.objects.get(
pk=iapk, order__isnull=True
)
except InvoiceAddress.DoesNotExist: except InvoiceAddress.DoesNotExist:
self.request._checkout_flow_invoice_address = InvoiceAddress() self.request._checkout_flow_invoice_address = InvoiceAddress()
return self.request._checkout_flow_invoice_address return self.request._checkout_flow_invoice_address
@@ -215,6 +219,7 @@ def get_cart_invoice_address(request):
request._checkout_flow_invoice_address = InvoiceAddress() request._checkout_flow_invoice_address = InvoiceAddress()
else: else:
try: try:
with scopes_disabled():
request._checkout_flow_invoice_address = InvoiceAddress.objects.get(pk=iapk, order__isnull=True) request._checkout_flow_invoice_address = InvoiceAddress.objects.get(pk=iapk, order__isnull=True)
except InvoiceAddress.DoesNotExist: except InvoiceAddress.DoesNotExist:
request._checkout_flow_invoice_address = InvoiceAddress() request._checkout_flow_invoice_address = InvoiceAddress()

View File

@@ -17,6 +17,7 @@ from django.utils.timezone import now
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views.decorators.clickjacking import xframe_options_exempt from django.views.decorators.clickjacking import xframe_options_exempt
from django.views.generic import TemplateView, View from django.views.generic import TemplateView, View
from django_scopes import scopes_disabled
from pretix.base.models import ( from pretix.base.models import (
CartPosition, InvoiceAddress, QuestionAnswer, SubEvent, Voucher, CartPosition, InvoiceAddress, QuestionAnswer, SubEvent, Voucher,
@@ -80,6 +81,7 @@ class CartActionMixin:
return InvoiceAddress() return InvoiceAddress()
try: try:
with scopes_disabled():
return InvoiceAddress.objects.get(pk=iapk, order__isnull=True) return InvoiceAddress.objects.get(pk=iapk, order__isnull=True)
except InvoiceAddress.DoesNotExist: except InvoiceAddress.DoesNotExist:
return InvoiceAddress() return InvoiceAddress()

View File

@@ -343,6 +343,7 @@ MIDDLEWARE = [
'pretix.base.middleware.LocaleMiddleware', 'pretix.base.middleware.LocaleMiddleware',
'pretix.base.middleware.SecurityMiddleware', 'pretix.base.middleware.SecurityMiddleware',
'pretix.presale.middleware.EventMiddleware', 'pretix.presale.middleware.EventMiddleware',
'pretix.api.middleware.ApiScopeMiddleware',
] ]
try: try:

View File

@@ -0,0 +1,10 @@
from django_scopes import scope
def classscope(attr='o'):
def wrap(fn):
def wrapped(self, *args, **kwargs):
with scope(organizer=getattr(self, attr)):
return fn(self, *args, **kwargs)
return wrapped
return wrap

View File

@@ -12,6 +12,7 @@ from pretix.settings import * # NOQA
DATA_DIR = tmpdir.name DATA_DIR = tmpdir.name
LOG_DIR = os.path.join(DATA_DIR, 'logs') LOG_DIR = os.path.join(DATA_DIR, 'logs')
MEDIA_ROOT = os.path.join(DATA_DIR, 'media') MEDIA_ROOT = os.path.join(DATA_DIR, 'media')
SITE_URL = "http://example.com"
atexit.register(tmpdir.cleanup) atexit.register(tmpdir.cleanup)

View File

@@ -9,6 +9,7 @@ django-formset-js-improved==0.5.0.2
django-compressor==2.2.* django-compressor==2.2.*
django-hierarkey==1.0.*,>=1.0.3 django-hierarkey==1.0.*,>=1.0.3
django-filter==2.1.* django-filter==2.1.*
django-scopes==1.1.*
reportlab==3.5.* reportlab==3.5.*
PyPDF2==1.26.* PyPDF2==1.26.*
Pillow==5.* Pillow==5.*

View File

@@ -97,6 +97,7 @@ setup(
'django-compressor==2.2.*', 'django-compressor==2.2.*',
'django-hierarkey==1.0.*,>=1.0.2', 'django-hierarkey==1.0.*,>=1.0.2',
'django-filter==2.1.*', 'django-filter==2.1.*',
'django-scopes==1.1.*',
'reportlab==3.5.*', 'reportlab==3.5.*',
'Pillow==5.*', 'Pillow==5.*',
'PyPDF2==1.26.*', 'PyPDF2==1.26.*',

View File

@@ -1,7 +1,9 @@
from datetime import datetime from datetime import datetime
import pytest import pytest
from django.test import utils
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from pytz import UTC from pytz import UTC
from rest_framework.test import APIClient from rest_framework.test import APIClient
@@ -15,16 +17,19 @@ def client():
@pytest.fixture @pytest.fixture
@scopes_disabled()
def organizer(): def organizer():
return Organizer.objects.create(name='Dummy', slug='dummy') return Organizer.objects.create(name='Dummy', slug='dummy')
@pytest.fixture @pytest.fixture
@scopes_disabled()
def meta_prop(organizer): def meta_prop(organizer):
return organizer.meta_properties.create(name="type", default="Concert") return organizer.meta_properties.create(name="type", default="Concert")
@pytest.fixture @pytest.fixture
@scopes_disabled()
def event(organizer, meta_prop): def event(organizer, meta_prop):
e = Event.objects.create( e = Event.objects.create(
organizer=organizer, name='Dummy', slug='dummy', organizer=organizer, name='Dummy', slug='dummy',
@@ -37,6 +42,7 @@ def event(organizer, meta_prop):
@pytest.fixture @pytest.fixture
@scopes_disabled()
def event2(organizer, meta_prop): def event2(organizer, meta_prop):
e = Event.objects.create( e = Event.objects.create(
organizer=organizer, name='Dummy2', slug='dummy2', organizer=organizer, name='Dummy2', slug='dummy2',
@@ -48,6 +54,7 @@ def event2(organizer, meta_prop):
@pytest.fixture @pytest.fixture
@scopes_disabled()
def event3(organizer, meta_prop): def event3(organizer, meta_prop):
e = Event.objects.create( e = Event.objects.create(
organizer=organizer, name='Dummy3', slug='dummy3', organizer=organizer, name='Dummy3', slug='dummy3',
@@ -59,6 +66,7 @@ def event3(organizer, meta_prop):
@pytest.fixture @pytest.fixture
@scopes_disabled()
def team(organizer): def team(organizer):
return Team.objects.create( return Team.objects.create(
organizer=organizer, organizer=organizer,
@@ -73,6 +81,7 @@ def team(organizer):
@pytest.fixture @pytest.fixture
@scopes_disabled()
def device(organizer): def device(organizer):
return Device.objects.create( return Device.objects.create(
organizer=organizer, organizer=organizer,
@@ -89,6 +98,7 @@ def user():
@pytest.fixture @pytest.fixture
@scopes_disabled()
def user_client(client, team, user): def user_client(client, team, user):
team.can_view_orders = True team.can_view_orders = True
team.can_view_vouchers = True team.can_view_vouchers = True
@@ -100,6 +110,7 @@ def user_client(client, team, user):
@pytest.fixture @pytest.fixture
@scopes_disabled()
def token_client(client, team): def token_client(client, team):
team.can_view_orders = True team.can_view_orders = True
team.can_view_vouchers = True team.can_view_vouchers = True
@@ -117,6 +128,7 @@ def device_client(client, device):
@pytest.fixture @pytest.fixture
@scopes_disabled()
def subevent(event, meta_prop): def subevent(event, meta_prop):
event.has_subevents = True event.has_subevents = True
event.save() event.save()
@@ -127,6 +139,7 @@ def subevent(event, meta_prop):
@pytest.fixture @pytest.fixture
@scopes_disabled()
def subevent2(event2, meta_prop): def subevent2(event2, meta_prop):
event2.has_subevents = True event2.has_subevents = True
event2.save() event2.save()
@@ -137,10 +150,15 @@ def subevent2(event2, meta_prop):
@pytest.fixture @pytest.fixture
@scopes_disabled()
def taxrule(event): def taxrule(event):
return event.tax_rules.create(name="VAT", rate=19) return event.tax_rules.create(name="VAT", rate=19)
@pytest.fixture @pytest.fixture
@scopes_disabled()
def taxrule2(event2): def taxrule2(event2):
return event2.tax_rules.create(name="VAT", rate=25) return event2.tax_rules.create(name="VAT", rate=25)
utils.setup_databases = scopes_disabled()(utils.setup_databases)

View File

@@ -13,7 +13,6 @@ def test_no_auth(client):
def test_session_auth_no_teams(client, user): def test_session_auth_no_teams(client, user):
client.login(email=user.email, password='dummy') client.login(email=user.email, password='dummy')
resp = client.get('/api/v1/organizers/') resp = client.get('/api/v1/organizers/')
print(resp.data)
assert resp.status_code == 200 assert resp.status_code == 200
assert len(resp.data['results']) == 0 assert len(resp.data['results']) == 0

View File

@@ -5,6 +5,7 @@ from unittest import mock
import pytest import pytest
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from pytz import UTC from pytz import UTC
from pretix.base.models import Question from pretix.base.models import Question
@@ -175,6 +176,7 @@ def test_cartpos_create(token_client, organizer, event, item, quota, question):
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
cp = CartPosition.objects.get(pk=resp.data['id']) cp = CartPosition.objects.get(pk=resp.data['id'])
assert cp.price == Decimal('23.00') assert cp.price == Decimal('23.00')
assert cp.item == item assert cp.item == item
@@ -193,6 +195,7 @@ def test_cartpos_create_name_optional(token_client, organizer, event, item, quot
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
cp = CartPosition.objects.get(pk=resp.data['id']) cp = CartPosition.objects.get(pk=resp.data['id'])
assert cp.price == Decimal('23.00') assert cp.price == Decimal('23.00')
assert cp.item == item assert cp.item == item
@@ -217,6 +220,7 @@ def test_cartpos_create_legacy_name(token_client, organizer, event, item, quota,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
cp = CartPosition.objects.get(pk=resp.data['id']) cp = CartPosition.objects.get(pk=resp.data['id'])
assert cp.price == Decimal('23.00') assert cp.price == Decimal('23.00')
assert cp.item == item assert cp.item == item
@@ -247,6 +251,7 @@ def test_cartpos_cart_id_optional(token_client, organizer, event, item, quota, q
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
cp = CartPosition.objects.get(pk=resp.data['id']) cp = CartPosition.objects.get(pk=resp.data['id'])
assert cp.price == Decimal('23.00') assert cp.price == Decimal('23.00')
assert cp.item == item assert cp.item == item
@@ -300,6 +305,7 @@ def test_cartpos_create_item_validation(token_client, organizer, event, item, it
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data == {'item': ['The specified item does not belong to this event.']} assert resp.data == {'item': ['The specified item does not belong to this event.']}
with scopes_disabled():
var2 = item2.variations.create(value="A") var2 = item2.variations.create(value="A")
res['item'] = item.pk res['item'] = item.pk
@@ -312,6 +318,7 @@ def test_cartpos_create_item_validation(token_client, organizer, event, item, it
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data == {'non_field_errors': ['You cannot specify a variation for this item.']} assert resp.data == {'non_field_errors': ['You cannot specify a variation for this item.']}
with scopes_disabled():
var1 = item.variations.create(value="A") var1 = item.variations.create(value="A")
res['item'] = item.pk res['item'] = item.pk
res['variation'] = var1.pk res['variation'] = var1.pk
@@ -361,6 +368,7 @@ def test_cartpos_expires_optional(token_client, organizer, event, item, quota, q
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
cp = CartPosition.objects.get(pk=resp.data['id']) cp = CartPosition.objects.get(pk=resp.data['id'])
assert cp.price == Decimal('23.00') assert cp.price == Decimal('23.00')
assert cp.item == item assert cp.item == item
@@ -410,6 +418,7 @@ def test_cartpos_create_answer_validation(token_client, organizer, event, item,
assert resp.data == { assert resp.data == {
'answers': [{'non_field_errors': ['You need to specify options if the question is of a choice type.']}]} 'answers': [{'non_field_errors': ['You need to specify options if the question is of a choice type.']}]}
with scopes_disabled():
question.options.create(answer="L") question.options.create(answer="L")
res['answers'][0]['options'] = [ res['answers'][0]['options'] = [
question.options.first().pk, question.options.first().pk,
@@ -445,6 +454,7 @@ def test_cartpos_create_answer_validation(token_client, organizer, event, item,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
pos = CartPosition.objects.get(pk=resp.data['id']) pos = CartPosition.objects.get(pk=resp.data['id'])
answ = pos.answers.first() answ = pos.answers.first()
assert answ.question == question assert answ.question == question
@@ -460,6 +470,7 @@ def test_cartpos_create_answer_validation(token_client, organizer, event, item,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
pos = CartPosition.objects.get(pk=resp.data['id']) pos = CartPosition.objects.get(pk=resp.data['id'])
answ = pos.answers.first() answ = pos.answers.first()
assert answ.answer == "3.45" assert answ.answer == "3.45"
@@ -486,6 +497,7 @@ def test_cartpos_create_answer_validation(token_client, organizer, event, item,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
pos = CartPosition.objects.get(pk=resp.data['id']) pos = CartPosition.objects.get(pk=resp.data['id'])
answ = pos.answers.first() answ = pos.answers.first()
assert answ.answer == "True" assert answ.answer == "True"
@@ -499,6 +511,7 @@ def test_cartpos_create_answer_validation(token_client, organizer, event, item,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
pos = CartPosition.objects.get(pk=resp.data['id']) pos = CartPosition.objects.get(pk=resp.data['id'])
answ = pos.answers.first() answ = pos.answers.first()
assert answ.answer == "False" assert answ.answer == "False"
@@ -523,6 +536,7 @@ def test_cartpos_create_answer_validation(token_client, organizer, event, item,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
pos = CartPosition.objects.get(pk=resp.data['id']) pos = CartPosition.objects.get(pk=resp.data['id'])
answ = pos.answers.first() answ = pos.answers.first()
assert answ.answer == "2018-05-14" assert answ.answer == "2018-05-14"
@@ -548,6 +562,7 @@ def test_cartpos_create_answer_validation(token_client, organizer, event, item,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
pos = CartPosition.objects.get(pk=resp.data['id']) pos = CartPosition.objects.get(pk=resp.data['id'])
answ = pos.answers.first() answ = pos.answers.first()
assert answ.answer == "2018-05-14 13:00:00+00:00" assert answ.answer == "2018-05-14 13:00:00+00:00"
@@ -574,6 +589,7 @@ def test_cartpos_create_answer_validation(token_client, organizer, event, item,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
pos = CartPosition.objects.get(pk=resp.data['id']) pos = CartPosition.objects.get(pk=resp.data['id'])
answ = pos.answers.first() answ = pos.answers.first()
assert answ.answer == "13:00:00" assert answ.answer == "13:00:00"

View File

@@ -6,6 +6,7 @@ from unittest import mock
import pytest import pytest
from django.utils.timezone import now from django.utils.timezone import now
from django_countries.fields import Country from django_countries.fields import Country
from django_scopes import scopes_disabled
from i18nfield.strings import LazyI18nString from i18nfield.strings import LazyI18nString
from pytz import UTC from pytz import UTC
@@ -157,6 +158,7 @@ def test_list_list(token_client, organizer, event, clist, item, subevent):
resp = token_client.get( resp = token_client.get(
'/api/v1/organizers/{}/events/{}/checkinlists/?subevent={}'.format(organizer.slug, event.slug, subevent.pk)) '/api/v1/organizers/{}/events/{}/checkinlists/?subevent={}'.format(organizer.slug, event.slug, subevent.pk))
assert [res] == resp.data['results'] assert [res] == resp.data['results']
with scopes_disabled():
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
resp = token_client.get( resp = token_client.get(
'/api/v1/organizers/{}/events/{}/checkinlists/?subevent={}'.format(organizer.slug, event.slug, se2.pk)) '/api/v1/organizers/{}/events/{}/checkinlists/?subevent={}'.format(organizer.slug, event.slug, se2.pk))
@@ -188,6 +190,7 @@ def test_list_create(token_client, organizer, event, item, item_on_wrong_event):
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
cl = CheckinList.objects.get(pk=resp.data['id']) cl = CheckinList.objects.get(pk=resp.data['id'])
assert cl.name == "VIP" assert cl.name == "VIP"
assert cl.limit_products.count() == 1 assert cl.limit_products.count() == 1
@@ -271,12 +274,14 @@ def test_list_update(token_client, organizer, event, clist):
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
cl = CheckinList.objects.get(pk=resp.data['id']) cl = CheckinList.objects.get(pk=resp.data['id'])
assert cl.name == "VIP" assert cl.name == "VIP"
@pytest.mark.django_db @pytest.mark.django_db
def test_list_all_items_positions(token_client, organizer, event, clist, clist_all, item, other_item, order): def test_list_all_items_positions(token_client, organizer, event, clist, clist_all, item, other_item, order):
with scopes_disabled():
p1 = dict(TEST_ORDERPOSITION1_RES) p1 = dict(TEST_ORDERPOSITION1_RES)
p1["id"] = order.positions.first().pk p1["id"] = order.positions.first().pk
p1["item"] = item.pk p1["item"] = item.pk
@@ -292,6 +297,7 @@ def test_list_all_items_positions(token_client, organizer, event, clist, clist_a
assert [p1, p2] == resp.data['results'] assert [p1, p2] == resp.data['results']
# Check-ins on other list ignored # Check-ins on other list ignored
with scopes_disabled():
order.positions.first().checkins.create(list=clist) order.positions.first().checkins.create(list=clist)
resp = token_client.get('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/?ordering=positionid'.format( resp = token_client.get('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/?ordering=positionid'.format(
organizer.slug, event.slug, clist_all.pk organizer.slug, event.slug, clist_all.pk
@@ -305,6 +311,7 @@ def test_list_all_items_positions(token_client, organizer, event, clist, clist_a
assert [] == resp.data['results'] assert [] == resp.data['results']
# Only checked in # Only checked in
with scopes_disabled():
c = order.positions.first().checkins.create(list=clist_all) c = order.positions.first().checkins.create(list=clist_all)
p1['checkins'] = [ p1['checkins'] = [
{ {
@@ -341,6 +348,7 @@ def test_list_all_items_positions(token_client, organizer, event, clist, clist_a
# Order by checkin date # Order by checkin date
time.sleep(1) time.sleep(1)
with scopes_disabled():
c = order.positions.last().checkins.create(list=clist_all) c = order.positions.last().checkins.create(list=clist_all)
p2['checkins'] = [ p2['checkins'] = [
{ {
@@ -388,6 +396,7 @@ def test_list_all_items_positions(token_client, organizer, event, clist, clist_a
@pytest.mark.django_db @pytest.mark.django_db
def test_list_limited_items_positions(token_client, organizer, event, clist, item, order): def test_list_limited_items_positions(token_client, organizer, event, clist, item, order):
p1 = dict(TEST_ORDERPOSITION1_RES) p1 = dict(TEST_ORDERPOSITION1_RES)
with scopes_disabled():
p1["id"] = order.positions.first().pk p1["id"] = order.positions.first().pk
p1["item"] = item.pk p1["item"] = item.pk
@@ -402,12 +411,13 @@ def test_list_limited_items_positions(token_client, organizer, event, clist, ite
@pytest.mark.django_db @pytest.mark.django_db
def test_list_limited_items_position_detail(token_client, organizer, event, clist, item, order): def test_list_limited_items_position_detail(token_client, organizer, event, clist, item, order):
p1 = dict(TEST_ORDERPOSITION1_RES) p1 = dict(TEST_ORDERPOSITION1_RES)
with scopes_disabled():
p1["id"] = order.positions.first().pk p1["id"] = order.positions.first().pk
p1["item"] = item.pk p1["item"] = item.pk
# All items # All items
resp = token_client.get('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/'.format( resp = token_client.get('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p1["id"]
)) ))
assert resp.status_code == 200 assert resp.status_code == 200
assert p1 == resp.data assert p1 == resp.data
@@ -415,6 +425,7 @@ def test_list_limited_items_position_detail(token_client, organizer, event, clis
@pytest.mark.django_db @pytest.mark.django_db
def test_status(token_client, organizer, event, clist_all, item, other_item, order): def test_status(token_client, organizer, event, clist_all, item, other_item, order):
with scopes_disabled():
op = order.positions.first() op = order.positions.first()
var1 = item.variations.create(value="XS") var1 = item.variations.create(value="XS")
var2 = item.variations.create(value="S") var2 = item.variations.create(value="S")
@@ -464,13 +475,16 @@ def test_status(token_client, organizer, event, clist_all, item, other_item, ord
def test_custom_datetime(token_client, organizer, clist, event, order): def test_custom_datetime(token_client, organizer, clist, event, order):
dt = now() - datetime.timedelta(days=1) dt = now() - datetime.timedelta(days=1)
dt = dt.replace(microsecond=0) dt = dt.replace(microsecond=0)
with scopes_disabled():
p = order.positions.first().pk
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p
), { ), {
'datetime': dt.isoformat() 'datetime': dt.isoformat()
}, format='json') }, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
with scopes_disabled():
assert Checkin.objects.last().datetime == dt assert Checkin.objects.last().datetime == dt
@@ -478,6 +492,7 @@ def test_custom_datetime(token_client, organizer, clist, event, order):
def test_name_fallback(token_client, organizer, clist, event, order): def test_name_fallback(token_client, organizer, clist, event, order):
order.invoice_address.name_parts = {'_legacy': 'Paul'} order.invoice_address.name_parts = {'_legacy': 'Paul'}
order.invoice_address.save() order.invoice_address.save()
with scopes_disabled():
op = order.positions.first() op = order.positions.first()
op.attendee_name_cached = None op.attendee_name_cached = None
op.attendee_name_parts = {} op.attendee_name_parts = {}
@@ -493,8 +508,10 @@ def test_name_fallback(token_client, organizer, clist, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_by_secret(token_client, organizer, clist, event, order): def test_by_secret(token_client, organizer, clist, event, order):
with scopes_disabled():
p = order.positions.first()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().secret organizer.slug, event.slug, clist.pk, p.secret
), {}, format='json') ), {}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
@@ -502,13 +519,15 @@ def test_by_secret(token_client, organizer, clist, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_only_once(token_client, organizer, clist, event, order): def test_only_once(token_client, organizer, clist, event, order):
with scopes_disabled():
p = order.positions.first()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {}, format='json') ), {}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {}, format='json') ), {}, format='json')
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data['status'] == 'error' assert resp.data['status'] == 'error'
@@ -517,13 +536,15 @@ def test_only_once(token_client, organizer, clist, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_reupload_same_nonce(token_client, organizer, clist, event, order): def test_reupload_same_nonce(token_client, organizer, clist, event, order):
with scopes_disabled():
p = order.positions.first()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'nonce': 'foobar'}, format='json') ), {'nonce': 'foobar'}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'nonce': 'foobar'}, format='json') ), {'nonce': 'foobar'}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
@@ -531,13 +552,15 @@ def test_reupload_same_nonce(token_client, organizer, clist, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_multiple_different_list(token_client, organizer, clist, clist_all, event, order): def test_multiple_different_list(token_client, organizer, clist, clist_all, event, order):
with scopes_disabled():
p = order.positions.first()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'nonce': 'foobar'}, format='json') ), {'nonce': 'foobar'}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist_all.pk, order.positions.first().pk organizer.slug, event.slug, clist_all.pk, p.pk
), {'nonce': 'baz'}, format='json') ), {'nonce': 'baz'}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
@@ -545,13 +568,15 @@ def test_multiple_different_list(token_client, organizer, clist, clist_all, even
@pytest.mark.django_db @pytest.mark.django_db
def test_forced_multiple(token_client, organizer, clist, event, order): def test_forced_multiple(token_client, organizer, clist, event, order):
with scopes_disabled():
p = order.positions.first()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {}, format='json') ), {}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'force': True}, format='json') ), {'force': True}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
@@ -559,17 +584,19 @@ def test_forced_multiple(token_client, organizer, clist, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_require_paid(token_client, organizer, clist, event, order): def test_require_paid(token_client, organizer, clist, event, order):
with scopes_disabled():
p = order.positions.first()
order.status = Order.STATUS_PENDING order.status = Order.STATUS_PENDING
order.save() order.save()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {}, format='json') ), {}, format='json')
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data['status'] == 'error' assert resp.data['status'] == 'error'
assert resp.data['reason'] == 'unpaid' assert resp.data['reason'] == 'unpaid'
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'ignore_unpaid': True}, format='json') ), {'ignore_unpaid': True}, format='json')
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data['status'] == 'error' assert resp.data['status'] == 'error'
@@ -579,14 +606,14 @@ def test_require_paid(token_client, organizer, clist, event, order):
clist.save() clist.save()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {}, format='json') ), {}, format='json')
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data['status'] == 'error' assert resp.data['status'] == 'error'
assert resp.data['reason'] == 'unpaid' assert resp.data['reason'] == 'unpaid'
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'ignore_unpaid': True}, format='json') ), {'ignore_unpaid': True}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
@@ -603,88 +630,105 @@ def question(event, item):
@pytest.mark.django_db @pytest.mark.django_db
def test_question_number(token_client, organizer, clist, event, order, question): def test_question_number(token_client, organizer, clist, event, order, question):
with scopes_disabled():
p = order.positions.first()
question[0].options.all().delete() question[0].options.all().delete()
question[0].type = 'N' question[0].type = 'N'
question[0].save() question[0].save()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {}, format='json') ), {}, format='json')
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data['status'] == 'incomplete' assert resp.data['status'] == 'incomplete'
with scopes_disabled():
assert resp.data['questions'] == [QuestionSerializer(question[0]).data] assert resp.data['questions'] == [QuestionSerializer(question[0]).data]
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'answers': {question[0].pk: "3.24"}}, format='json') ), {'answers': {question[0].pk: "3.24"}}, format='json')
print(resp.data)
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
with scopes_disabled():
assert order.positions.first().answers.get(question=question[0]).answer == '3.24' assert order.positions.first().answers.get(question=question[0]).answer == '3.24'
@pytest.mark.django_db @pytest.mark.django_db
def test_question_choice(token_client, organizer, clist, event, order, question): def test_question_choice(token_client, organizer, clist, event, order, question):
with scopes_disabled():
p = order.positions.first()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {}, format='json') ), {}, format='json')
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data['status'] == 'incomplete' assert resp.data['status'] == 'incomplete'
with scopes_disabled():
assert resp.data['questions'] == [QuestionSerializer(question[0]).data] assert resp.data['questions'] == [QuestionSerializer(question[0]).data]
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'answers': {question[0].pk: str(question[1].pk)}}, format='json') ), {'answers': {question[0].pk: str(question[1].pk)}}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
with scopes_disabled():
assert order.positions.first().answers.get(question=question[0]).answer == 'M' assert order.positions.first().answers.get(question=question[0]).answer == 'M'
assert list(order.positions.first().answers.get(question=question[0]).options.all()) == [question[1]] assert list(order.positions.first().answers.get(question=question[0]).options.all()) == [question[1]]
@pytest.mark.django_db @pytest.mark.django_db
def test_question_invalid(token_client, organizer, clist, event, order, question): def test_question_invalid(token_client, organizer, clist, event, order, question):
with scopes_disabled():
p = order.positions.first()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'answers': {question[0].pk: "A"}}, format='json') ), {'answers': {question[0].pk: "A"}}, format='json')
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data['status'] == 'incomplete' assert resp.data['status'] == 'incomplete'
with scopes_disabled():
assert resp.data['questions'] == [QuestionSerializer(question[0]).data] assert resp.data['questions'] == [QuestionSerializer(question[0]).data]
@pytest.mark.django_db @pytest.mark.django_db
def test_question_required(token_client, organizer, clist, event, order, question): def test_question_required(token_client, organizer, clist, event, order, question):
with scopes_disabled():
p = order.positions.first()
question[0].required = True question[0].required = True
question[0].save() question[0].save()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {}, format='json') ), {}, format='json')
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data['status'] == 'incomplete' assert resp.data['status'] == 'incomplete'
with scopes_disabled():
assert resp.data['questions'] == [QuestionSerializer(question[0]).data] assert resp.data['questions'] == [QuestionSerializer(question[0]).data]
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'answers': {question[0].pk: ""}}, format='json') ), {'answers': {question[0].pk: ""}}, format='json')
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data['status'] == 'incomplete' assert resp.data['status'] == 'incomplete'
with scopes_disabled():
assert resp.data['questions'] == [QuestionSerializer(question[0]).data] assert resp.data['questions'] == [QuestionSerializer(question[0]).data]
@pytest.mark.django_db @pytest.mark.django_db
def test_question_optional(token_client, organizer, clist, event, order, question): def test_question_optional(token_client, organizer, clist, event, order, question):
with scopes_disabled():
p = order.positions.first()
question[0].required = False question[0].required = False
question[0].save() question[0].save()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {}, format='json') ), {}, format='json')
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data['status'] == 'incomplete' assert resp.data['status'] == 'incomplete'
with scopes_disabled():
assert resp.data['questions'] == [QuestionSerializer(question[0]).data] assert resp.data['questions'] == [QuestionSerializer(question[0]).data]
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'answers': {question[0].pk: ""}}, format='json') ), {'answers': {question[0].pk: ""}}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
@@ -692,20 +736,24 @@ def test_question_optional(token_client, organizer, clist, event, order, questio
@pytest.mark.django_db @pytest.mark.django_db
def test_question_multiple_choice(token_client, organizer, clist, event, order, question): def test_question_multiple_choice(token_client, organizer, clist, event, order, question):
with scopes_disabled():
p = order.positions.first()
question[0].type = 'M' question[0].type = 'M'
question[0].save() question[0].save()
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {}, format='json') ), {}, format='json')
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data['status'] == 'incomplete' assert resp.data['status'] == 'incomplete'
with scopes_disabled():
assert resp.data['questions'] == [QuestionSerializer(question[0]).data] assert resp.data['questions'] == [QuestionSerializer(question[0]).data]
resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/checkinlists/{}/positions/{}/redeem/'.format(
organizer.slug, event.slug, clist.pk, order.positions.first().pk organizer.slug, event.slug, clist.pk, p.pk
), {'answers': {question[0].pk: "{},{}".format(question[1].pk, question[2].pk)}}, format='json') ), {'answers': {question[0].pk: "{},{}".format(question[1].pk, question[2].pk)}}, format='json')
assert resp.status_code == 201 assert resp.status_code == 201
assert resp.data['status'] == 'ok' assert resp.data['status'] == 'ok'
with scopes_disabled():
assert order.positions.first().answers.get(question=question[0]).answer == 'M, L' assert order.positions.first().answers.get(question=question[0]).answer == 'M, L'
assert set(order.positions.first().answers.get(question=question[0]).options.all()) == {question[1], question[2]} assert set(order.positions.first().answers.get(question=question[0]).options.all()) == {question[1], question[2]}

View File

@@ -5,6 +5,7 @@ from unittest import mock
import pytest import pytest
from django.conf import settings from django.conf import settings
from django_countries.fields import Country from django_countries.fields import Country
from django_scopes import scopes_disabled
from pytz import UTC from pytz import UTC
from pretix.base.models import Event, InvoiceAddress, Order, OrderPosition from pretix.base.models import Event, InvoiceAddress, Order, OrderPosition
@@ -161,6 +162,7 @@ def test_event_create(token_client, organizer, event, meta_prop):
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
assert not organizer.events.get(slug="2030").testmode assert not organizer.events.get(slug="2030").testmode
assert organizer.events.get(slug="2030").meta_values.filter( assert organizer.events.get(slug="2030").meta_values.filter(
property__name=meta_prop.name, value="Conference" property__name=meta_prop.name, value="Conference"
@@ -278,6 +280,7 @@ def test_event_create_with_clone(token_client, organizer, event, meta_prop):
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
cloned_event = Event.objects.get(organizer=organizer.pk, slug='2030') cloned_event = Event.objects.get(organizer=organizer.pk, slug='2030')
assert cloned_event.plugins == 'pretix.plugins.ticketoutputpdf' assert cloned_event.plugins == 'pretix.plugins.ticketoutputpdf'
assert cloned_event.is_public is False assert cloned_event.is_public is False
@@ -310,6 +313,7 @@ def test_event_create_with_clone(token_client, organizer, event, meta_prop):
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
cloned_event = Event.objects.get(organizer=organizer.pk, slug='2031') cloned_event = Event.objects.get(organizer=organizer.pk, slug='2031')
assert cloned_event.plugins == "pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf" assert cloned_event.plugins == "pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf"
assert cloned_event.is_public is True assert cloned_event.is_public is True
@@ -339,6 +343,7 @@ def test_event_create_with_clone(token_client, organizer, event, meta_prop):
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
cloned_event = Event.objects.get(organizer=organizer.pk, slug='2032') cloned_event = Event.objects.get(organizer=organizer.pk, slug='2032')
assert cloned_event.plugins == "" assert cloned_event.plugins == ""
@@ -388,6 +393,7 @@ def test_event_update(token_client, organizer, event, item, meta_prop):
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
event = Event.objects.get(organizer=organizer.pk, slug=resp.data['slug']) event = Event.objects.get(organizer=organizer.pk, slug=resp.data['slug'])
assert event.currency == "DKK" assert event.currency == "DKK"
assert organizer.events.get(slug=resp.data['slug']).meta_values.filter( assert organizer.events.get(slug=resp.data['slug']).meta_values.filter(
@@ -447,6 +453,7 @@ def test_event_update(token_client, organizer, event, item, meta_prop):
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert organizer.events.get(slug=resp.data['slug']).meta_values.filter( assert organizer.events.get(slug=resp.data['slug']).meta_values.filter(
property__name=meta_prop.name, value="Workshop" property__name=meta_prop.name, value="Workshop"
).exists() ).exists()
@@ -460,6 +467,7 @@ def test_event_update(token_client, organizer, event, item, meta_prop):
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert not organizer.events.get(slug=resp.data['slug']).meta_values.filter( assert not organizer.events.get(slug=resp.data['slug']).meta_values.filter(
property__name=meta_prop.name property__name=meta_prop.name
).exists() ).exists()
@@ -598,6 +606,7 @@ def test_event_detail(token_client, organizer, event, team):
def test_event_delete(token_client, organizer, event): def test_event_delete(token_client, organizer, event):
resp = token_client.delete('/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug)) resp = token_client.delete('/api/v1/organizers/{}/events/{}/'.format(organizer.slug, event.slug))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not organizer.events.filter(pk=event.id).exists() assert not organizer.events.filter(pk=event.id).exists()
@@ -607,4 +616,5 @@ def test_event_with_order_position_not_delete(token_client, organizer, event, it
assert resp.status_code == 403 assert resp.status_code == 403
assert resp.content.decode() == '{"detail":"The event can not be deleted as it already contains orders. Please ' \ assert resp.content.decode() == '{"detail":"The event can not be deleted as it already contains orders. Please ' \
'set \'live\' to false to hide the event and take the shop offline instead."}' 'set \'live\' to false to hide the event and take the shop offline instead."}'
with scopes_disabled():
assert organizer.events.filter(pk=event.id).exists() assert organizer.events.filter(pk=event.id).exists()

View File

@@ -5,6 +5,7 @@ from unittest import mock
import pytest import pytest
from django_countries.fields import Country from django_countries.fields import Country
from django_scopes import scopes_disabled
from pytz import UTC from pytz import UTC
from pretix.base.models import ( from pretix.base.models import (
@@ -169,6 +170,7 @@ def test_category_update(token_client, organizer, event, team, category):
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert ItemCategory.objects.get(pk=category.pk).name == {"en": "Test"} assert ItemCategory.objects.get(pk=category.pk).name == {"en": "Test"}
@@ -189,6 +191,7 @@ def test_category_delete(token_client, organizer, event, category3, item):
resp = token_client.delete( resp = token_client.delete(
'/api/v1/organizers/{}/events/{}/categories/{}/'.format(organizer.slug, event.slug, category3.pk)) '/api/v1/organizers/{}/events/{}/categories/{}/'.format(organizer.slug, event.slug, category3.pk))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not event.categories.filter(pk=category3.id).exists() assert not event.categories.filter(pk=category3.id).exists()
assert Item.objects.get(pk=item.pk).category is None assert Item.objects.get(pk=item.pk).category is None
@@ -308,6 +311,7 @@ def test_item_detail(token_client, organizer, event, team, item):
@pytest.mark.django_db @pytest.mark.django_db
def test_item_detail_variations(token_client, organizer, event, team, item): def test_item_detail_variations(token_client, organizer, event, team, item):
with scopes_disabled():
var = item.variations.create(value="Children") var = item.variations.create(value="Children")
res = dict(TEST_ITEM_RES) res = dict(TEST_ITEM_RES)
res["id"] = item.pk res["id"] = item.pk
@@ -349,6 +353,7 @@ def test_item_detail_addons(token_client, organizer, event, team, item, category
@pytest.mark.django_db @pytest.mark.django_db
def test_item_detail_bundles(token_client, organizer, event, team, item, category): def test_item_detail_bundles(token_client, organizer, event, team, item, category):
with scopes_disabled():
i = event.items.create(name="Included thing", default_price=2) i = event.items.create(name="Included thing", default_price=2)
item.bundles.create(bundled_item=i, count=1, designated_price=2) item.bundles.create(bundled_item=i, count=1, designated_price=2)
res = dict(TEST_ITEM_RES) res = dict(TEST_ITEM_RES)
@@ -398,6 +403,7 @@ def test_item_create(token_client, organizer, event, item, category, taxrule):
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
assert Item.objects.get(pk=resp.data['id']).sales_channels == ["web", "pretixpos"] assert Item.objects.get(pk=resp.data['id']).sales_channels == ["web", "pretixpos"]
@@ -445,6 +451,7 @@ def test_item_create_with_variation(token_client, organizer, event, item, catego
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
new_item = Item.objects.get(pk=resp.data['id']) new_item = Item.objects.get(pk=resp.data['id'])
assert new_item.variations.first().value.localize('de') == "Kommentar" assert new_item.variations.first().value.localize('de') == "Kommentar"
assert new_item.variations.first().value.localize('en') == "Comment" assert new_item.variations.first().value.localize('en') == "Comment"
@@ -490,6 +497,7 @@ def test_item_create_with_addon(token_client, organizer, event, item, category,
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
item = Item.objects.get(pk=resp.data['id']) item = Item.objects.get(pk=resp.data['id'])
assert item.addons.first().addon_category == category assert item.addons.first().addon_category == category
assert item.addons.first().max_count == 10 assert item.addons.first().max_count == 10
@@ -534,6 +542,7 @@ def test_item_create_with_addon(token_client, organizer, event, item, category,
) )
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.content.decode() == '{"addons":["The add-on\'s category must belong to the same event as the item."]}' assert resp.content.decode() == '{"addons":["The add-on\'s category must belong to the same event as the item."]}'
with scopes_disabled():
assert 2 == Item.objects.all().count() assert 2 == Item.objects.all().count()
resp = token_client.post( resp = token_client.post(
@@ -575,6 +584,7 @@ def test_item_create_with_addon(token_client, organizer, event, item, category,
) )
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.content.decode() == '{"addons":["The maximum count needs to be greater than the minimum count."]}' assert resp.content.decode() == '{"addons":["The maximum count needs to be greater than the minimum count."]}'
with scopes_disabled():
assert 2 == Item.objects.all().count() assert 2 == Item.objects.all().count()
resp = token_client.post( resp = token_client.post(
@@ -619,11 +629,13 @@ def test_item_create_with_addon(token_client, organizer, event, item, category,
'{"addons":["The minimum count needs to be equal to or greater than zero."]}', '{"addons":["The minimum count needs to be equal to or greater than zero."]}',
'{"addons":[{"min_count":["Ensure this value is greater than or equal to 0."]}]}', # mysql '{"addons":[{"min_count":["Ensure this value is greater than or equal to 0."]}]}', # mysql
] ]
with scopes_disabled():
assert 2 == Item.objects.all().count() assert 2 == Item.objects.all().count()
@pytest.mark.django_db @pytest.mark.django_db
def test_item_create_with_bundle(token_client, organizer, event, item, category, item2, taxrule): def test_item_create_with_bundle(token_client, organizer, event, item, category, item2, taxrule):
with scopes_disabled():
i = event.items.create(name="Included thing", default_price=2) i = event.items.create(name="Included thing", default_price=2)
resp = token_client.post( resp = token_client.post(
'/api/v1/organizers/{}/events/{}/items/'.format(organizer.slug, event.slug), '/api/v1/organizers/{}/events/{}/items/'.format(organizer.slug, event.slug),
@@ -662,6 +674,7 @@ def test_item_create_with_bundle(token_client, organizer, event, item, category,
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
item = Item.objects.get(pk=resp.data['id']) item = Item.objects.get(pk=resp.data['id'])
b = item.bundles.first() b = item.bundles.first()
assert b.bundled_item == i assert b.bundled_item == i
@@ -708,6 +721,7 @@ def test_item_create_with_bundle(token_client, organizer, event, item, category,
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.content.decode() == '{"bundles":["The bundled item must belong to the same event as the item."]}' assert resp.content.decode() == '{"bundles":["The bundled item must belong to the same event as the item."]}'
with scopes_disabled():
v = item2.variations.create(value="foo") v = item2.variations.create(value="foo")
resp = token_client.post( resp = token_client.post(
'/api/v1/organizers/{}/events/{}/items/'.format(organizer.slug, event.slug), '/api/v1/organizers/{}/events/{}/items/'.format(organizer.slug, event.slug),
@@ -760,6 +774,7 @@ def test_item_update(token_client, organizer, event, item, category, item2, cate
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert Item.objects.get(pk=item.pk).max_per_order == 2 assert Item.objects.get(pk=item.pk).max_per_order == 2
resp = token_client.patch( resp = token_client.patch(
@@ -896,6 +911,7 @@ def test_item_update_with_addon(token_client, organizer, event, item, category):
def test_items_delete(token_client, organizer, event, item): def test_items_delete(token_client, organizer, event, item):
resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/'.format(organizer.slug, event.slug, item.pk)) resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/'.format(organizer.slug, event.slug, item.pk))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not event.items.filter(pk=item.id).exists() assert not event.items.filter(pk=item.id).exists()
@@ -903,6 +919,7 @@ def test_items_delete(token_client, organizer, event, item):
def test_items_with_order_position_not_delete(token_client, organizer, event, item, order_position): def test_items_with_order_position_not_delete(token_client, organizer, event, item, order_position):
resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/'.format(organizer.slug, event.slug, item.pk)) resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/'.format(organizer.slug, event.slug, item.pk))
assert resp.status_code == 403 assert resp.status_code == 403
with scopes_disabled():
assert event.items.filter(pk=item.id).exists() assert event.items.filter(pk=item.id).exists()
@@ -910,6 +927,7 @@ def test_items_with_order_position_not_delete(token_client, organizer, event, it
def test_items_with_cart_position_delete(token_client, organizer, event, item, cart_position): def test_items_with_cart_position_delete(token_client, organizer, event, item, cart_position):
resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/'.format(organizer.slug, event.slug, item.pk)) resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/'.format(organizer.slug, event.slug, item.pk))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not event.items.filter(pk=item.id).exists() assert not event.items.filter(pk=item.id).exists()
@@ -996,6 +1014,7 @@ def test_variations_create(token_client, organizer, event, item, variation):
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
var = ItemVariation.objects.get(pk=resp.data['id']) var = ItemVariation.objects.get(pk=resp.data['id'])
assert var.position == 1 assert var.position == 1
assert var.price == 23.0 assert var.price == 23.0
@@ -1060,39 +1079,46 @@ def test_variations_update(token_client, organizer, event, item, item3, variatio
def test_variations_delete(token_client, organizer, event, item, variations, order): def test_variations_delete(token_client, organizer, event, item, variations, order):
resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/variations/{}/'.format(organizer.slug, event.slug, item.pk, variations[0].pk)) resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/variations/{}/'.format(organizer.slug, event.slug, item.pk, variations[0].pk))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not item.variations.filter(pk=variations[0].pk).exists() assert not item.variations.filter(pk=variations[0].pk).exists()
@pytest.mark.django_db @pytest.mark.django_db
def test_variations_with_order_position_not_delete(token_client, organizer, event, item, order, variations, order_position): def test_variations_with_order_position_not_delete(token_client, organizer, event, item, order, variations, order_position):
with scopes_disabled():
assert item.variations.filter(pk=variations[0].id).exists() assert item.variations.filter(pk=variations[0].id).exists()
resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/variations/{}/'.format(organizer.slug, event.slug, item.pk, variations[0].pk)) resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/variations/{}/'.format(organizer.slug, event.slug, item.pk, variations[0].pk))
assert resp.status_code == 403 assert resp.status_code == 403
assert resp.content.decode() == '{"detail":"This variation cannot be deleted because it has already been ordered ' \ assert resp.content.decode() == '{"detail":"This variation cannot be deleted because it has already been ordered ' \
'by a user or currently is in a users\'s cart. Please set the variation as ' \ 'by a user or currently is in a users\'s cart. Please set the variation as ' \
'\'inactive\' instead."}' '\'inactive\' instead."}'
with scopes_disabled():
assert item.variations.filter(pk=variations[0].id).exists() assert item.variations.filter(pk=variations[0].id).exists()
@pytest.mark.django_db @pytest.mark.django_db
def test_variations_with_cart_position_not_delete(token_client, organizer, event, item, variations, cart_position): def test_variations_with_cart_position_not_delete(token_client, organizer, event, item, variations, cart_position):
with scopes_disabled():
assert item.variations.filter(pk=variations[0].id).exists() assert item.variations.filter(pk=variations[0].id).exists()
resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/variations/{}/'.format(organizer.slug, event.slug, item.pk, variations[0].pk)) resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/variations/{}/'.format(organizer.slug, event.slug, item.pk, variations[0].pk))
assert resp.status_code == 403 assert resp.status_code == 403
assert resp.content.decode() == '{"detail":"This variation cannot be deleted because it has already been ordered ' \ assert resp.content.decode() == '{"detail":"This variation cannot be deleted because it has already been ordered ' \
'by a user or currently is in a users\'s cart. Please set the variation as ' \ 'by a user or currently is in a users\'s cart. Please set the variation as ' \
'\'inactive\' instead."}' '\'inactive\' instead."}'
with scopes_disabled():
assert item.variations.filter(pk=variations[0].id).exists() assert item.variations.filter(pk=variations[0].id).exists()
@pytest.mark.django_db @pytest.mark.django_db
def test_only_variation_not_delete(token_client, organizer, event, item, variation): def test_only_variation_not_delete(token_client, organizer, event, item, variation):
with scopes_disabled():
assert item.variations.filter(pk=variation.id).exists() assert item.variations.filter(pk=variation.id).exists()
resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/variations/{}/'.format(organizer.slug, event.slug, item.pk, variation.pk)) resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/variations/{}/'.format(organizer.slug, event.slug, item.pk, variation.pk))
assert resp.status_code == 403 assert resp.status_code == 403
assert resp.content.decode() == '{"detail":"This variation cannot be deleted because it is the only variation. ' \ assert resp.content.decode() == '{"detail":"This variation cannot be deleted because it is the only variation. ' \
'Changing a product with variations to a product without variations is not ' \ 'Changing a product with variations to a product without variations is not ' \
'allowed."}' 'allowed."}'
with scopes_disabled():
assert item.variations.filter(pk=variation.id).exists() assert item.variations.filter(pk=variation.id).exists()
@@ -1144,6 +1170,7 @@ def test_bundles_create(token_client, organizer, event, item, item2, item3):
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
b = ItemBundle.objects.get(pk=resp.data['id']) b = ItemBundle.objects.get(pk=resp.data['id'])
assert b.bundled_item == item3 assert b.bundled_item == item3
assert b.bundled_variation is None assert b.bundled_variation is None
@@ -1176,6 +1203,7 @@ def test_bundles_create(token_client, organizer, event, item, item2, item3):
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.content.decode() == '{"non_field_errors":["The bundled item must not be the same item as the bundling one."]}' assert resp.content.decode() == '{"non_field_errors":["The bundled item must not be the same item as the bundling one."]}'
with scopes_disabled():
item3.bundles.create(bundled_item=item, count=1, designated_price=3) item3.bundles.create(bundled_item=item, count=1, designated_price=3)
resp = token_client.post( resp = token_client.post(
'/api/v1/organizers/{}/events/{}/items/{}/bundles/'.format(organizer.slug, event.slug, item.pk), '/api/v1/organizers/{}/events/{}/items/{}/bundles/'.format(organizer.slug, event.slug, item.pk),
@@ -1201,6 +1229,7 @@ def test_bundles_update(token_client, organizer, event, item, bundle):
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
a = ItemBundle.objects.get(pk=bundle.pk) a = ItemBundle.objects.get(pk=bundle.pk)
assert a.count == 3 assert a.count == 3
@@ -1210,6 +1239,7 @@ def test_bundles_delete(token_client, organizer, event, item, bundle):
resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/bundles/{}/'.format(organizer.slug, event.slug, resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/bundles/{}/'.format(organizer.slug, event.slug,
item.pk, bundle.pk)) item.pk, bundle.pk))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not item.bundles.filter(pk=bundle.id).exists() assert not item.bundles.filter(pk=bundle.id).exists()
@@ -1270,6 +1300,7 @@ def test_addons_create(token_client, organizer, event, item, category, category2
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
addon = ItemAddOn.objects.get(pk=resp.data['id']) addon = ItemAddOn.objects.get(pk=resp.data['id'])
assert addon.position == 1 assert addon.position == 1
assert addon.addon_category == category assert addon.addon_category == category
@@ -1315,6 +1346,7 @@ def test_addons_update(token_client, organizer, event, item, addon):
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
a = ItemAddOn.objects.get(pk=addon.pk) a = ItemAddOn.objects.get(pk=addon.pk)
assert a.min_count == 100 assert a.min_count == 100
assert a.max_count == 101 assert a.max_count == 101
@@ -1337,6 +1369,7 @@ def test_addons_delete(token_client, organizer, event, item, addon):
resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/addons/{}/'.format(organizer.slug, event.slug, resp = token_client.delete('/api/v1/organizers/{}/events/{}/items/{}/addons/{}/'.format(organizer.slug, event.slug,
item.pk, addon.pk)) item.pk, addon.pk))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not item.addons.filter(pk=addon.id).exists() assert not item.addons.filter(pk=addon.id).exists()
@@ -1372,6 +1405,7 @@ def test_quota_list(token_client, organizer, event, quota, item, subevent):
resp = token_client.get( resp = token_client.get(
'/api/v1/organizers/{}/events/{}/quotas/?subevent={}'.format(organizer.slug, event.slug, subevent.pk)) '/api/v1/organizers/{}/events/{}/quotas/?subevent={}'.format(organizer.slug, event.slug, subevent.pk))
assert [res] == resp.data['results'] assert [res] == resp.data['results']
with scopes_disabled():
se2 = event.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) se2 = event.subevents.create(name="Foobar", date_from=datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
resp = token_client.get( resp = token_client.get(
'/api/v1/organizers/{}/events/{}/quotas/?subevent={}'.format(organizer.slug, event.slug, se2.pk)) '/api/v1/organizers/{}/events/{}/quotas/?subevent={}'.format(organizer.slug, event.slug, se2.pk))
@@ -1404,6 +1438,7 @@ def test_quota_create(token_client, organizer, event, event2, item):
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
quota = Quota.objects.get(pk=resp.data['id']) quota = Quota.objects.get(pk=resp.data['id'])
assert quota.name == "Ticket Quota" assert quota.name == "Ticket Quota"
assert quota.size == 200 assert quota.size == 200
@@ -1550,6 +1585,7 @@ def test_quota_update(token_client, organizer, event, quota, item):
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
quota = Quota.objects.get(pk=resp.data['id']) quota = Quota.objects.get(pk=resp.data['id'])
assert quota.name == "Ticket Quota Update" assert quota.name == "Ticket Quota Update"
assert quota.size == 111 assert quota.size == 111
@@ -1566,6 +1602,7 @@ def test_quota_update_unchanged(token_client, organizer, event, quota, item):
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
quota = Quota.objects.get(pk=resp.data['id']) quota = Quota.objects.get(pk=resp.data['id'])
assert quota.size == 200 assert quota.size == 200
assert quota.all_logentries().count() == 0 assert quota.all_logentries().count() == 0
@@ -1575,6 +1612,7 @@ def test_quota_update_unchanged(token_client, organizer, event, quota, item):
def test_quota_delete(token_client, organizer, event, quota): def test_quota_delete(token_client, organizer, event, quota):
resp = token_client.delete('/api/v1/organizers/{}/events/{}/quotas/{}/'.format(organizer.slug, event.slug, quota.pk)) resp = token_client.delete('/api/v1/organizers/{}/events/{}/quotas/{}/'.format(organizer.slug, event.slug, quota.pk))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not event.quotas.filter(pk=quota.id).exists() assert not event.quotas.filter(pk=quota.id).exists()
@@ -1690,6 +1728,7 @@ def test_question_create(token_client, organizer, event, event2, item):
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
question = Question.objects.get(pk=resp.data['id']) question = Question.objects.get(pk=resp.data['id'])
assert question.question == "What's your name?" assert question.question == "What's your name?"
assert question.type == "S" assert question.type == "S"
@@ -1784,6 +1823,7 @@ def test_question_create(token_client, organizer, event, event2, item):
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
q2 = Question.objects.get(pk=resp.data['id']) q2 = Question.objects.get(pk=resp.data['id'])
assert q2.dependency_question == question assert q2.dependency_question == question
@@ -1799,6 +1839,7 @@ def test_question_update(token_client, organizer, event, question):
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
question = Question.objects.get(pk=resp.data['id']) question = Question.objects.get(pk=resp.data['id'])
assert question.question == "What's your shoe size?" assert question.question == "What's your shoe size?"
assert question.type == "N" assert question.type == "N"
@@ -1806,6 +1847,7 @@ def test_question_update(token_client, organizer, event, question):
@pytest.mark.django_db @pytest.mark.django_db
def test_question_update_circular_dependency(token_client, organizer, event, question): def test_question_update_circular_dependency(token_client, organizer, event, question):
with scopes_disabled():
q2 = event.questions.create(question="T-Shirt size", type="B", identifier="FOO", dependency_question=question) q2 = event.questions.create(question="T-Shirt size", type="B", identifier="FOO", dependency_question=question)
resp = token_client.patch( resp = token_client.patch(
'/api/v1/organizers/{}/events/{}/questions/{}/'.format(organizer.slug, event.slug, question.pk), '/api/v1/organizers/{}/events/{}/questions/{}/'.format(organizer.slug, event.slug, question.pk),
@@ -1836,6 +1878,7 @@ def test_question_update_options(token_client, organizer, event, question, item)
def test_question_delete(token_client, organizer, event, question): def test_question_delete(token_client, organizer, event, question):
resp = token_client.delete('/api/v1/organizers/{}/events/{}/questions/{}/'.format(organizer.slug, event.slug, question.pk)) resp = token_client.delete('/api/v1/organizers/{}/events/{}/questions/{}/'.format(organizer.slug, event.slug, question.pk))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not event.questions.filter(pk=question.id).exists() assert not event.questions.filter(pk=question.id).exists()
@@ -1881,6 +1924,7 @@ def test_options_create(token_client, organizer, event, question):
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
option = QuestionOption.objects.get(pk=resp.data['id']) option = QuestionOption.objects.get(pk=resp.data['id'])
assert option.answer == "A" assert option.answer == "A"
@@ -1907,6 +1951,7 @@ def test_options_update(token_client, organizer, event, question, option):
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
a = QuestionOption.objects.get(pk=option.pk) a = QuestionOption.objects.get(pk=option.pk)
assert a.answer == "B" assert a.answer == "B"
@@ -1917,6 +1962,7 @@ def test_options_delete(token_client, organizer, event, question, option):
organizer.slug, event.slug, question.pk, option.pk organizer.slug, event.slug, question.pk, option.pk
)) ))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not question.options.filter(pk=option.id).exists() assert not question.options.filter(pk=option.id).exists()
@@ -1948,6 +1994,7 @@ def test_question_create_with_option(token_client, organizer, event, item):
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
question = Question.objects.get(pk=resp.data['id']) question = Question.objects.get(pk=resp.data['id'])
assert str(question.options.first().answer) == "A" assert str(question.options.first().answer) == "A"
assert question.options.first().identifier is not None assert question.options.first().identifier is not None

View File

@@ -8,6 +8,7 @@ import pytest
from django.core import mail as djmail from django.core import mail as djmail
from django.utils.timezone import now from django.utils.timezone import now
from django_countries.fields import Country from django_countries.fields import Country
from django_scopes import scopes_disabled
from pytz import UTC from pytz import UTC
from stripe.error import APIConnectionError from stripe.error import APIConnectionError
from tests.plugins.stripe.test_provider import MockedCharge from tests.plugins.stripe.test_provider import MockedCharge
@@ -229,6 +230,7 @@ TEST_ORDER_RES = {
@pytest.mark.django_db @pytest.mark.django_db
def test_order_list(token_client, organizer, event, order, item, taxrule, question): def test_order_list(token_client, organizer, event, order, item, taxrule, question):
res = dict(TEST_ORDER_RES) res = dict(TEST_ORDER_RES)
with scopes_disabled():
res["positions"][0]["id"] = order.positions.first().pk res["positions"][0]["id"] = order.positions.first().pk
res["positions"][0]["item"] = item.pk res["positions"][0]["item"] = item.pk
res["positions"][0]["answers"][0]["question"] = question.pk res["positions"][0]["answers"][0]["question"] = question.pk
@@ -285,6 +287,7 @@ def test_order_list(token_client, organizer, event, order, item, taxrule, questi
@pytest.mark.django_db @pytest.mark.django_db
def test_order_detail(token_client, organizer, event, order, item, taxrule, question): def test_order_detail(token_client, organizer, event, order, item, taxrule, question):
res = dict(TEST_ORDER_RES) res = dict(TEST_ORDER_RES)
with scopes_disabled():
res["positions"][0]["id"] = order.positions.first().pk res["positions"][0]["id"] = order.positions.first().pk
res["positions"][0]["item"] = item.pk res["positions"][0]["item"] = item.pk
res["fees"][0]["tax_rule"] = taxrule.pk res["fees"][0]["tax_rule"] = taxrule.pk
@@ -338,6 +341,7 @@ def test_payment_confirm(token_client, organizer, event, order):
resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/payments/2/confirm/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/payments/2/confirm/'.format(
organizer.slug, event.slug, order.code organizer.slug, event.slug, order.code
), format='json', data={'force': True}) ), format='json', data={'force': True})
with scopes_disabled():
p = order.payments.get(local_id=2) p = order.payments.get(local_id=2)
assert resp.status_code == 200 assert resp.status_code == 200
assert p.state == OrderPayment.PAYMENT_STATE_CONFIRMED assert p.state == OrderPayment.PAYMENT_STATE_CONFIRMED
@@ -353,6 +357,7 @@ def test_payment_cancel(token_client, organizer, event, order):
resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/payments/2/cancel/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/payments/2/cancel/'.format(
organizer.slug, event.slug, order.code organizer.slug, event.slug, order.code
)) ))
with scopes_disabled():
p = order.payments.get(local_id=2) p = order.payments.get(local_id=2)
assert resp.status_code == 200 assert resp.status_code == 200
assert p.state == OrderPayment.PAYMENT_STATE_CANCELED assert p.state == OrderPayment.PAYMENT_STATE_CANCELED
@@ -365,6 +370,7 @@ def test_payment_cancel(token_client, organizer, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_payment_refund_fail(token_client, organizer, event, order, monkeypatch): def test_payment_refund_fail(token_client, organizer, event, order, monkeypatch):
with scopes_disabled():
order.payments.last().confirm() order.payments.last().confirm()
resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/payments/2/refund/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/payments/2/refund/'.format(
organizer.slug, event.slug, order.code organizer.slug, event.slug, order.code
@@ -424,6 +430,7 @@ def test_payment_refund_success(token_client, organizer, event, order, monkeypat
c.refunds.create = refund_create c.refunds.create = refund_create
return c return c
with scopes_disabled():
p1 = order.payments.create( p1 = order.payments.create(
provider='stripe', provider='stripe',
state='confirmed', state='confirmed',
@@ -441,6 +448,7 @@ def test_payment_refund_success(token_client, organizer, event, order, monkeypat
'mark_canceled': False, 'mark_canceled': False,
}) })
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
r = order.refunds.get(local_id=resp.data['local_id']) r = order.refunds.get(local_id=resp.data['local_id'])
assert r.provider == "stripe" assert r.provider == "stripe"
assert r.state == OrderRefund.REFUND_STATE_DONE assert r.state == OrderRefund.REFUND_STATE_DONE
@@ -457,6 +465,7 @@ def test_payment_refund_unavailable(token_client, organizer, event, order, monke
c.refunds.create = refund_create c.refunds.create = refund_create
return c return c
with scopes_disabled():
p1 = order.payments.create( p1 = order.payments.create(
provider='stripe', provider='stripe',
state='confirmed', state='confirmed',
@@ -475,6 +484,7 @@ def test_payment_refund_unavailable(token_client, organizer, event, order, monke
}) })
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data == {'detail': 'External error: We had trouble communicating with Stripe. Please try again and contact support if the problem persists.'} assert resp.data == {'detail': 'External error: We had trouble communicating with Stripe. Please try again and contact support if the problem persists.'}
with scopes_disabled():
r = order.refunds.last() r = order.refunds.last()
assert r.provider == "stripe" assert r.provider == "stripe"
assert r.state == OrderRefund.REFUND_STATE_FAILED assert r.state == OrderRefund.REFUND_STATE_FAILED
@@ -499,12 +509,14 @@ def test_refund_detail(token_client, organizer, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_refund_done(token_client, organizer, event, order): def test_refund_done(token_client, organizer, event, order):
with scopes_disabled():
r = order.refunds.get(local_id=1) r = order.refunds.get(local_id=1)
r.state = 'transit' r.state = 'transit'
r.save() r.save()
resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/refunds/1/done/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/refunds/1/done/'.format(
organizer.slug, event.slug, order.code organizer.slug, event.slug, order.code
)) ))
with scopes_disabled():
r = order.refunds.get(local_id=1) r = order.refunds.get(local_id=1)
assert resp.status_code == 200 assert resp.status_code == 200
assert r.state == OrderRefund.REFUND_STATE_DONE assert r.state == OrderRefund.REFUND_STATE_DONE
@@ -517,11 +529,13 @@ def test_refund_done(token_client, organizer, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_refund_process_mark_refunded(token_client, organizer, event, order): def test_refund_process_mark_refunded(token_client, organizer, event, order):
with scopes_disabled():
p = order.payments.get(local_id=1) p = order.payments.get(local_id=1)
p.create_external_refund() p.create_external_refund()
resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/refunds/2/process/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/refunds/2/process/'.format(
organizer.slug, event.slug, order.code organizer.slug, event.slug, order.code
), format='json', data={'mark_canceled': True}) ), format='json', data={'mark_canceled': True})
with scopes_disabled():
r = order.refunds.get(local_id=1) r = order.refunds.get(local_id=1)
assert resp.status_code == 200 assert resp.status_code == 200
assert r.state == OrderRefund.REFUND_STATE_DONE assert r.state == OrderRefund.REFUND_STATE_DONE
@@ -536,11 +550,13 @@ def test_refund_process_mark_refunded(token_client, organizer, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_refund_process_mark_pending(token_client, organizer, event, order): def test_refund_process_mark_pending(token_client, organizer, event, order):
with scopes_disabled():
p = order.payments.get(local_id=1) p = order.payments.get(local_id=1)
p.create_external_refund() p.create_external_refund()
resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/refunds/2/process/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/refunds/2/process/'.format(
organizer.slug, event.slug, order.code organizer.slug, event.slug, order.code
), format='json', data={'mark_canceled': False}) ), format='json', data={'mark_canceled': False})
with scopes_disabled():
r = order.refunds.get(local_id=1) r = order.refunds.get(local_id=1)
assert resp.status_code == 200 assert resp.status_code == 200
assert r.state == OrderRefund.REFUND_STATE_DONE assert r.state == OrderRefund.REFUND_STATE_DONE
@@ -550,12 +566,14 @@ def test_refund_process_mark_pending(token_client, organizer, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_refund_cancel(token_client, organizer, event, order): def test_refund_cancel(token_client, organizer, event, order):
with scopes_disabled():
r = order.refunds.get(local_id=1) r = order.refunds.get(local_id=1)
r.state = 'transit' r.state = 'transit'
r.save() r.save()
resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/refunds/1/cancel/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/orders/{}/refunds/1/cancel/'.format(
organizer.slug, event.slug, order.code organizer.slug, event.slug, order.code
)) ))
with scopes_disabled():
r = order.refunds.get(local_id=1) r = order.refunds.get(local_id=1)
assert resp.status_code == 200 assert resp.status_code == 200
assert r.state == OrderRefund.REFUND_STATE_CANCELED assert r.state == OrderRefund.REFUND_STATE_CANCELED
@@ -571,6 +589,7 @@ def test_orderposition_list(token_client, organizer, event, order, item, subeven
i2 = copy.copy(item) i2 = copy.copy(item)
i2.pk = None i2.pk = None
i2.save() i2.save()
with scopes_disabled():
var = item.variations.create(value="Children") var = item.variations.create(value="Children")
var2 = item.variations.create(value="Children") var2 = item.variations.create(value="Children")
res = dict(TEST_ORDERPOSITION_RES) res = dict(TEST_ORDERPOSITION_RES)
@@ -665,6 +684,7 @@ def test_orderposition_list(token_client, organizer, event, order, item, subeven
'/api/v1/organizers/{}/events/{}/orderpositions/?has_checkin=true'.format(organizer.slug, event.slug)) '/api/v1/organizers/{}/events/{}/orderpositions/?has_checkin=true'.format(organizer.slug, event.slug))
assert [] == resp.data['results'] assert [] == resp.data['results']
with scopes_disabled():
cl = event.checkin_lists.create(name="Default") cl = event.checkin_lists.create(name="Default")
op.checkins.create(datetime=datetime.datetime(2017, 12, 26, 10, 0, 0, tzinfo=UTC), list=cl) op.checkins.create(datetime=datetime.datetime(2017, 12, 26, 10, 0, 0, tzinfo=UTC), list=cl)
res['checkins'] = [{'datetime': '2017-12-26T10:00:00Z', 'list': cl.pk}] res['checkins'] = [{'datetime': '2017-12-26T10:00:00Z', 'list': cl.pk}]
@@ -692,6 +712,7 @@ def test_orderposition_list(token_client, organizer, event, order, item, subeven
@pytest.mark.django_db @pytest.mark.django_db
def test_orderposition_detail(token_client, organizer, event, order, item, question): def test_orderposition_detail(token_client, organizer, event, order, item, question):
res = dict(TEST_ORDERPOSITION_RES) res = dict(TEST_ORDERPOSITION_RES)
with scopes_disabled():
op = order.positions.first() op = order.positions.first()
res["id"] = op.pk res["id"] = op.pk
res["item"] = item.pk res["item"] = item.pk
@@ -711,6 +732,7 @@ def test_orderposition_detail(token_client, organizer, event, order, item, quest
@pytest.mark.django_db @pytest.mark.django_db
def test_orderposition_detail_no_canceled(token_client, organizer, event, order, item, question): def test_orderposition_detail_no_canceled(token_client, organizer, event, order, item, question):
with scopes_disabled():
op = order.all_positions.filter(canceled=True).first() op = order.all_positions.filter(canceled=True).first()
resp = token_client.get('/api/v1/organizers/{}/events/{}/orderpositions/{}/'.format(organizer.slug, event.slug, resp = token_client.get('/api/v1/organizers/{}/events/{}/orderpositions/{}/'.format(organizer.slug, event.slug,
op.pk)) op.pk))
@@ -719,6 +741,7 @@ def test_orderposition_detail_no_canceled(token_client, organizer, event, order,
@pytest.mark.django_db @pytest.mark.django_db
def test_orderposition_delete(token_client, organizer, event, order, item, question): def test_orderposition_delete(token_client, organizer, event, order, item, question):
with scopes_disabled():
op = order.positions.first() op = order.positions.first()
resp = token_client.delete('/api/v1/organizers/{}/events/{}/orderpositions/{}/'.format( resp = token_client.delete('/api/v1/organizers/{}/events/{}/orderpositions/{}/'.format(
organizer.slug, event.slug, op.pk organizer.slug, event.slug, op.pk
@@ -726,6 +749,7 @@ def test_orderposition_delete(token_client, organizer, event, order, item, quest
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data == ['This operation would leave the order empty. Please cancel the order itself instead.'] assert resp.data == ['This operation would leave the order empty. Please cancel the order itself instead.']
with scopes_disabled():
op2 = OrderPosition.objects.create( op2 = OrderPosition.objects.create(
order=order, order=order,
item=item, item=item,
@@ -744,6 +768,7 @@ def test_orderposition_delete(token_client, organizer, event, order, item, quest
organizer.slug, event.slug, op2.pk organizer.slug, event.slug, op2.pk
)) ))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert order.positions.count() == 1 assert order.positions.count() == 1
assert order.all_positions.count() == 3 assert order.all_positions.count() == 3
order.refresh_from_db() order.refresh_from_db()
@@ -822,6 +847,7 @@ def test_invoice_list(token_client, organizer, event, order, invoice):
organizer.slug, event.slug)) organizer.slug, event.slug))
assert [] == resp.data['results'] assert [] == resp.data['results']
with scopes_disabled():
ic = generate_cancellation(invoice) ic = generate_cancellation(invoice)
resp = token_client.get('/api/v1/organizers/{}/events/{}/invoices/?is_cancellation=false'.format( resp = token_client.get('/api/v1/organizers/{}/events/{}/invoices/?is_cancellation=false'.format(
@@ -854,6 +880,7 @@ def test_invoice_detail(token_client, organizer, event, invoice):
@pytest.mark.django_db @pytest.mark.django_db
def test_invoice_regenerate(token_client, organizer, event, invoice): def test_invoice_regenerate(token_client, organizer, event, invoice):
with scopes_disabled():
InvoiceAddress.objects.filter(order=invoice.order).update(company="ACME Ltd") InvoiceAddress.objects.filter(order=invoice.order).update(company="ACME Ltd")
resp = token_client.post('/api/v1/organizers/{}/events/{}/invoices/{}/regenerate/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/invoices/{}/regenerate/'.format(
@@ -866,6 +893,7 @@ def test_invoice_regenerate(token_client, organizer, event, invoice):
@pytest.mark.django_db @pytest.mark.django_db
def test_invoice_reissue(token_client, organizer, event, invoice): def test_invoice_reissue(token_client, organizer, event, invoice):
with scopes_disabled():
InvoiceAddress.objects.filter(order=invoice.order).update(company="ACME Ltd") InvoiceAddress.objects.filter(order=invoice.order).update(company="ACME Ltd")
resp = token_client.post('/api/v1/organizers/{}/events/{}/invoices/{}/reissue/'.format( resp = token_client.post('/api/v1/organizers/{}/events/{}/invoices/{}/reissue/'.format(
@@ -874,6 +902,7 @@ def test_invoice_reissue(token_client, organizer, event, invoice):
assert resp.status_code == 204 assert resp.status_code == 204
invoice.refresh_from_db() invoice.refresh_from_db()
assert "ACME Ltd" not in invoice.invoice_to assert "ACME Ltd" not in invoice.invoice_to
with scopes_disabled():
assert invoice.order.invoices.count() == 3 assert invoice.order.invoices.count() == 3
invoice = invoice.order.invoices.last() invoice = invoice.order.invoices.last()
assert "ACME Ltd" in invoice.invoice_to assert "ACME Ltd" in invoice.invoice_to
@@ -1009,6 +1038,7 @@ def test_order_mark_canceled_expired(token_client, organizer, event, order):
def test_order_mark_paid_canceled_keep_fee(token_client, organizer, event, order): def test_order_mark_paid_canceled_keep_fee(token_client, organizer, event, order):
order.status = Order.STATUS_PAID order.status = Order.STATUS_PAID
order.save() order.save()
with scopes_disabled():
order.payments.create(state=OrderPayment.PAYMENT_STATE_CONFIRMED, amount=order.total) order.payments.create(state=OrderPayment.PAYMENT_STATE_CONFIRMED, amount=order.total)
resp = token_client.post( resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/{}/mark_canceled/'.format( '/api/v1/organizers/{}/events/{}/orders/{}/mark_canceled/'.format(
@@ -1186,6 +1216,7 @@ def test_order_extend_expired_quota_waiting_list(token_client, organizer, event,
order.save() order.save()
quota.size = 1 quota.size = 1
quota.save() quota.save()
with scopes_disabled():
event.waitinglistentries.create(item=item, email='foo@bar.com') event.waitinglistentries.create(item=item, email='foo@bar.com')
newdate = (now() + datetime.timedelta(days=20)).strftime("%Y-%m-%d") newdate = (now() + datetime.timedelta(days=20)).strftime("%Y-%m-%d")
resp = token_client.post( resp = token_client.post(
@@ -1353,6 +1384,7 @@ def test_order_create(token_client, organizer, event, item, quota, question):
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert o.email == "dummy@dummy.test" assert o.email == "dummy@dummy.test"
assert o.locale == "en" assert o.locale == "en"
@@ -1361,11 +1393,13 @@ def test_order_create(token_client, organizer, event, item, quota, question):
assert o.sales_channel == "web" assert o.sales_channel == "web"
assert not o.testmode assert not o.testmode
with scopes_disabled():
p = o.payments.first() p = o.payments.first()
assert p.provider == "banktransfer" assert p.provider == "banktransfer"
assert p.amount == o.total assert p.amount == o.total
assert p.state == "created" assert p.state == "created"
with scopes_disabled():
fee = o.fees.first() fee = o.fees.first()
assert fee.fee_type == "payment" assert fee.fee_type == "payment"
assert fee.value == Decimal('0.25') assert fee.value == Decimal('0.25')
@@ -1373,11 +1407,13 @@ def test_order_create(token_client, organizer, event, item, quota, question):
assert ia.company == "Sample company" assert ia.company == "Sample company"
assert ia.name_parts == {"full_name": "Fo", "_scheme": "full"} assert ia.name_parts == {"full_name": "Fo", "_scheme": "full"}
assert ia.name_cached == "Fo" assert ia.name_cached == "Fo"
with scopes_disabled():
assert o.positions.count() == 1 assert o.positions.count() == 1
pos = o.positions.first() pos = o.positions.first()
assert pos.item == item assert pos.item == item
assert pos.price == Decimal("23.00") assert pos.price == Decimal("23.00")
assert pos.attendee_name_parts == {"full_name": "Peter", "_scheme": "full"} assert pos.attendee_name_parts == {"full_name": "Peter", "_scheme": "full"}
with scopes_disabled():
answ = pos.answers.first() answ = pos.answers.first()
assert answ.question == question assert answ.question == question
assert answ.answer == "S" assert answ.answer == "S"
@@ -1395,6 +1431,7 @@ def test_order_create_invoice_address_optional(token_client, organizer, event, i
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
with pytest.raises(InvoiceAddress.DoesNotExist): with pytest.raises(InvoiceAddress.DoesNotExist):
o.invoice_address o.invoice_address
@@ -1412,6 +1449,7 @@ def test_order_create_sales_channel_optional(token_client, organizer, event, ite
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert o.sales_channel == "web" assert o.sales_channel == "web"
@@ -1443,6 +1481,7 @@ def test_order_create_in_test_mode(token_client, organizer, event, item, quota,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert o.testmode assert o.testmode
@@ -1460,6 +1499,7 @@ def test_order_create_attendee_name_optional(token_client, organizer, event, ite
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert o.positions.first().attendee_name_parts == {} assert o.positions.first().attendee_name_parts == {}
@@ -1484,6 +1524,8 @@ def test_order_create_legacy_attendee_name(token_client, organizer, event, item,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert o.positions.first().attendee_name_parts == {"_legacy": "Peter"} assert o.positions.first().attendee_name_parts == {"_legacy": "Peter"}
@@ -1508,6 +1550,7 @@ def test_order_create_legacy_invoice_name(token_client, organizer, event, item,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert o.invoice_address.name_parts == {"_legacy": "Peter"} assert o.invoice_address.name_parts == {"_legacy": "Peter"}
@@ -1524,6 +1567,7 @@ def test_order_create_code_optional(token_client, organizer, event, item, quota,
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert o.code == "ABCDE" assert o.code == "ABCDE"
@@ -1557,6 +1601,7 @@ def test_order_email_optional(token_client, organizer, event, item, quota, quest
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert not o.email assert not o.email
@@ -1572,7 +1617,6 @@ def test_order_create_payment_info_optional(token_client, organizer, event, item
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
o = Order.objects.get(code=resp.data['code'])
res['payment_info'] = { res['payment_info'] = {
'foo': { 'foo': {
@@ -1586,6 +1630,7 @@ def test_order_create_payment_info_optional(token_client, organizer, event, item
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
p = o.payments.first() p = o.payments.first()
@@ -1605,6 +1650,7 @@ def test_order_create_position_secret_optional(token_client, organizer, event, i
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert o.positions.first().secret assert o.positions.first().secret
@@ -1615,6 +1661,7 @@ def test_order_create_position_secret_optional(token_client, organizer, event, i
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert o.positions.first().secret == "aaa" assert o.positions.first().secret == "aaa"
@@ -1642,6 +1689,7 @@ def test_order_create_tax_rules(token_client, organizer, event, item, quota, que
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
fee = o.fees.first() fee = o.fees.first()
assert fee.fee_type == "payment" assert fee.fee_type == "payment"
@@ -1650,6 +1698,7 @@ def test_order_create_tax_rules(token_client, organizer, event, item, quota, que
assert fee.tax_rule == taxrule assert fee.tax_rule == taxrule
ia = o.invoice_address ia = o.invoice_address
assert ia.company == "Sample company" assert ia.company == "Sample company"
with scopes_disabled():
pos = o.positions.first() pos = o.positions.first()
assert pos.item == item assert pos.item == item
assert pos.tax_rate == Decimal('19.00') assert pos.tax_rate == Decimal('19.00')
@@ -1765,6 +1814,7 @@ def test_order_create_item_validation(token_client, organizer, event, item, item
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data == {'positions': [{'item': ['The specified item does not belong to this event.']}]} assert resp.data == {'positions': [{'item': ['The specified item does not belong to this event.']}]}
with scopes_disabled():
var2 = item2.variations.create(value="A") var2 = item2.variations.create(value="A")
quota.variations.add(var2) quota.variations.add(var2)
@@ -1778,6 +1828,7 @@ def test_order_create_item_validation(token_client, organizer, event, item, item
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data == {'positions': [{'variation': ['You cannot specify a variation for this item.']}]} assert resp.data == {'positions': [{'variation': ['You cannot specify a variation for this item.']}]}
with scopes_disabled():
var1 = item.variations.create(value="A") var1 = item.variations.create(value="A")
res['positions'][0]['item'] = item.pk res['positions'][0]['item'] = item.pk
res['positions'][0]['variation'] = var1.pk res['positions'][0]['variation'] = var1.pk
@@ -1789,6 +1840,7 @@ def test_order_create_item_validation(token_client, organizer, event, item, item
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data == {'positions': [{'item': ['The product "Budget Ticket" is not assigned to a quota.']}]} assert resp.data == {'positions': [{'item': ['The product "Budget Ticket" is not assigned to a quota.']}]}
with scopes_disabled():
quota.variations.add(var1) quota.variations.add(var1)
resp = token_client.post( resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/'.format( '/api/v1/organizers/{}/events/{}/orders/'.format(
@@ -1850,6 +1902,7 @@ def test_order_create_positionids_addons(token_client, organizer, event, item, q
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
pos1 = o.positions.first() pos1 = o.positions.first()
pos2 = o.positions.last() pos2 = o.positions.last()
@@ -2046,7 +2099,9 @@ def test_order_create_answer_validation(token_client, organizer, event, item, qu
assert resp.data == {'positions': [ assert resp.data == {'positions': [
{'answers': [{'non_field_errors': ['You need to specify options if the question is of a choice type.']}]}]} {'answers': [{'non_field_errors': ['You need to specify options if the question is of a choice type.']}]}]}
with scopes_disabled():
question.options.create(answer="L") question.options.create(answer="L")
with scopes_disabled():
res['positions'][0]['answers'][0]['options'] = [ res['positions'][0]['answers'][0]['options'] = [
question.options.first().pk, question.options.first().pk,
question.options.last().pk, question.options.last().pk,
@@ -2073,6 +2128,7 @@ def test_order_create_answer_validation(token_client, organizer, event, item, qu
question.type = Question.TYPE_CHOICE_MULTIPLE question.type = Question.TYPE_CHOICE_MULTIPLE
question.save() question.save()
with scopes_disabled():
res['positions'][0]['answers'][0]['options'] = [ res['positions'][0]['answers'][0]['options'] = [
question.options.first().pk, question.options.first().pk,
question.options.last().pk, question.options.last().pk,
@@ -2083,6 +2139,7 @@ def test_order_create_answer_validation(token_client, organizer, event, item, qu
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
pos = o.positions.first() pos = o.positions.first()
answ = pos.answers.first() answ = pos.answers.first()
@@ -2099,6 +2156,7 @@ def test_order_create_answer_validation(token_client, organizer, event, item, qu
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
pos = o.positions.first() pos = o.positions.first()
answ = pos.answers.first() answ = pos.answers.first()
@@ -2126,6 +2184,7 @@ def test_order_create_answer_validation(token_client, organizer, event, item, qu
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
pos = o.positions.first() pos = o.positions.first()
answ = pos.answers.first() answ = pos.answers.first()
@@ -2140,6 +2199,7 @@ def test_order_create_answer_validation(token_client, organizer, event, item, qu
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
pos = o.positions.first() pos = o.positions.first()
answ = pos.answers.first() answ = pos.answers.first()
@@ -2166,6 +2226,7 @@ def test_order_create_answer_validation(token_client, organizer, event, item, qu
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
pos = o.positions.first() pos = o.positions.first()
answ = pos.answers.first() answ = pos.answers.first()
@@ -2192,6 +2253,7 @@ def test_order_create_answer_validation(token_client, organizer, event, item, qu
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
pos = o.positions.first() pos = o.positions.first()
answ = pos.answers.first() answ = pos.answers.first()
@@ -2219,6 +2281,7 @@ def test_order_create_answer_validation(token_client, organizer, event, item, qu
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
pos = o.positions.first() pos = o.positions.first()
answ = pos.answers.first() answ = pos.answers.first()
@@ -2310,6 +2373,7 @@ def test_order_create_quota_consume_cart(token_client, organizer, event, item, q
res['positions'][0]['item'] = item.pk res['positions'][0]['item'] = item.pk
res['positions'][0]['answers'][0]['question'] = question.pk res['positions'][0]['answers'][0]['question'] = question.pk
with scopes_disabled():
cr = CartPosition.objects.create( cr = CartPosition.objects.create(
event=event, cart_id="uxLJBUMEcnxOLI2EuxLYN1hWJq9GKu4yWL9FEgs2m7M0vdFi@api", item=item, event=event, cart_id="uxLJBUMEcnxOLI2EuxLYN1hWJq9GKu4yWL9FEgs2m7M0vdFi@api", item=item,
price=23, price=23,
@@ -2337,6 +2401,7 @@ def test_order_create_quota_consume_cart(token_client, organizer, event, item, q
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
assert not CartPosition.objects.filter(pk=cr.pk).exists() assert not CartPosition.objects.filter(pk=cr.pk).exists()
@@ -2353,10 +2418,12 @@ def test_order_create_free(token_client, organizer, event, item, quota, question
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert o.total == Decimal('0.00') assert o.total == Decimal('0.00')
assert o.status == Order.STATUS_PAID assert o.status == Order.STATUS_PAID
with scopes_disabled():
p = o.payments.first() p = o.payments.first()
assert p.provider == "free" assert p.provider == "free"
assert p.amount == o.total assert p.amount == o.total
@@ -2437,6 +2504,7 @@ def test_order_create_paid_generate_invoice(token_client, organizer, event, item
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
o = Order.objects.get(code=resp.data['code']) o = Order.objects.get(code=resp.data['code'])
assert o.invoices.count() == 1 assert o.invoices.count() == 1
@@ -2472,6 +2540,7 @@ def test_refund_create(token_client, organizer, event, order):
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
r = order.refunds.get(local_id=resp.data['local_id']) r = order.refunds.get(local_id=resp.data['local_id'])
assert r.provider == "manual" assert r.provider == "manual"
assert r.amount == Decimal("23.00") assert r.amount == Decimal("23.00")
@@ -2493,6 +2562,7 @@ def test_refund_create_mark_refunded(token_client, organizer, event, order):
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
r = order.refunds.get(local_id=resp.data['local_id']) r = order.refunds.get(local_id=resp.data['local_id'])
assert r.provider == "manual" assert r.provider == "manual"
assert r.amount == Decimal("23.00") assert r.amount == Decimal("23.00")
@@ -2515,6 +2585,7 @@ def test_refund_optional_fields(token_client, organizer, event, order):
), format='json', data=res ), format='json', data=res
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
r = order.refunds.get(local_id=resp.data['local_id']) r = order.refunds.get(local_id=resp.data['local_id'])
assert r.provider == "manual" assert r.provider == "manual"
assert r.amount == Decimal("23.00") assert r.amount == Decimal("23.00")
@@ -2562,6 +2633,7 @@ def test_order_delete_test_mode(token_client, organizer, event, order):
) )
) )
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not Order.objects.filter(code=order.code).exists() assert not Order.objects.filter(code=order.code).exists()
@@ -2569,6 +2641,7 @@ def test_order_delete_test_mode(token_client, organizer, event, order):
def test_order_delete_test_mode_voucher(token_client, organizer, event, order, item): def test_order_delete_test_mode_voucher(token_client, organizer, event, order, item):
order.testmode = True order.testmode = True
order.save() order.save()
with scopes_disabled():
q = event.quotas.create(name="Quota") q = event.quotas.create(name="Quota")
q.items.add(item) q.items.add(item)
voucher = event.vouchers.create(price_mode="set", value=15, quota=q, redeemed=1) voucher = event.vouchers.create(price_mode="set", value=15, quota=q, redeemed=1)
@@ -2584,6 +2657,7 @@ def test_order_delete_test_mode_voucher(token_client, organizer, event, order, i
) )
) )
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not Order.objects.filter(code=order.code).exists() assert not Order.objects.filter(code=order.code).exists()
voucher.refresh_from_db() voucher.refresh_from_db()
assert voucher.redeemed == 0 assert voucher.redeemed == 0
@@ -2593,6 +2667,7 @@ def test_order_delete_test_mode_voucher(token_client, organizer, event, order, i
def test_order_delete_test_mode_voucher_cancelled_position(token_client, organizer, event, order, item): def test_order_delete_test_mode_voucher_cancelled_position(token_client, organizer, event, order, item):
order.testmode = True order.testmode = True
order.save() order.save()
with scopes_disabled():
q = event.quotas.create(name="Quota") q = event.quotas.create(name="Quota")
q.items.add(item) q.items.add(item)
voucher = event.vouchers.create(price_mode="set", value=15, quota=q, redeemed=42) voucher = event.vouchers.create(price_mode="set", value=15, quota=q, redeemed=42)
@@ -2606,6 +2681,7 @@ def test_order_delete_test_mode_voucher_cancelled_position(token_client, organiz
) )
) )
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not Order.objects.filter(code=order.code).exists() assert not Order.objects.filter(code=order.code).exists()
voucher.refresh_from_db() voucher.refresh_from_db()
assert voucher.redeemed == 42 assert voucher.redeemed == 42
@@ -2613,6 +2689,7 @@ def test_order_delete_test_mode_voucher_cancelled_position(token_client, organiz
@pytest.mark.django_db @pytest.mark.django_db
def test_order_delete_test_mode_voucher_cancelled_order(token_client, organizer, event, order, item): def test_order_delete_test_mode_voucher_cancelled_order(token_client, organizer, event, order, item):
with scopes_disabled():
order.testmode = True order.testmode = True
order.status = Order.STATUS_CANCELED order.status = Order.STATUS_CANCELED
order.save() order.save()
@@ -2629,6 +2706,7 @@ def test_order_delete_test_mode_voucher_cancelled_order(token_client, organizer,
) )
) )
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not Order.objects.filter(code=order.code).exists() assert not Order.objects.filter(code=order.code).exists()
voucher.refresh_from_db() voucher.refresh_from_db()
assert voucher.redeemed == 42 assert voucher.redeemed == 42
@@ -2697,6 +2775,7 @@ def test_order_update_allowed_fields(token_client, organizer, event, order):
assert str(order.invoice_address.country) == "FR" assert str(order.invoice_address.country) == "FR"
assert not order.invoice_address.vat_id_validated assert not order.invoice_address.vat_id_validated
assert order.invoice_address.city == "Paris" assert order.invoice_address.city == "Paris"
with scopes_disabled():
assert order.all_logentries().get(action_type='pretix.event.order.comment') assert order.all_logentries().get(action_type='pretix.event.order.comment')
assert order.all_logentries().get(action_type='pretix.event.order.checkin_attention') assert order.all_logentries().get(action_type='pretix.event.order.checkin_attention')
assert order.all_logentries().get(action_type='pretix.event.order.contact.changed') assert order.all_logentries().get(action_type='pretix.event.order.contact.changed')
@@ -2847,6 +2926,7 @@ def test_order_create_invoice(token_client, organizer, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_order_regenerate_secrets(token_client, organizer, event, order): def test_order_regenerate_secrets(token_client, organizer, event, order):
s = order.secret s = order.secret
with scopes_disabled():
ps = order.positions.first().secret ps = order.positions.first().secret
resp = token_client.post( resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orders/{}/regenerate_secrets/'.format( '/api/v1/organizers/{}/events/{}/orders/{}/regenerate_secrets/'.format(
@@ -2856,6 +2936,7 @@ def test_order_regenerate_secrets(token_client, organizer, event, order):
assert resp.status_code == 200 assert resp.status_code == 200
order.refresh_from_db() order.refresh_from_db()
assert s != order.secret assert s != order.secret
with scopes_disabled():
assert ps != order.positions.first().secret assert ps != order.positions.first().secret
@@ -2882,6 +2963,7 @@ def test_order_resend_link(token_client, organizer, event, order):
@pytest.mark.django_db @pytest.mark.django_db
def test_orderposition_price_calculation(token_client, organizer, event, order, item): def test_orderposition_price_calculation(token_client, organizer, event, order, item):
with scopes_disabled():
op = order.positions.first() op = order.positions.first()
resp = token_client.post( resp = token_client.post(
'/api/v1/organizers/{}/events/{}/orderpositions/{}/price_calc/'.format(organizer.slug, event.slug, op.pk), '/api/v1/organizers/{}/events/{}/orderpositions/{}/price_calc/'.format(organizer.slug, event.slug, op.pk),
@@ -2901,6 +2983,7 @@ def test_orderposition_price_calculation(token_client, organizer, event, order,
@pytest.mark.django_db @pytest.mark.django_db
def test_orderposition_price_calculation_item_with_tax(token_client, organizer, event, order, item, taxrule): def test_orderposition_price_calculation_item_with_tax(token_client, organizer, event, order, item, taxrule):
with scopes_disabled():
item2 = event.items.create(name="Budget Ticket", default_price=23, tax_rule=taxrule) item2 = event.items.create(name="Budget Ticket", default_price=23, tax_rule=taxrule)
op = order.positions.first() op = order.positions.first()
resp = token_client.post( resp = token_client.post(
@@ -2922,6 +3005,7 @@ def test_orderposition_price_calculation_item_with_tax(token_client, organizer,
@pytest.mark.django_db @pytest.mark.django_db
def test_orderposition_price_calculation_item_with_variation(token_client, organizer, event, order): def test_orderposition_price_calculation_item_with_variation(token_client, organizer, event, order):
with scopes_disabled():
item2 = event.items.create(name="Budget Ticket", default_price=23) item2 = event.items.create(name="Budget Ticket", default_price=23)
var = item2.variations.create(default_price=12, value="XS") var = item2.variations.create(default_price=12, value="XS")
op = order.positions.first() op = order.positions.first()
@@ -2945,6 +3029,7 @@ def test_orderposition_price_calculation_item_with_variation(token_client, organ
@pytest.mark.django_db @pytest.mark.django_db
def test_orderposition_price_calculation_subevent(token_client, organizer, event, order, subevent): def test_orderposition_price_calculation_subevent(token_client, organizer, event, order, subevent):
with scopes_disabled():
item2 = event.items.create(name="Budget Ticket", default_price=23) item2 = event.items.create(name="Budget Ticket", default_price=23)
op = order.positions.first() op = order.positions.first()
op.subevent = subevent op.subevent = subevent
@@ -2969,6 +3054,7 @@ def test_orderposition_price_calculation_subevent(token_client, organizer, event
@pytest.mark.django_db @pytest.mark.django_db
def test_orderposition_price_calculation_subevent_with_override(token_client, organizer, event, order, subevent): def test_orderposition_price_calculation_subevent_with_override(token_client, organizer, event, order, subevent):
with scopes_disabled():
item2 = event.items.create(name="Budget Ticket", default_price=23) item2 = event.items.create(name="Budget Ticket", default_price=23)
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
se2.subeventitem_set.create(item=item2, price=12) se2.subeventitem_set.create(item=item2, price=12)
@@ -2995,6 +3081,7 @@ def test_orderposition_price_calculation_subevent_with_override(token_client, or
@pytest.mark.django_db @pytest.mark.django_db
def test_orderposition_price_calculation_voucher_matching(token_client, organizer, event, order, subevent, item): def test_orderposition_price_calculation_voucher_matching(token_client, organizer, event, order, subevent, item):
with scopes_disabled():
item2 = event.items.create(name="Budget Ticket", default_price=23) item2 = event.items.create(name="Budget Ticket", default_price=23)
q = event.quotas.create(name="Quota") q = event.quotas.create(name="Quota")
q.items.add(item) q.items.add(item)
@@ -3022,6 +3109,7 @@ def test_orderposition_price_calculation_voucher_matching(token_client, organize
@pytest.mark.django_db @pytest.mark.django_db
def test_orderposition_price_calculation_voucher_not_matching(token_client, organizer, event, order, subevent, item): def test_orderposition_price_calculation_voucher_not_matching(token_client, organizer, event, order, subevent, item):
with scopes_disabled():
item2 = event.items.create(name="Budget Ticket", default_price=23) item2 = event.items.create(name="Budget Ticket", default_price=23)
q = event.quotas.create(name="Quota") q = event.quotas.create(name="Quota")
q.items.add(item) q.items.add(item)
@@ -3050,6 +3138,7 @@ def test_orderposition_price_calculation_voucher_not_matching(token_client, orga
def test_orderposition_price_calculation_net_price(token_client, organizer, event, order, subevent, item, taxrule): def test_orderposition_price_calculation_net_price(token_client, organizer, event, order, subevent, item, taxrule):
taxrule.price_includes_tax = False taxrule.price_includes_tax = False
taxrule.save() taxrule.save()
with scopes_disabled():
item2 = event.items.create(name="Budget Ticket", default_price=10, tax_rule=taxrule) item2 = event.items.create(name="Budget Ticket", default_price=10, tax_rule=taxrule)
op = order.positions.first() op = order.positions.first()
resp = token_client.post( resp = token_client.post(
@@ -3080,6 +3169,7 @@ def test_orderposition_price_calculation_reverse_charge(token_client, organizer,
order.invoice_address.vat_id_validated = True order.invoice_address.vat_id_validated = True
order.invoice_address.country = Country('AT') order.invoice_address.country = Country('AT')
order.invoice_address.save() order.invoice_address.save()
with scopes_disabled():
item2 = event.items.create(name="Budget Ticket", default_price=10, tax_rule=taxrule) item2 = event.items.create(name="Budget Ticket", default_price=10, tax_rule=taxrule)
op = order.positions.first() op = order.positions.first()
resp = token_client.post( resp = token_client.post(

View File

@@ -4,6 +4,7 @@ from unittest import mock
import pytest import pytest
from django_countries.fields import Country from django_countries.fields import Country
from django_scopes import scopes_disabled
from pytz import UTC from pytz import UTC
from pretix.base.models import InvoiceAddress, Order, OrderPosition from pretix.base.models import InvoiceAddress, Order, OrderPosition
@@ -159,6 +160,7 @@ def test_subevent_create(token_client, organizer, event, subevent, meta_prop, it
) )
assert resp.status_code == 201 assert resp.status_code == 201
assert not subevent.active assert not subevent.active
with scopes_disabled():
assert subevent.meta_values.filter( assert subevent.meta_values.filter(
property__name=meta_prop.name, value="Workshop" property__name=meta_prop.name, value="Workshop"
).exists() ).exists()
@@ -217,6 +219,7 @@ def test_subevent_create(token_client, organizer, event, subevent, meta_prop, it
) )
assert resp.status_code == 201 assert resp.status_code == 201
assert item.default_price == Decimal('23.00') assert item.default_price == Decimal('23.00')
with scopes_disabled():
assert event.subevents.get(id=resp.data['id']).item_price_overrides[item.pk] == Decimal('23.42') assert event.subevents.get(id=resp.data['id']).item_price_overrides[item.pk] == Decimal('23.42')
resp = token_client.post( resp = token_client.post(
@@ -261,6 +264,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
subevent = event.subevents.get(id=subevent.id) subevent = event.subevents.get(id=subevent.id)
assert subevent.date_from == datetime(2018, 12, 27, 10, 0, tzinfo=UTC) assert subevent.date_from == datetime(2018, 12, 27, 10, 0, tzinfo=UTC)
assert subevent.date_to == datetime(2018, 12, 28, 10, 0, tzinfo=UTC) assert subevent.date_to == datetime(2018, 12, 28, 10, 0, tzinfo=UTC)
@@ -297,6 +301,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert organizer.events.get(slug=event.slug).subevents.get(id=resp.data['id']).meta_values.filter( assert organizer.events.get(slug=event.slug).subevents.get(id=resp.data['id']).meta_values.filter(
property__name=meta_prop.name, value="Conference" property__name=meta_prop.name, value="Conference"
).exists() ).exists()
@@ -310,6 +315,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert not subevent.meta_values.filter( assert not subevent.meta_values.filter(
property__name=meta_prop.name property__name=meta_prop.name
).exists() ).exists()
@@ -339,6 +345,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert subevent.items.get(id=item.pk).default_price == Decimal('23.00') assert subevent.items.get(id=item.pk).default_price == Decimal('23.00')
assert subevent.item_price_overrides[item.pk] == Decimal('99.99') assert subevent.item_price_overrides[item.pk] == Decimal('99.99')
@@ -355,6 +362,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert event.subevents.get(id=subevent.id).item_price_overrides[item.pk] == Decimal('88.88') assert event.subevents.get(id=subevent.id).item_price_overrides[item.pk] == Decimal('88.88')
resp = token_client.patch( resp = token_client.patch(
@@ -370,6 +378,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert item.pk not in event.subevents.get(id=subevent.id).item_price_overrides assert item.pk not in event.subevents.get(id=subevent.id).item_price_overrides
resp = token_client.patch( resp = token_client.patch(
@@ -385,6 +394,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert event.subevents.get(id=subevent.id).item_price_overrides[item.pk] == Decimal('12.34') assert event.subevents.get(id=subevent.id).item_price_overrides[item.pk] == Decimal('12.34')
resp = token_client.patch( resp = token_client.patch(
@@ -395,6 +405,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert item.pk not in event.subevents.get(id=subevent.id).item_price_overrides assert item.pk not in event.subevents.get(id=subevent.id).item_price_overrides
resp = token_client.patch( resp = token_client.patch(
@@ -440,6 +451,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert subevent.variations.get(id=variations[0].pk).default_price == Decimal('12.00') assert subevent.variations.get(id=variations[0].pk).default_price == Decimal('12.00')
assert subevent.var_price_overrides[variations[0].pk] == Decimal('99.99') assert subevent.var_price_overrides[variations[0].pk] == Decimal('99.99')
@@ -456,6 +468,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert event.subevents.get(id=subevent.id).var_price_overrides[variations[0].pk] == Decimal('88.88') assert event.subevents.get(id=subevent.id).var_price_overrides[variations[0].pk] == Decimal('88.88')
resp = token_client.patch( resp = token_client.patch(
@@ -471,6 +484,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert variations[0].pk not in event.subevents.get(id=subevent.id).var_price_overrides assert variations[0].pk not in event.subevents.get(id=subevent.id).var_price_overrides
resp = token_client.patch( resp = token_client.patch(
@@ -486,6 +500,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert event.subevents.get(id=subevent.id).var_price_overrides[variations[0].pk] == Decimal('12.34') assert event.subevents.get(id=subevent.id).var_price_overrides[variations[0].pk] == Decimal('12.34')
resp = token_client.patch( resp = token_client.patch(
@@ -496,6 +511,7 @@ def test_subevent_update(token_client, organizer, event, subevent, item, item2,
format='json' format='json'
) )
assert resp.status_code == 200 assert resp.status_code == 200
with scopes_disabled():
assert variations[0].pk not in event.subevents.get(id=subevent.id).var_price_overrides assert variations[0].pk not in event.subevents.get(id=subevent.id).var_price_overrides
resp = token_client.patch( resp = token_client.patch(
@@ -544,6 +560,7 @@ def test_subevent_delete(token_client, organizer, event, subevent):
resp = token_client.delete('/api/v1/organizers/{}/events/{}/subevents/{}/'.format(organizer.slug, event.slug, resp = token_client.delete('/api/v1/organizers/{}/events/{}/subevents/{}/'.format(organizer.slug, event.slug,
subevent.pk)) subevent.pk))
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not event.subevents.filter(pk=subevent.id).exists() assert not event.subevents.filter(pk=subevent.id).exists()
@@ -554,4 +571,5 @@ def test_subevent_with_order_position_not_delete(token_client, organizer, event,
assert resp.status_code == 403 assert resp.status_code == 403
assert resp.content.decode() == '{"detail":"The sub-event can not be deleted as it has already been used in ' \ assert resp.content.decode() == '{"detail":"The sub-event can not be deleted as it has already been used in ' \
'orders. Please set \'active\' to false instead to hide it from users."}' 'orders. Please set \'active\' to false instead to hide it from users."}'
with scopes_disabled():
assert event.subevents.filter(pk=subevent.id).exists() assert event.subevents.filter(pk=subevent.id).exists()

View File

@@ -1,6 +1,7 @@
from decimal import Decimal from decimal import Decimal
import pytest import pytest
from django_scopes import scopes_disabled
from pretix.base.models import TaxRule from pretix.base.models import TaxRule
@@ -80,6 +81,7 @@ def test_rule_delete(token_client, organizer, event, taxrule):
@pytest.mark.django_db @pytest.mark.django_db
def test_rule_delete_forbidden(token_client, organizer, event, taxrule): def test_rule_delete_forbidden(token_client, organizer, event, taxrule):
with scopes_disabled():
event.items.create(name="Budget Ticket", default_price=23, tax_rule=taxrule) event.items.create(name="Budget Ticket", default_price=23, tax_rule=taxrule)
resp = token_client.delete( resp = token_client.delete(
'/api/v1/organizers/{}/events/{}/taxrules/{}/'.format(organizer.slug, event.slug, taxrule.pk), '/api/v1/organizers/{}/events/{}/taxrules/{}/'.format(organizer.slug, event.slug, taxrule.pk),

View File

@@ -5,6 +5,7 @@ from decimal import Decimal
import pytest import pytest
from django.utils import timezone from django.utils import timezone
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from pytz import UTC from pytz import UTC
from pretix.base.models import Event, Voucher from pretix.base.models import Event, Voucher
@@ -58,6 +59,7 @@ def test_voucher_list(token_client, organizer, event, voucher, item, quota, sube
i2 = copy.copy(item) i2 = copy.copy(item)
i2.pk = None i2.pk = None
i2.save() i2.save()
with scopes_disabled():
var2 = i2.variations.create(value="foo") var2 = i2.variations.create(value="foo")
resp = token_client.get('/api/v1/organizers/{}/events/{}/vouchers/'.format(organizer.slug, event.slug)) resp = token_client.get('/api/v1/organizers/{}/events/{}/vouchers/'.format(organizer.slug, event.slug))
@@ -136,6 +138,7 @@ def test_voucher_list(token_client, organizer, event, voucher, item, quota, sube
) )
assert [] == resp.data['results'] assert [] == resp.data['results']
with scopes_disabled():
var = item.variations.create(value='VIP') var = item.variations.create(value='VIP')
voucher.variation = var voucher.variation = var
voucher.save() voucher.save()
@@ -208,6 +211,7 @@ def test_voucher_list(token_client, organizer, event, voucher, item, quota, sube
resp = token_client.get( resp = token_client.get(
'/api/v1/organizers/{}/events/{}/vouchers/?subevent={}'.format(organizer.slug, event.slug, subevent.pk)) '/api/v1/organizers/{}/events/{}/vouchers/?subevent={}'.format(organizer.slug, event.slug, subevent.pk))
assert [res] == resp.data['results'] assert [res] == resp.data['results']
with scopes_disabled():
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
resp = token_client.get( resp = token_client.get(
'/api/v1/organizers/{}/events/{}/vouchers/?subevent={}'.format(organizer.slug, event.slug, '/api/v1/organizers/{}/events/{}/vouchers/?subevent={}'.format(organizer.slug, event.slug,
@@ -237,6 +241,7 @@ def create_voucher(token_client, organizer, event, data, expected_failure=False)
assert resp.status_code == 400 assert resp.status_code == 400
else: else:
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
return Voucher.objects.get(pk=resp.data['id']) return Voucher.objects.get(pk=resp.data['id'])
@@ -324,6 +329,7 @@ def test_create_non_blocking_item_voucher(token_client, organizer, event, item):
@pytest.mark.django_db @pytest.mark.django_db
def test_create_non_blocking_variation_voucher(token_client, organizer, event, item): def test_create_non_blocking_variation_voucher(token_client, organizer, event, item):
with scopes_disabled():
variation = item.variations.create(value="XL") variation = item.variations.create(value="XL")
v = create_voucher( v = create_voucher(
token_client, organizer, event, token_client, organizer, event,
@@ -394,6 +400,7 @@ def test_create_blocking_item_voucher_quota_full_invalid(token_client, organizer
@pytest.mark.django_db @pytest.mark.django_db
def test_create_blocking_variation_voucher_quota_free(token_client, organizer, event, item, quota): def test_create_blocking_variation_voucher_quota_free(token_client, organizer, event, item, quota):
with scopes_disabled():
variation = item.variations.create(value="XL") variation = item.variations.create(value="XL")
quota.variations.add(variation) quota.variations.add(variation)
v = create_voucher( v = create_voucher(
@@ -421,6 +428,7 @@ def test_create_short_code(token_client, organizer, event, item):
@pytest.mark.django_db @pytest.mark.django_db
def test_create_blocking_variation_voucher_quota_full(token_client, organizer, event, item, quota): def test_create_blocking_variation_voucher_quota_full(token_client, organizer, event, item, quota):
with scopes_disabled():
variation = item.variations.create(value="XL") variation = item.variations.create(value="XL")
quota.variations.add(variation) quota.variations.add(variation)
quota.size = 0 quota.size = 0
@@ -463,6 +471,7 @@ def test_create_blocking_quota_voucher_quota_full(token_client, organizer, event
@pytest.mark.django_db @pytest.mark.django_db
def test_create_duplicate_code(token_client, organizer, event, quota): def test_create_duplicate_code(token_client, organizer, event, quota):
with scopes_disabled():
v = event.vouchers.create(quota=quota) v = event.vouchers.create(quota=quota)
create_voucher( create_voucher(
token_client, organizer, event, token_client, organizer, event,
@@ -501,6 +510,7 @@ def test_subevent_required_for_blocking(token_client, organizer, event, item, su
@pytest.mark.django_db @pytest.mark.django_db
def test_subevent_blocking_quota_free(token_client, organizer, event, item, quota, subevent): def test_subevent_blocking_quota_free(token_client, organizer, event, item, quota, subevent):
with scopes_disabled():
se2 = event.subevents.create(name="Bar", date_from=now()) se2 = event.subevents.create(name="Bar", date_from=now())
quota.subevent = subevent quota.subevent = subevent
quota.save() quota.save()
@@ -521,6 +531,7 @@ def test_subevent_blocking_quota_free(token_client, organizer, event, item, quot
@pytest.mark.django_db @pytest.mark.django_db
def test_subevent_blocking_quota_full(token_client, organizer, event, item, quota, subevent): def test_subevent_blocking_quota_full(token_client, organizer, event, item, quota, subevent):
with scopes_disabled():
se2 = event.subevents.create(name="Bar", date_from=now()) se2 = event.subevents.create(name="Bar", date_from=now())
quota.subevent = subevent quota.subevent = subevent
quota.size = 0 quota.size = 0
@@ -553,6 +564,7 @@ def change_voucher(token_client, organizer, event, voucher, data, expected_failu
@pytest.mark.django_db @pytest.mark.django_db
def test_change_to_item_of_other_event(token_client, organizer, event, item): def test_change_to_item_of_other_event(token_client, organizer, event, item):
with scopes_disabled():
e2 = Event.objects.create( e2 = Event.objects.create(
organizer=organizer, organizer=organizer,
name='Dummy2', name='Dummy2',
@@ -575,6 +587,7 @@ def test_change_to_item_of_other_event(token_client, organizer, event, item):
@pytest.mark.django_db @pytest.mark.django_db
def test_change_non_blocking_voucher(token_client, organizer, event, item, quota): def test_change_non_blocking_voucher(token_client, organizer, event, item, quota):
with scopes_disabled():
v = event.vouchers.create(item=item) v = event.vouchers.create(item=item)
change_voucher( change_voucher(
token_client, organizer, event, v, token_client, organizer, event, v,
@@ -589,6 +602,7 @@ def test_change_non_blocking_voucher(token_client, organizer, event, item, quota
@pytest.mark.django_db @pytest.mark.django_db
def test_change_voucher_reduce_max_usages(token_client, organizer, event, item, quota): def test_change_voucher_reduce_max_usages(token_client, organizer, event, item, quota):
with scopes_disabled():
v = event.vouchers.create(item=item, max_usages=5, redeemed=3) v = event.vouchers.create(item=item, max_usages=5, redeemed=3)
change_voucher( change_voucher(
token_client, organizer, event, v, token_client, organizer, event, v,
@@ -604,6 +618,7 @@ def test_change_voucher_reduce_max_usages(token_client, organizer, event, item,
def test_change_blocking_voucher_unchanged_quota_full(token_client, organizer, event, item, quota): def test_change_blocking_voucher_unchanged_quota_full(token_client, organizer, event, item, quota):
quota.size = 0 quota.size = 0
quota.save() quota.save()
with scopes_disabled():
v = event.vouchers.create(item=item, block_quota=True) v = event.vouchers.create(item=item, block_quota=True)
change_voucher( change_voucher(
token_client, organizer, event, v, token_client, organizer, event, v,
@@ -620,6 +635,7 @@ def test_change_blocking_voucher_unchanged_quota_full(token_client, organizer, e
def test_change_voucher_to_blocking_quota_full(token_client, organizer, event, item, quota): def test_change_voucher_to_blocking_quota_full(token_client, organizer, event, item, quota):
quota.size = 0 quota.size = 0
quota.save() quota.save()
with scopes_disabled():
v = event.vouchers.create(item=item) v = event.vouchers.create(item=item)
change_voucher( change_voucher(
token_client, organizer, event, v, token_client, organizer, event, v,
@@ -632,6 +648,7 @@ def test_change_voucher_to_blocking_quota_full(token_client, organizer, event, i
@pytest.mark.django_db @pytest.mark.django_db
def test_change_voucher_to_blocking_quota_free(token_client, organizer, event, item, quota): def test_change_voucher_to_blocking_quota_free(token_client, organizer, event, item, quota):
with scopes_disabled():
v = event.vouchers.create(item=item) v = event.vouchers.create(item=item)
change_voucher( change_voucher(
token_client, organizer, event, v, token_client, organizer, event, v,
@@ -646,6 +663,7 @@ def test_change_voucher_to_blocking_quota_free(token_client, organizer, event, i
def test_change_voucher_validity_to_valid_quota_full(token_client, organizer, event, item, quota): def test_change_voucher_validity_to_valid_quota_full(token_client, organizer, event, item, quota):
quota.size = 0 quota.size = 0
quota.save() quota.save()
with scopes_disabled():
v = event.vouchers.create(item=item, valid_until=now() - datetime.timedelta(days=3), v = event.vouchers.create(item=item, valid_until=now() - datetime.timedelta(days=3),
block_quota=True) block_quota=True)
change_voucher( change_voucher(
@@ -660,6 +678,7 @@ def test_change_voucher_validity_to_valid_quota_full(token_client, organizer, ev
@pytest.mark.django_db @pytest.mark.django_db
def test_change_voucher_validity_to_valid_quota_free(token_client, organizer, event, item, quota): def test_change_voucher_validity_to_valid_quota_free(token_client, organizer, event, item, quota):
with scopes_disabled():
v = event.vouchers.create(item=item, valid_until=now() - datetime.timedelta(days=3), v = event.vouchers.create(item=item, valid_until=now() - datetime.timedelta(days=3),
block_quota=True) block_quota=True)
change_voucher( change_voucher(
@@ -673,6 +692,7 @@ def test_change_voucher_validity_to_valid_quota_free(token_client, organizer, ev
@pytest.mark.django_db @pytest.mark.django_db
def test_change_item_of_blocking_voucher_quota_free(token_client, organizer, event, item, quota): def test_change_item_of_blocking_voucher_quota_free(token_client, organizer, event, item, quota):
with scopes_disabled():
ticket2 = event.items.create(name='Late-bird ticket', default_price=23) ticket2 = event.items.create(name='Late-bird ticket', default_price=23)
quota.items.add(ticket2) quota.items.add(ticket2)
v = event.vouchers.create(item=item, block_quota=True) v = event.vouchers.create(item=item, block_quota=True)
@@ -687,6 +707,7 @@ def test_change_item_of_blocking_voucher_quota_free(token_client, organizer, eve
@pytest.mark.django_db @pytest.mark.django_db
def test_change_item_of_blocking_voucher_quota_full(token_client, organizer, event, item, quota): def test_change_item_of_blocking_voucher_quota_full(token_client, organizer, event, item, quota):
with scopes_disabled():
ticket2 = event.items.create(name='Late-bird ticket', default_price=23) ticket2 = event.items.create(name='Late-bird ticket', default_price=23)
quota2 = event.quotas.create(name='Late', size=0) quota2 = event.quotas.create(name='Late', size=0)
quota2.items.add(ticket2) quota2.items.add(ticket2)
@@ -702,6 +723,7 @@ def test_change_item_of_blocking_voucher_quota_full(token_client, organizer, eve
@pytest.mark.django_db @pytest.mark.django_db
def test_change_variation_of_blocking_voucher_quota_free(token_client, organizer, event): def test_change_variation_of_blocking_voucher_quota_free(token_client, organizer, event):
with scopes_disabled():
shirt = event.items.create(name='Shirt', default_price=23) shirt = event.items.create(name='Shirt', default_price=23)
vs = shirt.variations.create(value='S') vs = shirt.variations.create(value='S')
vm = shirt.variations.create(value='M') vm = shirt.variations.create(value='M')
@@ -721,6 +743,7 @@ def test_change_variation_of_blocking_voucher_quota_free(token_client, organizer
@pytest.mark.django_db @pytest.mark.django_db
def test_change_variation_of_blocking_voucher_without_quota_change(token_client, organizer, event): def test_change_variation_of_blocking_voucher_without_quota_change(token_client, organizer, event):
with scopes_disabled():
shirt = event.items.create(name='Shirt', default_price=23) shirt = event.items.create(name='Shirt', default_price=23)
vs = shirt.variations.create(value='S') vs = shirt.variations.create(value='S')
vm = shirt.variations.create(value='M') vm = shirt.variations.create(value='M')
@@ -739,6 +762,7 @@ def test_change_variation_of_blocking_voucher_without_quota_change(token_client,
@pytest.mark.django_db @pytest.mark.django_db
def test_change_variation_of_blocking_voucher_quota_full(token_client, organizer, event): def test_change_variation_of_blocking_voucher_quota_full(token_client, organizer, event):
with scopes_disabled():
shirt = event.items.create(name='Shirt', default_price=23) shirt = event.items.create(name='Shirt', default_price=23)
vs = shirt.variations.create(value='S') vs = shirt.variations.create(value='S')
vm = shirt.variations.create(value='M') vm = shirt.variations.create(value='M')
@@ -758,6 +782,7 @@ def test_change_variation_of_blocking_voucher_quota_full(token_client, organizer
@pytest.mark.django_db @pytest.mark.django_db
def test_change_quota_of_blocking_voucher_quota_free(token_client, organizer, event): def test_change_quota_of_blocking_voucher_quota_free(token_client, organizer, event):
with scopes_disabled():
qs = event.quotas.create(name='S', size=2) qs = event.quotas.create(name='S', size=2)
qm = event.quotas.create(name='M', size=2) qm = event.quotas.create(name='M', size=2)
v = event.vouchers.create(quota=qs, block_quota=True) v = event.vouchers.create(quota=qs, block_quota=True)
@@ -772,6 +797,7 @@ def test_change_quota_of_blocking_voucher_quota_free(token_client, organizer, ev
@pytest.mark.django_db @pytest.mark.django_db
def test_change_quota_of_blocking_voucher_quota_full(token_client, organizer, event): def test_change_quota_of_blocking_voucher_quota_full(token_client, organizer, event):
with scopes_disabled():
qs = event.quotas.create(name='S', size=2) qs = event.quotas.create(name='S', size=2)
qm = event.quotas.create(name='M', size=0) qm = event.quotas.create(name='M', size=0)
v = event.vouchers.create(quota=qs, block_quota=True) v = event.vouchers.create(quota=qs, block_quota=True)
@@ -786,6 +812,7 @@ def test_change_quota_of_blocking_voucher_quota_full(token_client, organizer, ev
@pytest.mark.django_db @pytest.mark.django_db
def test_change_item_of_blocking_voucher_without_quota_change(token_client, organizer, event, item, quota): def test_change_item_of_blocking_voucher_without_quota_change(token_client, organizer, event, item, quota):
with scopes_disabled():
quota.size = 0 quota.size = 0
quota.save() quota.save()
ticket2 = event.items.create(name='Standard Ticket', default_price=23) ticket2 = event.items.create(name='Standard Ticket', default_price=23)
@@ -802,6 +829,7 @@ def test_change_item_of_blocking_voucher_without_quota_change(token_client, orga
@pytest.mark.django_db @pytest.mark.django_db
def test_change_code_to_duplicate(token_client, organizer, event, item, quota): def test_change_code_to_duplicate(token_client, organizer, event, item, quota):
with scopes_disabled():
v1 = event.vouchers.create(quota=quota) v1 = event.vouchers.create(quota=quota)
v2 = event.vouchers.create(quota=quota) v2 = event.vouchers.create(quota=quota)
change_voucher( change_voucher(
@@ -815,6 +843,7 @@ def test_change_code_to_duplicate(token_client, organizer, event, item, quota):
@pytest.mark.django_db @pytest.mark.django_db
def test_change_subevent_blocking_quota_free(token_client, organizer, event, item, quota, subevent): def test_change_subevent_blocking_quota_free(token_client, organizer, event, item, quota, subevent):
with scopes_disabled():
quota.subevent = subevent quota.subevent = subevent
quota.save() quota.save()
se2 = event.subevents.create(name="Bar", date_from=now()) se2 = event.subevents.create(name="Bar", date_from=now())
@@ -833,6 +862,7 @@ def test_change_subevent_blocking_quota_free(token_client, organizer, event, ite
@pytest.mark.django_db @pytest.mark.django_db
def test_change_subevent_blocking_quota_full(token_client, organizer, event, item, quota, subevent): def test_change_subevent_blocking_quota_full(token_client, organizer, event, item, quota, subevent):
with scopes_disabled():
quota.subevent = subevent quota.subevent = subevent
quota.save() quota.save()
se2 = event.subevents.create(name="Bar", date_from=now()) se2 = event.subevents.create(name="Bar", date_from=now())
@@ -851,26 +881,31 @@ def test_change_subevent_blocking_quota_full(token_client, organizer, event, ite
@pytest.mark.django_db @pytest.mark.django_db
def test_delete_voucher(token_client, organizer, event, quota): def test_delete_voucher(token_client, organizer, event, quota):
with scopes_disabled():
v = event.vouchers.create(quota=quota) v = event.vouchers.create(quota=quota)
resp = token_client.delete( resp = token_client.delete(
'/api/v1/organizers/{}/events/{}/vouchers/{}/'.format(organizer.slug, event.slug, v.pk), '/api/v1/organizers/{}/events/{}/vouchers/{}/'.format(organizer.slug, event.slug, v.pk),
) )
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not event.vouchers.filter(pk=v.id).exists() assert not event.vouchers.filter(pk=v.id).exists()
@pytest.mark.django_db @pytest.mark.django_db
def test_delete_voucher_redeemed(token_client, organizer, event, quota): def test_delete_voucher_redeemed(token_client, organizer, event, quota):
with scopes_disabled():
v = event.vouchers.create(quota=quota, redeemed=1) v = event.vouchers.create(quota=quota, redeemed=1)
resp = token_client.delete( resp = token_client.delete(
'/api/v1/organizers/{}/events/{}/vouchers/{}/'.format(organizer.slug, event.slug, v.pk), '/api/v1/organizers/{}/events/{}/vouchers/{}/'.format(organizer.slug, event.slug, v.pk),
) )
assert resp.status_code == 403 assert resp.status_code == 403
with scopes_disabled():
assert event.vouchers.filter(pk=v.id).exists() assert event.vouchers.filter(pk=v.id).exists()
@pytest.mark.django_db @pytest.mark.django_db
def test_redeemed_is_not_writable(token_client, organizer, event, item): def test_redeemed_is_not_writable(token_client, organizer, event, item):
with scopes_disabled():
v = event.vouchers.create(item=item) v = event.vouchers.create(item=item)
change_voucher( change_voucher(
token_client, organizer, event, v, token_client, organizer, event, v,
@@ -919,6 +954,7 @@ def test_create_multiple_vouchers(token_client, organizer, event, item):
], format='json' ], format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
assert Voucher.objects.count() == 2 assert Voucher.objects.count() == 2
assert resp.data[0]['code'] == 'ABCDEFGHI' assert resp.data[0]['code'] == 'ABCDEFGHI'
v1 = Voucher.objects.get(code='ABCDEFGHI') v1 = Voucher.objects.get(code='ABCDEFGHI')
@@ -967,6 +1003,7 @@ def test_create_multiple_vouchers_one_invalid(token_client, organizer, event, it
) )
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data == [{}, {'code': ['Ensure this field has at least 5 characters.']}] assert resp.data == [{}, {'code': ['Ensure this field has at least 5 characters.']}]
with scopes_disabled():
assert Voucher.objects.count() == 0 assert Voucher.objects.count() == 0
@@ -1009,4 +1046,5 @@ def test_create_multiple_vouchers_duplicate_code(token_client, organizer, event,
) )
assert resp.status_code == 400 assert resp.status_code == 400
assert resp.data == [{}, {'code': ['Duplicate voucher code in request.']}] assert resp.data == [{}, {'code': ['Duplicate voucher code in request.']}]
with scopes_disabled():
assert Voucher.objects.count() == 0 assert Voucher.objects.count() == 0

View File

@@ -3,6 +3,7 @@ import datetime
from unittest import mock from unittest import mock
import pytest import pytest
from django_scopes import scopes_disabled
from pytz import UTC from pytz import UTC
from pretix.base.models import WaitingListEntry from pretix.base.models import WaitingListEntry
@@ -44,6 +45,7 @@ TEST_WLE_RES = {
@pytest.mark.django_db @pytest.mark.django_db
def test_wle_list(token_client, organizer, event, wle, item, subevent): def test_wle_list(token_client, organizer, event, wle, item, subevent):
with scopes_disabled():
var = item.variations.create(value="Children") var = item.variations.create(value="Children")
var2 = item.variations.create(value="Children") var2 = item.variations.create(value="Children")
res = dict(TEST_WLE_RES) res = dict(TEST_WLE_RES)
@@ -97,6 +99,7 @@ def test_wle_list(token_client, organizer, event, wle, item, subevent):
'/api/v1/organizers/{}/events/{}/waitinglistentries/?has_voucher=true'.format(organizer.slug, event.slug)) '/api/v1/organizers/{}/events/{}/waitinglistentries/?has_voucher=true'.format(organizer.slug, event.slug))
assert [] == resp.data['results'] assert [] == resp.data['results']
with scopes_disabled():
v = event.vouchers.create(item=item, price_mode='set', value=12, tag='Foo') v = event.vouchers.create(item=item, price_mode='set', value=12, tag='Foo')
wle.voucher = v wle.voucher = v
wle.save() wle.save()
@@ -112,6 +115,7 @@ def test_wle_list(token_client, organizer, event, wle, item, subevent):
resp = token_client.get( resp = token_client.get(
'/api/v1/organizers/{}/events/{}/waitinglistentries/?subevent={}'.format(organizer.slug, event.slug, subevent.pk)) '/api/v1/organizers/{}/events/{}/waitinglistentries/?subevent={}'.format(organizer.slug, event.slug, subevent.pk))
assert [res] == resp.data['results'] assert [res] == resp.data['results']
with scopes_disabled():
se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC)) se2 = event.subevents.create(name="Foobar", date_from=datetime.datetime(2017, 12, 27, 10, 0, 0, tzinfo=UTC))
resp = token_client.get( resp = token_client.get(
'/api/v1/organizers/{}/events/{}/waitinglistentries/?subevent={}'.format(organizer.slug, event.slug, '/api/v1/organizers/{}/events/{}/waitinglistentries/?subevent={}'.format(organizer.slug, event.slug,
@@ -136,11 +140,13 @@ def test_delete_wle(token_client, organizer, event, wle, item):
'/api/v1/organizers/{}/events/{}/waitinglistentries/{}/'.format(organizer.slug, event.slug, wle.pk), '/api/v1/organizers/{}/events/{}/waitinglistentries/{}/'.format(organizer.slug, event.slug, wle.pk),
) )
assert resp.status_code == 204 assert resp.status_code == 204
with scopes_disabled():
assert not event.waitinglistentries.filter(pk=wle.id).exists() assert not event.waitinglistentries.filter(pk=wle.id).exists()
@pytest.mark.django_db @pytest.mark.django_db
def test_delete_wle_assigned(token_client, organizer, event, wle, item): def test_delete_wle_assigned(token_client, organizer, event, wle, item):
with scopes_disabled():
v = event.vouchers.create(item=item, price_mode='set', value=12, tag='Foo') v = event.vouchers.create(item=item, price_mode='set', value=12, tag='Foo')
wle.voucher = v wle.voucher = v
wle.save() wle.save()
@@ -148,6 +154,7 @@ def test_delete_wle_assigned(token_client, organizer, event, wle, item):
'/api/v1/organizers/{}/events/{}/waitinglistentries/{}/'.format(organizer.slug, event.slug, wle.pk), '/api/v1/organizers/{}/events/{}/waitinglistentries/{}/'.format(organizer.slug, event.slug, wle.pk),
) )
assert resp.status_code == 403 assert resp.status_code == 403
with scopes_disabled():
assert event.waitinglistentries.filter(pk=wle.id).exists() assert event.waitinglistentries.filter(pk=wle.id).exists()
@@ -159,8 +166,8 @@ def create_wle(token_client, organizer, event, data, expected_failure=False):
if expected_failure: if expected_failure:
assert resp.status_code == 400 assert resp.status_code == 400
else: else:
print(resp.data)
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
return WaitingListEntry.objects.get(pk=resp.data['id']) return WaitingListEntry.objects.get(pk=resp.data['id'])
@@ -205,6 +212,7 @@ def test_wle_require_fields(token_client, organizer, event, item, quota):
}, },
expected_failure=True expected_failure=True
) )
with scopes_disabled():
v = item.variations.create(value="S") v = item.variations.create(value="S")
create_wle( create_wle(
token_client, organizer, event, token_client, organizer, event,
@@ -300,6 +308,7 @@ def test_wle_change_email(token_client, organizer, event, item, wle, quota):
@pytest.mark.django_db @pytest.mark.django_db
def test_wle_change_assigned(token_client, organizer, event, item, wle, quota): def test_wle_change_assigned(token_client, organizer, event, item, wle, quota):
with scopes_disabled():
v = event.vouchers.create(item=item, price_mode='set', value=12, tag='Foo') v = event.vouchers.create(item=item, price_mode='set', value=12, tag='Foo')
wle.voucher = v wle.voucher = v
wle.save() wle.save()
@@ -315,6 +324,7 @@ def test_wle_change_assigned(token_client, organizer, event, item, wle, quota):
@pytest.mark.django_db @pytest.mark.django_db
def test_wle_change_to_available_item(token_client, organizer, event, item, wle, quota): def test_wle_change_to_available_item(token_client, organizer, event, item, wle, quota):
with scopes_disabled():
i = event.items.create(name="Budget Ticket", default_price=23) i = event.items.create(name="Budget Ticket", default_price=23)
q = event.quotas.create(name="Budget Ticket", size=1) q = event.quotas.create(name="Budget Ticket", size=1)
q.items.add(i) q.items.add(i)
@@ -330,6 +340,7 @@ def test_wle_change_to_available_item(token_client, organizer, event, item, wle,
@pytest.mark.django_db @pytest.mark.django_db
def test_wle_change_to_unavailable_item(token_client, organizer, event, item, wle, quota): def test_wle_change_to_unavailable_item(token_client, organizer, event, item, wle, quota):
with scopes_disabled():
i = event.items.create(name="Budget Ticket", default_price=23) i = event.items.create(name="Budget Ticket", default_price=23)
v = i.variations.create(value="S") v = i.variations.create(value="S")
q = event.quotas.create(name="Budget Ticket", size=0) q = event.quotas.create(name="Budget Ticket", size=0)
@@ -349,6 +360,7 @@ def test_wle_change_to_unavailable_item(token_client, organizer, event, item, wl
@pytest.mark.django_db @pytest.mark.django_db
def test_wle_change_to_unavailable_item_missing_var(token_client, organizer, event, item, wle, quota): def test_wle_change_to_unavailable_item_missing_var(token_client, organizer, event, item, wle, quota):
with scopes_disabled():
i = event.items.create(name="Budget Ticket", default_price=23) i = event.items.create(name="Budget Ticket", default_price=23)
v = i.variations.create(value="S") v = i.variations.create(value="S")
q = event.quotas.create(name="Budget Ticket", size=0) q = event.quotas.create(name="Budget Ticket", size=0)

View File

@@ -1,6 +1,7 @@
import copy import copy
import pytest import pytest
from django_scopes import scopes_disabled
from pretix.api.models import WebHook from pretix.api.models import WebHook
@@ -64,6 +65,7 @@ def test_hook_create(token_client, organizer, event):
format='json' format='json'
) )
assert resp.status_code == 201 assert resp.status_code == 201
with scopes_disabled():
cl = WebHook.objects.get(pk=resp.data['id']) cl = WebHook.objects.get(pk=resp.data['id'])
assert cl.target_url == "https://google.com" assert cl.target_url == "https://google.com"
assert cl.limit_events.count() == 1 assert cl.limit_events.count() == 1
@@ -136,6 +138,7 @@ def test_hook_patch_url(token_client, organizer, event, webhook):
assert resp.status_code == 200 assert resp.status_code == 200
webhook.refresh_from_db() webhook.refresh_from_db()
assert webhook.target_url == "https://pretix.eu" assert webhook.target_url == "https://pretix.eu"
with scopes_disabled():
assert webhook.limit_events.count() == 1 assert webhook.limit_events.count() == 1
assert set(webhook.listeners.values_list('action_type', flat=True)) == {'pretix.event.order.placed', assert set(webhook.listeners.values_list('action_type', flat=True)) == {'pretix.event.order.placed',
'pretix.event.order.paid'} 'pretix.event.order.paid'}
@@ -153,6 +156,7 @@ def test_hook_patch_types(token_client, organizer, event, webhook):
) )
assert resp.status_code == 200 assert resp.status_code == 200
webhook.refresh_from_db() webhook.refresh_from_db()
with scopes_disabled():
assert webhook.limit_events.count() == 1 assert webhook.limit_events.count() == 1
assert set(webhook.listeners.values_list('action_type', flat=True)) == {'pretix.event.order.placed', assert set(webhook.listeners.values_list('action_type', flat=True)) == {'pretix.event.order.placed',
'pretix.event.order.canceled'} 'pretix.event.order.canceled'}

View File

@@ -6,13 +6,13 @@ class SoupTest(TestCase):
def get_doc(self, *args, **kwargs): def get_doc(self, *args, **kwargs):
response = self.client.get(*args, **kwargs) response = self.client.get(*args, **kwargs)
return BeautifulSoup(response.rendered_content, "lxml") return BeautifulSoup(response.render().content, "lxml")
def post_doc(self, *args, **kwargs): def post_doc(self, *args, **kwargs):
kwargs['follow'] = True kwargs['follow'] = True
response = self.client.post(*args, **kwargs) response = self.client.post(*args, **kwargs)
try: try:
return BeautifulSoup(response.rendered_content, "lxml") return BeautifulSoup(response.render().content, "lxml")
except AttributeError: except AttributeError:
return BeautifulSoup(response.content, "lxml") return BeautifulSoup(response.content, "lxml")

View File

@@ -7,6 +7,7 @@ from django.core.serializers.json import DjangoJSONEncoder
from django.db import DatabaseError, transaction from django.db import DatabaseError, transaction
from django.utils.timezone import now from django.utils.timezone import now
from django_countries.fields import Country from django_countries.fields import Country
from django_scopes import scope, scopes_disabled
from pretix.base.models import ( from pretix.base.models import (
Event, Invoice, InvoiceAddress, Item, ItemVariation, Order, OrderPosition, Event, Invoice, InvoiceAddress, Item, ItemVariation, Order, OrderPosition,
@@ -24,6 +25,7 @@ from pretix.base.settings import GlobalSettingsObject
@pytest.fixture @pytest.fixture
def env(): def env():
o = Organizer.objects.create(name='Dummy', slug='dummy') o = Organizer.objects.create(name='Dummy', slug='dummy')
with scope(organizer=o):
event = Event.objects.create( event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy', organizer=o, name='Dummy', slug='dummy',
date_from=now(), plugins='pretix.plugins.banktransfer' date_from=now(), plugins='pretix.plugins.banktransfer'
@@ -82,13 +84,14 @@ def env():
"GBP": "0.89350", "GBP": "0.89350",
"SEK": "9.5883" "SEK": "9.5883"
}, cls=DjangoJSONEncoder) }, cls=DjangoJSONEncoder)
return event, o yield event, o
@pytest.mark.django_db @pytest.mark.django_db
def test_locale_setting(env): def test_locale_setting(env):
event, order = env event, order = env
event.settings.set('invoice_language', 'de') event.settings.set('invoice_language', 'de')
with scopes_disabled():
inv = generate_invoice(order) inv = generate_invoice(order)
assert inv.locale == 'de' assert inv.locale == 'de'

View File

@@ -2,6 +2,7 @@ import time
import pytest import pytest
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scope, scopes_disabled
from pretix.base.models import Event, Organizer from pretix.base.models import Event, Organizer
from pretix.base.services import locking from pretix.base.services import locking
@@ -17,13 +18,15 @@ def event():
organizer=o, name='Dummy', slug='dummy', organizer=o, name='Dummy', slug='dummy',
date_from=now() date_from=now()
) )
return event with scope(organizer=o):
yield event
@pytest.mark.django_db @pytest.mark.django_db
def test_locking_exclusive(event): def test_locking_exclusive(event):
with event.lock(): with event.lock():
with pytest.raises(LockTimeoutException): with pytest.raises(LockTimeoutException):
with scopes_disabled():
ev = Event.objects.get(id=event.id) ev = Event.objects.get(id=event.id)
with ev.lock(): with ev.lock():
pass pass

View File

@@ -5,6 +5,7 @@ from django.conf import settings
from django.core import mail as djmail from django.core import mail as djmail
from django.utils.timezone import now from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django_scopes import scope
from pretix.base.models import Event, Organizer, User from pretix.base.models import Event, Organizer, User
from pretix.base.services.mail import mail from pretix.base.services.mail import mail
@@ -20,7 +21,8 @@ def env():
user = User.objects.create_user('dummy@dummy.dummy', 'dummy') user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
user.email = 'dummy@dummy.dummy' user.email = 'dummy@dummy.dummy'
user.save() user.save()
return event, user, o with scope(organizer=o):
yield event, user, o
@pytest.mark.django_db @pytest.mark.django_db

View File

@@ -12,6 +12,7 @@ from django.core.files.storage import default_storage
from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase from django.test import TestCase
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scope
from pretix.base.i18n import language from pretix.base.i18n import language
from pretix.base.models import ( from pretix.base.models import (
@@ -25,6 +26,7 @@ from pretix.base.models.items import (
) )
from pretix.base.reldate import RelativeDate, RelativeDateWrapper from pretix.base.reldate import RelativeDate, RelativeDateWrapper
from pretix.base.services.orders import OrderError, cancel_order, perform_order from pretix.base.services.orders import OrderError, cancel_order, perform_order
from pretix.testutils.scope import classscope
class UserTestCase(TestCase): class UserTestCase(TestCase):
@@ -44,9 +46,9 @@ class UserTestCase(TestCase):
class BaseQuotaTestCase(TestCase): class BaseQuotaTestCase(TestCase):
def setUp(self): def setUp(self):
o = Organizer.objects.create(name='Dummy', slug='dummy') self.o = Organizer.objects.create(name='Dummy', slug='dummy')
self.event = Event.objects.create( self.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy', organizer=self.o, name='Dummy', slug='dummy',
date_from=now(), plugins='tests.testdummy' date_from=now(), plugins='tests.testdummy'
) )
self.quota = Quota.objects.create(name="Test", size=2, event=self.event) self.quota = Quota.objects.create(name="Test", size=2, event=self.event)
@@ -60,6 +62,7 @@ class BaseQuotaTestCase(TestCase):
class QuotaTestCase(BaseQuotaTestCase): class QuotaTestCase(BaseQuotaTestCase):
@classscope(attr='o')
def test_available(self): def test_available(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 2)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 2))
@@ -72,6 +75,7 @@ class QuotaTestCase(BaseQuotaTestCase):
pass pass
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 2)) self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 2))
@classscope(attr='o')
def test_sold_out(self): def test_sold_out(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
order = Order.objects.create(event=self.event, status=Order.STATUS_PAID, order = Order.objects.create(event=self.event, status=Order.STATUS_PAID,
@@ -93,6 +97,7 @@ class QuotaTestCase(BaseQuotaTestCase):
OrderPosition.objects.create(order=order, item=self.item2, variation=self.var1, price=2) OrderPosition.objects.create(order=order, item=self.item2, variation=self.var1, price=2)
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_GONE, 0)) self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_GONE, 0))
@classscope(attr='o')
def test_ordered(self): def test_ordered(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
order = Order.objects.create(event=self.event, status=Order.STATUS_PAID, order = Order.objects.create(event=self.event, status=Order.STATUS_PAID,
@@ -115,6 +120,7 @@ class QuotaTestCase(BaseQuotaTestCase):
order.save() order.save()
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_ordered_multi_quota(self): def test_ordered_multi_quota(self):
quota2 = Quota.objects.create(name="Test", size=2, event=self.event) quota2 = Quota.objects.create(name="Test", size=2, event=self.event)
quota2.items.add(self.item2) quota2.items.add(self.item2)
@@ -129,6 +135,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(quota2.availability(), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(quota2.availability(), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_position_canceled(self): def test_position_canceled(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
self.quota.size = 3 self.quota.size = 3
@@ -142,6 +149,7 @@ class QuotaTestCase(BaseQuotaTestCase):
op.save() op.save()
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 3)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 3))
@classscope(attr='o')
def test_reserved(self): def test_reserved(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
self.quota.size = 3 self.quota.size = 3
@@ -172,6 +180,7 @@ class QuotaTestCase(BaseQuotaTestCase):
price=2, expires=now() + timedelta(days=3)) price=2, expires=now() + timedelta(days=3))
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_RESERVED, 0)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_RESERVED, 0))
@classscope(attr='o')
def test_multiple(self): def test_multiple(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 2)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 2))
@@ -184,6 +193,7 @@ class QuotaTestCase(BaseQuotaTestCase):
quota2.save() quota2.save()
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_GONE, 0)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_GONE, 0))
@classscope(attr='o')
def test_ignore_quotas(self): def test_ignore_quotas(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
quota2 = Quota.objects.create(event=self.event, name="Test 2", size=0) quota2 = Quota.objects.create(event=self.event, name="Test 2", size=0)
@@ -193,6 +203,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.item1.check_quotas(ignored_quotas=[self.quota, quota2]), self.assertEqual(self.item1.check_quotas(ignored_quotas=[self.quota, quota2]),
(Quota.AVAILABILITY_OK, sys.maxsize)) (Quota.AVAILABILITY_OK, sys.maxsize))
@classscope(attr='o')
def test_unlimited(self): def test_unlimited(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
order = Order.objects.create(event=self.event, status=Order.STATUS_PAID, order = Order.objects.create(event=self.event, status=Order.STATUS_PAID,
@@ -206,6 +217,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.quota.save() self.quota.save()
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, None)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, None))
@classscope(attr='o')
def test_voucher_product(self): def test_voucher_product(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
self.quota.size = 1 self.quota.size = 1
@@ -219,6 +231,7 @@ class QuotaTestCase(BaseQuotaTestCase):
v.save() v.save()
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0))
@classscope(attr='o')
def test_voucher_variation(self): def test_voucher_variation(self):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = 1 self.quota.size = 1
@@ -232,6 +245,7 @@ class QuotaTestCase(BaseQuotaTestCase):
v.save() v.save()
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0)) self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0))
@classscope(attr='o')
def test_voucher_quota(self): def test_voucher_quota(self):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = 1 self.quota.size = 1
@@ -245,6 +259,7 @@ class QuotaTestCase(BaseQuotaTestCase):
v.save() v.save()
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0)) self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0))
@classscope(attr='o')
def test_voucher_quota_multiuse(self): def test_voucher_quota_multiuse(self):
self.quota.size = 5 self.quota.size = 5
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
@@ -254,12 +269,14 @@ class QuotaTestCase(BaseQuotaTestCase):
Voucher.objects.create(quota=self.quota, event=self.event, block_quota=True, max_usages=2) Voucher.objects.create(quota=self.quota, event=self.event, block_quota=True, max_usages=2)
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0)) self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0))
@classscope(attr='o')
def test_voucher_multiuse_count_overredeemed(self): def test_voucher_multiuse_count_overredeemed(self):
if 'sqlite' not in settings.DATABASES['default']['ENGINE']: if 'sqlite' not in settings.DATABASES['default']['ENGINE']:
pytest.xfail('This should raise a type error on most databases') pytest.xfail('This should raise a type error on most databases')
Voucher.objects.create(quota=self.quota, event=self.event, block_quota=True, max_usages=2, redeemed=4) Voucher.objects.create(quota=self.quota, event=self.event, block_quota=True, max_usages=2, redeemed=4)
self.assertEqual(self.quota.count_blocking_vouchers(), 0) self.assertEqual(self.quota.count_blocking_vouchers(), 0)
@classscope(attr='o')
def test_voucher_quota_multiuse_multiproduct(self): def test_voucher_quota_multiuse_multiproduct(self):
q2 = Quota.objects.create(event=self.event, name="foo", size=10) q2 = Quota.objects.create(event=self.event, name="foo", size=10)
q2.items.add(self.item1) q2.items.add(self.item1)
@@ -278,6 +295,7 @@ class QuotaTestCase(BaseQuotaTestCase):
redeemed=2) redeemed=2)
self.assertEqual(self.quota.count_blocking_vouchers(), 9) self.assertEqual(self.quota.count_blocking_vouchers(), 9)
@classscope(attr='o')
def test_voucher_quota_expiring_soon(self): def test_voucher_quota_expiring_soon(self):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = 1 self.quota.size = 1
@@ -286,6 +304,7 @@ class QuotaTestCase(BaseQuotaTestCase):
block_quota=True) block_quota=True)
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0)) self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0))
@classscope(attr='o')
def test_voucher_quota_expired(self): def test_voucher_quota_expired(self):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = 1 self.quota.size = 1
@@ -295,6 +314,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
self.assertFalse(v.is_active()) self.assertFalse(v.is_active())
@classscope(attr='o')
def test_blocking_voucher_in_cart(self): def test_blocking_voucher_in_cart(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
v = Voucher.objects.create(quota=self.quota, event=self.event, valid_until=now() + timedelta(days=5), v = Voucher.objects.create(quota=self.quota, event=self.event, valid_until=now() + timedelta(days=5),
@@ -306,6 +326,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.quota.count_in_cart(), 0) self.assertEqual(self.quota.count_in_cart(), 0)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_blocking_voucher_in_cart_inifinitely_valid(self): def test_blocking_voucher_in_cart_inifinitely_valid(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
v = Voucher.objects.create(quota=self.quota, event=self.event, block_quota=True) v = Voucher.objects.create(quota=self.quota, event=self.event, block_quota=True)
@@ -315,6 +336,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.quota.count_in_cart(), 0) self.assertEqual(self.quota.count_in_cart(), 0)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_blocking_expired_voucher_in_cart(self): def test_blocking_expired_voucher_in_cart(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
v = Voucher.objects.create(quota=self.quota, event=self.event, valid_until=now() - timedelta(days=5), v = Voucher.objects.create(quota=self.quota, event=self.event, valid_until=now() - timedelta(days=5),
@@ -325,6 +347,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.quota.count_in_cart(), 1) self.assertEqual(self.quota.count_in_cart(), 1)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_nonblocking_voucher_in_cart(self): def test_nonblocking_voucher_in_cart(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
v = Voucher.objects.create(quota=self.quota, event=self.event) v = Voucher.objects.create(quota=self.quota, event=self.event)
@@ -334,6 +357,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.quota.count_in_cart(), 1) self.assertEqual(self.quota.count_in_cart(), 1)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_waitinglist_item_active(self): def test_waitinglist_item_active(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
self.quota.size = 1 self.quota.size = 1
@@ -344,6 +368,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0)) self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0))
self.assertEqual(self.item1.check_quotas(count_waitinglist=False), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.item1.check_quotas(count_waitinglist=False), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_waitinglist_variation_active(self): def test_waitinglist_variation_active(self):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = 1 self.quota.size = 1
@@ -354,6 +379,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0)) self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0))
self.assertEqual(self.var1.check_quotas(count_waitinglist=False), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.var1.check_quotas(count_waitinglist=False), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_waitinglist_variation_fulfilled(self): def test_waitinglist_variation_fulfilled(self):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = 1 self.quota.size = 1
@@ -365,6 +391,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
self.assertEqual(self.var1.check_quotas(count_waitinglist=False), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.var1.check_quotas(count_waitinglist=False), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_waitinglist_variation_other(self): def test_waitinglist_variation_other(self):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = 1 self.quota.size = 1
@@ -375,6 +402,7 @@ class QuotaTestCase(BaseQuotaTestCase):
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
self.assertEqual(self.var1.check_quotas(count_waitinglist=False), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.var1.check_quotas(count_waitinglist=False), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_quota_cache(self): def test_quota_cache(self):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = 1 self.quota.size = 1
@@ -396,6 +424,7 @@ class QuotaTestCase(BaseQuotaTestCase):
with self.assertNumQueries(1): with self.assertNumQueries(1):
self.assertEqual(self.var1.check_quotas(_cache=cache, count_waitinglist=False), (Quota.AVAILABILITY_OK, 1)) self.assertEqual(self.var1.check_quotas(_cache=cache, count_waitinglist=False), (Quota.AVAILABILITY_OK, 1))
@classscope(attr='o')
def test_subevent_isolation(self): def test_subevent_isolation(self):
self.event.has_subevents = True self.event.has_subevents = True
self.event.save() self.event.save()
@@ -480,17 +509,21 @@ class BundleQuotaTestCase(BaseQuotaTestCase):
count=1 count=1
) )
@classscope(attr='o')
def test_only_respect_with_flag(self): def test_only_respect_with_flag(self):
assert self.item1.check_quotas() == (Quota.AVAILABILITY_OK, 5) assert self.item1.check_quotas() == (Quota.AVAILABILITY_OK, 5)
@classscope(attr='o')
def test_do_not_exceed(self): def test_do_not_exceed(self):
assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 5) assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 5)
@classscope(attr='o')
def test_limited_by_bundled_quita(self): def test_limited_by_bundled_quita(self):
self.transquota.size = 3 self.transquota.size = 3
self.transquota.save() self.transquota.save()
assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 3) assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 3)
@classscope(attr='o')
def test_multiple_bundles(self): def test_multiple_bundles(self):
ItemBundle.objects.create( ItemBundle.objects.create(
base_item=self.item1, base_item=self.item1,
@@ -502,6 +535,7 @@ class BundleQuotaTestCase(BaseQuotaTestCase):
self.transquota.save() self.transquota.save()
assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 1) assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 1)
@classscope(attr='o')
def test_bundle_count(self): def test_bundle_count(self):
self.bundle1.count = 2 self.bundle1.count = 2
self.bundle1.save() self.bundle1.save()
@@ -509,29 +543,35 @@ class BundleQuotaTestCase(BaseQuotaTestCase):
self.transquota.save() self.transquota.save()
assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 1) assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 1)
@classscope(attr='o')
def test_bundled_unlimited(self): def test_bundled_unlimited(self):
self.transquota.size = None self.transquota.size = None
self.transquota.save() self.transquota.save()
assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 5) assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 5)
assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 5) assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 5)
@classscope(attr='o')
def test_item_unlimited(self): def test_item_unlimited(self):
self.quota.size = None self.quota.size = None
self.quota.save() self.quota.save()
assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 10) assert self.item1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 10)
assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 10) assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 10)
@classscope(attr='o')
def test_var_only_respect_with_flag(self): def test_var_only_respect_with_flag(self):
assert self.var1.check_quotas() == (Quota.AVAILABILITY_OK, 5) assert self.var1.check_quotas() == (Quota.AVAILABILITY_OK, 5)
@classscope(attr='o')
def test_var_do_not_exceed(self): def test_var_do_not_exceed(self):
assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 5) assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 5)
@classscope(attr='o')
def test_var_limited_by_bundled_quita(self): def test_var_limited_by_bundled_quita(self):
self.transquota.size = 3 self.transquota.size = 3
self.transquota.save() self.transquota.save()
assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 3) assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 3)
@classscope(attr='o')
def test_var_multiple_bundles(self): def test_var_multiple_bundles(self):
ItemBundle.objects.create( ItemBundle.objects.create(
base_item=self.item2, base_item=self.item2,
@@ -543,6 +583,7 @@ class BundleQuotaTestCase(BaseQuotaTestCase):
self.transquota.save() self.transquota.save()
assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 1) assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 1)
@classscope(attr='o')
def test_var_bundle_count(self): def test_var_bundle_count(self):
self.bundle2.count = 2 self.bundle2.count = 2
self.bundle2.save() self.bundle2.save()
@@ -550,6 +591,7 @@ class BundleQuotaTestCase(BaseQuotaTestCase):
self.transquota.save() self.transquota.save()
assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 1) assert self.var1.check_quotas(include_bundled=True) == (Quota.AVAILABILITY_OK, 1)
@classscope(attr='o')
def test_bundled_variation(self): def test_bundled_variation(self):
v = self.trans.variations.create(value="foo", default_price=4) v = self.trans.variations.create(value="foo", default_price=4)
self.transquota.variations.add(v) self.transquota.variations.add(v)
@@ -562,6 +604,7 @@ class BundleQuotaTestCase(BaseQuotaTestCase):
class WaitingListTestCase(BaseQuotaTestCase): class WaitingListTestCase(BaseQuotaTestCase):
@classscope(attr='o')
def test_duplicate(self): def test_duplicate(self):
w1 = WaitingListEntry.objects.create( w1 = WaitingListEntry.objects.create(
event=self.event, item=self.item2, variation=self.var1, email='foo@bar.com' event=self.event, item=self.item2, variation=self.var1, email='foo@bar.com'
@@ -573,6 +616,7 @@ class WaitingListTestCase(BaseQuotaTestCase):
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
w2.clean() w2.clean()
@classscope(attr='o')
def test_duplicate_of_successful(self): def test_duplicate_of_successful(self):
v = Voucher.objects.create(quota=self.quota, event=self.event, block_quota=True, redeemed=1) v = Voucher.objects.create(quota=self.quota, event=self.event, block_quota=True, redeemed=1)
w1 = WaitingListEntry.objects.create( w1 = WaitingListEntry.objects.create(
@@ -585,6 +629,7 @@ class WaitingListTestCase(BaseQuotaTestCase):
) )
w2.clean() w2.clean()
@classscope(attr='o')
def test_missing_variation(self): def test_missing_variation(self):
w2 = WaitingListEntry( w2 = WaitingListEntry(
event=self.event, item=self.item2, email='foo@bar.com' event=self.event, item=self.item2, email='foo@bar.com'
@@ -595,6 +640,7 @@ class WaitingListTestCase(BaseQuotaTestCase):
class VoucherTestCase(BaseQuotaTestCase): class VoucherTestCase(BaseQuotaTestCase):
@classscope(attr='o')
def test_voucher_reuse(self): def test_voucher_reuse(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
v = Voucher.objects.create(quota=self.quota, event=self.event, valid_until=now() + timedelta(days=5)) v = Voucher.objects.create(quota=self.quota, event=self.event, valid_until=now() + timedelta(days=5))
@@ -631,18 +677,21 @@ class VoucherTestCase(BaseQuotaTestCase):
expires=now() + timedelta(days=3), voucher=v) expires=now() + timedelta(days=3), voucher=v)
perform_order(event=self.event.id, payment_provider='free', positions=[cart.id]) perform_order(event=self.event.id, payment_provider='free', positions=[cart.id])
@classscope(attr='o')
def test_voucher_applicability_quota(self): def test_voucher_applicability_quota(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
v = Voucher.objects.create(quota=self.quota, event=self.event) v = Voucher.objects.create(quota=self.quota, event=self.event)
self.assertTrue(v.applies_to(self.item1)) self.assertTrue(v.applies_to(self.item1))
self.assertFalse(v.applies_to(self.item2)) self.assertFalse(v.applies_to(self.item2))
@classscope(attr='o')
def test_voucher_applicability_item(self): def test_voucher_applicability_item(self):
v = Voucher.objects.create(item=self.var1.item, event=self.event) v = Voucher.objects.create(item=self.var1.item, event=self.event)
self.assertFalse(v.applies_to(self.item1)) self.assertFalse(v.applies_to(self.item1))
self.assertTrue(v.applies_to(self.var1.item)) self.assertTrue(v.applies_to(self.var1.item))
self.assertTrue(v.applies_to(self.var1.item, self.var1)) self.assertTrue(v.applies_to(self.var1.item, self.var1))
@classscope(attr='o')
def test_voucher_applicability_variation(self): def test_voucher_applicability_variation(self):
v = Voucher.objects.create(item=self.var1.item, variation=self.var1, event=self.event) v = Voucher.objects.create(item=self.var1.item, variation=self.var1, event=self.event)
self.assertFalse(v.applies_to(self.item1)) self.assertFalse(v.applies_to(self.item1))
@@ -650,6 +699,7 @@ class VoucherTestCase(BaseQuotaTestCase):
self.assertTrue(v.applies_to(self.var1.item, self.var1)) self.assertTrue(v.applies_to(self.var1.item, self.var1))
self.assertFalse(v.applies_to(self.var1.item, self.var2)) self.assertFalse(v.applies_to(self.var1.item, self.var2))
@classscope(attr='o')
def test_voucher_applicability_variation_through_quota(self): def test_voucher_applicability_variation_through_quota(self):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.items.add(self.var1.item) self.quota.items.add(self.var1.item)
@@ -659,51 +709,62 @@ class VoucherTestCase(BaseQuotaTestCase):
self.assertTrue(v.applies_to(self.var1.item, self.var1)) self.assertTrue(v.applies_to(self.var1.item, self.var1))
self.assertFalse(v.applies_to(self.var1.item, self.var2)) self.assertFalse(v.applies_to(self.var1.item, self.var2))
@classscope(attr='o')
def test_voucher_no_item_with_quota(self): def test_voucher_no_item_with_quota(self):
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
v = Voucher(quota=self.quota, item=self.item1, event=self.event) v = Voucher(quota=self.quota, item=self.item1, event=self.event)
v.clean() v.clean()
@classscope(attr='o')
def test_voucher_item_with_no_variation(self): def test_voucher_item_with_no_variation(self):
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
v = Voucher(item=self.item1, variation=self.var1, event=self.event) v = Voucher(item=self.item1, variation=self.var1, event=self.event)
v.clean() v.clean()
@classscope(attr='o')
def test_voucher_item_does_not_match_variation(self): def test_voucher_item_does_not_match_variation(self):
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
v = Voucher(item=self.item2, variation=self.var3, event=self.event) v = Voucher(item=self.item2, variation=self.var3, event=self.event)
v.clean() v.clean()
@classscope(attr='o')
def test_voucher_specify_variation_for_block_quota(self): def test_voucher_specify_variation_for_block_quota(self):
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
v = Voucher(item=self.item2, block_quota=True, event=self.event) v = Voucher(item=self.item2, block_quota=True, event=self.event)
v.clean() v.clean()
@classscope(attr='o')
def test_voucher_no_item_but_variation(self): def test_voucher_no_item_but_variation(self):
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
v = Voucher(variation=self.var1, event=self.event) v = Voucher(variation=self.var1, event=self.event)
v.clean() v.clean()
@classscope(attr='o')
def test_calculate_price_none(self): def test_calculate_price_none(self):
v = Voucher.objects.create(event=self.event, price_mode='none', value=Decimal('10.00')) v = Voucher.objects.create(event=self.event, price_mode='none', value=Decimal('10.00'))
assert v.calculate_price(Decimal('23.42')) == Decimal('23.42') assert v.calculate_price(Decimal('23.42')) == Decimal('23.42')
@classscope(attr='o')
def test_calculate_price_set_empty(self): def test_calculate_price_set_empty(self):
v = Voucher.objects.create(event=self.event, price_mode='set') v = Voucher.objects.create(event=self.event, price_mode='set')
assert v.calculate_price(Decimal('23.42')) == Decimal('23.42') assert v.calculate_price(Decimal('23.42')) == Decimal('23.42')
@classscope(attr='o')
def test_calculate_price_set(self): def test_calculate_price_set(self):
v = Voucher.objects.create(event=self.event, price_mode='set', value=Decimal('10.00')) v = Voucher.objects.create(event=self.event, price_mode='set', value=Decimal('10.00'))
assert v.calculate_price(Decimal('23.42')) == Decimal('10.00') assert v.calculate_price(Decimal('23.42')) == Decimal('10.00')
@classscope(attr='o')
def test_calculate_price_set_zero(self): def test_calculate_price_set_zero(self):
v = Voucher.objects.create(event=self.event, price_mode='set', value=Decimal('0.00')) v = Voucher.objects.create(event=self.event, price_mode='set', value=Decimal('0.00'))
assert v.calculate_price(Decimal('23.42')) == Decimal('0.00') assert v.calculate_price(Decimal('23.42')) == Decimal('0.00')
@classscope(attr='o')
def test_calculate_price_subtract(self): def test_calculate_price_subtract(self):
v = Voucher.objects.create(event=self.event, price_mode='subtract', value=Decimal('10.00')) v = Voucher.objects.create(event=self.event, price_mode='subtract', value=Decimal('10.00'))
assert v.calculate_price(Decimal('23.42')) == Decimal('13.42') assert v.calculate_price(Decimal('23.42')) == Decimal('13.42')
@classscope(attr='o')
def test_calculate_price_percent(self): def test_calculate_price_percent(self):
v = Voucher.objects.create(event=self.event, price_mode='percent', value=Decimal('23.00')) v = Voucher.objects.create(event=self.event, price_mode='percent', value=Decimal('23.00'))
assert v.calculate_price(Decimal('100.00')) == Decimal('77.00') assert v.calculate_price(Decimal('100.00')) == Decimal('77.00')
@@ -712,6 +773,7 @@ class VoucherTestCase(BaseQuotaTestCase):
class OrderTestCase(BaseQuotaTestCase): class OrderTestCase(BaseQuotaTestCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
with scope(organizer=self.o):
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy') self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
self.order = Order.objects.create( self.order = Order.objects.create(
status=Order.STATUS_PENDING, event=self.event, status=Order.STATUS_PENDING, event=self.event,
@@ -724,6 +786,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.op2 = OrderPosition.objects.create(order=self.order, item=self.item1, self.op2 = OrderPosition.objects.create(order=self.order, item=self.item1,
variation=None, price=23) variation=None, price=23)
@classscope(attr='o')
def test_paid_in_time(self): def test_paid_in_time(self):
self.quota.size = 0 self.quota.size = 0
self.quota.save() self.quota.save()
@@ -734,6 +797,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.assertEqual(self.order.status, Order.STATUS_PAID) self.assertEqual(self.order.status, Order.STATUS_PAID)
assert not self.order.all_logentries().filter(action_type='pretix.event.order.overpaid').exists() assert not self.order.all_logentries().filter(action_type='pretix.event.order.overpaid').exists()
@classscope(attr='o')
def test_paid_expired_available(self): def test_paid_expired_available(self):
self.event.settings.payment_term_last = (now() + timedelta(days=2)).strftime('%Y-%m-%d') self.event.settings.payment_term_last = (now() + timedelta(days=2)).strftime('%Y-%m-%d')
self.order.status = Order.STATUS_EXPIRED self.order.status = Order.STATUS_EXPIRED
@@ -745,6 +809,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.order = Order.objects.get(id=self.order.id) self.order = Order.objects.get(id=self.order.id)
self.assertEqual(self.order.status, Order.STATUS_PAID) self.assertEqual(self.order.status, Order.STATUS_PAID)
@classscope(attr='o')
def test_paid_expired_after_last_date(self): def test_paid_expired_after_last_date(self):
self.event.settings.payment_term_last = (now() - timedelta(days=2)).strftime('%Y-%m-%d') self.event.settings.payment_term_last = (now() - timedelta(days=2)).strftime('%Y-%m-%d')
self.order.status = Order.STATUS_EXPIRED self.order.status = Order.STATUS_EXPIRED
@@ -757,6 +822,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.order = Order.objects.get(id=self.order.id) self.order = Order.objects.get(id=self.order.id)
self.assertEqual(self.order.status, Order.STATUS_EXPIRED) self.assertEqual(self.order.status, Order.STATUS_EXPIRED)
@classscope(attr='o')
def test_paid_expired_after_last_date_subevent_relative(self): def test_paid_expired_after_last_date_subevent_relative(self):
self.event.has_subevents = True self.event.has_subevents = True
self.event.save() self.event.save()
@@ -782,6 +848,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.event.has_subevents = False self.event.has_subevents = False
self.event.save() self.event.save()
@classscope(attr='o')
def test_paid_expired_late_not_allowed(self): def test_paid_expired_late_not_allowed(self):
self.event.settings.payment_term_accept_late = False self.event.settings.payment_term_accept_late = False
self.order.status = Order.STATUS_EXPIRED self.order.status = Order.STATUS_EXPIRED
@@ -794,6 +861,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.order = Order.objects.get(id=self.order.id) self.order = Order.objects.get(id=self.order.id)
self.assertEqual(self.order.status, Order.STATUS_EXPIRED) self.assertEqual(self.order.status, Order.STATUS_EXPIRED)
@classscope(attr='o')
def test_paid_expired_unavailable(self): def test_paid_expired_unavailable(self):
self.event.settings.payment_term_accept_late = True self.event.settings.payment_term_accept_late = True
self.order.expires = now() - timedelta(days=2) self.order.expires = now() - timedelta(days=2)
@@ -808,6 +876,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.order = Order.objects.get(id=self.order.id) self.order = Order.objects.get(id=self.order.id)
self.assertIn(self.order.status, (Order.STATUS_PENDING, Order.STATUS_EXPIRED)) self.assertIn(self.order.status, (Order.STATUS_PENDING, Order.STATUS_EXPIRED))
@classscope(attr='o')
def test_paid_after_deadline_but_not_expired(self): def test_paid_after_deadline_but_not_expired(self):
self.event.settings.payment_term_accept_late = True self.event.settings.payment_term_accept_late = True
self.order.expires = now() - timedelta(days=2) self.order.expires = now() - timedelta(days=2)
@@ -818,6 +887,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.order = Order.objects.get(id=self.order.id) self.order = Order.objects.get(id=self.order.id)
self.assertEqual(self.order.status, Order.STATUS_PAID) self.assertEqual(self.order.status, Order.STATUS_PAID)
@classscope(attr='o')
def test_paid_expired_unavailable_force(self): def test_paid_expired_unavailable_force(self):
self.event.settings.payment_term_accept_late = True self.event.settings.payment_term_accept_late = True
self.order.expires = now() - timedelta(days=2) self.order.expires = now() - timedelta(days=2)
@@ -831,6 +901,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.order = Order.objects.get(id=self.order.id) self.order = Order.objects.get(id=self.order.id)
self.assertEqual(self.order.status, Order.STATUS_PAID) self.assertEqual(self.order.status, Order.STATUS_PAID)
@classscope(attr='o')
def test_paid_expired_unavailable_waiting_list(self): def test_paid_expired_unavailable_waiting_list(self):
self.event.settings.payment_term_accept_late = True self.event.settings.payment_term_accept_late = True
self.event.waitinglistentries.create(item=self.item1, email='foo@bar.com') self.event.waitinglistentries.create(item=self.item1, email='foo@bar.com')
@@ -846,6 +917,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.order = Order.objects.get(id=self.order.id) self.order = Order.objects.get(id=self.order.id)
self.assertEqual(self.order.status, Order.STATUS_EXPIRED) self.assertEqual(self.order.status, Order.STATUS_EXPIRED)
@classscope(attr='o')
def test_paid_expired_unavailable_waiting_list_ignore(self): def test_paid_expired_unavailable_waiting_list_ignore(self):
self.event.waitinglistentries.create(item=self.item1, email='foo@bar.com') self.event.waitinglistentries.create(item=self.item1, email='foo@bar.com')
self.order.expires = now() - timedelta(days=2) self.order.expires = now() - timedelta(days=2)
@@ -859,6 +931,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.order = Order.objects.get(id=self.order.id) self.order = Order.objects.get(id=self.order.id)
self.assertEqual(self.order.status, Order.STATUS_PAID) self.assertEqual(self.order.status, Order.STATUS_PAID)
@classscope(attr='o')
def test_paid_overpaid(self): def test_paid_overpaid(self):
self.quota.size = 2 self.quota.size = 2
self.quota.save() self.quota.save()
@@ -869,6 +942,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.assertEqual(self.order.status, Order.STATUS_PAID) self.assertEqual(self.order.status, Order.STATUS_PAID)
assert self.order.all_logentries().filter(action_type='pretix.event.order.overpaid').exists() assert self.order.all_logentries().filter(action_type='pretix.event.order.overpaid').exists()
@classscope(attr='o')
def test_can_modify_answers(self): def test_can_modify_answers(self):
self.event.settings.set('invoice_address_asked', False) self.event.settings.set('invoice_address_asked', False)
self.event.settings.set('attendee_names_asked', True) self.event.settings.set('attendee_names_asked', True)
@@ -887,6 +961,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.event.settings.set('last_order_modification_date', now() - timedelta(days=1)) self.event.settings.set('last_order_modification_date', now() - timedelta(days=1))
assert not self.order.can_modify_answers assert not self.order.can_modify_answers
@classscope(attr='o')
def test_can_modify_answers_subevent(self): def test_can_modify_answers_subevent(self):
self.event.has_subevents = True self.event.has_subevents = True
self.event.save() self.event.save()
@@ -907,6 +982,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.event.has_subevents = False self.event.has_subevents = False
self.event.save() self.event.save()
@classscope(attr='o')
def test_payment_term_last_relative(self): def test_payment_term_last_relative(self):
self.event.settings.set('payment_term_last', date(2017, 5, 3)) self.event.settings.set('payment_term_last', date(2017, 5, 3))
assert self.order.payment_term_last == datetime.datetime(2017, 5, 3, 23, 59, 59, tzinfo=pytz.UTC) assert self.order.payment_term_last == datetime.datetime(2017, 5, 3, 23, 59, 59, tzinfo=pytz.UTC)
@@ -917,6 +993,7 @@ class OrderTestCase(BaseQuotaTestCase):
)) ))
assert self.order.payment_term_last == datetime.datetime(2017, 5, 1, 23, 59, 59, tzinfo=pytz.UTC) assert self.order.payment_term_last == datetime.datetime(2017, 5, 1, 23, 59, 59, tzinfo=pytz.UTC)
@classscope(attr='o')
def test_payment_term_last_subevent(self): def test_payment_term_last_subevent(self):
self.event.has_subevents = True self.event.has_subevents = True
self.event.save() self.event.save()
@@ -937,6 +1014,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.event.has_subevents = False self.event.has_subevents = False
self.event.save() self.event.save()
@classscope(attr='o')
def test_ticket_download_date_relative(self): def test_ticket_download_date_relative(self):
self.event.settings.set('ticket_download_date', datetime.datetime(2017, 5, 3, 12, 59, 59, tzinfo=pytz.UTC)) self.event.settings.set('ticket_download_date', datetime.datetime(2017, 5, 3, 12, 59, 59, tzinfo=pytz.UTC))
assert self.order.ticket_download_date == datetime.datetime(2017, 5, 3, 12, 59, 59, tzinfo=pytz.UTC) assert self.order.ticket_download_date == datetime.datetime(2017, 5, 3, 12, 59, 59, tzinfo=pytz.UTC)
@@ -947,6 +1025,7 @@ class OrderTestCase(BaseQuotaTestCase):
)) ))
assert self.order.ticket_download_date == datetime.datetime(2017, 5, 1, 12, 0, 0, tzinfo=pytz.UTC) assert self.order.ticket_download_date == datetime.datetime(2017, 5, 1, 12, 0, 0, tzinfo=pytz.UTC)
@classscope(attr='o')
def test_ticket_download_date_subevent(self): def test_ticket_download_date_subevent(self):
self.event.has_subevents = True self.event.has_subevents = True
self.event.save() self.event.save()
@@ -967,6 +1046,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.event.has_subevents = False self.event.has_subevents = False
self.event.save() self.event.save()
@classscope(attr='o')
def test_can_cancel_order(self): def test_can_cancel_order(self):
item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23, item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23,
admission=True, allow_cancel=True) admission=True, allow_cancel=True)
@@ -976,6 +1056,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.event.settings.cancel_allow_user = False self.event.settings.cancel_allow_user = False
assert not self.order.user_cancel_allowed assert not self.order.user_cancel_allowed
@classscope(attr='o')
def test_can_cancel_order_free(self): def test_can_cancel_order_free(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.total = Decimal('0.00') self.order.total = Decimal('0.00')
@@ -984,6 +1065,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.event.settings.cancel_allow_user = False self.event.settings.cancel_allow_user = False
assert not self.order.user_cancel_allowed assert not self.order.user_cancel_allowed
@classscope(attr='o')
def test_can_cancel_order_paid(self): def test_can_cancel_order_paid(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -992,6 +1074,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.event.settings.cancel_allow_user_paid = True self.event.settings.cancel_allow_user_paid = True
assert self.order.user_cancel_allowed assert self.order.user_cancel_allowed
@classscope(attr='o')
def test_can_cancel_checked_in(self): def test_can_cancel_checked_in(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -1004,6 +1087,7 @@ class OrderTestCase(BaseQuotaTestCase):
) )
assert not self.order.user_cancel_allowed assert not self.order.user_cancel_allowed
@classscope(attr='o')
def test_can_cancel_order_multiple(self): def test_can_cancel_order_multiple(self):
item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23, item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23,
admission=True, allow_cancel=True) admission=True, allow_cancel=True)
@@ -1015,6 +1099,7 @@ class OrderTestCase(BaseQuotaTestCase):
variation=None, price=23) variation=None, price=23)
assert self.order.user_cancel_allowed assert self.order.user_cancel_allowed
@classscope(attr='o')
def test_can_not_cancel_order(self): def test_can_not_cancel_order(self):
item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23, item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23,
admission=True, allow_cancel=False) admission=True, allow_cancel=False)
@@ -1022,6 +1107,7 @@ class OrderTestCase(BaseQuotaTestCase):
variation=None, price=23) variation=None, price=23)
assert self.order.user_cancel_allowed is False assert self.order.user_cancel_allowed is False
@classscope(attr='o')
def test_can_not_cancel_order_multiple(self): def test_can_not_cancel_order_multiple(self):
item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23, item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23,
admission=True, allow_cancel=False) admission=True, allow_cancel=False)
@@ -1033,6 +1119,7 @@ class OrderTestCase(BaseQuotaTestCase):
variation=None, price=23) variation=None, price=23)
assert self.order.user_cancel_allowed is False assert self.order.user_cancel_allowed is False
@classscope(attr='o')
def test_can_not_cancel_order_multiple_mixed(self): def test_can_not_cancel_order_multiple_mixed(self):
item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23, item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23,
admission=True, allow_cancel=False) admission=True, allow_cancel=False)
@@ -1044,6 +1131,7 @@ class OrderTestCase(BaseQuotaTestCase):
variation=None, price=23) variation=None, price=23)
assert self.order.user_cancel_allowed is False assert self.order.user_cancel_allowed is False
@classscope(attr='o')
def test_no_duplicate_position_secret(self): def test_no_duplicate_position_secret(self):
item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23, item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23,
admission=True, allow_cancel=False) admission=True, allow_cancel=False)
@@ -1054,6 +1142,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert p1.secret != p2.secret assert p1.secret != p2.secret
assert self.order.user_cancel_allowed is False assert self.order.user_cancel_allowed is False
@classscope(attr='o')
def test_user_cancel_absolute_deadline_unpaid_no_subevents(self): def test_user_cancel_absolute_deadline_unpaid_no_subevents(self):
assert self.order.user_cancel_deadline is None assert self.order.user_cancel_deadline is None
self.event.settings.set('cancel_allow_user_until', RelativeDateWrapper( self.event.settings.set('cancel_allow_user_until', RelativeDateWrapper(
@@ -1069,6 +1158,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert self.order.user_cancel_deadline < now() assert self.order.user_cancel_deadline < now()
assert not self.order.user_cancel_allowed assert not self.order.user_cancel_allowed
@classscope(attr='o')
def test_user_cancel_relative_deadline_unpaid_no_subevents(self): def test_user_cancel_relative_deadline_unpaid_no_subevents(self):
self.event.date_from = now() + timedelta(days=3) self.event.date_from = now() + timedelta(days=3)
self.event.save() self.event.save()
@@ -1087,6 +1177,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert self.order.user_cancel_deadline < now() assert self.order.user_cancel_deadline < now()
assert not self.order.user_cancel_allowed assert not self.order.user_cancel_allowed
@classscope(attr='o')
def test_user_cancel_absolute_deadline_paid_no_subevents(self): def test_user_cancel_absolute_deadline_paid_no_subevents(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -1105,6 +1196,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert self.order.user_cancel_deadline < now() assert self.order.user_cancel_deadline < now()
assert not self.order.user_cancel_allowed assert not self.order.user_cancel_allowed
@classscope(attr='o')
def test_user_cancel_relative_deadline_paid_no_subevents(self): def test_user_cancel_relative_deadline_paid_no_subevents(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -1126,6 +1218,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert self.order.user_cancel_deadline < now() assert self.order.user_cancel_deadline < now()
assert not self.order.user_cancel_allowed assert not self.order.user_cancel_allowed
@classscope(attr='o')
def test_user_cancel_relative_deadline_to_subevents(self): def test_user_cancel_relative_deadline_to_subevents(self):
self.event.date_from = now() + timedelta(days=3) self.event.date_from = now() + timedelta(days=3)
self.event.has_subevents = True self.event.has_subevents = True
@@ -1147,6 +1240,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.order = Order.objects.get(pk=self.order.pk) self.order = Order.objects.get(pk=self.order.pk)
assert self.order.user_cancel_deadline > now() assert self.order.user_cancel_deadline > now()
@classscope(attr='o')
def test_user_cancel_fee(self): def test_user_cancel_fee(self):
self.order.fees.create(fee_type=OrderFee.FEE_TYPE_SHIPPING, value=Decimal('2.00')) self.order.fees.create(fee_type=OrderFee.FEE_TYPE_SHIPPING, value=Decimal('2.00'))
self.order.total = 48 self.order.total = 48
@@ -1166,6 +1260,7 @@ class OrderTestCase(BaseQuotaTestCase):
self.order = Order.objects.get(pk=self.order.pk) self.order = Order.objects.get(pk=self.order.pk)
assert self.order.user_cancel_fee == Decimal('9.30') assert self.order.user_cancel_fee == Decimal('9.30')
@classscope(attr='o')
def test_paid_order_underpaid(self): def test_paid_order_underpaid(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -1186,6 +1281,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert not o.has_pending_refund assert not o.has_pending_refund
assert not o.has_external_refund assert not o.has_external_refund
@classscope(attr='o')
def test_pending_order_underpaid(self): def test_pending_order_underpaid(self):
self.order.payments.create( self.order.payments.create(
amount=Decimal('46.00'), amount=Decimal('46.00'),
@@ -1204,6 +1300,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert not o.has_pending_refund assert not o.has_pending_refund
assert not o.has_external_refund assert not o.has_external_refund
@classscope(attr='o')
def test_canceled_order_overpaid(self): def test_canceled_order_overpaid(self):
self.order.status = Order.STATUS_CANCELED self.order.status = Order.STATUS_CANCELED
self.order.save() self.order.save()
@@ -1224,6 +1321,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert not o.has_pending_refund assert not o.has_pending_refund
assert not o.has_external_refund assert not o.has_external_refund
@classscope(attr='o')
def test_paid_order_external_refund(self): def test_paid_order_external_refund(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -1244,6 +1342,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert not o.has_pending_refund assert not o.has_pending_refund
assert o.has_external_refund assert o.has_external_refund
@classscope(attr='o')
def test_pending_order_pending_refund(self): def test_pending_order_pending_refund(self):
self.order.status = Order.STATUS_CANCELED self.order.status = Order.STATUS_CANCELED
self.order.save() self.order.save()
@@ -1264,6 +1363,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert o.has_pending_refund assert o.has_pending_refund
assert not o.has_external_refund assert not o.has_external_refund
@classscope(attr='o')
def test_paid_order_overpaid(self): def test_paid_order_overpaid(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -1284,6 +1384,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert not o.has_pending_refund assert not o.has_pending_refund
assert not o.has_external_refund assert not o.has_external_refund
@classscope(attr='o')
def test_pending_order_overpaid(self): def test_pending_order_overpaid(self):
self.order.status = Order.STATUS_PENDING self.order.status = Order.STATUS_PENDING
self.order.save() self.order.save()
@@ -1305,6 +1406,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert not o.has_pending_refund assert not o.has_pending_refund
assert not o.has_external_refund assert not o.has_external_refund
@classscope(attr='o')
def test_canceled_positions(self): def test_canceled_positions(self):
self.op1.canceled = True self.op1.canceled = True
self.op1.save() self.op1.save()
@@ -1313,6 +1415,7 @@ class OrderTestCase(BaseQuotaTestCase):
assert self.order.positions.count() == 1 assert self.order.positions.count() == 1
assert self.order.all_positions.count() == 2 assert self.order.all_positions.count() == 2
@classscope(attr='o')
def test_propose_auto_refunds(self): def test_propose_auto_refunds(self):
p1 = self.order.payments.create( p1 = self.order.payments.create(
amount=Decimal('23.00'), amount=Decimal('23.00'),
@@ -1358,12 +1461,13 @@ class ItemCategoryTest(TestCase):
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
o = Organizer.objects.create(name='Dummy', slug='dummy') cls.o = Organizer.objects.create(name='Dummy', slug='dummy')
cls.event = Event.objects.create( cls.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy', organizer=cls.o, name='Dummy', slug='dummy',
date_from=now(), date_from=now(),
) )
@classscope(attr='o')
def test_sorting(self): def test_sorting(self):
c1 = ItemCategory.objects.create(event=self.event) c1 = ItemCategory.objects.create(event=self.event)
c2 = ItemCategory.objects.create(event=self.event) c2 = ItemCategory.objects.create(event=self.event)
@@ -1386,12 +1490,13 @@ class ItemTest(TestCase):
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
o = Organizer.objects.create(name='Dummy', slug='dummy') cls.o = Organizer.objects.create(name='Dummy', slug='dummy')
cls.event = Event.objects.create( cls.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy', organizer=cls.o, name='Dummy', slug='dummy',
date_from=now(), date_from=now(),
) )
@classscope(attr='o')
def test_is_available(self): def test_is_available(self):
i = Item.objects.create( i = Item.objects.create(
event=self.event, name="Ticket", default_price=23, event=self.event, name="Ticket", default_price=23,
@@ -1412,6 +1517,7 @@ class ItemTest(TestCase):
i.active = False i.active = False
assert not i.is_available() assert not i.is_available()
@classscope(attr='o')
def test_availability_filter(self): def test_availability_filter(self):
i = Item.objects.create( i = Item.objects.create(
event=self.event, name="Ticket", default_price=23, event=self.event, name="Ticket", default_price=23,
@@ -1463,6 +1569,7 @@ class EventTest(TestCase):
def setUpTestData(cls): def setUpTestData(cls):
cls.organizer = Organizer.objects.create(name='Dummy', slug='dummy') cls.organizer = Organizer.objects.create(name='Dummy', slug='dummy')
@classscope(attr='organizer')
def test_event_end_before_start(self): def test_event_end_before_start(self):
event = Event( event = Event(
organizer=self.organizer, name='Dummy', slug='dummy', organizer=self.organizer, name='Dummy', slug='dummy',
@@ -1473,6 +1580,7 @@ class EventTest(TestCase):
self.assertIn('date_to', str(context.exception)) self.assertIn('date_to', str(context.exception))
@classscope(attr='organizer')
def test_presale_end_before_start(self): def test_presale_end_before_start(self):
event = Event( event = Event(
organizer=self.organizer, name='Dummy', slug='dummy', organizer=self.organizer, name='Dummy', slug='dummy',
@@ -1483,6 +1591,7 @@ class EventTest(TestCase):
self.assertIn('presale_end', str(context.exception)) self.assertIn('presale_end', str(context.exception))
@classscope(attr='organizer')
def test_slug_validation(self): def test_slug_validation(self):
event = Event( event = Event(
organizer=self.organizer, name='Download', slug='download', organizer=self.organizer, name='Download', slug='download',
@@ -1493,6 +1602,7 @@ class EventTest(TestCase):
self.assertIn('slug', str(context.exception)) self.assertIn('slug', str(context.exception))
@classscope(attr='organizer')
def test_copy(self): def test_copy(self):
event1 = Event.objects.create( event1 = Event.objects.create(
organizer=self.organizer, name='Download', slug='ab1234', organizer=self.organizer, name='Download', slug='ab1234',
@@ -1547,6 +1657,7 @@ class EventTest(TestCase):
assert event2.checkin_lists.count() == 1 assert event2.checkin_lists.count() == 1
assert [i.pk for i in event2.checkin_lists.first().limit_products.all()] == [i1new.pk] assert [i.pk for i in event2.checkin_lists.first().limit_products.all()] == [i1new.pk]
@classscope(attr='organizer')
def test_presale_has_ended(self): def test_presale_has_ended(self):
event = Event( event = Event(
organizer=self.organizer, name='Download', slug='download', organizer=self.organizer, name='Download', slug='download',
@@ -1579,6 +1690,7 @@ class EventTest(TestCase):
assert event.presale_has_ended assert event.presale_has_ended
assert not event.presale_is_running assert not event.presale_is_running
@classscope(attr='organizer')
def test_active_quotas_annotation(self): def test_active_quotas_annotation(self):
event = Event.objects.create( event = Event.objects.create(
organizer=self.organizer, name='Download', slug='download', organizer=self.organizer, name='Download', slug='download',
@@ -1592,6 +1704,7 @@ class EventTest(TestCase):
assert Event.annotated(Event.objects).first().active_quotas == [q] assert Event.annotated(Event.objects).first().active_quotas == [q]
assert Event.annotated(Event.objects, 'foo').first().active_quotas == [] assert Event.annotated(Event.objects, 'foo').first().active_quotas == []
@classscope(attr='organizer')
def test_active_quotas_annotation_product_inactive(self): def test_active_quotas_annotation_product_inactive(self):
event = Event.objects.create( event = Event.objects.create(
organizer=self.organizer, name='Download', slug='download', organizer=self.organizer, name='Download', slug='download',
@@ -1602,6 +1715,7 @@ class EventTest(TestCase):
q.items.add(item) q.items.add(item)
assert Event.annotated(Event.objects).first().active_quotas == [] assert Event.annotated(Event.objects).first().active_quotas == []
@classscope(attr='organizer')
def test_active_quotas_annotation_product_addon(self): def test_active_quotas_annotation_product_addon(self):
event = Event.objects.create( event = Event.objects.create(
organizer=self.organizer, name='Download', slug='download', organizer=self.organizer, name='Download', slug='download',
@@ -1617,6 +1731,7 @@ class EventTest(TestCase):
q.items.add(item) q.items.add(item)
assert Event.annotated(Event.objects).first().active_quotas == [] assert Event.annotated(Event.objects).first().active_quotas == []
@classscope(attr='organizer')
def test_active_quotas_annotation_product_unavailable(self): def test_active_quotas_annotation_product_unavailable(self):
event = Event.objects.create( event = Event.objects.create(
organizer=self.organizer, name='Download', slug='download', organizer=self.organizer, name='Download', slug='download',
@@ -1627,6 +1742,7 @@ class EventTest(TestCase):
q.items.add(item) q.items.add(item)
assert Event.annotated(Event.objects).first().active_quotas == [] assert Event.annotated(Event.objects).first().active_quotas == []
@classscope(attr='organizer')
def test_active_quotas_annotation_variation_not_in_quota(self): def test_active_quotas_annotation_variation_not_in_quota(self):
event = Event.objects.create( event = Event.objects.create(
organizer=self.organizer, name='Download', slug='download', organizer=self.organizer, name='Download', slug='download',
@@ -1638,6 +1754,7 @@ class EventTest(TestCase):
q.items.add(item) q.items.add(item)
assert Event.annotated(Event.objects).first().active_quotas == [] assert Event.annotated(Event.objects).first().active_quotas == []
@classscope(attr='organizer')
def test_active_quotas_annotation_variation(self): def test_active_quotas_annotation_variation(self):
event = Event.objects.create( event = Event.objects.create(
organizer=self.organizer, name='Download', slug='download', organizer=self.organizer, name='Download', slug='download',
@@ -1687,6 +1804,7 @@ class SubEventTest(TestCase):
name='Testsub', date_from=now(), event=cls.event name='Testsub', date_from=now(), event=cls.event
) )
@classscope(attr='organizer')
def test_override_prices(self): def test_override_prices(self):
i = Item.objects.create( i = Item.objects.create(
event=self.event, name="Ticket", default_price=23, event=self.event, name="Ticket", default_price=23,
@@ -1697,6 +1815,7 @@ class SubEventTest(TestCase):
i.pk: Decimal('30.00') i.pk: Decimal('30.00')
} }
@classscope(attr='organizer')
def test_override_var_prices(self): def test_override_var_prices(self):
i = Item.objects.create( i = Item.objects.create(
event=self.event, name="Ticket", default_price=23, event=self.event, name="Ticket", default_price=23,
@@ -1708,6 +1827,7 @@ class SubEventTest(TestCase):
v.pk: Decimal('30.00') v.pk: Decimal('30.00')
} }
@classscope(attr='organizer')
def test_active_quotas_annotation(self): def test_active_quotas_annotation(self):
q = Quota.objects.create(event=self.event, name='Quota', size=2, q = Quota.objects.create(event=self.event, name='Quota', size=2,
subevent=self.se) subevent=self.se)
@@ -1716,6 +1836,7 @@ class SubEventTest(TestCase):
assert SubEvent.annotated(SubEvent.objects).first().active_quotas == [q] assert SubEvent.annotated(SubEvent.objects).first().active_quotas == [q]
assert SubEvent.annotated(SubEvent.objects, 'foo').first().active_quotas == [] assert SubEvent.annotated(SubEvent.objects, 'foo').first().active_quotas == []
@classscope(attr='organizer')
def test_active_quotas_annotation_no_interference(self): def test_active_quotas_annotation_no_interference(self):
se2 = SubEvent.objects.create( se2 = SubEvent.objects.create(
name='Testsub', date_from=now(), event=self.event name='Testsub', date_from=now(), event=self.event
@@ -1727,6 +1848,7 @@ class SubEventTest(TestCase):
assert SubEvent.annotated(SubEvent.objects).filter(pk=self.se.pk).first().active_quotas == [] assert SubEvent.annotated(SubEvent.objects).filter(pk=self.se.pk).first().active_quotas == []
assert SubEvent.annotated(SubEvent.objects).filter(pk=se2.pk).first().active_quotas == [q] assert SubEvent.annotated(SubEvent.objects).filter(pk=se2.pk).first().active_quotas == [q]
@classscope(attr='organizer')
def test_best_availability(self): def test_best_availability(self):
q = Quota.objects.create(event=self.event, name='Quota', size=0, q = Quota.objects.create(event=self.event, name='Quota', size=0,
subevent=self.se) subevent=self.se)
@@ -1768,6 +1890,7 @@ class CheckinListTestCase(TestCase):
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
cls.organizer = Organizer.objects.create(name='Dummy', slug='dummy') cls.organizer = Organizer.objects.create(name='Dummy', slug='dummy')
with scope(organizer=cls.organizer):
cls.event = Event.objects.create( cls.event = Event.objects.create(
organizer=cls.organizer, name='Dummy', slug='dummy', organizer=cls.organizer, name='Dummy', slug='dummy',
date_from=now(), date_to=now() - timedelta(hours=1), date_from=now(), date_to=now() - timedelta(hours=1),
@@ -1830,6 +1953,7 @@ class CheckinListTestCase(TestCase):
) )
op4.checkins.create(list=cls.cl_all_pending) op4.checkins.create(list=cls.cl_all_pending)
@classscope(attr='organizer')
def test_annotated(self): def test_annotated(self):
lists = list(CheckinList.annotate_with_numbers(self.event.checkin_lists.order_by('name'), self.event)) lists = list(CheckinList.annotate_with_numbers(self.event.checkin_lists.order_by('name'), self.event))
assert lists == [self.cl_all, self.cl_both, self.cl_tickets, self.cl_all_pending] assert lists == [self.cl_all, self.cl_both, self.cl_tickets, self.cl_all_pending]
@@ -1881,6 +2005,7 @@ class CheckinListTestCase(TestCase):
]) ])
def test_question_answer_validation(qtype, answer, expected): def test_question_answer_validation(qtype, answer, expected):
o = Organizer.objects.create(name='Dummy', slug='dummy') o = Organizer.objects.create(name='Dummy', slug='dummy')
with scope(organizer=o):
event = Event.objects.create( event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy', organizer=o, name='Dummy', slug='dummy',
date_from=now(), date_from=now(),
@@ -1906,6 +2031,7 @@ def test_question_answer_validation_localized_decimal():
@pytest.mark.django_db @pytest.mark.django_db
def test_question_answer_validation_choice(): def test_question_answer_validation_choice():
organizer = Organizer.objects.create(name='Dummy', slug='dummy') organizer = Organizer.objects.create(name='Dummy', slug='dummy')
with scope(organizer=organizer):
event = Event.objects.create( event = Event.objects.create(
organizer=organizer, name='Dummy', slug='dummy', organizer=organizer, name='Dummy', slug='dummy',
date_from=now(), date_to=now() - timedelta(hours=1), date_from=now(), date_to=now() - timedelta(hours=1),
@@ -1930,6 +2056,7 @@ def test_question_answer_validation_choice():
@pytest.mark.django_db @pytest.mark.django_db
def test_question_answer_validation_multiple_choice(): def test_question_answer_validation_multiple_choice():
organizer = Organizer.objects.create(name='Dummy', slug='dummy') organizer = Organizer.objects.create(name='Dummy', slug='dummy')
with scope(organizer=organizer):
event = Event.objects.create( event = Event.objects.create(
organizer=organizer, name='Dummy', slug='dummy', organizer=organizer, name='Dummy', slug='dummy',
date_from=now(), date_to=now() - timedelta(hours=1), date_from=now(), date_to=now() - timedelta(hours=1),

View File

@@ -5,6 +5,7 @@ import pytest
from django.core import mail as djmail from django.core import mail as djmail
from django.db import transaction from django.db import transaction
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scope
from pretix.base.models import ( from pretix.base.models import (
Event, Item, Order, OrderPosition, Organizer, User, Event, Item, Order, OrderPosition, Organizer, User,
@@ -18,7 +19,8 @@ def event():
organizer=o, name='Dummy', slug='dummy', organizer=o, name='Dummy', slug='dummy',
date_from=now() date_from=now()
) )
return event with scope(organizer=o):
yield event
@pytest.fixture @pytest.fixture

View File

@@ -7,6 +7,7 @@ from django.core import mail as djmail
from django.test import TestCase from django.test import TestCase
from django.utils.timezone import make_aware, now from django.utils.timezone import make_aware, now
from django_countries.fields import Country from django_countries.fields import Country
from django_scopes import scope
from pretix.base.decimal import round_decimal from pretix.base.decimal import round_decimal
from pretix.base.models import ( from pretix.base.models import (
@@ -21,9 +22,10 @@ from pretix.base.services.orders import (
OrderChangeManager, OrderError, _create_order, approve_order, cancel_order, OrderChangeManager, OrderError, _create_order, approve_order, cancel_order,
deny_order, expire_orders, send_download_reminders, send_expiry_warnings, deny_order, expire_orders, send_download_reminders, send_expiry_warnings,
) )
from pretix.testutils.scope import classscope
@pytest.fixture @pytest.fixture(scope='function')
def event(): def event():
o = Organizer.objects.create(name='Dummy', slug='dummy') o = Organizer.objects.create(name='Dummy', slug='dummy')
event = Event.objects.create( event = Event.objects.create(
@@ -31,7 +33,8 @@ def event():
date_from=now(), date_from=now(),
plugins='pretix.plugins.banktransfer' plugins='pretix.plugins.banktransfer'
) )
return event with scope(organizer=o):
yield event
@pytest.mark.django_db @pytest.mark.django_db
@@ -312,9 +315,10 @@ def test_deny(event):
class PaymentReminderTests(TestCase): class PaymentReminderTests(TestCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
o = Organizer.objects.create(name='Dummy', slug='dummy') self.o = Organizer.objects.create(name='Dummy', slug='dummy')
with scope(organizer=self.o):
self.event = Event.objects.create( self.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy', organizer=self.o, name='Dummy', slug='dummy',
date_from=now() + timedelta(days=2), date_from=now() + timedelta(days=2),
plugins='pretix.plugins.banktransfer' plugins='pretix.plugins.banktransfer'
) )
@@ -333,21 +337,25 @@ class PaymentReminderTests(TestCase):
) )
djmail.outbox = [] djmail.outbox = []
@classscope(attr='o')
def test_disabled(self): def test_disabled(self):
send_expiry_warnings(sender=self.event) send_expiry_warnings(sender=self.event)
assert len(djmail.outbox) == 0 assert len(djmail.outbox) == 0
@classscope(attr='o')
def test_sent_once(self): def test_sent_once(self):
self.event.settings.mail_days_order_expire_warning = 12 self.event.settings.mail_days_order_expire_warning = 12
send_expiry_warnings(sender=self.event) send_expiry_warnings(sender=self.event)
assert len(djmail.outbox) == 1 assert len(djmail.outbox) == 1
@classscope(attr='o')
def test_paid(self): def test_paid(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
send_expiry_warnings(sender=self.event) send_expiry_warnings(sender=self.event)
assert len(djmail.outbox) == 0 assert len(djmail.outbox) == 0
@classscope(attr='o')
def test_sent_days(self): def test_sent_days(self):
self.event.settings.mail_days_order_expire_warning = 9 self.event.settings.mail_days_order_expire_warning = 9
send_expiry_warnings(sender=self.event) send_expiry_warnings(sender=self.event)
@@ -356,6 +364,7 @@ class PaymentReminderTests(TestCase):
send_expiry_warnings(sender=self.event) send_expiry_warnings(sender=self.event)
assert len(djmail.outbox) == 1 assert len(djmail.outbox) == 1
@classscope(attr='o')
def test_sent_not_immediately_after_purchase(self): def test_sent_not_immediately_after_purchase(self):
self.order.datetime = now() self.order.datetime = now()
self.order.expires = now() + timedelta(hours=3) self.order.expires = now() + timedelta(hours=3)
@@ -368,9 +377,10 @@ class PaymentReminderTests(TestCase):
class DownloadReminderTests(TestCase): class DownloadReminderTests(TestCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
o = Organizer.objects.create(name='Dummy', slug='dummy') self.o = Organizer.objects.create(name='Dummy', slug='dummy')
with scope(organizer=self.o):
self.event = Event.objects.create( self.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy', organizer=self.o, name='Dummy', slug='dummy',
date_from=now() + timedelta(days=2), date_from=now() + timedelta(days=2),
plugins='pretix.plugins.banktransfer' plugins='pretix.plugins.banktransfer'
) )
@@ -389,10 +399,12 @@ class DownloadReminderTests(TestCase):
) )
djmail.outbox = [] djmail.outbox = []
@classscope(attr='o')
def test_disabled(self): def test_disabled(self):
send_download_reminders(sender=self.event) send_download_reminders(sender=self.event)
assert len(djmail.outbox) == 0 assert len(djmail.outbox) == 0
@classscope(attr='o')
def test_sent_once(self): def test_sent_once(self):
self.event.settings.mail_days_download_reminder = 2 self.event.settings.mail_days_download_reminder = 2
send_download_reminders(sender=self.event) send_download_reminders(sender=self.event)
@@ -401,6 +413,7 @@ class DownloadReminderTests(TestCase):
send_download_reminders(sender=self.event) send_download_reminders(sender=self.event)
assert len(djmail.outbox) == 1 assert len(djmail.outbox) == 1
@classscope(attr='o')
def test_send_to_attendees(self): def test_send_to_attendees(self):
self.event.settings.mail_send_download_reminder_attendee = True self.event.settings.mail_send_download_reminder_attendee = True
self.event.settings.mail_days_download_reminder = 2 self.event.settings.mail_days_download_reminder = 2
@@ -413,6 +426,7 @@ class DownloadReminderTests(TestCase):
assert '/ticket/' in djmail.outbox[1].body assert '/ticket/' in djmail.outbox[1].body
assert '/order/' not in djmail.outbox[1].body assert '/order/' not in djmail.outbox[1].body
@classscope(attr='o')
def test_send_not_to_attendees_with_same_address(self): def test_send_not_to_attendees_with_same_address(self):
self.event.settings.mail_send_download_reminder_attendee = True self.event.settings.mail_send_download_reminder_attendee = True
self.event.settings.mail_days_download_reminder = 2 self.event.settings.mail_days_download_reminder = 2
@@ -423,6 +437,7 @@ class DownloadReminderTests(TestCase):
assert djmail.outbox[0].to == ['dummy@dummy.test'] assert djmail.outbox[0].to == ['dummy@dummy.test']
assert '/order/' in djmail.outbox[0].body assert '/order/' in djmail.outbox[0].body
@classscope(attr='o')
def test_sent_paid_only(self): def test_sent_paid_only(self):
self.event.settings.mail_days_download_reminder = 2 self.event.settings.mail_days_download_reminder = 2
self.order.status = Order.STATUS_PENDING self.order.status = Order.STATUS_PENDING
@@ -430,11 +445,13 @@ class DownloadReminderTests(TestCase):
send_download_reminders(sender=self.event) send_download_reminders(sender=self.event)
assert len(djmail.outbox) == 0 assert len(djmail.outbox) == 0
@classscope(attr='o')
def test_not_sent_too_early(self): def test_not_sent_too_early(self):
self.event.settings.mail_days_download_reminder = 1 self.event.settings.mail_days_download_reminder = 1
send_download_reminders(sender=self.event) send_download_reminders(sender=self.event)
assert len(djmail.outbox) == 0 assert len(djmail.outbox) == 0
@classscope(attr='o')
def test_not_sent_too_soon_after_purchase(self): def test_not_sent_too_soon_after_purchase(self):
self.order.datetime = now() self.order.datetime = now()
self.order.save() self.order.save()
@@ -446,8 +463,9 @@ class DownloadReminderTests(TestCase):
class OrderCancelTests(TestCase): class OrderCancelTests(TestCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
o = Organizer.objects.create(name='Dummy', slug='dummy') self.o = Organizer.objects.create(name='Dummy', slug='dummy')
self.event = Event.objects.create(organizer=o, name='Dummy', slug='dummy', date_from=now(), with scope(organizer=self.o):
self.event = Event.objects.create(organizer=self.o, name='Dummy', slug='dummy', date_from=now(),
plugins='tests.testdummy') plugins='tests.testdummy')
self.order = Order.objects.create( self.order = Order.objects.create(
code='FOO', event=self.event, email='dummy@dummy.test', code='FOO', event=self.event, email='dummy@dummy.test',
@@ -468,20 +486,24 @@ class OrderCancelTests(TestCase):
generate_invoice(self.order) generate_invoice(self.order)
djmail.outbox = [] djmail.outbox = []
@classscope(attr='o')
def test_cancel_canceled(self): def test_cancel_canceled(self):
self.order.status = Order.STATUS_CANCELED self.order.status = Order.STATUS_CANCELED
self.order.save() self.order.save()
with pytest.raises(OrderError): with pytest.raises(OrderError):
cancel_order(self.order.pk) cancel_order(self.order.pk)
@classscope(attr='o')
def test_cancel_send_mail(self): def test_cancel_send_mail(self):
cancel_order(self.order.pk, send_mail=True) cancel_order(self.order.pk, send_mail=True)
assert len(djmail.outbox) == 1 assert len(djmail.outbox) == 1
@classscope(attr='o')
def test_cancel_send_no_mail(self): def test_cancel_send_no_mail(self):
cancel_order(self.order.pk, send_mail=False) cancel_order(self.order.pk, send_mail=False)
assert len(djmail.outbox) == 0 assert len(djmail.outbox) == 0
@classscope(attr='o')
def test_cancel_unpaid(self): def test_cancel_unpaid(self):
cancel_order(self.order.pk) cancel_order(self.order.pk)
self.order.refresh_from_db() self.order.refresh_from_db()
@@ -489,6 +511,7 @@ class OrderCancelTests(TestCase):
assert self.order.all_logentries().last().action_type == 'pretix.event.order.canceled' assert self.order.all_logentries().last().action_type == 'pretix.event.order.canceled'
assert self.order.invoices.count() == 2 assert self.order.invoices.count() == 2
@classscope(attr='o')
def test_cancel_unpaid_with_voucher(self): def test_cancel_unpaid_with_voucher(self):
self.op1.voucher = self.event.vouchers.create(item=self.ticket, redeemed=1) self.op1.voucher = self.event.vouchers.create(item=self.ticket, redeemed=1)
self.op1.save() self.op1.save()
@@ -500,6 +523,7 @@ class OrderCancelTests(TestCase):
assert self.op1.voucher.redeemed == 0 assert self.op1.voucher.redeemed == 0
assert self.order.invoices.count() == 2 assert self.order.invoices.count() == 2
@classscope(attr='o')
def test_cancel_paid(self): def test_cancel_paid(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -509,6 +533,7 @@ class OrderCancelTests(TestCase):
assert self.order.all_logentries().last().action_type == 'pretix.event.order.canceled' assert self.order.all_logentries().last().action_type == 'pretix.event.order.canceled'
assert self.order.invoices.count() == 2 assert self.order.invoices.count() == 2
@classscope(attr='o')
def test_cancel_paid_with_too_high_fee(self): def test_cancel_paid_with_too_high_fee(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -519,6 +544,7 @@ class OrderCancelTests(TestCase):
assert self.order.status == Order.STATUS_PAID assert self.order.status == Order.STATUS_PAID
assert self.order.total == 46 assert self.order.total == 46
@classscope(attr='o')
def test_cancel_paid_with_fee(self): def test_cancel_paid_with_fee(self):
f = self.order.fees.create(fee_type=OrderFee.FEE_TYPE_SHIPPING, value=2.5) f = self.order.fees.create(fee_type=OrderFee.FEE_TYPE_SHIPPING, value=2.5)
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
@@ -543,6 +569,7 @@ class OrderCancelTests(TestCase):
assert self.order.invoices.count() == 3 assert self.order.invoices.count() == 3
assert not self.order.invoices.last().is_cancellation assert not self.order.invoices.last().is_cancellation
@classscope(attr='o')
def test_auto_refund_possible(self): def test_auto_refund_possible(self):
p1 = self.order.payments.create( p1 = self.order.payments.create(
amount=Decimal('46.00'), amount=Decimal('46.00'),
@@ -558,6 +585,7 @@ class OrderCancelTests(TestCase):
assert self.order.all_logentries().filter(action_type='pretix.event.order.refund.created').exists() assert self.order.all_logentries().filter(action_type='pretix.event.order.refund.created').exists()
assert not self.order.all_logentries().filter(action_type='pretix.event.order.refund.requested').exists() assert not self.order.all_logentries().filter(action_type='pretix.event.order.refund.requested').exists()
@classscope(attr='o')
def test_auto_refund_impossible(self): def test_auto_refund_impossible(self):
self.order.payments.create( self.order.payments.create(
amount=Decimal('46.00'), amount=Decimal('46.00'),
@@ -572,8 +600,9 @@ class OrderCancelTests(TestCase):
class OrderChangeManagerTests(TestCase): class OrderChangeManagerTests(TestCase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
o = Organizer.objects.create(name='Dummy', slug='dummy') self.o = Organizer.objects.create(name='Dummy', slug='dummy')
self.event = Event.objects.create(organizer=o, name='Dummy', slug='dummy', date_from=now(), with scope(organizer=self.o):
self.event = Event.objects.create(organizer=self.o, name='Dummy', slug='dummy', date_from=now(),
plugins='pretix.plugins.banktransfer') plugins='pretix.plugins.banktransfer')
self.order = Order.objects.create( self.order = Order.objects.create(
code='FOO', event=self.event, email='dummy@dummy.test', code='FOO', event=self.event, email='dummy@dummy.test',
@@ -618,6 +647,7 @@ class OrderChangeManagerTests(TestCase):
country=Country('AT') country=Country('AT')
) )
@classscope(attr='o')
def test_multiple_commits_forbidden(self): def test_multiple_commits_forbidden(self):
self.ocm.change_price(self.op1, Decimal('10.00')) self.ocm.change_price(self.op1, Decimal('10.00'))
self.ocm.commit() self.ocm.commit()
@@ -625,6 +655,7 @@ class OrderChangeManagerTests(TestCase):
with self.assertRaises(OrderError): with self.assertRaises(OrderError):
self.ocm.commit() self.ocm.commit()
@classscope(attr='o')
def test_change_subevent_quota_required(self): def test_change_subevent_quota_required(self):
self.event.has_subevents = True self.event.has_subevents = True
self.event.save() self.event.save()
@@ -637,6 +668,7 @@ class OrderChangeManagerTests(TestCase):
with self.assertRaises(OrderError): with self.assertRaises(OrderError):
self.ocm.change_subevent(self.op1, se2) self.ocm.change_subevent(self.op1, se2)
@classscope(attr='o')
def test_change_subevent_success(self): def test_change_subevent_success(self):
self.event.has_subevents = True self.event.has_subevents = True
self.event.save() self.event.save()
@@ -656,6 +688,7 @@ class OrderChangeManagerTests(TestCase):
assert self.op1.price == Decimal('23.00') assert self.op1.price == Decimal('23.00')
assert self.order.total == self.op1.price + self.op2.price assert self.order.total == self.op1.price + self.op2.price
@classscope(attr='o')
def test_change_subevent_with_price_success(self): def test_change_subevent_with_price_success(self):
self.event.has_subevents = True self.event.has_subevents = True
self.event.save() self.event.save()
@@ -676,6 +709,7 @@ class OrderChangeManagerTests(TestCase):
assert self.op1.price == Decimal('12.00') assert self.op1.price == Decimal('12.00')
assert self.order.total == self.op1.price + self.op2.price assert self.order.total == self.op1.price + self.op2.price
@classscope(attr='o')
def test_change_subevent_sold_out(self): def test_change_subevent_sold_out(self):
self.event.has_subevents = True self.event.has_subevents = True
self.event.save() self.event.save()
@@ -693,11 +727,13 @@ class OrderChangeManagerTests(TestCase):
self.op1.refresh_from_db() self.op1.refresh_from_db()
assert self.op1.subevent == se1 assert self.op1.subevent == se1
@classscope(attr='o')
def test_change_item_quota_required(self): def test_change_item_quota_required(self):
self.quota.delete() self.quota.delete()
with self.assertRaises(OrderError): with self.assertRaises(OrderError):
self.ocm.change_item(self.op1, self.shirt, None) self.ocm.change_item(self.op1, self.shirt, None)
@classscope(attr='o')
def test_change_item_keep_price(self): def test_change_item_keep_price(self):
p = self.op1.price p = self.op1.price
self.ocm.change_item(self.op1, self.shirt, None) self.ocm.change_item(self.op1, self.shirt, None)
@@ -709,6 +745,7 @@ class OrderChangeManagerTests(TestCase):
assert self.op1.tax_value == Decimal('3.67') assert self.op1.tax_value == Decimal('3.67')
assert self.op1.tax_rule == self.shirt.tax_rule assert self.op1.tax_rule == self.shirt.tax_rule
@classscope(attr='o')
def test_change_item_success(self): def test_change_item_success(self):
self.ocm.change_item(self.op1, self.shirt, None) self.ocm.change_item(self.op1, self.shirt, None)
self.ocm.commit() self.ocm.commit()
@@ -720,6 +757,7 @@ class OrderChangeManagerTests(TestCase):
assert round_decimal(self.op1.price * (1 - 100 / (100 + self.op1.tax_rate))) == self.op1.tax_value assert round_decimal(self.op1.price * (1 - 100 / (100 + self.op1.tax_rate))) == self.op1.tax_value
assert self.order.total == self.op1.price + self.op2.price assert self.order.total == self.op1.price + self.op2.price
@classscope(attr='o')
def test_change_item_with_price_success(self): def test_change_item_with_price_success(self):
self.ocm.change_item(self.op1, self.shirt, None) self.ocm.change_item(self.op1, self.shirt, None)
self.ocm.change_price(self.op1, Decimal('12.00')) self.ocm.change_price(self.op1, Decimal('12.00'))
@@ -732,6 +770,7 @@ class OrderChangeManagerTests(TestCase):
assert round_decimal(self.op1.price * (1 - 100 / (100 + self.op1.tax_rate))) == self.op1.tax_value assert round_decimal(self.op1.price * (1 - 100 / (100 + self.op1.tax_rate))) == self.op1.tax_value
assert self.order.total == self.op1.price + self.op2.price assert self.order.total == self.op1.price + self.op2.price
@classscope(attr='o')
def test_change_price_success(self): def test_change_price_success(self):
self.ocm.change_price(self.op1, Decimal('24.00')) self.ocm.change_price(self.op1, Decimal('24.00'))
self.ocm.commit() self.ocm.commit()
@@ -742,6 +781,7 @@ class OrderChangeManagerTests(TestCase):
assert round_decimal(self.op1.price * (1 - 100 / (100 + self.op1.tax_rate))) == self.op1.tax_value assert round_decimal(self.op1.price * (1 - 100 / (100 + self.op1.tax_rate))) == self.op1.tax_value
assert self.order.total == self.op1.price + self.op2.price assert self.order.total == self.op1.price + self.op2.price
@classscope(attr='o')
def test_change_price_net_success(self): def test_change_price_net_success(self):
self.tr7.price_includes_tax = False self.tr7.price_includes_tax = False
self.tr7.save() self.tr7.save()
@@ -754,6 +794,7 @@ class OrderChangeManagerTests(TestCase):
assert round_decimal(self.op1.price * (1 - 100 / (100 + self.op1.tax_rate))) == self.op1.tax_value assert round_decimal(self.op1.price * (1 - 100 / (100 + self.op1.tax_rate))) == self.op1.tax_value
assert self.order.total == self.op1.price + self.op2.price assert self.order.total == self.op1.price + self.op2.price
@classscope(attr='o')
def test_cancel_success(self): def test_cancel_success(self):
self.ocm.cancel(self.op1) self.ocm.cancel(self.op1)
self.ocm.commit() self.ocm.commit()
@@ -763,6 +804,7 @@ class OrderChangeManagerTests(TestCase):
self.op1.refresh_from_db() self.op1.refresh_from_db()
assert self.op1.canceled assert self.op1.canceled
@classscope(attr='o')
def test_cancel_with_addon(self): def test_cancel_with_addon(self):
self.shirt.category = self.event.categories.create(name='Add-ons', is_addon=True) self.shirt.category = self.event.categories.create(name='Add-ons', is_addon=True)
self.ticket.addons.create(addon_category=self.shirt.category) self.ticket.addons.create(addon_category=self.shirt.category)
@@ -781,6 +823,7 @@ class OrderChangeManagerTests(TestCase):
assert self.op1.canceled assert self.op1.canceled
assert self.op1.addons.first().canceled assert self.op1.addons.first().canceled
@classscope(attr='o')
def test_free_to_paid(self): def test_free_to_paid(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -796,6 +839,7 @@ class OrderChangeManagerTests(TestCase):
assert self.op1.price == Decimal('24.00') assert self.op1.price == Decimal('24.00')
assert self.order.status == Order.STATUS_PENDING assert self.order.status == Order.STATUS_PENDING
@classscope(attr='o')
def test_cancel_all_in_order(self): def test_cancel_all_in_order(self):
self.ocm.cancel(self.op1) self.ocm.cancel(self.op1)
self.ocm.cancel(self.op2) self.ocm.cancel(self.op2)
@@ -803,9 +847,11 @@ class OrderChangeManagerTests(TestCase):
self.ocm.commit() self.ocm.commit()
assert self.order.positions.count() == 2 assert self.order.positions.count() == 2
@classscope(attr='o')
def test_empty(self): def test_empty(self):
self.ocm.commit() self.ocm.commit()
@classscope(attr='o')
def test_quota_unlimited(self): def test_quota_unlimited(self):
q = self.event.quotas.create(name='Test', size=None) q = self.event.quotas.create(name='Test', size=None)
q.items.add(self.shirt) q.items.add(self.shirt)
@@ -814,6 +860,7 @@ class OrderChangeManagerTests(TestCase):
self.op1.refresh_from_db() self.op1.refresh_from_db()
assert self.op1.item == self.shirt assert self.op1.item == self.shirt
@classscope(attr='o')
def test_quota_full(self): def test_quota_full(self):
q = self.event.quotas.create(name='Test', size=0) q = self.event.quotas.create(name='Test', size=0)
q.items.add(self.shirt) q.items.add(self.shirt)
@@ -823,6 +870,7 @@ class OrderChangeManagerTests(TestCase):
self.op1.refresh_from_db() self.op1.refresh_from_db()
assert self.op1.item == self.ticket assert self.op1.item == self.ticket
@classscope(attr='o')
def test_quota_ignore(self): def test_quota_ignore(self):
q = self.event.quotas.create(name='Test', size=0) q = self.event.quotas.create(name='Test', size=0)
q.items.add(self.shirt) q.items.add(self.shirt)
@@ -831,6 +879,7 @@ class OrderChangeManagerTests(TestCase):
self.op1.refresh_from_db() self.op1.refresh_from_db()
assert self.op1.item == self.shirt assert self.op1.item == self.shirt
@classscope(attr='o')
def test_quota_full_but_in_same(self): def test_quota_full_but_in_same(self):
q = self.event.quotas.create(name='Test', size=0) q = self.event.quotas.create(name='Test', size=0)
q.items.add(self.shirt) q.items.add(self.shirt)
@@ -840,6 +889,7 @@ class OrderChangeManagerTests(TestCase):
self.op1.refresh_from_db() self.op1.refresh_from_db()
assert self.op1.item == self.shirt assert self.op1.item == self.shirt
@classscope(attr='o')
def test_multiple_quotas_shared_full(self): def test_multiple_quotas_shared_full(self):
q1 = self.event.quotas.create(name='Test', size=0) q1 = self.event.quotas.create(name='Test', size=0)
q2 = self.event.quotas.create(name='Test', size=2) q2 = self.event.quotas.create(name='Test', size=2)
@@ -851,6 +901,7 @@ class OrderChangeManagerTests(TestCase):
self.op1.refresh_from_db() self.op1.refresh_from_db()
assert self.op1.item == self.shirt assert self.op1.item == self.shirt
@classscope(attr='o')
def test_multiple_quotas_unshared_full(self): def test_multiple_quotas_unshared_full(self):
q1 = self.event.quotas.create(name='Test', size=2) q1 = self.event.quotas.create(name='Test', size=2)
q2 = self.event.quotas.create(name='Test', size=0) q2 = self.event.quotas.create(name='Test', size=0)
@@ -863,6 +914,7 @@ class OrderChangeManagerTests(TestCase):
self.op1.refresh_from_db() self.op1.refresh_from_db()
assert self.op1.item == self.ticket assert self.op1.item == self.ticket
@classscope(attr='o')
def test_multiple_items_success(self): def test_multiple_items_success(self):
q1 = self.event.quotas.create(name='Test', size=2) q1 = self.event.quotas.create(name='Test', size=2)
q1.items.add(self.shirt) q1.items.add(self.shirt)
@@ -874,6 +926,7 @@ class OrderChangeManagerTests(TestCase):
assert self.op1.item == self.shirt assert self.op1.item == self.shirt
assert self.op2.item == self.shirt assert self.op2.item == self.shirt
@classscope(attr='o')
def test_multiple_items_quotas_partially_full(self): def test_multiple_items_quotas_partially_full(self):
q1 = self.event.quotas.create(name='Test', size=1) q1 = self.event.quotas.create(name='Test', size=1)
q1.items.add(self.shirt) q1.items.add(self.shirt)
@@ -886,6 +939,7 @@ class OrderChangeManagerTests(TestCase):
assert self.op1.item == self.ticket assert self.op1.item == self.ticket
assert self.op2.item == self.ticket assert self.op2.item == self.ticket
@classscope(attr='o')
def test_payment_fee_calculation(self): def test_payment_fee_calculation(self):
self.event.settings.set('tax_rate_default', self.tr19.pk) self.event.settings.set('tax_rate_default', self.tr19.pk)
prov = self.ocm._get_payment_provider() prov = self.ocm._get_payment_provider()
@@ -899,6 +953,7 @@ class OrderChangeManagerTests(TestCase):
assert fee.tax_rate == Decimal('19.00') assert fee.tax_rate == Decimal('19.00')
assert round_decimal(fee.value * (1 - 100 / (100 + fee.tax_rate))) == fee.tax_value assert round_decimal(fee.value * (1 - 100 / (100 + fee.tax_rate))) == fee.tax_value
@classscope(attr='o')
def test_pending_free_order_stays_pending(self): def test_pending_free_order_stays_pending(self):
self.event.settings.set('tax_rate_default', self.tr19.pk) self.event.settings.set('tax_rate_default', self.tr19.pk)
self.ocm.change_price(self.op1, Decimal('0.00')) self.ocm.change_price(self.op1, Decimal('0.00'))
@@ -914,6 +969,7 @@ class OrderChangeManagerTests(TestCase):
self.order.refresh_from_db() self.order.refresh_from_db()
assert self.order.status == Order.STATUS_PENDING assert self.order.status == Order.STATUS_PENDING
@classscope(attr='o')
def test_require_pending(self): def test_require_pending(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -922,6 +978,7 @@ class OrderChangeManagerTests(TestCase):
self.op1.refresh_from_db() self.op1.refresh_from_db()
assert self.op1.item == self.shirt assert self.op1.item == self.shirt
@classscope(attr='o')
def test_change_price_to_free_marked_as_paid(self): def test_change_price_to_free_marked_as_paid(self):
self.ocm.change_price(self.op1, Decimal('0.00')) self.ocm.change_price(self.op1, Decimal('0.00'))
self.ocm.change_price(self.op2, Decimal('0.00')) self.ocm.change_price(self.op2, Decimal('0.00'))
@@ -931,6 +988,7 @@ class OrderChangeManagerTests(TestCase):
assert self.order.status == Order.STATUS_PAID assert self.order.status == Order.STATUS_PAID
assert self.order.payments.last().provider == 'free' assert self.order.payments.last().provider == 'free'
@classscope(attr='o')
def test_change_price_to_free_require_approval(self): def test_change_price_to_free_require_approval(self):
self.order.require_approval = True self.order.require_approval = True
self.order.save() self.order.save()
@@ -942,6 +1000,7 @@ class OrderChangeManagerTests(TestCase):
assert self.order.total == 0 assert self.order.total == 0
assert self.order.status == Order.STATUS_PENDING assert self.order.status == Order.STATUS_PENDING
@classscope(attr='o')
def test_change_paid_same_price(self): def test_change_paid_same_price(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -951,6 +1010,7 @@ class OrderChangeManagerTests(TestCase):
assert self.order.total == 46 assert self.order.total == 46
assert self.order.status == Order.STATUS_PAID assert self.order.status == Order.STATUS_PAID
@classscope(attr='o')
def test_change_paid_different_price(self): def test_change_paid_different_price(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -960,6 +1020,7 @@ class OrderChangeManagerTests(TestCase):
assert self.order.total == Decimal('28.00') assert self.order.total == Decimal('28.00')
assert self.order.status == Order.STATUS_PAID assert self.order.status == Order.STATUS_PAID
@classscope(attr='o')
def test_change_paid_to_pending(self): def test_change_paid_to_pending(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -975,6 +1036,7 @@ class OrderChangeManagerTests(TestCase):
assert self.order.pending_sum == Decimal('2.00') assert self.order.pending_sum == Decimal('2.00')
assert self.order.status == Order.STATUS_PENDING assert self.order.status == Order.STATUS_PENDING
@classscope(attr='o')
def test_change_paid_stays_paid_when_overpaid(self): def test_change_paid_stays_paid_when_overpaid(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -996,11 +1058,13 @@ class OrderChangeManagerTests(TestCase):
assert self.order.pending_sum == Decimal('0.00') assert self.order.pending_sum == Decimal('0.00')
assert self.order.status == Order.STATUS_PAID assert self.order.status == Order.STATUS_PAID
@classscope(attr='o')
def test_add_item_quota_required(self): def test_add_item_quota_required(self):
self.quota.delete() self.quota.delete()
with self.assertRaises(OrderError): with self.assertRaises(OrderError):
self.ocm.add_position(self.shirt, None, None, None) self.ocm.add_position(self.shirt, None, None, None)
@classscope(attr='o')
def test_add_item_success(self): def test_add_item_success(self):
self.ocm.add_position(self.shirt, None, None, None) self.ocm.add_position(self.shirt, None, None, None)
self.ocm.commit() self.ocm.commit()
@@ -1014,6 +1078,7 @@ class OrderChangeManagerTests(TestCase):
assert self.order.total == self.op1.price + self.op2.price + nop.price assert self.order.total == self.op1.price + self.op2.price + nop.price
assert nop.positionid == 3 assert nop.positionid == 3
@classscope(attr='o')
def test_add_item_net_price_success(self): def test_add_item_net_price_success(self):
self.tr19.price_includes_tax = False self.tr19.price_includes_tax = False
self.tr19.save() self.tr19.save()
@@ -1029,6 +1094,7 @@ class OrderChangeManagerTests(TestCase):
assert self.order.total == self.op1.price + self.op2.price + nop.price assert self.order.total == self.op1.price + self.op2.price + nop.price
assert nop.positionid == 3 assert nop.positionid == 3
@classscope(attr='o')
def test_add_item_reverse_charge(self): def test_add_item_reverse_charge(self):
self._enable_reverse_charge() self._enable_reverse_charge()
self.ocm.add_position(self.shirt, None, None, None) self.ocm.add_position(self.shirt, None, None, None)
@@ -1043,6 +1109,7 @@ class OrderChangeManagerTests(TestCase):
assert self.order.total == self.op1.price + self.op2.price + nop.price assert self.order.total == self.op1.price + self.op2.price + nop.price
assert nop.positionid == 3 assert nop.positionid == 3
@classscope(attr='o')
def test_add_item_custom_price(self): def test_add_item_custom_price(self):
self.ocm.add_position(self.shirt, None, Decimal('13.00'), None) self.ocm.add_position(self.shirt, None, Decimal('13.00'), None)
self.ocm.commit() self.ocm.commit()
@@ -1055,6 +1122,7 @@ class OrderChangeManagerTests(TestCase):
assert round_decimal(nop.price * (1 - 100 / (100 + self.shirt.tax_rule.rate))) == nop.tax_value assert round_decimal(nop.price * (1 - 100 / (100 + self.shirt.tax_rule.rate))) == nop.tax_value
assert self.order.total == self.op1.price + self.op2.price + nop.price assert self.order.total == self.op1.price + self.op2.price + nop.price
@classscope(attr='o')
def test_add_item_custom_price_tax_always_included(self): def test_add_item_custom_price_tax_always_included(self):
self.tr19.price_includes_tax = False self.tr19.price_includes_tax = False
self.tr19.save() self.tr19.save()
@@ -1069,6 +1137,7 @@ class OrderChangeManagerTests(TestCase):
assert round_decimal(nop.price * (1 - 100 / (100 + self.shirt.tax_rule.rate))) == nop.tax_value assert round_decimal(nop.price * (1 - 100 / (100 + self.shirt.tax_rule.rate))) == nop.tax_value
assert self.order.total == self.op1.price + self.op2.price + nop.price assert self.order.total == self.op1.price + self.op2.price + nop.price
@classscope(attr='o')
def test_add_item_quota_full(self): def test_add_item_quota_full(self):
q1 = self.event.quotas.create(name='Test', size=0) q1 = self.event.quotas.create(name='Test', size=0)
q1.items.add(self.shirt) q1.items.add(self.shirt)
@@ -1077,6 +1146,7 @@ class OrderChangeManagerTests(TestCase):
self.ocm.commit() self.ocm.commit()
assert self.order.positions.count() == 2 assert self.order.positions.count() == 2
@classscope(attr='o')
def test_add_item_addon(self): def test_add_item_addon(self):
self.shirt.category = self.event.categories.create(name='Add-ons', is_addon=True) self.shirt.category = self.event.categories.create(name='Add-ons', is_addon=True)
self.ticket.addons.create(addon_category=self.shirt.category) self.ticket.addons.create(addon_category=self.shirt.category)
@@ -1088,6 +1158,7 @@ class OrderChangeManagerTests(TestCase):
assert nop.item == self.shirt assert nop.item == self.shirt
assert nop.addon_to == self.op1 assert nop.addon_to == self.op1
@classscope(attr='o')
def test_add_item_addon_invalid(self): def test_add_item_addon_invalid(self):
with self.assertRaises(OrderError): with self.assertRaises(OrderError):
self.ocm.add_position(self.shirt, None, Decimal('13.00'), self.op1) self.ocm.add_position(self.shirt, None, Decimal('13.00'), self.op1)
@@ -1095,12 +1166,14 @@ class OrderChangeManagerTests(TestCase):
with self.assertRaises(OrderError): with self.assertRaises(OrderError):
self.ocm.add_position(self.shirt, None, Decimal('13.00'), None) self.ocm.add_position(self.shirt, None, Decimal('13.00'), None)
@classscope(attr='o')
def test_add_item_subevent_required(self): def test_add_item_subevent_required(self):
self.event.has_subevents = True self.event.has_subevents = True
self.event.save() self.event.save()
with self.assertRaises(OrderError): with self.assertRaises(OrderError):
self.ocm.add_position(self.ticket, None, None, None) self.ocm.add_position(self.ticket, None, None, None)
@classscope(attr='o')
def test_add_item_subevent_price(self): def test_add_item_subevent_price(self):
self.event.has_subevents = True self.event.has_subevents = True
self.event.save() self.event.save()
@@ -1118,6 +1191,7 @@ class OrderChangeManagerTests(TestCase):
assert nop.price == Decimal('12.00') assert nop.price == Decimal('12.00')
assert nop.subevent == se1 assert nop.subevent == se1
@classscope(attr='o')
def test_reissue_invoice(self): def test_reissue_invoice(self):
generate_invoice(self.order) generate_invoice(self.order)
assert self.order.invoices.count() == 1 assert self.order.invoices.count() == 1
@@ -1125,6 +1199,7 @@ class OrderChangeManagerTests(TestCase):
self.ocm.commit() self.ocm.commit()
assert self.order.invoices.count() == 3 assert self.order.invoices.count() == 3
@classscope(attr='o')
def test_dont_reissue_invoice_on_free_product_changes(self): def test_dont_reissue_invoice_on_free_product_changes(self):
self.event.settings.invoice_include_free = False self.event.settings.invoice_include_free = False
generate_invoice(self.order) generate_invoice(self.order)
@@ -1133,6 +1208,7 @@ class OrderChangeManagerTests(TestCase):
self.ocm.commit() self.ocm.commit()
assert self.order.invoices.count() == 1 assert self.order.invoices.count() == 1
@classscope(attr='o')
def test_recalculate_reverse_charge(self): def test_recalculate_reverse_charge(self):
self.event.settings.set('tax_rate_default', self.tr19.pk) self.event.settings.set('tax_rate_default', self.tr19.pk)
prov = self.ocm._get_payment_provider() prov = self.ocm._get_payment_provider()
@@ -1179,6 +1255,7 @@ class OrderChangeManagerTests(TestCase):
assert fee.tax_rate == Decimal('19.00') assert fee.tax_rate == Decimal('19.00')
assert fee.tax_value == Decimal('0.05') assert fee.tax_value == Decimal('0.05')
@classscope(attr='o')
def test_split_simple(self): def test_split_simple(self):
old_secret = self.op2.secret old_secret = self.op2.secret
self.ocm.split(self.op2) self.ocm.split(self.op2)
@@ -1198,6 +1275,7 @@ class OrderChangeManagerTests(TestCase):
assert not self.order.invoices.exists() assert not self.order.invoices.exists()
assert not o2.invoices.exists() assert not o2.invoices.exists()
@classscope(attr='o')
def test_split_require_approval(self): def test_split_require_approval(self):
self.op2.item.require_approval = True self.op2.item.require_approval = True
self.op2.item.save() self.op2.item.save()
@@ -1222,6 +1300,7 @@ class OrderChangeManagerTests(TestCase):
assert not self.order.invoices.exists() assert not self.order.invoices.exists()
assert not o2.invoices.exists() assert not o2.invoices.exists()
@classscope(attr='o')
def test_split_pending_payment_fees(self): def test_split_pending_payment_fees(self):
# Set payment fees # Set payment fees
self.event.settings.set('tax_rate_default', self.tr19.pk) self.event.settings.set('tax_rate_default', self.tr19.pk)
@@ -1262,6 +1341,7 @@ class OrderChangeManagerTests(TestCase):
assert o2.positions.count() == 1 assert o2.positions.count() == 1
assert o2.fees.count() == 1 assert o2.fees.count() == 1
@classscope(attr='o')
def test_split_paid_no_payment_fees(self): def test_split_paid_no_payment_fees(self):
self.order.status = Order.STATUS_PAID self.order.status = Order.STATUS_PAID
self.order.save() self.order.save()
@@ -1299,6 +1379,7 @@ class OrderChangeManagerTests(TestCase):
assert p.amount == Decimal('23.00') assert p.amount == Decimal('23.00')
assert p.state == OrderPayment.PAYMENT_STATE_CONFIRMED assert p.state == OrderPayment.PAYMENT_STATE_CONFIRMED
@classscope(attr='o')
def test_split_invoice_address(self): def test_split_invoice_address(self):
ia = InvoiceAddress.objects.create( ia = InvoiceAddress.objects.create(
order=self.order, is_business=True, vat_id='ATU1234567', vat_id_validated=True, order=self.order, is_business=True, vat_id='ATU1234567', vat_id_validated=True,
@@ -1325,6 +1406,7 @@ class OrderChangeManagerTests(TestCase):
assert o2.invoice_address != ia assert o2.invoice_address != ia
assert o2.invoice_address.company == 'Sample' assert o2.invoice_address.company == 'Sample'
@classscope(attr='o')
def test_change_price_of_pending_order_with_payment(self): def test_change_price_of_pending_order_with_payment(self):
self.order.status = Order.STATUS_PENDING self.order.status = Order.STATUS_PENDING
self.order.save() self.order.save()
@@ -1337,6 +1419,7 @@ class OrderChangeManagerTests(TestCase):
assert self.order.payments.last().state == OrderPayment.PAYMENT_STATE_CANCELED assert self.order.payments.last().state == OrderPayment.PAYMENT_STATE_CANCELED
assert self.order.payments.last().amount == Decimal('46.00') assert self.order.payments.last().amount == Decimal('46.00')
@classscope(attr='o')
def test_split_reverse_charge(self): def test_split_reverse_charge(self):
ia = self._enable_reverse_charge() ia = self._enable_reverse_charge()
@@ -1393,6 +1476,7 @@ class OrderChangeManagerTests(TestCase):
assert o2.invoice_address != ia assert o2.invoice_address != ia
assert o2.invoice_address.vat_id_validated is True assert o2.invoice_address.vat_id_validated is True
@classscope(attr='o')
def test_split_other_fees(self): def test_split_other_fees(self):
# Check if reverse charge is active # Check if reverse charge is active
self.order.fees.create(fee_type=OrderFee.FEE_TYPE_SHIPPING, tax_rule=self.tr19, value=Decimal('2.50')) self.order.fees.create(fee_type=OrderFee.FEE_TYPE_SHIPPING, tax_rule=self.tr19, value=Decimal('2.50'))
@@ -1424,12 +1508,14 @@ class OrderChangeManagerTests(TestCase):
assert o2.positions.first().price == Decimal('23.00') assert o2.positions.first().price == Decimal('23.00')
assert o2.fees.count() == 1 assert o2.fees.count() == 1
@classscope(attr='o')
def test_split_to_empty(self): def test_split_to_empty(self):
self.ocm.split(self.op1) self.ocm.split(self.op1)
self.ocm.split(self.op2) self.ocm.split(self.op2)
with self.assertRaises(OrderError): with self.assertRaises(OrderError):
self.ocm.commit() self.ocm.commit()
@classscope(attr='o')
def test_split_paid_payment_fees(self): def test_split_paid_payment_fees(self):
# Set payment fees # Set payment fees
self.event.settings.set('tax_rate_default', self.tr19.pk) self.event.settings.set('tax_rate_default', self.tr19.pk)
@@ -1472,6 +1558,7 @@ class OrderChangeManagerTests(TestCase):
assert o2.total == Decimal('23.00') assert o2.total == Decimal('23.00')
assert o2.fees.count() == 0 assert o2.fees.count() == 0
@classscope(attr='o')
def test_split_invoice(self): def test_split_invoice(self):
generate_invoice(self.order) generate_invoice(self.order)
assert self.order.invoices.count() == 1 assert self.order.invoices.count() == 1
@@ -1487,6 +1574,7 @@ class OrderChangeManagerTests(TestCase):
assert o2.invoices.count() == 1 assert o2.invoices.count() == 1
assert o2.invoices.last().lines.count() == 1 assert o2.invoices.last().lines.count() == 1
@classscope(attr='o')
def test_split_to_free_invoice(self): def test_split_to_free_invoice(self):
self.event.settings.invoice_include_free = False self.event.settings.invoice_include_free = False
self.ocm.change_price(self.op2, Decimal('0.00')) self.ocm.change_price(self.op2, Decimal('0.00'))
@@ -1508,6 +1596,7 @@ class OrderChangeManagerTests(TestCase):
assert self.order.invoices.last().lines.count() == 1 assert self.order.invoices.last().lines.count() == 1
assert o2.invoices.count() == 0 assert o2.invoices.count() == 0
@classscope(attr='o')
def test_split_to_original_free(self): def test_split_to_original_free(self):
self.ocm.change_price(self.op2, Decimal('0.00')) self.ocm.change_price(self.op2, Decimal('0.00'))
self.ocm.commit() self.ocm.commit()
@@ -1525,6 +1614,7 @@ class OrderChangeManagerTests(TestCase):
assert o2.total == Decimal('23.00') assert o2.total == Decimal('23.00')
assert o2.status == Order.STATUS_PENDING assert o2.status == Order.STATUS_PENDING
@classscope(attr='o')
def test_split_to_new_free(self): def test_split_to_new_free(self):
self.ocm.change_price(self.op2, Decimal('0.00')) self.ocm.change_price(self.op2, Decimal('0.00'))
self.ocm.commit() self.ocm.commit()

View File

@@ -4,6 +4,7 @@ from decimal import Decimal
import pytest import pytest
import pytz import pytz
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scope
from tests.testdummy.payment import DummyPaymentProvider from tests.testdummy.payment import DummyPaymentProvider
from pretix.base.models import ( from pretix.base.models import (
@@ -19,7 +20,8 @@ def event():
organizer=o, name='Dummy', slug='dummy', organizer=o, name='Dummy', slug='dummy',
date_from=now() date_from=now()
) )
return event with scope(organizer=o):
yield event
@pytest.mark.django_db @pytest.mark.django_db

View File

@@ -1,6 +1,7 @@
import pytest import pytest
from django.test import RequestFactory from django.test import RequestFactory
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scope
from pretix.base.models import Event, Organizer, Team, User from pretix.base.models import Event, Organizer, Team, User
from pretix.multidomain.middlewares import SessionMiddleware from pretix.multidomain.middlewares import SessionMiddleware
@@ -8,7 +9,9 @@ from pretix.multidomain.middlewares import SessionMiddleware
@pytest.fixture @pytest.fixture
def organizer(): def organizer():
return Organizer.objects.create(name='Dummy', slug='dummy') o = Organizer.objects.create(name='Dummy', slug='dummy')
with scope(organizer=o):
yield o
@pytest.fixture @pytest.fixture
@@ -251,6 +254,7 @@ def test_list_of_events(event, user, admin, admin_request):
team2.limit_events.add(event) team2.limit_events.add(event)
team3.limit_events.add(event3) team3.limit_events.add(event3)
with scope(organizer=[event.organizer, orga2]):
events = list(user.get_events_with_any_permission(request=admin_request)) events = list(user.get_events_with_any_permission(request=admin_request))
assert event in events assert event in events
assert event2 in events assert event2 in events

View File

@@ -2,6 +2,7 @@ from datetime import datetime, time
import pytest import pytest
import pytz import pytz
from django_scopes import scope
from pretix.base.models import Event, Organizer from pretix.base.models import Event, Organizer
from pretix.base.reldate import RelativeDate, RelativeDateWrapper from pretix.base.reldate import RelativeDate, RelativeDateWrapper
@@ -41,6 +42,7 @@ def test_relative_date_without_time(event):
@pytest.mark.django_db @pytest.mark.django_db
def test_relative_date_other_base_point(event): def test_relative_date_other_base_point(event):
with scope(organizer=event.organizer):
rdw = RelativeDateWrapper(RelativeDate(days_before=1, time=None, base_date_name='presale_start')) rdw = RelativeDateWrapper(RelativeDate(days_before=1, time=None, base_date_name='presale_start'))
assert rdw.datetime(event) == TOKYO.localize(datetime(2017, 11, 30, 5, 0, 0)) assert rdw.datetime(event) == TOKYO.localize(datetime(2017, 11, 30, 5, 0, 0))
assert rdw.to_string() == 'RELDATE/1/-/presale_start/' assert rdw.to_string() == 'RELDATE/1/-/presale_start/'

View File

@@ -1,5 +1,6 @@
from django.test import TestCase from django.test import TestCase
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from i18nfield.strings import LazyI18nString from i18nfield.strings import LazyI18nString
from pretix.base import settings from pretix.base import settings
@@ -43,6 +44,7 @@ class SettingsTestCase(TestCase):
sandbox['bar'] = 'baz' sandbox['bar'] = 'baz'
sandbox.baz = 42 sandbox.baz = 42
with scopes_disabled():
self.event = Event.objects.get(id=self.event.id) self.event = Event.objects.get(id=self.event.id)
sandbox = SettingsSandbox('testing', 'foo', self.event) sandbox = SettingsSandbox('testing', 'foo', self.event)
self.assertEqual(sandbox['bar'], 'baz') self.assertEqual(sandbox['bar'], 'baz')

View File

@@ -6,6 +6,7 @@ from decimal import Decimal
import pytest import pytest
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scope
from pretix.base.models import ( from pretix.base.models import (
CachedCombinedTicket, CachedTicket, Event, InvoiceAddress, Order, CachedCombinedTicket, CachedTicket, Event, InvoiceAddress, Order,
@@ -27,7 +28,8 @@ def event():
organizer=o, name='Dummy', slug='dummy', organizer=o, name='Dummy', slug='dummy',
date_from=now(), plugins='pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf' date_from=now(), plugins='pretix.plugins.banktransfer,pretix.plugins.ticketoutputpdf'
) )
return event with scope(organizer=o):
yield event
@pytest.fixture @pytest.fixture

View File

@@ -4,6 +4,7 @@ from decimal import Decimal
import pytest import pytest
from django.utils.timezone import now from django.utils.timezone import now
from django_countries.fields import Country from django_countries.fields import Country
from django_scopes import scope
from pretix.base.models import Event, InvoiceAddress, Organizer, TaxRule from pretix.base.models import Event, InvoiceAddress, Organizer, TaxRule
@@ -15,7 +16,8 @@ def event():
organizer=o, name='Dummy', slug='dummy', organizer=o, name='Dummy', slug='dummy',
date_from=now() date_from=now()
) )
return event with scope(organizer=o):
yield event
@pytest.mark.django_db @pytest.mark.django_db

View File

@@ -3,6 +3,7 @@ from decimal import Decimal
import pytest import pytest
import pytz import pytz
from django_scopes import scope
from pretix.base.models import Event, Organizer from pretix.base.models import Event, Organizer
from pretix.base.timeline import timeline_for_event from pretix.base.timeline import timeline_for_event
@@ -29,7 +30,8 @@ def event():
date_from=datetime(2017, 10, 22, 12, 0, 0, tzinfo=tz), date_from=datetime(2017, 10, 22, 12, 0, 0, tzinfo=tz),
date_to=datetime(2017, 10, 23, 23, 0, 0, tzinfo=tz), date_to=datetime(2017, 10, 23, 23, 0, 0, tzinfo=tz),
) )
return event with scope(organizer=o):
yield event
@pytest.fixture @pytest.fixture

View File

@@ -3,6 +3,7 @@ from datetime import timedelta
from django.core import mail as djmail from django.core import mail as djmail
from django.test import TestCase from django.test import TestCase
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scope
from pretix.base.models import ( from pretix.base.models import (
Event, Item, ItemVariation, Organizer, Quota, Voucher, WaitingListEntry, Event, Item, ItemVariation, Organizer, Quota, Voucher, WaitingListEntry,
@@ -11,19 +12,21 @@ from pretix.base.models.waitinglist import WaitingListException
from pretix.base.services.waitinglist import ( from pretix.base.services.waitinglist import (
assign_automatically, process_waitinglist, assign_automatically, process_waitinglist,
) )
from pretix.testutils.scope import classscope
class WaitingListTestCase(TestCase): class WaitingListTestCase(TestCase):
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
o = Organizer.objects.create(name='Dummy', slug='dummy') cls.o = Organizer.objects.create(name='Dummy', slug='dummy')
cls.event = Event.objects.create( cls.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy', organizer=cls.o, name='Dummy', slug='dummy',
date_from=now(), live=True date_from=now(), live=True
) )
def setUp(self): def setUp(self):
djmail.outbox = [] djmail.outbox = []
with scope(organizer=self.o):
self.quota = Quota.objects.create(name="Test", size=2, event=self.event) self.quota = Quota.objects.create(name="Test", size=2, event=self.event)
self.item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23, self.item1 = Item.objects.create(event=self.event, name="Ticket", default_price=23,
admission=True) admission=True)
@@ -33,6 +36,7 @@ class WaitingListTestCase(TestCase):
self.var2 = ItemVariation.objects.create(item=self.item2, value='M') self.var2 = ItemVariation.objects.create(item=self.item2, value='M')
self.var3 = ItemVariation.objects.create(item=self.item3, value='Fancy') self.var3 = ItemVariation.objects.create(item=self.item3, value='Fancy')
@classscope(attr='o')
def test_send_unavailable(self): def test_send_unavailable(self):
self.quota.items.add(self.item1) self.quota.items.add(self.item1)
self.quota.size = 0 self.quota.size = 0
@@ -43,6 +47,7 @@ class WaitingListTestCase(TestCase):
with self.assertRaises(WaitingListException): with self.assertRaises(WaitingListException):
wle.send_voucher() wle.send_voucher()
@classscope(attr='o')
def test_send_double(self): def test_send_double(self):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = 1 self.quota.size = 1
@@ -54,6 +59,7 @@ class WaitingListTestCase(TestCase):
with self.assertRaises(WaitingListException): with self.assertRaises(WaitingListException):
wle.send_voucher() wle.send_voucher()
@classscope(attr='o')
def test_send_variation(self): def test_send_variation(self):
wle = WaitingListEntry.objects.create( wle = WaitingListEntry.objects.create(
event=self.event, item=self.item2, variation=self.var1, email='foo@bar.com' event=self.event, item=self.item2, variation=self.var1, email='foo@bar.com'
@@ -72,6 +78,7 @@ class WaitingListTestCase(TestCase):
assert len(djmail.outbox) == 1 assert len(djmail.outbox) == 1
assert djmail.outbox[0].to == [wle.email] assert djmail.outbox[0].to == [wle.email]
@classscope(attr='o')
def test_send_custom_validity(self): def test_send_custom_validity(self):
self.event.settings.set('waiting_list_hours', 24) self.event.settings.set('waiting_list_hours', 24)
wle = WaitingListEntry.objects.create( wle = WaitingListEntry.objects.create(
@@ -83,6 +90,7 @@ class WaitingListTestCase(TestCase):
assert 3600 * 23 < (wle.voucher.valid_until - now()).seconds < 3600 * 24 assert 3600 * 23 < (wle.voucher.valid_until - now()).seconds < 3600 * 24
def test_send_auto(self): def test_send_auto(self):
with scope(organizer=self.o):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = 7 self.quota.size = 7
self.quota.save() self.quota.save()
@@ -95,6 +103,7 @@ class WaitingListTestCase(TestCase):
) )
assign_automatically.apply(args=(self.event.pk,)) assign_automatically.apply(args=(self.event.pk,))
with scope(organizer=self.o):
assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 3 assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 3
assert Voucher.objects.count() == 17 assert Voucher.objects.count() == 17
assert sorted(list(WaitingListEntry.objects.filter(voucher__isnull=True).values_list('email', flat=True))) == [ assert sorted(list(WaitingListEntry.objects.filter(voucher__isnull=True).values_list('email', flat=True))) == [
@@ -102,6 +111,7 @@ class WaitingListTestCase(TestCase):
] ]
def test_send_auto_respect_priority(self): def test_send_auto_respect_priority(self):
with scope(organizer=self.o):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = 7 self.quota.size = 7
self.quota.save() self.quota.save()
@@ -116,6 +126,7 @@ class WaitingListTestCase(TestCase):
) )
assign_automatically.apply(args=(self.event.pk,)) assign_automatically.apply(args=(self.event.pk,))
with scope(organizer=self.o):
assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 3 assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 3
assert Voucher.objects.count() == 17 assert Voucher.objects.count() == 17
assert sorted(list(WaitingListEntry.objects.filter(voucher__isnull=True).values_list('email', flat=True))) == [ assert sorted(list(WaitingListEntry.objects.filter(voucher__isnull=True).values_list('email', flat=True))) == [
@@ -123,6 +134,7 @@ class WaitingListTestCase(TestCase):
] ]
def test_send_auto_quota_infinite(self): def test_send_auto_quota_infinite(self):
with scope(organizer=self.o):
self.quota.variations.add(self.var1) self.quota.variations.add(self.var1)
self.quota.size = None self.quota.size = None
self.quota.save() self.quota.save()
@@ -135,6 +147,7 @@ class WaitingListTestCase(TestCase):
) )
assign_automatically.apply(args=(self.event.pk,)) assign_automatically.apply(args=(self.event.pk,))
with scope(organizer=self.o):
assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 10 assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 10
assert Voucher.objects.count() == 10 assert Voucher.objects.count() == 10
@@ -143,11 +156,13 @@ class WaitingListTestCase(TestCase):
self.event.settings.set('waiting_list_auto', True) self.event.settings.set('waiting_list_auto', True)
self.event.presale_end = now() - timedelta(days=1) self.event.presale_end = now() - timedelta(days=1)
self.event.save() self.event.save()
with scope(organizer=self.o):
for i in range(5): for i in range(5):
WaitingListEntry.objects.create( WaitingListEntry.objects.create(
event=self.event, item=self.item2, variation=self.var1, email='foo{}@bar.com'.format(i) event=self.event, item=self.item2, variation=self.var1, email='foo{}@bar.com'.format(i)
) )
process_waitinglist(None) process_waitinglist(None)
with scope(organizer=self.o):
assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 5 assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 5
assert Voucher.objects.count() == 0 assert Voucher.objects.count() == 0
self.event.presale_end = now() + timedelta(days=1) self.event.presale_end = now() + timedelta(days=1)
@@ -156,30 +171,36 @@ class WaitingListTestCase(TestCase):
def test_send_periodic(self): def test_send_periodic(self):
self.event.settings.set('waiting_list_enabled', True) self.event.settings.set('waiting_list_enabled', True)
self.event.settings.set('waiting_list_auto', True) self.event.settings.set('waiting_list_auto', True)
with scope(organizer=self.o):
for i in range(5): for i in range(5):
WaitingListEntry.objects.create( WaitingListEntry.objects.create(
event=self.event, item=self.item2, variation=self.var1, email='foo{}@bar.com'.format(i) event=self.event, item=self.item2, variation=self.var1, email='foo{}@bar.com'.format(i)
) )
process_waitinglist(None) process_waitinglist(None)
with scope(organizer=self.o):
assert Voucher.objects.count() == 5 assert Voucher.objects.count() == 5
def test_send_periodic_disabled(self): def test_send_periodic_disabled(self):
self.event.settings.set('waiting_list_enabled', True) self.event.settings.set('waiting_list_enabled', True)
self.event.settings.set('waiting_list_auto', False) self.event.settings.set('waiting_list_auto', False)
with scope(organizer=self.o):
for i in range(5): for i in range(5):
WaitingListEntry.objects.create( WaitingListEntry.objects.create(
event=self.event, item=self.item2, variation=self.var1, email='foo{}@bar.com'.format(i) event=self.event, item=self.item2, variation=self.var1, email='foo{}@bar.com'.format(i)
) )
process_waitinglist(None) process_waitinglist(None)
with scope(organizer=self.o):
assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 5 assert WaitingListEntry.objects.filter(voucher__isnull=True).count() == 5
assert Voucher.objects.count() == 0 assert Voucher.objects.count() == 0
def test_send_periodic_disabled2(self): def test_send_periodic_disabled2(self):
self.event.settings.set('waiting_list_enabled', False) self.event.settings.set('waiting_list_enabled', False)
self.event.settings.set('waiting_list_auto', True) self.event.settings.set('waiting_list_auto', True)
with scope(organizer=self.o):
for i in range(5): for i in range(5):
WaitingListEntry.objects.create( WaitingListEntry.objects.create(
event=self.event, item=self.item2, variation=self.var1, email='foo{}@bar.com'.format(i) event=self.event, item=self.item2, variation=self.var1, email='foo{}@bar.com'.format(i)
) )
process_waitinglist(None) process_waitinglist(None)
with scope(organizer=self.o):
assert Voucher.objects.count() == 5 assert Voucher.objects.count() == 5

View File

@@ -6,6 +6,7 @@ import pytest
import responses import responses
from django.db import transaction from django.db import transaction
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from pretix.base.models import Event, Item, Order, OrderPosition, Organizer from pretix.base.models import Event, Item, Order, OrderPosition, Organizer
@@ -83,6 +84,7 @@ def test_webhook_trigger_event_specific(event, order, webhook, monkeypatch_on_co
"code": "FOO", "code": "FOO",
"action": "pretix.event.order.paid" "action": "pretix.event.order.paid"
} }
with scopes_disabled():
first = webhook.calls.last() first = webhook.calls.last()
assert first.webhook == webhook assert first.webhook == webhook
assert first.target_url == 'https://google.com' assert first.target_url == 'https://google.com'
@@ -170,6 +172,7 @@ def test_webhook_retry(event, order, webhook, monkeypatch_on_commit):
with transaction.atomic(): with transaction.atomic():
order.log_action('pretix.event.order.paid', {}) order.log_action('pretix.event.order.paid', {})
assert len(responses.calls) == 2 assert len(responses.calls) == 2
with scopes_disabled():
second = webhook.objects.first() second = webhook.objects.first()
first = webhook.objects.last() first = webhook.objects.last()

View File

@@ -1,4 +1,7 @@
import inspect
import pytest import pytest
from django_scopes import scopes_disabled
from xdist.dsession import DSession from xdist.dsession import DSession
CRASHED_ITEMS = set() CRASHED_ITEMS = set()
@@ -31,3 +34,16 @@ def pytest_configure(config):
self.sched.check_schedule(node) self.sched.check_schedule(node)
DSession.handle_crashitem = _handle_crashitem DSession.handle_crashitem = _handle_crashitem
@pytest.hookimpl(hookwrapper=True)
def pytest_fixture_setup(fixturedef, request):
"""
This hack automatically disables django-scopes for all fixtures which are not yield fixtures.
This saves us a *lot* of decorcators…
"""
if inspect.isgeneratorfunction(fixturedef.func):
yield
else:
with scopes_disabled():
yield

View File

@@ -239,7 +239,7 @@ class Login2FAFormTest(TestCase):
def test_totp_invalid(self): def test_totp_invalid(self):
response = self.client.get('/control/login/2fa') response = self.client.get('/control/login/2fa')
assert 'token' in response.rendered_content assert 'token' in response.content.decode()
d = TOTPDevice.objects.create(user=self.user, name='test') d = TOTPDevice.objects.create(user=self.user, name='test')
totp = TOTP(d.bin_key, d.step, d.t0, d.digits, d.drift) totp = TOTP(d.bin_key, d.step, d.t0, d.digits, d.drift)
totp.time = time.time() totp.time = time.time()
@@ -251,7 +251,7 @@ class Login2FAFormTest(TestCase):
def test_totp_valid(self): def test_totp_valid(self):
response = self.client.get('/control/login/2fa') response = self.client.get('/control/login/2fa')
assert 'token' in response.rendered_content assert 'token' in response.content.decode()
d = TOTPDevice.objects.create(user=self.user, name='test') d = TOTPDevice.objects.create(user=self.user, name='test')
totp = TOTP(d.bin_key, d.step, d.t0, d.digits, d.drift) totp = TOTP(d.bin_key, d.step, d.t0, d.digits, d.drift)
totp.time = time.time() totp.time = time.time()
@@ -274,7 +274,7 @@ class Login2FAFormTest(TestCase):
d = U2FDevice.objects.create(user=self.user, name='test', json_data="{}") d = U2FDevice.objects.create(user=self.user, name='test', json_data="{}")
response = self.client.get('/control/login/2fa') response = self.client.get('/control/login/2fa')
assert 'token' in response.rendered_content assert 'token' in response.content.decode()
response = self.client.post('/control/login/2fa'.format(d.pk), { response = self.client.post('/control/login/2fa'.format(d.pk), {
'token': '{"response": "true"}' 'token': '{"response": "true"}'
}) })
@@ -291,7 +291,7 @@ class Login2FAFormTest(TestCase):
d = U2FDevice.objects.create(user=self.user, name='test', json_data="{}") d = U2FDevice.objects.create(user=self.user, name='test', json_data="{}")
response = self.client.get('/control/login/2fa') response = self.client.get('/control/login/2fa')
assert 'token' in response.rendered_content assert 'token' in response.content.decode()
response = self.client.post('/control/login/2fa'.format(d.pk), { response = self.client.post('/control/login/2fa'.format(d.pk), {
'token': '{"response": "true"}' 'token': '{"response": "true"}'
}) })

View File

@@ -3,6 +3,7 @@ from decimal import Decimal
import pytest import pytest
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from pretix.base.models import ( from pretix.base.models import (
Checkin, Event, Item, ItemAddOn, ItemCategory, LogEntry, Order, Checkin, Event, Item, ItemAddOn, ItemCategory, LogEntry, Order,
@@ -58,12 +59,14 @@ def dashboard_env():
@pytest.mark.django_db @pytest.mark.django_db
@scopes_disabled()
def test_dashboard(dashboard_env): def test_dashboard(dashboard_env):
c = checkin_widget(dashboard_env[0]) c = checkin_widget(dashboard_env[0])
assert '0/2' in c[0]['content'] assert '0/2' in c[0]['content']
@pytest.mark.django_db @pytest.mark.django_db
@scopes_disabled()
def test_dashboard_pending_not_count(dashboard_env): def test_dashboard_pending_not_count(dashboard_env):
c = checkin_widget(dashboard_env[0]) c = checkin_widget(dashboard_env[0])
order_pending = Order.objects.create( order_pending = Order.objects.create(
@@ -83,6 +86,7 @@ def test_dashboard_pending_not_count(dashboard_env):
@pytest.mark.django_db @pytest.mark.django_db
@scopes_disabled()
def test_dashboard_with_checkin(dashboard_env): def test_dashboard_with_checkin(dashboard_env):
op = OrderPosition.objects.get( op = OrderPosition.objects.get(
order=dashboard_env[3], order=dashboard_env[3],
@@ -256,10 +260,12 @@ def test_checkins_list_mixed(client, checkin_list_env, query, expected):
@pytest.mark.django_db @pytest.mark.django_db
def test_manual_checkins(client, checkin_list_env): def test_manual_checkins(client, checkin_list_env):
client.login(email='dummy@dummy.dummy', password='dummy') client.login(email='dummy@dummy.dummy', password='dummy')
with scopes_disabled():
assert not checkin_list_env[5][3].checkins.exists() assert not checkin_list_env[5][3].checkins.exists()
client.post('/control/event/dummy/dummy/checkinlists/{}/'.format(checkin_list_env[6].pk), { client.post('/control/event/dummy/dummy/checkinlists/{}/'.format(checkin_list_env[6].pk), {
'checkin': [checkin_list_env[5][3].pk] 'checkin': [checkin_list_env[5][3].pk]
}) })
with scopes_disabled():
assert checkin_list_env[5][3].checkins.exists() assert checkin_list_env[5][3].checkins.exists()
assert LogEntry.objects.filter( assert LogEntry.objects.filter(
action_type='pretix.event.checkin', object_id=checkin_list_env[5][3].order.pk action_type='pretix.event.checkin', object_id=checkin_list_env[5][3].order.pk
@@ -269,6 +275,7 @@ def test_manual_checkins(client, checkin_list_env):
@pytest.mark.django_db @pytest.mark.django_db
def test_manual_checkins_revert(client, checkin_list_env): def test_manual_checkins_revert(client, checkin_list_env):
client.login(email='dummy@dummy.dummy', password='dummy') client.login(email='dummy@dummy.dummy', password='dummy')
with scopes_disabled():
assert not checkin_list_env[5][3].checkins.exists() assert not checkin_list_env[5][3].checkins.exists()
client.post('/control/event/dummy/dummy/checkinlists/{}/'.format(checkin_list_env[6].pk), { client.post('/control/event/dummy/dummy/checkinlists/{}/'.format(checkin_list_env[6].pk), {
'checkin': [checkin_list_env[5][3].pk] 'checkin': [checkin_list_env[5][3].pk]
@@ -277,6 +284,7 @@ def test_manual_checkins_revert(client, checkin_list_env):
'checkin': [checkin_list_env[5][3].pk], 'checkin': [checkin_list_env[5][3].pk],
'revert': 'true' 'revert': 'true'
}) })
with scopes_disabled():
assert not checkin_list_env[5][3].checkins.exists() assert not checkin_list_env[5][3].checkins.exists()
assert LogEntry.objects.filter( assert LogEntry.objects.filter(
action_type='pretix.event.checkin', object_id=checkin_list_env[5][3].order.pk action_type='pretix.event.checkin', object_id=checkin_list_env[5][3].order.pk
@@ -381,11 +389,11 @@ def test_checkins_attendee_name_from_addon_available(client, checkin_list_with_a
class CheckinListFormTest(SoupTest): class CheckinListFormTest(SoupTest):
@scopes_disabled()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy') self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
self.orga1 = Organizer.objects.create(name='CCC', slug='ccc') self.orga1 = Organizer.objects.create(name='CCC', slug='ccc')
self.orga2 = Organizer.objects.create(name='MRM', slug='mrm')
self.event1 = Event.objects.create( self.event1 = Event.objects.create(
organizer=self.orga1, name='30C3', slug='30c3', organizer=self.orga1, name='30C3', slug='30c3',
date_from=datetime(2013, 12, 26, tzinfo=timezone.utc), date_from=datetime(2013, 12, 26, tzinfo=timezone.utc),
@@ -404,11 +412,13 @@ class CheckinListFormTest(SoupTest):
doc = self.post_doc('/control/event/%s/%s/checkinlists/add' % (self.orga1.slug, self.event1.slug), form_data) doc = self.post_doc('/control/event/%s/%s/checkinlists/add' % (self.orga1.slug, self.event1.slug), form_data)
assert doc.select(".alert-success") assert doc.select(".alert-success")
self.assertIn("All", doc.select("#page-wrapper table")[0].text) self.assertIn("All", doc.select("#page-wrapper table")[0].text)
with scopes_disabled():
assert self.event1.checkin_lists.get( assert self.event1.checkin_lists.get(
name='All', all_products=True name='All', all_products=True
) )
def test_update(self): def test_update(self):
with scopes_disabled():
cl = self.event1.checkin_lists.create(name='All', all_products=True) cl = self.event1.checkin_lists.create(name='All', all_products=True)
doc = self.get_doc('/control/event/%s/%s/checkinlists/%s/change' % (self.orga1.slug, self.event1.slug, cl.id)) doc = self.get_doc('/control/event/%s/%s/checkinlists/%s/change' % (self.orga1.slug, self.event1.slug, cl.id))
form_data = extract_form_fields(doc.select('.container-fluid form')[0]) form_data = extract_form_fields(doc.select('.container-fluid form')[0])
@@ -419,9 +429,11 @@ class CheckinListFormTest(SoupTest):
assert doc.select(".alert-success") assert doc.select(".alert-success")
cl.refresh_from_db() cl.refresh_from_db()
assert not cl.all_products assert not cl.all_products
with scopes_disabled():
assert list(cl.limit_products.all()) == [self.item_ticket] assert list(cl.limit_products.all()) == [self.item_ticket]
def test_delete(self): def test_delete(self):
with scopes_disabled():
cl = self.event1.checkin_lists.create(name='All', all_products=True) cl = self.event1.checkin_lists.create(name='All', all_products=True)
doc = self.get_doc('/control/event/%s/%s/checkinlists/%s/delete' % (self.orga1.slug, self.event1.slug, cl.id)) doc = self.get_doc('/control/event/%s/%s/checkinlists/%s/delete' % (self.orga1.slug, self.event1.slug, cl.id))
form_data = extract_form_fields(doc.select('.container-fluid form')[0]) form_data = extract_form_fields(doc.select('.container-fluid form')[0])
@@ -429,4 +441,5 @@ class CheckinListFormTest(SoupTest):
form_data) form_data)
assert doc.select(".alert-success") assert doc.select(".alert-success")
self.assertNotIn("VAT", doc.select("#page-wrapper")[0].text) self.assertNotIn("VAT", doc.select("#page-wrapper")[0].text)
with scopes_disabled():
assert not self.event1.checkin_lists.exists() assert not self.event1.checkin_lists.exists()

View File

@@ -1,5 +1,6 @@
import pytest import pytest
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from pretix.base.models import Device, Event, Organizer, Team, User from pretix.base.models import Device, Event, Organizer, Team, User
from pretix.base.models.devices import generate_api_token from pretix.base.models.devices import generate_api_token
@@ -40,7 +41,7 @@ def admin_team(organizer):
def test_list_of_devices(event, admin_user, client, device): def test_list_of_devices(event, admin_user, client, device):
client.login(email='dummy@dummy.dummy', password='dummy') client.login(email='dummy@dummy.dummy', password='dummy')
resp = client.get('/control/organizer/dummy/devices') resp = client.get('/control/organizer/dummy/devices')
assert 'Cashdesk' in resp.rendered_content assert 'Cashdesk' in resp.content.decode()
@pytest.mark.django_db @pytest.mark.django_db
@@ -50,6 +51,8 @@ def test_create_device(event, admin_user, admin_team, client):
'name': 'Foo', 'name': 'Foo',
'limit_events': str(event.pk), 'limit_events': str(event.pk),
}, follow=True) }, follow=True)
print(resp.status_code, resp.content)
with scopes_disabled():
d = Device.objects.last() d = Device.objects.last()
assert d.name == 'Foo' assert d.name == 'Foo'
assert not d.all_events assert not d.all_events
@@ -67,12 +70,14 @@ def test_update_device(event, admin_user, admin_team, device, client):
device.refresh_from_db() device.refresh_from_db()
assert device.name == 'Cashdesk 2' assert device.name == 'Cashdesk 2'
assert not device.all_events assert not device.all_events
with scopes_disabled():
assert list(device.limit_events.all()) == [event] assert list(device.limit_events.all()) == [event]
@pytest.mark.django_db @pytest.mark.django_db
def test_revoke_device(event, admin_user, admin_team, device, client): def test_revoke_device(event, admin_user, admin_team, device, client):
client.login(email='dummy@dummy.dummy', password='dummy') client.login(email='dummy@dummy.dummy', password='dummy')
with scopes_disabled():
device.api_token = generate_api_token() device.api_token = generate_api_token()
device.initialized = now() device.initialized = now()
device.save() device.save()

View File

@@ -3,6 +3,7 @@ from decimal import Decimal
import pytz import pytz
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from i18nfield.strings import LazyI18nString from i18nfield.strings import LazyI18nString
from pytz import timezone from pytz import timezone
from tests.base import SoupTest, extract_form_fields from tests.base import SoupTest, extract_form_fields
@@ -15,6 +16,7 @@ from pretix.testutils.mock import mocker_context
class EventsTest(SoupTest): class EventsTest(SoupTest):
@scopes_disabled()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy') self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
@@ -49,6 +51,7 @@ class EventsTest(SoupTest):
self.assertNotIn("MRMCD14", tabletext) self.assertNotIn("MRMCD14", tabletext)
def test_quick_setup_later(self): def test_quick_setup_later(self):
with scopes_disabled():
self.event1.quotas.create(name='foo', size=2) self.event1.quotas.create(name='foo', size=2)
resp = self.client.get('/control/event/%s/%s/quickstart/' % (self.orga1.slug, self.event1.slug)) resp = self.client.get('/control/event/%s/%s/quickstart/' % (self.orga1.slug, self.event1.slug))
self.assertRedirects(resp, '/control/event/%s/%s/' % (self.orga1.slug, self.event1.slug)) self.assertRedirects(resp, '/control/event/%s/%s/' % (self.orga1.slug, self.event1.slug))
@@ -86,6 +89,7 @@ class EventsTest(SoupTest):
assert self.event1.settings.payment_banktransfer__enabled assert self.event1.settings.payment_banktransfer__enabled
assert self.event1.settings.get('payment_banktransfer_bank_details', as_type=LazyI18nString).localize('en') == "Foo" assert self.event1.settings.get('payment_banktransfer_bank_details', as_type=LazyI18nString).localize('en') == "Foo"
assert 'pretix.plugins.banktransfer' in self.event1.plugins assert 'pretix.plugins.banktransfer' in self.event1.plugins
with scopes_disabled():
assert self.event1.items.count() == 2 assert self.event1.items.count() == 2
i = self.event1.items.first() i = self.event1.items.first()
assert str(i.name) == "Normal ticket" assert str(i.name) == "Normal ticket"
@@ -132,6 +136,7 @@ class EventsTest(SoupTest):
assert self.event1.settings.payment_banktransfer__enabled assert self.event1.settings.payment_banktransfer__enabled
assert self.event1.settings.get('payment_banktransfer_bank_details', as_type=LazyI18nString).localize('en') == "Foo" assert self.event1.settings.get('payment_banktransfer_bank_details', as_type=LazyI18nString).localize('en') == "Foo"
assert 'pretix.plugins.banktransfer' in self.event1.plugins assert 'pretix.plugins.banktransfer' in self.event1.plugins
with scopes_disabled():
assert self.event1.items.count() == 2 assert self.event1.items.count() == 2
i = self.event1.items.first() i = self.event1.items.first()
assert str(i.name) == "Normal ticket" assert str(i.name) == "Normal ticket"
@@ -182,6 +187,7 @@ class EventsTest(SoupTest):
assert self.event1.settings.payment_banktransfer__enabled assert self.event1.settings.payment_banktransfer__enabled
assert self.event1.settings.get('payment_banktransfer_bank_details', as_type=LazyI18nString).localize('en') == "Foo" assert self.event1.settings.get('payment_banktransfer_bank_details', as_type=LazyI18nString).localize('en') == "Foo"
assert 'pretix.plugins.banktransfer' in self.event1.plugins assert 'pretix.plugins.banktransfer' in self.event1.plugins
with scopes_disabled():
assert self.event1.items.count() == 2 assert self.event1.items.count() == 2
i = self.event1.items.first() i = self.event1.items.first()
assert str(i.name) == "Normal ticket" assert str(i.name) == "Normal ticket"
@@ -257,6 +263,7 @@ class EventsTest(SoupTest):
assert self.event1.testmode assert self.event1.testmode
def test_testmode_disable(self): def test_testmode_disable(self):
with scopes_disabled():
o = Order.objects.create( o = Order.objects.create(
code='FOO', event=self.event1, email='dummy@dummy.test', code='FOO', event=self.event1, email='dummy@dummy.test',
status=Order.STATUS_PENDING, status=Order.STATUS_PENDING,
@@ -275,10 +282,12 @@ class EventsTest(SoupTest):
{'testmode': 'false'}) {'testmode': 'false'})
self.event1.refresh_from_db() self.event1.refresh_from_db()
assert not self.event1.testmode assert not self.event1.testmode
with scopes_disabled():
assert Order.objects.filter(pk=o.pk).exists() assert Order.objects.filter(pk=o.pk).exists()
assert Order.objects.filter(pk=o2.pk).exists() assert Order.objects.filter(pk=o2.pk).exists()
def test_testmode_disable_delete(self): def test_testmode_disable_delete(self):
with scopes_disabled():
o = Order.objects.create( o = Order.objects.create(
code='FOO', event=self.event1, email='dummy@dummy.test', code='FOO', event=self.event1, email='dummy@dummy.test',
status=Order.STATUS_PENDING, status=Order.STATUS_PENDING,
@@ -297,6 +306,7 @@ class EventsTest(SoupTest):
{'testmode': 'false', 'delete': 'yes'}) {'testmode': 'false', 'delete': 'yes'})
self.event1.refresh_from_db() self.event1.refresh_from_db()
assert not self.event1.testmode assert not self.event1.testmode
with scopes_disabled():
assert not Order.objects.filter(pk=o.pk).exists() assert not Order.objects.filter(pk=o.pk).exists()
assert Order.objects.filter(pk=o2.pk).exists() assert Order.objects.filter(pk=o2.pk).exists()
@@ -309,6 +319,7 @@ class EventsTest(SoupTest):
assert not self.event1.live assert not self.event1.live
def test_live_ok(self): def test_live_ok(self):
with scopes_disabled():
self.event1.items.create(name='Test', default_price=5) self.event1.items.create(name='Test', default_price=5)
self.event1.settings.set('payment_banktransfer__enabled', True) self.event1.settings.set('payment_banktransfer__enabled', True)
self.event1.quotas.create(name='Test quota') self.event1.quotas.create(name='Test quota')
@@ -320,6 +331,7 @@ class EventsTest(SoupTest):
assert self.event1.live assert self.event1.live
def test_live_dont_require_payment_method_free(self): def test_live_dont_require_payment_method_free(self):
with scopes_disabled():
self.event1.items.create(name='Test', default_price=0) self.event1.items.create(name='Test', default_price=0)
self.event1.settings.set('payment_banktransfer__enabled', False) self.event1.settings.set('payment_banktransfer__enabled', False)
self.event1.quotas.create(name='Test quota') self.event1.quotas.create(name='Test quota')
@@ -327,6 +339,7 @@ class EventsTest(SoupTest):
assert len(doc.select("input[name=live]")) assert len(doc.select("input[name=live]"))
def test_live_require_payment_method(self): def test_live_require_payment_method(self):
with scopes_disabled():
self.event1.items.create(name='Test', default_price=5) self.event1.items.create(name='Test', default_price=5)
self.event1.settings.set('payment_banktransfer__enabled', False) self.event1.settings.set('payment_banktransfer__enabled', False)
self.event1.quotas.create(name='Test quota') self.event1.quotas.create(name='Test quota')
@@ -378,6 +391,7 @@ class EventsTest(SoupTest):
self.event1.save(update_fields=['presale_end']) self.event1.save(update_fields=['presale_end'])
def test_payment_settings_relative_date_payment_after_presale_end(self): def test_payment_settings_relative_date_payment_after_presale_end(self):
with scopes_disabled():
tr19 = self.event1.tax_rules.create(rate=Decimal('19.00')) tr19 = self.event1.tax_rules.create(rate=Decimal('19.00'))
self.event1.presale_end = self.event1.date_from - datetime.timedelta(days=5) self.event1.presale_end = self.event1.date_from - datetime.timedelta(days=5)
self.event1.save(update_fields=['presale_end']) self.event1.save(update_fields=['presale_end'])
@@ -578,6 +592,7 @@ class EventsTest(SoupTest):
'copy-copy_from_event': '' 'copy-copy_from_event': ''
}) })
with scopes_disabled():
ev = Event.objects.get(slug='33c3') ev = Event.objects.get(slug='33c3')
assert ev.name == LazyI18nString({'de': '33C3', 'en': '33C3'}) assert ev.name == LazyI18nString({'de': '33C3', 'en': '33C3'})
assert ev.settings.locales == ['en', 'de'] assert ev.settings.locales == ['en', 'de']
@@ -635,11 +650,13 @@ class EventsTest(SoupTest):
'event_wizard-prefix': 'event_wizard', 'event_wizard-prefix': 'event_wizard',
'copy-copy_from_event': '' 'copy-copy_from_event': ''
}) })
with scopes_disabled():
ev = Event.objects.get(slug='33c3') ev = Event.objects.get(slug='33c3')
assert ev.has_subevents assert ev.has_subevents
assert ev.subevents.count() == 1 assert ev.subevents.count() == 1
def test_create_event_copy_success(self): def test_create_event_copy_success(self):
with scopes_disabled():
tr = self.event1.tax_rules.create( tr = self.event1.tax_rules.create(
rate=19, name="VAT" rate=19, name="VAT"
) )
@@ -688,6 +705,7 @@ class EventsTest(SoupTest):
'copy-copy_from_event': self.event1.pk 'copy-copy_from_event': self.event1.pk
}) })
with scopes_disabled():
ev = Event.objects.get(slug='33c3') ev = Event.objects.get(slug='33c3')
assert ev.name == LazyI18nString({'de': '33C3', 'en': '33C3'}) assert ev.name == LazyI18nString({'de': '33C3', 'en': '33C3'})
assert ev.settings.locales == ['en', 'de'] assert ev.settings.locales == ['en', 'de']
@@ -708,6 +726,7 @@ class EventsTest(SoupTest):
assert ev.tax_rules.filter(rate=Decimal('19.00')).count() == 1 assert ev.tax_rules.filter(rate=Decimal('19.00')).count() == 1
def test_create_event_clone_success(self): def test_create_event_clone_success(self):
with scopes_disabled():
tr = self.event1.tax_rules.create( tr = self.event1.tax_rules.create(
rate=19, name="VAT" rate=19, name="VAT"
) )
@@ -754,6 +773,7 @@ class EventsTest(SoupTest):
assert not doc.select("#id_copy-copy_from_event_1") assert not doc.select("#id_copy-copy_from_event_1")
with scopes_disabled():
ev = Event.objects.get(slug='33c3') ev = Event.objects.get(slug='33c3')
assert ev.name == LazyI18nString({'de': '33C3', 'en': '33C3'}) assert ev.name == LazyI18nString({'de': '33C3', 'en': '33C3'})
assert ev.settings.locales == ['en', 'de'] assert ev.settings.locales == ['en', 'de']
@@ -806,6 +826,7 @@ class EventsTest(SoupTest):
'copy-copy_from_event': '' 'copy-copy_from_event': ''
}) })
with scopes_disabled():
ev = Event.objects.get(slug='33c3') ev = Event.objects.get(slug='33c3')
assert ev.name == LazyI18nString({'en': '33C3'}) assert ev.name == LazyI18nString({'en': '33C3'})
assert ev.settings.locales == ['en'] assert ev.settings.locales == ['en']
@@ -909,6 +930,7 @@ class EventsTest(SoupTest):
class SubEventsTest(SoupTest): class SubEventsTest(SoupTest):
@scopes_disabled()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy') self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
@@ -967,6 +989,7 @@ class SubEventsTest(SoupTest):
'item-%d-price' % self.ticket.pk: '12' 'item-%d-price' % self.ticket.pk: '12'
}) })
assert doc.select(".alert-success") assert doc.select(".alert-success")
with scopes_disabled():
se = self.event1.subevents.first() se = self.event1.subevents.first()
assert str(se.name) == "SE2" assert str(se.name) == "SE2"
assert se.active assert se.active
@@ -1022,6 +1045,7 @@ class SubEventsTest(SoupTest):
assert str(se.location) == "Hamburg" assert str(se.location) == "Hamburg"
assert se.presale_start.isoformat() == "2017-06-20T10:00:00+00:00" assert se.presale_start.isoformat() == "2017-06-20T10:00:00+00:00"
assert not se.presale_end assert not se.presale_end
with scopes_disabled():
assert se.quotas.count() == 1 assert se.quotas.count() == 1
q = se.quotas.last() q = se.quotas.last()
assert q.name == "Q1" assert q.name == "Q1"
@@ -1039,10 +1063,12 @@ class SubEventsTest(SoupTest):
# deleting the second event # deleting the second event
doc = self.post_doc('/control/event/ccc/30c3/subevents/%d/delete' % self.subevent2.pk, {}) doc = self.post_doc('/control/event/ccc/30c3/subevents/%d/delete' % self.subevent2.pk, {})
assert doc.select(".alert-success") assert doc.select(".alert-success")
with scopes_disabled():
assert not SubEvent.objects.filter(pk=self.subevent2.pk).exists() assert not SubEvent.objects.filter(pk=self.subevent2.pk).exists()
assert not SubEvent.objects.filter(pk=self.subevent1.pk).exists() assert not SubEvent.objects.filter(pk=self.subevent1.pk).exists()
def test_delete_with_orders(self): def test_delete_with_orders(self):
with scopes_disabled():
o = Order.objects.create( o = Order.objects.create(
code='FOO', event=self.event1, email='dummy@dummy.test', code='FOO', event=self.event1, email='dummy@dummy.test',
status=Order.STATUS_PENDING, status=Order.STATUS_PENDING,
@@ -1059,9 +1085,11 @@ class SubEventsTest(SoupTest):
assert doc.select(".alert-danger") assert doc.select(".alert-danger")
doc = self.post_doc('/control/event/ccc/30c3/subevents/%d/delete' % self.subevent1.pk, {}, follow=True) doc = self.post_doc('/control/event/ccc/30c3/subevents/%d/delete' % self.subevent1.pk, {}, follow=True)
assert doc.select(".alert-danger") assert doc.select(".alert-danger")
with scopes_disabled():
assert self.event1.subevents.filter(pk=self.subevent1.pk).exists() assert self.event1.subevents.filter(pk=self.subevent1.pk).exists()
def test_create_bulk(self): def test_create_bulk(self):
with scopes_disabled():
self.event1.subevents.all().delete() self.event1.subevents.all().delete()
self.event1.settings.timezone = 'Europe/Berlin' self.event1.settings.timezone = 'Europe/Berlin'
@@ -1120,6 +1148,7 @@ class SubEventsTest(SoupTest):
'checkinlist_set-0-limit_products': str(self.ticket.pk), 'checkinlist_set-0-limit_products': str(self.ticket.pk),
}) })
assert doc.select(".alert-success") assert doc.select(".alert-success")
with scopes_disabled():
ses = list(self.event1.subevents.order_by('date_from')) ses = list(self.event1.subevents.order_by('date_from'))
assert len(ses) == 10 assert len(ses) == 10
@@ -1128,6 +1157,7 @@ class SubEventsTest(SoupTest):
assert ses[0].date_to.isoformat() == "2018-04-03T13:29:31+00:00" assert ses[0].date_to.isoformat() == "2018-04-03T13:29:31+00:00"
assert not ses[0].presale_start assert not ses[0].presale_start
assert ses[0].presale_end.isoformat() == "2018-04-02T11:29:31+00:00" assert ses[0].presale_end.isoformat() == "2018-04-02T11:29:31+00:00"
with scopes_disabled():
assert ses[0].quotas.count() == 1 assert ses[0].quotas.count() == 1
assert list(ses[0].quotas.first().items.all()) == [self.ticket] assert list(ses[0].quotas.first().items.all()) == [self.ticket]
assert SubEventItem.objects.get(subevent=ses[0], item=self.ticket).price == 16 assert SubEventItem.objects.get(subevent=ses[0], item=self.ticket).price == 16
@@ -1138,6 +1168,7 @@ class SubEventsTest(SoupTest):
assert ses[1].date_to.isoformat() == "2019-04-03T13:29:31+00:00" assert ses[1].date_to.isoformat() == "2019-04-03T13:29:31+00:00"
assert not ses[1].presale_start assert not ses[1].presale_start
assert ses[1].presale_end.isoformat() == "2019-04-02T11:29:31+00:00" assert ses[1].presale_end.isoformat() == "2019-04-02T11:29:31+00:00"
with scopes_disabled():
assert ses[1].quotas.count() == 1 assert ses[1].quotas.count() == 1
assert list(ses[1].quotas.first().items.all()) == [self.ticket] assert list(ses[1].quotas.first().items.all()) == [self.ticket]
assert SubEventItem.objects.get(subevent=ses[0], item=self.ticket).price == 16 assert SubEventItem.objects.get(subevent=ses[0], item=self.ticket).price == 16
@@ -1146,6 +1177,7 @@ class SubEventsTest(SoupTest):
assert ses[-1].date_from.isoformat() == "2027-04-03T11:29:31+00:00" assert ses[-1].date_from.isoformat() == "2027-04-03T11:29:31+00:00"
def test_create_bulk_daily_interval(self): def test_create_bulk_daily_interval(self):
with scopes_disabled():
self.event1.subevents.all().delete() self.event1.subevents.all().delete()
self.event1.settings.timezone = 'Europe/Berlin' self.event1.settings.timezone = 'Europe/Berlin'
@@ -1194,6 +1226,7 @@ class SubEventsTest(SoupTest):
'checkinlist_set-MAX_NUM_FORMS': '1000', 'checkinlist_set-MAX_NUM_FORMS': '1000',
}) })
assert doc.select(".alert-success") assert doc.select(".alert-success")
with scopes_disabled():
ses = list(self.event1.subevents.order_by('date_from')) ses = list(self.event1.subevents.order_by('date_from'))
assert len(ses) == 183 assert len(ses) == 183
@@ -1202,6 +1235,7 @@ class SubEventsTest(SoupTest):
assert ses[-1].date_from.isoformat() == "2019-04-02T11:29:31+00:00" assert ses[-1].date_from.isoformat() == "2019-04-02T11:29:31+00:00"
def test_create_bulk_exclude(self): def test_create_bulk_exclude(self):
with scopes_disabled():
self.event1.subevents.all().delete() self.event1.subevents.all().delete()
self.event1.settings.timezone = 'Europe/Berlin' self.event1.settings.timezone = 'Europe/Berlin'
@@ -1265,6 +1299,7 @@ class SubEventsTest(SoupTest):
'checkinlist_set-MAX_NUM_FORMS': '1000', 'checkinlist_set-MAX_NUM_FORMS': '1000',
}) })
assert doc.select(".alert-success") assert doc.select(".alert-success")
with scopes_disabled():
ses = list(self.event1.subevents.order_by('date_from')) ses = list(self.event1.subevents.order_by('date_from'))
assert len(ses) == 314 assert len(ses) == 314
@@ -1273,6 +1308,7 @@ class SubEventsTest(SoupTest):
assert ses[6].date_from.isoformat() == "2018-04-10T11:29:31+00:00" assert ses[6].date_from.isoformat() == "2018-04-10T11:29:31+00:00"
def test_create_bulk_monthly_interval(self): def test_create_bulk_monthly_interval(self):
with scopes_disabled():
self.event1.subevents.all().delete() self.event1.subevents.all().delete()
self.event1.settings.timezone = 'Europe/Berlin' self.event1.settings.timezone = 'Europe/Berlin'
@@ -1320,6 +1356,7 @@ class SubEventsTest(SoupTest):
'checkinlist_set-MAX_NUM_FORMS': '1000', 'checkinlist_set-MAX_NUM_FORMS': '1000',
}) })
assert doc.select(".alert-success") assert doc.select(".alert-success")
with scopes_disabled():
ses = list(self.event1.subevents.order_by('date_from')) ses = list(self.event1.subevents.order_by('date_from'))
assert len(ses) == 12 assert len(ses) == 12
@@ -1328,6 +1365,7 @@ class SubEventsTest(SoupTest):
assert ses[-1].date_from.isoformat() == "2019-03-29T12:29:31+00:00" assert ses[-1].date_from.isoformat() == "2019-03-29T12:29:31+00:00"
def test_create_bulk_weekly_interval(self): def test_create_bulk_weekly_interval(self):
with scopes_disabled():
self.event1.subevents.all().delete() self.event1.subevents.all().delete()
self.event1.settings.timezone = 'Europe/Berlin' self.event1.settings.timezone = 'Europe/Berlin'
@@ -1375,6 +1413,7 @@ class SubEventsTest(SoupTest):
'checkinlist_set-MAX_NUM_FORMS': '1000', 'checkinlist_set-MAX_NUM_FORMS': '1000',
}) })
assert doc.select(".alert-success") assert doc.select(".alert-success")
with scopes_disabled():
ses = list(self.event1.subevents.order_by('date_from')) ses = list(self.event1.subevents.order_by('date_from'))
assert len(ses) == 52 assert len(ses) == 52
@@ -1385,6 +1424,7 @@ class SubEventsTest(SoupTest):
def test_delete_bulk(self): def test_delete_bulk(self):
self.subevent2.active = True self.subevent2.active = True
self.subevent2.save() self.subevent2.save()
with scopes_disabled():
o = Order.objects.create( o = Order.objects.create(
code='FOO', event=self.event1, email='dummy@dummy.test', code='FOO', event=self.event1, email='dummy@dummy.test',
status=Order.STATUS_PENDING, status=Order.STATUS_PENDING,
@@ -1402,6 +1442,7 @@ class SubEventsTest(SoupTest):
'action': 'delete_confirm' 'action': 'delete_confirm'
}, follow=True) }, follow=True)
assert doc.select(".alert-success") assert doc.select(".alert-success")
with scopes_disabled():
assert not self.event1.subevents.filter(pk=self.subevent2.pk).exists() assert not self.event1.subevents.filter(pk=self.subevent2.pk).exists()
assert self.event1.subevents.get(pk=self.subevent1.pk).active is False assert self.event1.subevents.get(pk=self.subevent1.pk).active is False
@@ -1413,6 +1454,7 @@ class SubEventsTest(SoupTest):
'action': 'disable' 'action': 'disable'
}, follow=True) }, follow=True)
assert doc.select(".alert-success") assert doc.select(".alert-success")
with scopes_disabled():
assert self.event1.subevents.get(pk=self.subevent2.pk).active is False assert self.event1.subevents.get(pk=self.subevent2.pk).active is False
def test_enable_bulk(self): def test_enable_bulk(self):
@@ -1423,10 +1465,12 @@ class SubEventsTest(SoupTest):
'action': 'enable' 'action': 'enable'
}, follow=True) }, follow=True)
assert doc.select(".alert-success") assert doc.select(".alert-success")
with scopes_disabled():
assert self.event1.subevents.get(pk=self.subevent2.pk).active is True assert self.event1.subevents.get(pk=self.subevent2.pk).active is True
class EventDeletionTest(SoupTest): class EventDeletionTest(SoupTest):
@scopes_disabled()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy') self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
@@ -1454,6 +1498,7 @@ class EventDeletionTest(SoupTest):
'slug': '30c3' 'slug': '30c3'
}) })
with scopes_disabled():
assert not self.orga1.events.exists() assert not self.orga1.events.exists()
def test_delete_wrong_slug(self): def test_delete_wrong_slug(self):
@@ -1461,6 +1506,7 @@ class EventDeletionTest(SoupTest):
'user_pw': 'dummy', 'user_pw': 'dummy',
'slug': '31c3' 'slug': '31c3'
}) })
with scopes_disabled():
assert self.orga1.events.exists() assert self.orga1.events.exists()
def test_delete_wrong_pw(self): def test_delete_wrong_pw(self):
@@ -1468,6 +1514,7 @@ class EventDeletionTest(SoupTest):
'user_pw': 'invalid', 'user_pw': 'invalid',
'slug': '30c3' 'slug': '30c3'
}) })
with scopes_disabled():
assert self.orga1.events.exists() assert self.orga1.events.exists()
def test_delete_orders(self): def test_delete_orders(self):
@@ -1481,4 +1528,5 @@ class EventDeletionTest(SoupTest):
'user_pw': 'dummy', 'user_pw': 'dummy',
'slug': '30c3' 'slug': '30c3'
}) })
with scopes_disabled():
assert self.orga1.events.exists() assert self.orga1.events.exists()

View File

@@ -2,6 +2,7 @@ import datetime
from decimal import Decimal from decimal import Decimal
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from tests.base import SoupTest, extract_form_fields from tests.base import SoupTest, extract_form_fields
from pretix.base.models import ( from pretix.base.models import (
@@ -11,6 +12,7 @@ from pretix.base.models import (
class ItemFormTest(SoupTest): class ItemFormTest(SoupTest):
@scopes_disabled()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy') self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
@@ -47,9 +49,11 @@ class CategoriesTest(ItemFormTest):
assert doc.select(".alert-success") assert doc.select(".alert-success")
self.assertIn("T-Shirts", doc.select("#page-wrapper table")[0].text) self.assertIn("T-Shirts", doc.select("#page-wrapper table")[0].text)
self.assertNotIn("Entry tickets", doc.select("#page-wrapper table")[0].text) self.assertNotIn("Entry tickets", doc.select("#page-wrapper table")[0].text)
with scopes_disabled():
assert str(ItemCategory.objects.get(id=c.id).name) == 'T-Shirts' assert str(ItemCategory.objects.get(id=c.id).name) == 'T-Shirts'
def test_sort(self): def test_sort(self):
with scopes_disabled():
c1 = ItemCategory.objects.create(event=self.event1, name="Entry tickets", position=0) c1 = ItemCategory.objects.create(event=self.event1, name="Entry tickets", position=0)
ItemCategory.objects.create(event=self.event1, name="T-Shirts", position=1) ItemCategory.objects.create(event=self.event1, name="T-Shirts", position=1)
doc = self.get_doc('/control/event/%s/%s/categories/' % (self.orga1.slug, self.event1.slug)) doc = self.get_doc('/control/event/%s/%s/categories/' % (self.orga1.slug, self.event1.slug))
@@ -67,6 +71,7 @@ class CategoriesTest(ItemFormTest):
self.assertIn("T-Shirts", doc.select("table > tbody > tr")[1].text) self.assertIn("T-Shirts", doc.select("table > tbody > tr")[1].text)
def test_delete(self): def test_delete(self):
with scopes_disabled():
c = ItemCategory.objects.create(event=self.event1, name="Entry tickets") c = ItemCategory.objects.create(event=self.event1, name="Entry tickets")
doc = self.get_doc('/control/event/%s/%s/categories/%s/delete' % (self.orga1.slug, self.event1.slug, c.id)) doc = self.get_doc('/control/event/%s/%s/categories/%s/delete' % (self.orga1.slug, self.event1.slug, c.id))
form_data = extract_form_fields(doc.select('.container-fluid form')[0]) form_data = extract_form_fields(doc.select('.container-fluid form')[0])
@@ -74,6 +79,7 @@ class CategoriesTest(ItemFormTest):
form_data) form_data)
assert doc.select(".alert-success") assert doc.select(".alert-success")
self.assertNotIn("Entry tickets", doc.select("#page-wrapper")[0].text) self.assertNotIn("Entry tickets", doc.select("#page-wrapper")[0].text)
with scopes_disabled():
assert not ItemCategory.objects.filter(id=c.id).exists() assert not ItemCategory.objects.filter(id=c.id).exists()
@@ -90,6 +96,7 @@ class QuestionsTest(ItemFormTest):
self.assertIn("shoe size", doc.select("#page-wrapper table")[0].text) self.assertIn("shoe size", doc.select("#page-wrapper table")[0].text)
def test_update_choices(self): def test_update_choices(self):
with scopes_disabled():
c = Question.objects.create(event=self.event1, question="What country are you from?", type="C", required=True) c = Question.objects.create(event=self.event1, question="What country are you from?", type="C", required=True)
o1 = c.options.create(answer='Germany') o1 = c.options.create(answer='Germany')
doc = self.get_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id)) doc = self.get_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id))
@@ -104,10 +111,12 @@ class QuestionsTest(ItemFormTest):
self.post_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id), self.post_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id),
form_data) form_data)
c.refresh_from_db() c.refresh_from_db()
with scopes_disabled():
assert c.options.exists() assert c.options.exists()
assert str(c.options.first().answer) == 'England' assert str(c.options.first().answer) == 'England'
def test_delete_choices(self): def test_delete_choices(self):
with scopes_disabled():
c = Question.objects.create(event=self.event1, question="What country are you from?", type="C", required=True) c = Question.objects.create(event=self.event1, question="What country are you from?", type="C", required=True)
o1 = c.options.create(answer='Germany') o1 = c.options.create(answer='Germany')
doc = self.get_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id)) doc = self.get_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id))
@@ -123,9 +132,11 @@ class QuestionsTest(ItemFormTest):
self.post_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id), self.post_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id),
form_data) form_data)
c.refresh_from_db() c.refresh_from_db()
with scopes_disabled():
assert not c.options.exists() assert not c.options.exists()
def test_add_choices(self): def test_add_choices(self):
with scopes_disabled():
c = Question.objects.create(event=self.event1, question="What country are you from?", type="N", required=True) c = Question.objects.create(event=self.event1, question="What country are you from?", type="N", required=True)
doc = self.get_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id)) doc = self.get_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id))
form_data = extract_form_fields(doc.select('.container-fluid form')[0]) form_data = extract_form_fields(doc.select('.container-fluid form')[0])
@@ -139,11 +150,13 @@ class QuestionsTest(ItemFormTest):
form_data['form-0-answer_0'] = 'Germany' form_data['form-0-answer_0'] = 'Germany'
self.post_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id), self.post_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id),
form_data) form_data)
with scopes_disabled():
c = Question.objects.get(id=c.id) c = Question.objects.get(id=c.id)
assert c.options.exists() assert c.options.exists()
assert str(c.options.first().answer) == 'Germany' assert str(c.options.first().answer) == 'Germany'
def test_update(self): def test_update(self):
with scopes_disabled():
c = Question.objects.create(event=self.event1, question="What is your shoe size?", type="N", required=True) c = Question.objects.create(event=self.event1, question="What is your shoe size?", type="N", required=True)
doc = self.get_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id)) doc = self.get_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, c.id))
form_data = extract_form_fields(doc.select('.container-fluid form')[0]) form_data = extract_form_fields(doc.select('.container-fluid form')[0])
@@ -153,11 +166,13 @@ class QuestionsTest(ItemFormTest):
form_data) form_data)
self.assertIn("How old", doc.select("#page-wrapper table")[0].text) self.assertIn("How old", doc.select("#page-wrapper table")[0].text)
self.assertNotIn("shoe size", doc.select("#page-wrapper table")[0].text) self.assertNotIn("shoe size", doc.select("#page-wrapper table")[0].text)
with scopes_disabled():
c = Question.objects.get(id=c.id) c = Question.objects.get(id=c.id)
self.assertTrue(c.required) self.assertTrue(c.required)
assert str(Question.objects.get(id=c.id).question) == 'How old are you?' assert str(Question.objects.get(id=c.id).question) == 'How old are you?'
def test_sort(self): def test_sort(self):
with scopes_disabled():
q1 = Question.objects.create(event=self.event1, question="Vegetarian?", type="N", required=True, position=0) q1 = Question.objects.create(event=self.event1, question="Vegetarian?", type="N", required=True, position=0)
Question.objects.create(event=self.event1, question="Food allergies?", position=1) Question.objects.create(event=self.event1, question="Food allergies?", position=1)
doc = self.get_doc('/control/event/%s/%s/questions/' % (self.orga1.slug, self.event1.slug)) doc = self.get_doc('/control/event/%s/%s/questions/' % (self.orga1.slug, self.event1.slug))
@@ -175,6 +190,7 @@ class QuestionsTest(ItemFormTest):
self.assertIn("Food allergies?", doc.select("table > tbody > tr")[1].text) self.assertIn("Food allergies?", doc.select("table > tbody > tr")[1].text)
def test_delete(self): def test_delete(self):
with scopes_disabled():
c = Question.objects.create(event=self.event1, question="What is your shoe size?", type="N", required=True) c = Question.objects.create(event=self.event1, question="What is your shoe size?", type="N", required=True)
doc = self.get_doc('/control/event/%s/%s/questions/%s/delete' % (self.orga1.slug, self.event1.slug, c.id)) doc = self.get_doc('/control/event/%s/%s/questions/%s/delete' % (self.orga1.slug, self.event1.slug, c.id))
form_data = extract_form_fields(doc.select('.container-fluid form')[0]) form_data = extract_form_fields(doc.select('.container-fluid form')[0])
@@ -182,9 +198,11 @@ class QuestionsTest(ItemFormTest):
form_data) form_data)
assert doc.select(".alert-success") assert doc.select(".alert-success")
self.assertNotIn("shoe size", doc.select("#page-wrapper")[0].text) self.assertNotIn("shoe size", doc.select("#page-wrapper")[0].text)
with scopes_disabled():
assert not Question.objects.filter(id=c.id).exists() assert not Question.objects.filter(id=c.id).exists()
def test_question_view(self): def test_question_view(self):
with scopes_disabled():
c = Question.objects.create(event=self.event1, question="What is your shoe size?", type="N", required=True) c = Question.objects.create(event=self.event1, question="What is your shoe size?", type="N", required=True)
item1 = Item.objects.create(event=self.event1, name="Standard", default_price=0, position=1) item1 = Item.objects.create(event=self.event1, name="Standard", default_price=0, position=1)
@@ -219,6 +237,7 @@ class QuestionsTest(ItemFormTest):
assert tbl.select('tr')[0].select('td')[0].text.strip() == '42' assert tbl.select('tr')[0].select('td')[0].text.strip() == '42'
def test_set_dependency(self): def test_set_dependency(self):
with scopes_disabled():
q1 = Question.objects.create(event=self.event1, question="What country are you from?", type="C", required=True) q1 = Question.objects.create(event=self.event1, question="What country are you from?", type="C", required=True)
q2 = Question.objects.create(event=self.event1, question="What city are you from?", type="T", required=True) q2 = Question.objects.create(event=self.event1, question="What city are you from?", type="T", required=True)
o1 = q1.options.create(answer='Germany') o1 = q1.options.create(answer='Germany')
@@ -235,6 +254,7 @@ class QuestionsTest(ItemFormTest):
assert q2.dependency_value == o1.identifier assert q2.dependency_value == o1.identifier
def test_set_dependency_circular(self): def test_set_dependency_circular(self):
with scopes_disabled():
q1 = Question.objects.create(event=self.event1, question="What country are you from?", type="C", required=True) q1 = Question.objects.create(event=self.event1, question="What country are you from?", type="C", required=True)
o1 = q1.options.create(answer='Germany') o1 = q1.options.create(answer='Germany')
q2 = Question.objects.create(event=self.event1, question="What city are you from?", type="C", required=True, q2 = Question.objects.create(event=self.event1, question="What city are you from?", type="C", required=True,
@@ -248,6 +268,7 @@ class QuestionsTest(ItemFormTest):
assert not doc.select(".alert-success") assert not doc.select(".alert-success")
def test_set_dependency_to_non_choice(self): def test_set_dependency_to_non_choice(self):
with scopes_disabled():
q1 = Question.objects.create(event=self.event1, question="What country are you from?", type="N", required=True) q1 = Question.objects.create(event=self.event1, question="What country are you from?", type="N", required=True)
q2 = Question.objects.create(event=self.event1, question="What city are you from?", type="T", required=True) q2 = Question.objects.create(event=self.event1, question="What city are you from?", type="T", required=True)
doc = self.get_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, q2.id)) doc = self.get_doc('/control/event/%s/%s/questions/%s/change' % (self.orga1.slug, self.event1.slug, q2.id))
@@ -271,6 +292,7 @@ class QuotaTest(ItemFormTest):
self.assertIn("Full house", doc.select("#page-wrapper table")[0].text) self.assertIn("Full house", doc.select("#page-wrapper table")[0].text)
def test_update(self): def test_update(self):
with scopes_disabled():
c = Quota.objects.create(event=self.event1, name="Full house", size=500) c = Quota.objects.create(event=self.event1, name="Full house", size=500)
item1 = Item.objects.create(event=self.event1, name="Standard", default_price=0) item1 = Item.objects.create(event=self.event1, name="Standard", default_price=0)
item2 = Item.objects.create(event=self.event1, name="Business", default_price=0) item2 = Item.objects.create(event=self.event1, name="Business", default_price=0)
@@ -285,12 +307,14 @@ class QuotaTest(ItemFormTest):
doc = self.get_doc('/control/event/%s/%s/quotas/' % (self.orga1.slug, self.event1.slug)) doc = self.get_doc('/control/event/%s/%s/quotas/' % (self.orga1.slug, self.event1.slug))
self.assertIn("350", doc.select("#page-wrapper table")[0].text) self.assertIn("350", doc.select("#page-wrapper table")[0].text)
self.assertNotIn("500", doc.select("#page-wrapper table")[0].text) self.assertNotIn("500", doc.select("#page-wrapper table")[0].text)
with scopes_disabled():
assert Quota.objects.get(id=c.id).size == 350 assert Quota.objects.get(id=c.id).size == 350
assert item1 in Quota.objects.get(id=c.id).items.all() assert item1 in Quota.objects.get(id=c.id).items.all()
def test_update_subevent(self): def test_update_subevent(self):
self.event1.has_subevents = True self.event1.has_subevents = True
self.event1.save() self.event1.save()
with scopes_disabled():
se1 = self.event1.subevents.create(name="Foo", date_from=now()) se1 = self.event1.subevents.create(name="Foo", date_from=now())
se2 = self.event1.subevents.create(name="Bar", date_from=now()) se2 = self.event1.subevents.create(name="Bar", date_from=now())
c = Quota.objects.create(event=self.event1, name="Full house", size=500, subevent=se1) c = Quota.objects.create(event=self.event1, name="Full house", size=500, subevent=se1)
@@ -299,9 +323,11 @@ class QuotaTest(ItemFormTest):
form_data['subevent'] = se2.pk form_data['subevent'] = se2.pk
self.post_doc('/control/event/%s/%s/quotas/%s/change' % (self.orga1.slug, self.event1.slug, c.id), self.post_doc('/control/event/%s/%s/quotas/%s/change' % (self.orga1.slug, self.event1.slug, c.id),
form_data) form_data)
with scopes_disabled():
assert Quota.objects.get(id=c.id).subevent == se2 assert Quota.objects.get(id=c.id).subevent == se2
def test_delete(self): def test_delete(self):
with scopes_disabled():
c = Quota.objects.create(event=self.event1, name="Full house", size=500) c = Quota.objects.create(event=self.event1, name="Full house", size=500)
doc = self.get_doc('/control/event/%s/%s/quotas/%s/delete' % (self.orga1.slug, self.event1.slug, c.id)) doc = self.get_doc('/control/event/%s/%s/quotas/%s/delete' % (self.orga1.slug, self.event1.slug, c.id))
form_data = extract_form_fields(doc.select('.container-fluid form')[0]) form_data = extract_form_fields(doc.select('.container-fluid form')[0])
@@ -309,11 +335,13 @@ class QuotaTest(ItemFormTest):
form_data) form_data)
assert doc.select(".alert-success") assert doc.select(".alert-success")
self.assertNotIn("Full house", doc.select("#page-wrapper")[0].text) self.assertNotIn("Full house", doc.select("#page-wrapper")[0].text)
with scopes_disabled():
assert not Quota.objects.filter(id=c.id).exists() assert not Quota.objects.filter(id=c.id).exists()
class ItemsTest(ItemFormTest): class ItemsTest(ItemFormTest):
@scopes_disabled()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.item2 = Item.objects.create(event=self.event1, name="Business", default_price=0, position=2, self.item2 = Item.objects.create(event=self.event1, name="Business", default_price=0, position=2,
@@ -341,7 +369,7 @@ class ItemsTest(ItemFormTest):
'tax_rate': '19.00' 'tax_rate': '19.00'
}) })
resp = self.client.get('/control/event/%s/%s/items/' % (self.orga1.slug, self.event1.slug)) resp = self.client.get('/control/event/%s/%s/items/' % (self.orga1.slug, self.event1.slug))
assert 'T-Shirt' in resp.rendered_content assert 'T-Shirt' in resp.content.decode()
def test_update(self): def test_update(self):
self.client.post('/control/event/%s/%s/items/%d/' % (self.orga1.slug, self.event1.slug, self.item1.id), { self.client.post('/control/event/%s/%s/items/%d/' % (self.orga1.slug, self.event1.slug, self.item1.id), {
@@ -366,19 +394,22 @@ class ItemsTest(ItemFormTest):
'form-0-min_count': '1', 'form-0-min_count': '1',
'form-0-max_count': '2', 'form-0-max_count': '2',
}) })
with scopes_disabled():
assert self.item2.addons.exists() assert self.item2.addons.exists()
assert self.item2.addons.first().addon_category == self.addoncat assert self.item2.addons.first().addon_category == self.addoncat
a = self.item2.addons.first()
self.client.post('/control/event/%s/%s/items/%d/addons' % (self.orga1.slug, self.event1.slug, self.item2.id), { self.client.post('/control/event/%s/%s/items/%d/addons' % (self.orga1.slug, self.event1.slug, self.item2.id), {
'form-TOTAL_FORMS': '1', 'form-TOTAL_FORMS': '1',
'form-INITIAL_FORMS': '1', 'form-INITIAL_FORMS': '1',
'form-MIN_NUM_FORMS': '0', 'form-MIN_NUM_FORMS': '0',
'form-MAX_NUM_FORMS': '1000', 'form-MAX_NUM_FORMS': '1000',
'form-0-id': str(self.item2.addons.first().pk), 'form-0-id': str(a.pk),
'form-0-addon_category': str(self.addoncat.pk), 'form-0-addon_category': str(self.addoncat.pk),
'form-0-min_count': '1', 'form-0-min_count': '1',
'form-0-max_count': '2', 'form-0-max_count': '2',
'form-0-DELETE': 'on', 'form-0-DELETE': 'on',
}) })
with scopes_disabled():
assert not self.item2.addons.exists() assert not self.item2.addons.exists()
# Do not allow duplicates # Do not allow duplicates
@@ -396,6 +427,7 @@ class ItemsTest(ItemFormTest):
'form-1-min_count': '1', 'form-1-min_count': '1',
'form-1-max_count': '2', 'form-1-max_count': '2',
}) })
with scopes_disabled():
assert not self.item2.addons.exists() assert not self.item2.addons.exists()
def test_manipulate_bundles(self): def test_manipulate_bundles(self):
@@ -409,6 +441,7 @@ class ItemsTest(ItemFormTest):
'form-0-count': '2', 'form-0-count': '2',
'form-0-designated_price': '2.00', 'form-0-designated_price': '2.00',
}) })
with scopes_disabled():
assert self.item2.bundles.exists() assert self.item2.bundles.exists()
assert self.item2.bundles.first().bundled_item == self.item1 assert self.item2.bundles.first().bundled_item == self.item1
self.client.post('/control/event/%s/%s/items/%d/bundles' % (self.orga1.slug, self.event1.slug, self.item2.id), { self.client.post('/control/event/%s/%s/items/%d/bundles' % (self.orga1.slug, self.event1.slug, self.item2.id), {
@@ -422,6 +455,7 @@ class ItemsTest(ItemFormTest):
'form-0-designated_price': '2.00', 'form-0-designated_price': '2.00',
'form-0-DELETE': 'on', 'form-0-DELETE': 'on',
}) })
with scopes_disabled():
assert not self.item2.bundles.exists() assert not self.item2.bundles.exists()
# Do not allow self-reference # Do not allow self-reference
@@ -435,9 +469,11 @@ class ItemsTest(ItemFormTest):
'form-0-count': '2', 'form-0-count': '2',
'form-0-designated_price': '2.00', 'form-0-designated_price': '2.00',
}) })
with scopes_disabled():
assert not self.item2.bundles.exists() assert not self.item2.bundles.exists()
# Do not allow multi-level bundles # Do not allow multi-level bundles
with scopes_disabled():
self.item1.bundles.create(bundled_item=self.item1, count=1, designated_price=0) self.item1.bundles.create(bundled_item=self.item1, count=1, designated_price=0)
self.client.post('/control/event/%s/%s/items/%d/bundles' % (self.orga1.slug, self.event1.slug, self.item2.id), { self.client.post('/control/event/%s/%s/items/%d/bundles' % (self.orga1.slug, self.event1.slug, self.item2.id), {
'form-TOTAL_FORMS': '1', 'form-TOTAL_FORMS': '1',
@@ -449,6 +485,7 @@ class ItemsTest(ItemFormTest):
'form-0-count': '2', 'form-0-count': '2',
'form-0-designated_price': '2.00', 'form-0-designated_price': '2.00',
}) })
with scopes_disabled():
assert not self.item2.bundles.exists() assert not self.item2.bundles.exists()
def test_update_variations(self): def test_update_variations(self):
@@ -491,17 +528,21 @@ class ItemsTest(ItemFormTest):
'active': 'yes', 'active': 'yes',
'allow_cancel': 'yes' 'allow_cancel': 'yes'
}) })
with scopes_disabled():
assert not self.item2.variations.filter(pk=self.var2.pk).exists() assert not self.item2.variations.filter(pk=self.var2.pk).exists()
def test_delete(self): def test_delete(self):
self.client.post('/control/event/%s/%s/items/%d/delete' % (self.orga1.slug, self.event1.slug, self.item1.id), self.client.post('/control/event/%s/%s/items/%d/delete' % (self.orga1.slug, self.event1.slug, self.item1.id),
{}) {})
with scopes_disabled():
assert not self.event1.items.filter(pk=self.item1.pk).exists() assert not self.event1.items.filter(pk=self.item1.pk).exists()
self.client.post('/control/event/%s/%s/items/%d/delete' % (self.orga1.slug, self.event1.slug, self.item2.id), self.client.post('/control/event/%s/%s/items/%d/delete' % (self.orga1.slug, self.event1.slug, self.item2.id),
{}) {})
with scopes_disabled():
assert not self.event1.items.filter(pk=self.item2.pk).exists() assert not self.event1.items.filter(pk=self.item2.pk).exists()
def test_delete_ordered(self): def test_delete_ordered(self):
with scopes_disabled():
o = Order.objects.create( o = Order.objects.create(
code='FOO', event=self.event1, email='dummy@dummy.test', code='FOO', event=self.event1, email='dummy@dummy.test',
status=Order.STATUS_PENDING, status=Order.STATUS_PENDING,
@@ -517,11 +558,13 @@ class ItemsTest(ItemFormTest):
) )
self.client.post('/control/event/%s/%s/items/%d/delete' % (self.orga1.slug, self.event1.slug, self.item1.id), self.client.post('/control/event/%s/%s/items/%d/delete' % (self.orga1.slug, self.event1.slug, self.item1.id),
{}) {})
with scopes_disabled():
assert self.event1.items.filter(pk=self.item1.pk).exists() assert self.event1.items.filter(pk=self.item1.pk).exists()
self.item1.refresh_from_db() self.item1.refresh_from_db()
assert not self.item1.active assert not self.item1.active
def test_create_copy(self): def test_create_copy(self):
with scopes_disabled():
q = Question.objects.create(event=self.event1, question="Size", type="N") q = Question.objects.create(event=self.event1, question="Size", type="N")
q.items.add(self.item2) q.items.add(self.item2)
self.item2.sales_channels = ["web", "bar"] self.item2.sales_channels = ["web", "bar"]
@@ -533,6 +576,7 @@ class ItemsTest(ItemFormTest):
'copy_from': str(self.item2.pk), 'copy_from': str(self.item2.pk),
'has_variations': '1' 'has_variations': '1'
}) })
with scopes_disabled():
i_old = Item.objects.get(name__icontains='Business') i_old = Item.objects.get(name__icontains='Business')
i_new = Item.objects.get(name__icontains='Intermediate') i_new = Item.objects.get(name__icontains='Intermediate')
assert i_new.category == i_old.category assert i_new.category == i_old.category
@@ -548,6 +592,7 @@ class ItemsTest(ItemFormTest):
assert set([str(v.value) for v in i_new.variations.all()]) == set([str(v.value) for v in i_old.variations.all()]) assert set([str(v.value) for v in i_new.variations.all()]) == set([str(v.value) for v in i_old.variations.all()])
def test_add_to_existing_quota(self): def test_add_to_existing_quota(self):
with scopes_disabled():
q = Quota.objects.create(event=self.event1, name="New Test Quota", size=50) q = Quota.objects.create(event=self.event1, name="New Test Quota", size=50)
doc = self.get_doc('/control/event/%s/%s/items/add' % (self.orga1.slug, self.event1.slug)) doc = self.get_doc('/control/event/%s/%s/items/add' % (self.orga1.slug, self.event1.slug))
@@ -558,6 +603,7 @@ class ItemsTest(ItemFormTest):
form_data['quota_add_existing'] = str(q.pk) form_data['quota_add_existing'] = str(q.pk)
doc = self.post_doc('/control/event/%s/%s/items/add' % (self.orga1.slug, self.event1.slug), form_data) doc = self.post_doc('/control/event/%s/%s/items/add' % (self.orga1.slug, self.event1.slug), form_data)
with scopes_disabled():
i = Item.objects.get(name__icontains='Existing') i = Item.objects.get(name__icontains='Existing')
assert doc.select(".alert-success") assert doc.select(".alert-success")
@@ -574,6 +620,7 @@ class ItemsTest(ItemFormTest):
doc = self.post_doc('/control/event/%s/%s/items/add' % (self.orga1.slug, self.event1.slug), form_data) doc = self.post_doc('/control/event/%s/%s/items/add' % (self.orga1.slug, self.event1.slug), form_data)
assert doc.select(".alert-success") assert doc.select(".alert-success")
with scopes_disabled():
assert Quota.objects.filter(name__icontains='New Quota').exists() assert Quota.objects.filter(name__icontains='New Quota').exists()
assert Item.objects.filter(name__icontains='New Item').exists() assert Item.objects.filter(name__icontains='New Item').exists()
i = Item.objects.get(name__icontains='New Item') i = Item.objects.get(name__icontains='New Item')

File diff suppressed because it is too large Load Diff

View File

@@ -1,11 +1,13 @@
import datetime import datetime
from django_scopes import scopes_disabled
from tests.base import SoupTest, extract_form_fields from tests.base import SoupTest, extract_form_fields
from pretix.base.models import Event, Organizer, Team, User from pretix.base.models import Event, Organizer, Team, User
class OrganizerTest(SoupTest): class OrganizerTest(SoupTest):
@scopes_disabled()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy') self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')

View File

@@ -2,6 +2,7 @@ import datetime
from decimal import Decimal from decimal import Decimal
from django.utils.timezone import now from django.utils.timezone import now
from django_scopes import scopes_disabled
from tests.base import SoupTest from tests.base import SoupTest
from pretix.base.models import ( from pretix.base.models import (
@@ -10,6 +11,7 @@ from pretix.base.models import (
class OrderSearchTest(SoupTest): class OrderSearchTest(SoupTest):
@scopes_disabled()
def setUp(self): def setUp(self):
super().setUp() super().setUp()
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy') self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy')
@@ -67,21 +69,21 @@ class OrderSearchTest(SoupTest):
self.client.login(email='dummy@dummy.dummy', password='dummy') self.client.login(email='dummy@dummy.dummy', password='dummy')
def test_team_limit_event(self): def test_team_limit_event(self):
resp = self.client.get('/control/search/orders/').rendered_content resp = self.client.get('/control/search/orders/').content.decode()
assert 'FO1' in resp assert 'FO1' in resp
assert 'FO2' not in resp assert 'FO2' not in resp
def test_team_limit_event_wrong_permission(self): def test_team_limit_event_wrong_permission(self):
self.team.can_view_orders = False self.team.can_view_orders = False
self.team.save() self.team.save()
resp = self.client.get('/control/search/orders/').rendered_content resp = self.client.get('/control/search/orders/').content.decode()
assert 'FO1' not in resp assert 'FO1' not in resp
assert 'FO2' not in resp assert 'FO2' not in resp
def test_team_all_events(self): def test_team_all_events(self):
self.team.all_events = True self.team.all_events = True
self.team.save() self.team.save()
resp = self.client.get('/control/search/orders/').rendered_content resp = self.client.get('/control/search/orders/').content.decode()
assert 'FO1' in resp assert 'FO1' in resp
assert 'FO2' in resp assert 'FO2' in resp
@@ -89,13 +91,13 @@ class OrderSearchTest(SoupTest):
self.team.all_events = True self.team.all_events = True
self.team.can_view_orders = False self.team.can_view_orders = False
self.team.save() self.team.save()
resp = self.client.get('/control/search/orders/').rendered_content resp = self.client.get('/control/search/orders/').content.decode()
assert 'FO1' not in resp assert 'FO1' not in resp
assert 'FO2' not in resp assert 'FO2' not in resp
def test_team_none(self): def test_team_none(self):
self.team.members.clear() self.team.members.clear()
resp = self.client.get('/control/search/orders/').rendered_content resp = self.client.get('/control/search/orders/').content.decode()
assert 'FO1' not in resp assert 'FO1' not in resp
assert 'FO2' not in resp assert 'FO2' not in resp
@@ -104,44 +106,44 @@ class OrderSearchTest(SoupTest):
self.user.staffsession_set.create(date_start=now(), session_key=self.client.session.session_key) self.user.staffsession_set.create(date_start=now(), session_key=self.client.session.session_key)
self.user.save() self.user.save()
self.team.members.clear() self.team.members.clear()
resp = self.client.get('/control/search/orders/').rendered_content resp = self.client.get('/control/search/orders/').content.decode()
assert 'FO1' in resp assert 'FO1' in resp
assert 'FO2' in resp assert 'FO2' in resp
def test_filter_email(self): def test_filter_email(self):
resp = self.client.get('/control/search/orders/?query=dummy1@dummy').rendered_content resp = self.client.get('/control/search/orders/?query=dummy1@dummy').content.decode()
assert 'FO1' in resp assert 'FO1' in resp
resp = self.client.get('/control/search/orders/?query=dummynope').rendered_content resp = self.client.get('/control/search/orders/?query=dummynope').content.decode()
assert 'FO1' not in resp assert 'FO1' not in resp
def test_filter_attendee_name(self): def test_filter_attendee_name(self):
resp = self.client.get('/control/search/orders/?query=Pete').rendered_content resp = self.client.get('/control/search/orders/?query=Pete').content.decode()
assert 'FO1' in resp assert 'FO1' in resp
resp = self.client.get('/control/search/orders/?query=Mark').rendered_content resp = self.client.get('/control/search/orders/?query=Mark').content.decode()
assert 'FO1' not in resp assert 'FO1' not in resp
def test_filter_attendee_email(self): def test_filter_attendee_email(self):
resp = self.client.get('/control/search/orders/?query=att.com').rendered_content resp = self.client.get('/control/search/orders/?query=att.com').content.decode()
assert 'FO1' in resp assert 'FO1' in resp
resp = self.client.get('/control/search/orders/?query=nope.com').rendered_content resp = self.client.get('/control/search/orders/?query=nope.com').content.decode()
assert 'FO1' not in resp assert 'FO1' not in resp
def test_filter_invoice_address(self): def test_filter_invoice_address(self):
resp = self.client.get('/control/search/orders/?query=Ltd').rendered_content resp = self.client.get('/control/search/orders/?query=Ltd').content.decode()
assert 'FO1' in resp assert 'FO1' in resp
resp = self.client.get('/control/search/orders/?query=Miller').rendered_content resp = self.client.get('/control/search/orders/?query=Miller').content.decode()
assert 'FO1' in resp assert 'FO1' in resp
def test_filter_code(self): def test_filter_code(self):
resp = self.client.get('/control/search/orders/?query=FO1').rendered_content resp = self.client.get('/control/search/orders/?query=FO1').content.decode()
assert '30C3-FO1' in resp assert '30C3-FO1' in resp
resp = self.client.get('/control/search/orders/?query=30c3-FO1').rendered_content resp = self.client.get('/control/search/orders/?query=30c3-FO1').content.decode()
assert '30C3-FO1' in resp assert '30C3-FO1' in resp
resp = self.client.get('/control/search/orders/?query=30C3-fO1A').rendered_content resp = self.client.get('/control/search/orders/?query=30C3-fO1A').content.decode()
assert '30C3-FO1' in resp assert '30C3-FO1' in resp
resp = self.client.get('/control/search/orders/?query=30C3-fo14').rendered_content resp = self.client.get('/control/search/orders/?query=30C3-fo14').content.decode()
assert '30C3-FO1' in resp assert '30C3-FO1' in resp
resp = self.client.get('/control/search/orders/?query=31c3-FO1').rendered_content resp = self.client.get('/control/search/orders/?query=31c3-FO1').content.decode()
assert '30C3-FO1' not in resp assert '30C3-FO1' not in resp
resp = self.client.get('/control/search/orders/?query=FO2').rendered_content resp = self.client.get('/control/search/orders/?query=FO2').content.decode()
assert '30C3-FO1' not in resp assert '30C3-FO1' not in resp

Some files were not shown because too many files have changed in this diff Show More