mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
* Stop using ordinal numbers in English date represenation (Z#23210534) * ADjust more tests
953 lines
51 KiB
Python
953 lines
51 KiB
Python
#
|
||
# This file is part of pretix (Community Edition).
|
||
#
|
||
# Copyright (C) 2014-2020 Raphael Michel and contributors
|
||
# Copyright (C) 2020-today pretix GmbH and contributors
|
||
#
|
||
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General
|
||
# Public License as published by the Free Software Foundation in version 3 of the License.
|
||
#
|
||
# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are
|
||
# applicable granting you additional permissions and placing additional restrictions on your usage of this software.
|
||
# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive
|
||
# this file, see <https://pretix.eu/about/en/license>.
|
||
#
|
||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||
# details.
|
||
#
|
||
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
|
||
# <https://www.gnu.org/licenses/>.
|
||
#
|
||
import datetime
|
||
import json
|
||
from decimal import Decimal
|
||
|
||
from bs4 import BeautifulSoup
|
||
from django.conf import settings
|
||
from django.test import TestCase, override_settings
|
||
from django.utils.timezone import now
|
||
from django_scopes import scopes_disabled
|
||
from freezegun import freeze_time
|
||
|
||
from pretix.base.models import Order, OrderPosition
|
||
|
||
from .test_cart import CartTestMixin
|
||
|
||
|
||
class WidgetCartTest(CartTestMixin, TestCase):
|
||
@scopes_disabled()
|
||
def setUp(self):
|
||
super().setUp()
|
||
self.order = Order.objects.create(
|
||
status=Order.STATUS_PENDING,
|
||
event=self.event,
|
||
email='admin@localhost',
|
||
datetime=now() - datetime.timedelta(days=3),
|
||
expires=now() + datetime.timedelta(days=11),
|
||
total=Decimal("23"),
|
||
locale='en',
|
||
sales_channel=self.orga.sales_channels.get(identifier="web"),
|
||
)
|
||
self.ticket_pos = OrderPosition.objects.create(
|
||
order=self.order,
|
||
item=self.ticket,
|
||
variation=None,
|
||
price=Decimal("23"),
|
||
attendee_name_parts={'full_name': "Peter"}
|
||
)
|
||
|
||
def test_iframe_entry_view_wrapper(self):
|
||
self.event.settings.locales = ["de", "en"]
|
||
r = self.client.get('/%s/%s/?iframe=1&locale=de' % (self.orga.slug, self.event.slug), headers={
|
||
"Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8",
|
||
})
|
||
assert 'iframe_session' in self.client.session
|
||
assert self.client.cookies[settings.LANGUAGE_COOKIE_NAME].value == "de"
|
||
assert r.headers["Content-Language"] == "de"
|
||
|
||
def test_allow_frame_if_namespaced(self):
|
||
response = self.client.get('/%s/%s/' % (self.orga.slug, self.event.slug))
|
||
assert 'X-Frame-Options' in response
|
||
response = self.client.get('/%s/%s/w/aaaaaaaaaaaaaaaa/' % (self.orga.slug, self.event.slug))
|
||
assert 'X-Frame-Options' not in response
|
||
|
||
response = self.client.get('/%s/%s/waitinglist' % (self.orga.slug, self.event.slug))
|
||
assert 'X-Frame-Options' in response
|
||
response = self.client.get('/%s/%s/w/aaaaaaaaaaaaaaaa/waitinglist' % (self.orga.slug, self.event.slug))
|
||
assert 'X-Frame-Options' not in response
|
||
|
||
def test_allow_frame_on_order(self):
|
||
response = self.client.get('/%s/%s/order/%s/%s/' % (self.orga.slug, self.event.slug, self.order.code,
|
||
self.order.secret))
|
||
assert 'X-Frame-Options' not in response
|
||
response = self.client.get('/%s/%s/order/%s/%s/modify' % (self.orga.slug, self.event.slug, self.order.code,
|
||
self.order.secret))
|
||
assert 'X-Frame-Options' not in response
|
||
response = self.client.get('/%s/%s/order/%s/%s/pay/change' % (self.orga.slug, self.event.slug, self.order.code,
|
||
self.order.secret))
|
||
assert 'X-Frame-Options' not in response
|
||
response = self.client.get('/%s/%s/order/%s/%s/cancel' % (self.orga.slug, self.event.slug, self.order.code,
|
||
self.order.secret))
|
||
assert 'X-Frame-Options' not in response
|
||
|
||
def test_allow_cors_if_namespaced(self):
|
||
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
|
||
'item_%d' % self.ticket.id: '1',
|
||
'ajax': 1
|
||
})
|
||
assert 'Access-Control-Allow-Origin' not in response
|
||
response = self.client.post('/%s/%s/w/aaaaaaaaaaaaaaaa/cart/add' % (self.orga.slug, self.event.slug), {
|
||
'item_%d' % self.ticket.id: '1',
|
||
'ajax': 1
|
||
})
|
||
assert response['Access-Control-Allow-Origin'] == '*'
|
||
|
||
def test_cart_isolation(self):
|
||
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
|
||
'item_%d' % self.ticket.id: '1'
|
||
}, follow=True)
|
||
self.assertRedirects(response, '/%s/%s/?require_cookie=true' % (self.orga.slug, self.event.slug),
|
||
target_status_code=200)
|
||
doc = BeautifulSoup(response.rendered_content, "lxml")
|
||
assert len(doc.select('.cart .cart-row')) == 2
|
||
self.assertIn('Early-bird', doc.select('.cart .cart-row')[0].select('strong')[0].text)
|
||
self.assertIn('1', doc.select('.cart .cart-row')[0].select('.count')[0].text)
|
||
self.assertIn('23', doc.select('.cart .cart-row')[0].select('.price')[0].text)
|
||
self.assertIn('23', doc.select('.cart .cart-row')[0].select('.price')[1].text)
|
||
|
||
response = self.client.get('/%s/%s/w/aaaaaaaaaaaaaaaa/' % (self.orga.slug, self.event.slug))
|
||
doc = BeautifulSoup(response.rendered_content, "lxml")
|
||
assert len(doc.select('.cart .cart-row')) == 0
|
||
response = self.client.post('/%s/%s/w/aaaaaaaaaaaaaaaa/cart/add' % (self.orga.slug, self.event.slug), {
|
||
'item_%d' % self.ticket.id: '1'
|
||
}, follow=True)
|
||
self.assertRedirects(response, '/%s/%s/w/aaaaaaaaaaaaaaaa/?require_cookie=true' % (self.orga.slug, self.event.slug),
|
||
target_status_code=200)
|
||
doc = BeautifulSoup(response.rendered_content, "lxml")
|
||
assert len(doc.select('.cart .cart-row')) == 2
|
||
self.assertIn('Early-bird', doc.select('.cart .cart-row')[0].select('strong')[0].text)
|
||
self.assertIn('1', doc.select('.cart .cart-row')[0].select('.count')[0].text)
|
||
self.assertIn('23', doc.select('.cart .cart-row')[0].select('.price')[0].text)
|
||
self.assertIn('23', doc.select('.cart .cart-row')[0].select('.price')[1].text)
|
||
|
||
response = self.client.get('/%s/%s/w/aaaaaaaaaaaaaaab/' % (self.orga.slug, self.event.slug))
|
||
doc = BeautifulSoup(response.rendered_content, "lxml")
|
||
assert len(doc.select('.cart .cart-row')) == 0
|
||
response = self.client.post('/%s/%s/w/aaaaaaaaaaaaaaab/cart/add' % (self.orga.slug, self.event.slug), {
|
||
'item_%d' % self.ticket.id: '1'
|
||
}, follow=True)
|
||
self.assertRedirects(response, '/%s/%s/w/aaaaaaaaaaaaaaab/?require_cookie=true' % (self.orga.slug, self.event.slug),
|
||
target_status_code=200)
|
||
doc = BeautifulSoup(response.rendered_content, "lxml")
|
||
assert len(doc.select('.cart .cart-row')) == 2
|
||
self.assertIn('Early-bird', doc.select('.cart .cart-row')[0].select('strong')[0].text)
|
||
self.assertIn('1', doc.select('.cart .cart-row')[0].select('.count')[0].text)
|
||
self.assertIn('23', doc.select('.cart .cart-row')[0].select('.price')[0].text)
|
||
self.assertIn('23', doc.select('.cart .cart-row')[0].select('.price')[1].text)
|
||
|
||
def test_saleschannel_disabled(self):
|
||
self.event.all_sales_channels = False
|
||
self.event.save()
|
||
response = self.client.get('/%s/%s/widget/product_list' % (self.orga.slug, self.event.slug))
|
||
data = json.loads(response.content.decode())
|
||
assert data == {
|
||
"error": "Tickets for this event cannot be purchased on this sales channel.",
|
||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||
}
|
||
self.assertEqual(response.status_code, 200)
|
||
response = self.client.post('/%s/%s/w/aaaaaaaaaaaaaaab/cart/add' % (self.orga.slug, self.event.slug), {
|
||
'item_%d' % self.ticket.id: '1'
|
||
}, follow=True)
|
||
self.assertEqual(response.status_code, 404)
|
||
|
||
def test_product_list_view(self):
|
||
response = self.client.get('/%s/%s/widget/product_list' % (self.orga.slug, self.event.slug))
|
||
assert response['Access-Control-Allow-Origin'] == '*'
|
||
data = json.loads(response.content.decode())
|
||
assert data == {
|
||
"target_url": "http://example.com/ccc/30c3/",
|
||
"subevent": None,
|
||
"name": "30C3",
|
||
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26, {self.event.date_from.year} 00:00",
|
||
"frontpage_text": "",
|
||
"location": "",
|
||
"currency": "EUR",
|
||
"show_variations_expanded": False,
|
||
"display_net_prices": False,
|
||
"use_native_spinners": False,
|
||
"vouchers_exist": False,
|
||
"waiting_list_enabled": False,
|
||
"error": None,
|
||
"has_seating_plan": False,
|
||
"has_seating_plan_waitinglist": False,
|
||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||
"items_by_category": [
|
||
{
|
||
"items": [
|
||
{
|
||
"current_unavailability_reason": None,
|
||
"order_min": None,
|
||
"max_price": None,
|
||
"price": {"gross": "23.00", "net": "19.33", "tax": "3.67", "name": "", "rate": "19.00", "includes_mixed_tax_rate": False},
|
||
"suggested_price": {"gross": "23.00", "net": "19.33", "tax": "3.67", "name": "", "rate": "19.00", "includes_mixed_tax_rate": False},
|
||
"picture": None,
|
||
"picture_fullsize": None,
|
||
"has_variations": 0,
|
||
"allow_waitinglist": True,
|
||
"mandatory_priced_addons": False,
|
||
"description": None,
|
||
"min_price": None,
|
||
"avail": [100, None],
|
||
"variations": [],
|
||
"id": self.ticket.pk,
|
||
"free_price": False,
|
||
"original_price": None,
|
||
"name": "Early-bird ticket",
|
||
"order_max": 4
|
||
},
|
||
{
|
||
"current_unavailability_reason": None,
|
||
"order_min": None,
|
||
"max_price": "14.00",
|
||
"price": None,
|
||
"suggested_price": None,
|
||
"picture": None,
|
||
"picture_fullsize": None,
|
||
"has_variations": 4,
|
||
"allow_waitinglist": True,
|
||
"mandatory_priced_addons": False,
|
||
"description": None,
|
||
"min_price": "12.00",
|
||
"avail": None,
|
||
"variations": [
|
||
{
|
||
"value": "Red",
|
||
"id": self.shirt_red.pk,
|
||
'original_price': None,
|
||
"price": {"gross": "14.00", "net": "11.76", "tax": "2.24", "name": "",
|
||
"rate": "19.00", "includes_mixed_tax_rate": False},
|
||
"suggested_price": {"gross": "14.00", "net": "11.76", "tax": "2.24", "name": "",
|
||
"rate": "19.00", "includes_mixed_tax_rate": False},
|
||
"description": None,
|
||
"avail": [100, None],
|
||
"order_max": 2,
|
||
"current_unavailability_reason": None,
|
||
},
|
||
{
|
||
"value": "Blue",
|
||
"id": self.shirt_blue.pk,
|
||
'original_price': None,
|
||
"price": {"gross": "12.00", "net": "10.08", "tax": "1.92", "name": "",
|
||
"rate": "19.00", "includes_mixed_tax_rate": False},
|
||
"suggested_price": {"gross": "12.00", "net": "10.08", "tax": "1.92", "name": "",
|
||
"rate": "19.00", "includes_mixed_tax_rate": False},
|
||
"description": None,
|
||
"avail": [100, None],
|
||
"order_max": 2,
|
||
"current_unavailability_reason": None,
|
||
}
|
||
],
|
||
"id": self.shirt.pk,
|
||
"free_price": False,
|
||
"original_price": None,
|
||
"name": "T-Shirt",
|
||
"order_max": None
|
||
}
|
||
],
|
||
"description": None,
|
||
"id": self.category.pk,
|
||
"name": "Everything"
|
||
}
|
||
],
|
||
"itemnum": 2,
|
||
"display_add_to_cart": True,
|
||
"cart_exists": False,
|
||
"voucher_explanation_text": "",
|
||
}
|
||
|
||
def test_product_list_view_filter(self):
|
||
response = self.client.get('/%s/%s/widget/product_list?items=%s' % (self.orga.slug, self.event.slug,
|
||
self.ticket.pk))
|
||
assert response['Access-Control-Allow-Origin'] == '*'
|
||
data = json.loads(response.content.decode())
|
||
assert data['items_by_category'] == [
|
||
{
|
||
"items": [
|
||
{
|
||
"current_unavailability_reason": None,
|
||
"order_min": None,
|
||
"max_price": None,
|
||
"price": {"gross": "23.00", "net": "19.33", "tax": "3.67", "name": "", "rate": "19.00",
|
||
"includes_mixed_tax_rate": False},
|
||
"suggested_price": {"gross": "23.00", "net": "19.33", "tax": "3.67", "name": "", "rate": "19.00",
|
||
"includes_mixed_tax_rate": False},
|
||
"picture": None,
|
||
"picture_fullsize": None,
|
||
"has_variations": 0,
|
||
"allow_waitinglist": True,
|
||
"mandatory_priced_addons": False,
|
||
"description": None,
|
||
"min_price": None,
|
||
"avail": [100, None],
|
||
"variations": [],
|
||
"id": self.ticket.pk,
|
||
"free_price": False,
|
||
"original_price": None,
|
||
"name": "Early-bird ticket",
|
||
"order_max": 4
|
||
}
|
||
],
|
||
"description": None,
|
||
"id": self.category.pk,
|
||
"name": "Everything"
|
||
}
|
||
]
|
||
|
||
response = self.client.get('/%s/%s/widget/product_list?categories=0,%s' % (self.orga.slug, self.event.slug,
|
||
self.category.pk))
|
||
assert response['Access-Control-Allow-Origin'] == '*'
|
||
data = json.loads(response.content.decode())
|
||
assert len(data['items_by_category']) == 1
|
||
|
||
response = self.client.get('/%s/%s/widget/product_list?categories=0' % (self.orga.slug, self.event.slug))
|
||
assert response['Access-Control-Allow-Origin'] == '*'
|
||
data = json.loads(response.content.decode())
|
||
assert len(data['items_by_category']) == 0
|
||
|
||
def test_product_list_view_variation_filter(self):
|
||
response = self.client.get('/%s/%s/widget/product_list?variations=%s' % (self.orga.slug, self.event.slug,
|
||
self.shirt_red.pk))
|
||
assert response['Access-Control-Allow-Origin'] == '*'
|
||
data = json.loads(response.content.decode())
|
||
assert data['items_by_category'] == [
|
||
{
|
||
"items": [
|
||
{
|
||
"current_unavailability_reason": None,
|
||
"order_min": None,
|
||
"max_price": "14.00",
|
||
"price": None,
|
||
"suggested_price": None,
|
||
"picture": None,
|
||
"picture_fullsize": None,
|
||
"has_variations": 4,
|
||
"allow_waitinglist": True,
|
||
"mandatory_priced_addons": False,
|
||
"description": None,
|
||
"min_price": "12.00",
|
||
"avail": None,
|
||
"variations": [
|
||
{
|
||
"value": "Red",
|
||
"id": self.shirt_red.pk,
|
||
'original_price': None,
|
||
"price": {"gross": "14.00", "net": "11.76", "tax": "2.24", "name": "",
|
||
"rate": "19.00", "includes_mixed_tax_rate": False},
|
||
"suggested_price": {"gross": "14.00", "net": "11.76", "tax": "2.24", "name": "",
|
||
"rate": "19.00", "includes_mixed_tax_rate": False},
|
||
"description": None,
|
||
"avail": [100, None],
|
||
"order_max": 2,
|
||
"current_unavailability_reason": None,
|
||
}
|
||
],
|
||
"id": self.shirt.pk,
|
||
"free_price": False,
|
||
"original_price": None,
|
||
"name": "T-Shirt",
|
||
"order_max": None
|
||
}
|
||
],
|
||
"description": None,
|
||
"id": self.category.pk,
|
||
"name": "Everything"
|
||
}
|
||
]
|
||
|
||
def test_product_list_view_with_voucher(self):
|
||
with scopes_disabled():
|
||
self.event.vouchers.create(item=self.ticket, code="ABCDE", max_usages=1)
|
||
response = self.client.get('/%s/%s/widget/product_list?voucher=ABCDE' % (self.orga.slug, self.event.slug))
|
||
assert response['Access-Control-Allow-Origin'] == '*'
|
||
data = json.loads(response.content.decode())
|
||
assert data == {
|
||
"target_url": "http://example.com/ccc/30c3/",
|
||
"subevent": None,
|
||
"name": "30C3",
|
||
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26, {self.event.date_from.year} 00:00",
|
||
"frontpage_text": "",
|
||
"location": "",
|
||
"currency": "EUR",
|
||
"show_variations_expanded": False,
|
||
"display_net_prices": False,
|
||
"use_native_spinners": False,
|
||
"has_seating_plan": False,
|
||
"has_seating_plan_waitinglist": False,
|
||
"vouchers_exist": True,
|
||
"waiting_list_enabled": False,
|
||
"error": None,
|
||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||
"items_by_category": [
|
||
{
|
||
"items": [
|
||
{
|
||
"current_unavailability_reason": None,
|
||
"order_min": None,
|
||
"max_price": None,
|
||
"price": {"gross": "23.00", "net": "19.33", "tax": "3.67", "name": "", "rate": "19.00", "includes_mixed_tax_rate": False},
|
||
"suggested_price": {"gross": "23.00", "net": "19.33", "tax": "3.67", "name": "", "rate": "19.00", "includes_mixed_tax_rate": False},
|
||
"picture": None,
|
||
"picture_fullsize": None,
|
||
"has_variations": 0,
|
||
"allow_waitinglist": True,
|
||
"mandatory_priced_addons": False,
|
||
"description": None,
|
||
"min_price": None,
|
||
"avail": [100, None],
|
||
"variations": [],
|
||
"id": self.ticket.pk,
|
||
"free_price": False,
|
||
"original_price": None,
|
||
"name": "Early-bird ticket",
|
||
"order_max": 1
|
||
},
|
||
],
|
||
"description": None,
|
||
"id": self.category.pk,
|
||
"name": "Everything"
|
||
}
|
||
],
|
||
"itemnum": 1,
|
||
"voucher_explanation_text": "",
|
||
"display_add_to_cart": True,
|
||
"cart_exists": False
|
||
}
|
||
|
||
def test_product_list_view_with_voucher_variation_through_quota(self):
|
||
with scopes_disabled():
|
||
self.event.vouchers.create(quota=self.quota_shirts, code="ABCDE", max_usages=1)
|
||
self.quota_shirts.variations.remove(self.shirt_blue)
|
||
response = self.client.get('/%s/%s/widget/product_list?voucher=ABCDE' % (self.orga.slug, self.event.slug))
|
||
assert response['Access-Control-Allow-Origin'] == '*'
|
||
data = json.loads(response.content.decode())
|
||
assert data == {
|
||
"target_url": "http://example.com/ccc/30c3/",
|
||
"subevent": None,
|
||
"name": "30C3",
|
||
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26, {self.event.date_from.year} 00:00",
|
||
"frontpage_text": "",
|
||
"location": "",
|
||
"currency": "EUR",
|
||
"show_variations_expanded": False,
|
||
"display_net_prices": False,
|
||
"use_native_spinners": False,
|
||
"vouchers_exist": True,
|
||
"has_seating_plan": False,
|
||
"has_seating_plan_waitinglist": False,
|
||
"waiting_list_enabled": False,
|
||
"error": None,
|
||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||
"items_by_category": [
|
||
{
|
||
"items": [
|
||
{
|
||
'id': self.shirt.pk,
|
||
'name': 'T-Shirt',
|
||
'picture': None,
|
||
"picture_fullsize": None,
|
||
'description': None,
|
||
'has_variations': 2,
|
||
"allow_waitinglist": True,
|
||
"mandatory_priced_addons": False,
|
||
'current_unavailability_reason': None,
|
||
'order_min': None,
|
||
'order_max': None,
|
||
'price': None,
|
||
'suggested_price': None,
|
||
'min_price': '14.00',
|
||
'max_price': '14.00',
|
||
'free_price': False,
|
||
'avail': None,
|
||
'original_price': None,
|
||
'variations': [
|
||
{
|
||
'id': self.shirt_red.pk,
|
||
'value': 'Red',
|
||
'order_max': 1,
|
||
'description': None,
|
||
'original_price': None,
|
||
'price': {
|
||
'gross': '14.00',
|
||
'net': '11.76',
|
||
'tax': '2.24',
|
||
'rate': '19.00',
|
||
'name': '',
|
||
'includes_mixed_tax_rate': False
|
||
},
|
||
'suggested_price': {
|
||
'gross': '14.00',
|
||
'net': '11.76',
|
||
'tax': '2.24',
|
||
'rate': '19.00',
|
||
'name': '',
|
||
'includes_mixed_tax_rate': False
|
||
},
|
||
'avail': [100, None],
|
||
'current_unavailability_reason': None,
|
||
},
|
||
]
|
||
}
|
||
],
|
||
"description": None,
|
||
"id": self.category.pk,
|
||
"name": "Everything"
|
||
}
|
||
],
|
||
"itemnum": 1,
|
||
"display_add_to_cart": True,
|
||
"voucher_explanation_text": "",
|
||
"cart_exists": False
|
||
}
|
||
|
||
def test_product_list_view_with_voucher_expired(self):
|
||
with scopes_disabled():
|
||
self.event.vouchers.create(item=self.ticket, code="ABCDE", valid_until=now() - datetime.timedelta(days=1))
|
||
response = self.client.get('/%s/%s/widget/product_list?voucher=ABCDE' % (self.orga.slug, self.event.slug))
|
||
assert response['Access-Control-Allow-Origin'] == '*'
|
||
data = json.loads(response.content.decode())
|
||
assert data == {
|
||
"target_url": "http://example.com/ccc/30c3/",
|
||
"subevent": None,
|
||
"name": "30C3",
|
||
"date_range": f"{self.event.date_from.strftime('%a')}, Dec. 26, {self.event.date_from.year} 00:00",
|
||
"frontpage_text": "",
|
||
"location": "",
|
||
"currency": "EUR",
|
||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||
"show_variations_expanded": False,
|
||
"display_net_prices": False,
|
||
"use_native_spinners": False,
|
||
"has_seating_plan": False,
|
||
"has_seating_plan_waitinglist": False,
|
||
"vouchers_exist": False,
|
||
"waiting_list_enabled": False,
|
||
"error": "This voucher is expired.",
|
||
"items_by_category": [],
|
||
"display_add_to_cart": False,
|
||
"cart_exists": False,
|
||
"voucher_explanation_text": "",
|
||
"itemnum": 0,
|
||
}
|
||
|
||
@override_settings(COMPRESS_PRECOMPILERS=settings.COMPRESS_PRECOMPILERS_ORIGINAL)
|
||
def test_css_customized(self):
|
||
response = self.client.get('/%s/%s/widget/v2.css' % (self.orga.slug, self.event.slug))
|
||
c = b"".join(response.streaming_content).decode()
|
||
assert '#8E44B3' in c
|
||
assert '#33c33c' not in c
|
||
assert '#34c34c' not in c
|
||
|
||
self.orga.settings.primary_color = "#33c33c"
|
||
self.orga.cache.clear()
|
||
response = self.client.get('/%s/%s/widget/v2.css' % (self.orga.slug, self.event.slug))
|
||
c = b"".join(response.streaming_content).decode()
|
||
assert '#8E44B3' not in c
|
||
assert '#33c33c' in c
|
||
assert '#34c34c' not in c
|
||
|
||
self.event.settings.primary_color = "#34c34c"
|
||
self.event.cache.clear()
|
||
response = self.client.get('/%s/%s/widget/v2.css' % (self.orga.slug, self.event.slug))
|
||
c = b"".join(response.streaming_content).decode()
|
||
assert '#8E44B3' not in c
|
||
assert '#33c33c' not in c
|
||
assert '#34c34c' in c
|
||
|
||
def test_js_localized(self):
|
||
response = self.client.get('/widget/v2.en.js')
|
||
c = response.content.decode()
|
||
assert '%m/%d/%Y' in c
|
||
assert '%d.%m.%Y' not in c
|
||
response = self.client.get('/widget/v2.de.js')
|
||
c = response.content.decode()
|
||
assert '%m/%d/%Y' not in c
|
||
assert '%d.%m.%Y' in c
|
||
|
||
def test_product_list_view_with_bundle_sold_out(self):
|
||
self.quota_shirts.size = 0
|
||
self.quota_shirts.save()
|
||
self.ticket.bundles.create(bundled_item=self.shirt, bundled_variation=self.shirt_blue,
|
||
designated_price=2, count=1)
|
||
response = self.client.get('/%s/%s/widget/product_list' % (self.orga.slug, self.event.slug))
|
||
assert response['Access-Control-Allow-Origin'] == '*'
|
||
data = json.loads(response.content.decode())
|
||
assert data["items_by_category"][0]["items"][0]["avail"] == [0, None]
|
||
|
||
def test_product_list_view_with_bundle_mixed_tax_rate(self):
|
||
with scopes_disabled():
|
||
self.tr7 = self.event.tax_rules.create(rate=Decimal('7.00'))
|
||
self.shirt.tax_rule = self.tr7
|
||
self.shirt.require_bundling = True
|
||
self.shirt.save()
|
||
self.ticket.bundles.create(bundled_item=self.shirt, bundled_variation=self.shirt_blue,
|
||
designated_price=2, count=1)
|
||
response = self.client.get('/%s/%s/widget/product_list' % (self.orga.slug, self.event.slug))
|
||
assert response['Access-Control-Allow-Origin'] == '*'
|
||
data = json.loads(response.content.decode())
|
||
assert len(data["items_by_category"][0]["items"]) == 1
|
||
assert data["items_by_category"][0]["items"][0]["price"] == {
|
||
"gross": "23.00",
|
||
"net": "19.52",
|
||
"tax": "3.48",
|
||
"name": "MIXED!",
|
||
"rate": "19.00",
|
||
"includes_mixed_tax_rate": True
|
||
}
|
||
|
||
def test_subevent_list(self):
|
||
self.event.has_subevents = True
|
||
self.event.settings.timezone = 'Europe/Berlin'
|
||
self.event.save()
|
||
with freeze_time("2019-01-01 10:00:00"):
|
||
with scopes_disabled():
|
||
self.event.subevents.create(name="Past", active=True, date_from=now() - datetime.timedelta(days=3))
|
||
se1 = self.event.subevents.create(name="Present", active=True, date_from=now())
|
||
se2 = self.event.subevents.create(name="Future", active=True, date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Disabled", active=False, date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Hidden", active=True, is_public=False, date_from=now() + datetime.timedelta(days=3))
|
||
|
||
response = self.client.get('/%s/%s/widget/product_list' % (self.orga.slug, self.event.slug))
|
||
data = json.loads(response.content.decode())
|
||
assert data == {
|
||
'list_type': 'list',
|
||
'meta_filter_fields': [],
|
||
'name': '30C3',
|
||
'frontpage_text': '',
|
||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||
'has_more_events': False,
|
||
'events': [
|
||
{'name': 'Present', 'date_range': 'Tue, Jan. 1, 2019 11:00', 'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se1.pk, 'location': ''},
|
||
{'name': 'Future', 'date_range': 'Fri, Jan. 4, 2019 11:00', 'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se2.pk, 'location': ''}
|
||
]
|
||
}
|
||
|
||
def test_subevent_calendar(self):
|
||
self.event.has_subevents = True
|
||
self.event.settings.timezone = 'Europe/Berlin'
|
||
self.event.save()
|
||
with freeze_time("2019-01-01 10:00:00"):
|
||
with scopes_disabled():
|
||
self.event.subevents.create(name="Past", active=True, date_from=now() - datetime.timedelta(days=3))
|
||
se1 = self.event.subevents.create(name="Present", active=True, date_from=now())
|
||
se2 = self.event.subevents.create(name="Future", active=True, date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Disabled", active=False, date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Hidden", active=True, is_public=False, date_from=now() + datetime.timedelta(days=3))
|
||
|
||
response = self.client.get('/%s/%s/widget/product_list?style=calendar' % (self.orga.slug, self.event.slug))
|
||
data = json.loads(response.content.decode())
|
||
assert data == {
|
||
'list_type': 'calendar',
|
||
'meta_filter_fields': [],
|
||
'date': '2019-01-01',
|
||
'name': '30C3',
|
||
'frontpage_text': '',
|
||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||
'weeks': [
|
||
[
|
||
None,
|
||
{'day': 1, 'date': '2019-01-01', 'events': [
|
||
{'name': 'Present', 'time': '11:00', 'continued': False, 'date_range': 'Tue, Jan. 1, 2019 11:00',
|
||
'location': '',
|
||
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se1.pk}]},
|
||
{'day': 2, 'date': '2019-01-02', 'events': []},
|
||
{'day': 3, 'date': '2019-01-03', 'events': []},
|
||
{'day': 4, 'date': '2019-01-04', 'events': [
|
||
{'name': 'Future', 'time': '11:00', 'continued': False, 'date_range': 'Fri, Jan. 4, 2019 11:00',
|
||
'location': '',
|
||
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se2.pk}]},
|
||
{'day': 5, 'date': '2019-01-05', 'events': []},
|
||
{'day': 6, 'date': '2019-01-06', 'events': []}
|
||
],
|
||
[
|
||
{'day': 7, 'date': '2019-01-07', 'events': []},
|
||
{'day': 8, 'date': '2019-01-08', 'events': []},
|
||
{'day': 9, 'date': '2019-01-09', 'events': []},
|
||
{'day': 10, 'date': '2019-01-10', 'events': []},
|
||
{'day': 11, 'date': '2019-01-11', 'events': []},
|
||
{'day': 12, 'date': '2019-01-12', 'events': []},
|
||
{'day': 13, 'date': '2019-01-13', 'events': []}
|
||
],
|
||
[
|
||
{'day': 14, 'date': '2019-01-14', 'events': []},
|
||
{'day': 15, 'date': '2019-01-15', 'events': []},
|
||
{'day': 16, 'date': '2019-01-16', 'events': []},
|
||
{'day': 17, 'date': '2019-01-17', 'events': []},
|
||
{'day': 18, 'date': '2019-01-18', 'events': []},
|
||
{'day': 19, 'date': '2019-01-19', 'events': []},
|
||
{'day': 20, 'date': '2019-01-20', 'events': []}
|
||
],
|
||
[
|
||
{'day': 21, 'date': '2019-01-21', 'events': []},
|
||
{'day': 22, 'date': '2019-01-22', 'events': []},
|
||
{'day': 23, 'date': '2019-01-23', 'events': []},
|
||
{'day': 24, 'date': '2019-01-24', 'events': []},
|
||
{'day': 25, 'date': '2019-01-25', 'events': []},
|
||
{'day': 26, 'date': '2019-01-26', 'events': []},
|
||
{'day': 27, 'date': '2019-01-27', 'events': []}
|
||
],
|
||
[
|
||
{'day': 28, 'date': '2019-01-28', 'events': []},
|
||
{'day': 29, 'date': '2019-01-29', 'events': []},
|
||
{'day': 30, 'date': '2019-01-30', 'events': []},
|
||
{'day': 31, 'date': '2019-01-31', 'events': []},
|
||
None, None, None
|
||
]
|
||
]
|
||
}
|
||
|
||
def test_subevent_week_calendar(self):
|
||
self.event.has_subevents = True
|
||
self.event.settings.timezone = 'Europe/Berlin'
|
||
self.event.save()
|
||
with freeze_time("2019-01-01 10:00:00"):
|
||
with scopes_disabled():
|
||
self.event.subevents.create(name="Past", active=True, date_from=now() - datetime.timedelta(days=3))
|
||
se1 = self.event.subevents.create(name="Present", active=True, date_from=now())
|
||
se2 = self.event.subevents.create(name="Future", active=True, date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Disabled", active=False, date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Hidden", active=True, is_public=False, date_from=now() + datetime.timedelta(days=3))
|
||
|
||
response = self.client.get('/%s/%s/widget/product_list?style=week' % (self.orga.slug, self.event.slug))
|
||
data = json.loads(response.content.decode())
|
||
assert data == {
|
||
'list_type': 'week',
|
||
'meta_filter_fields': [],
|
||
'name': '30C3',
|
||
'frontpage_text': '',
|
||
'week': [2019, 1],
|
||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||
'days': [
|
||
{'day_formatted': 'Mon, Dec 31', 'date': '2018-12-31', 'events': [], 'today': False},
|
||
{'day_formatted': 'Tue, Jan 1', 'date': '2019-01-01', 'events': [
|
||
{'name': 'Present', 'time': '11:00', 'continued': False, 'date_range': 'Tue, Jan. 1, 2019 11:00',
|
||
'location': '',
|
||
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se1.pk}], 'today': True},
|
||
{'day_formatted': 'Wed, Jan 2', 'date': '2019-01-02', 'events': [], 'today': False},
|
||
{'day_formatted': 'Thu, Jan 3', 'date': '2019-01-03', 'events': [], 'today': False},
|
||
{'day_formatted': 'Fri, Jan 4', 'date': '2019-01-04', 'events': [
|
||
{'name': 'Future', 'time': '11:00', 'continued': False, 'date_range': 'Fri, Jan. 4, 2019 11:00',
|
||
'location': '',
|
||
'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'event_url': 'http://example.com/ccc/30c3/', 'subevent': se2.pk}], 'today': False},
|
||
{'day_formatted': 'Sat, Jan 5', 'date': '2019-01-05', 'events': [], 'today': False},
|
||
{'day_formatted': 'Sun, Jan 6', 'date': '2019-01-06', 'events': [], 'today': False}
|
||
],
|
||
}
|
||
|
||
def test_event_list(self):
|
||
self.event.has_subevents = True
|
||
self.event.settings.timezone = 'Europe/Berlin'
|
||
self.event.save()
|
||
with freeze_time("2019-01-01 10:00:00"):
|
||
with scopes_disabled():
|
||
self.orga.events.create(name="Past", live=True, is_public=True, slug='past', date_from=now() - datetime.timedelta(days=3))
|
||
self.orga.events.create(name="Present", live=True, is_public=True, slug='present', date_from=now())
|
||
self.orga.events.create(name="Future", live=True, is_public=True, slug='future', date_from=now() + datetime.timedelta(days=3))
|
||
self.orga.events.create(name="Disabled", live=False, is_public=True, slug='disabled', date_from=now() + datetime.timedelta(days=3))
|
||
self.orga.events.create(name="Secret", live=True, is_public=False, slug='secret', date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Past", active=True, date_from=now() - datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Present", active=True, date_from=now())
|
||
self.event.subevents.create(name="Future", active=True, date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Disabled", active=False, date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Hidden", active=True, is_public=False, date_from=now() + datetime.timedelta(days=3))
|
||
|
||
response = self.client.get('/%s/widget/product_list' % (self.orga.slug,))
|
||
data = json.loads(response.content.decode())
|
||
assert data == {
|
||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||
'events': [
|
||
{'availability': {'color': 'none', 'text': 'Event series'},
|
||
'date_range': 'Jan. 1 – 4, 2019',
|
||
'event_url': 'http://example.com/ccc/30c3/',
|
||
'location': '',
|
||
'name': '30C3'},
|
||
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'date_range': 'Tue, Jan. 1, 2019 10:00',
|
||
'location': '',
|
||
'event_url': 'http://example.com/ccc/present/',
|
||
'name': 'Present'},
|
||
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'date_range': 'Fri, Jan. 4, 2019 10:00',
|
||
'location': '',
|
||
'event_url': 'http://example.com/ccc/future/',
|
||
'name': 'Future'}
|
||
],
|
||
'list_type': 'list',
|
||
'meta_filter_fields': [],
|
||
}
|
||
|
||
def test_event_list_filtersets_from_allowed_values(self):
|
||
self.event.has_subevents = True
|
||
self.event.settings.timezone = 'Europe/Berlin'
|
||
self.event.save()
|
||
with freeze_time("2019-01-01 10:00:00"):
|
||
with scopes_disabled():
|
||
self.orga.meta_properties.create(
|
||
name="Language",
|
||
default="EN",
|
||
filter_public=True,
|
||
choices=[
|
||
{"key": "EN", "label": "English"},
|
||
{"key": "DE", "label": "German"},
|
||
]
|
||
)
|
||
|
||
response = self.client.get('/%s/widget/product_list' % (self.orga.slug,))
|
||
data = json.loads(response.content.decode())
|
||
assert data["meta_filter_fields"] == [
|
||
{
|
||
"choices": [["", "-- all --"], ["EN", "English"], ["DE", "German"]],
|
||
"key": "attr[Language]",
|
||
"label": "Language"
|
||
}
|
||
]
|
||
|
||
def test_event_list_filtersets_from_existing_values(self):
|
||
self.event.has_subevents = True
|
||
self.event.settings.timezone = 'Europe/Berlin'
|
||
self.event.save()
|
||
with freeze_time("2019-01-01 10:00:00"):
|
||
with scopes_disabled():
|
||
p = self.orga.meta_properties.create(
|
||
name="Language",
|
||
default="DE",
|
||
filter_public=True,
|
||
)
|
||
e = self.orga.events.create(name="Future", live=True, is_public=True, slug='future', date_from=now() + datetime.timedelta(days=3))
|
||
se = self.event.subevents.create(name="Future", active=True, date_from=now() + datetime.timedelta(days=3))
|
||
e.meta_values.create(property=p, value="EN")
|
||
se.meta_values.create(property=p, value="DE")
|
||
|
||
response = self.client.get('/%s/widget/product_list' % (self.orga.slug,))
|
||
data = json.loads(response.content.decode())
|
||
assert data["meta_filter_fields"] == [
|
||
{
|
||
"choices": [["", "-- all --"], ["DE", "DE"], ["EN", "EN"]],
|
||
"key": "attr[Language]",
|
||
"label": "Language"
|
||
}
|
||
]
|
||
|
||
response = self.client.get('/%s/%s/widget/product_list' % (self.orga.slug, self.event.slug))
|
||
data = json.loads(response.content.decode())
|
||
assert data["meta_filter_fields"] == [
|
||
{
|
||
"choices": [["", "-- all --"], ["DE", "DE"]],
|
||
"key": "attr[Language]",
|
||
"label": "Language"
|
||
}
|
||
]
|
||
|
||
def test_event_calendar(self):
|
||
self.event.has_subevents = True
|
||
self.event.settings.timezone = 'Europe/Berlin'
|
||
self.event.save()
|
||
with freeze_time("2019-01-01 10:00:00"):
|
||
with scopes_disabled():
|
||
self.orga.events.create(name="Past", live=True, is_public=True, slug='past', date_from=now() - datetime.timedelta(days=3))
|
||
self.orga.events.create(name="Present", live=True, is_public=True, slug='present', date_from=now())
|
||
self.orga.events.create(name="Future", live=True, is_public=True, slug='future', date_from=now() + datetime.timedelta(days=3))
|
||
self.orga.events.create(name="Disabled", live=False, is_public=True, slug='disabled', date_from=now() + datetime.timedelta(days=3))
|
||
self.orga.events.create(name="Secret", live=True, is_public=False, slug='secret', date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Past", active=True, date_from=now() - datetime.timedelta(days=3))
|
||
se1 = self.event.subevents.create(name="Present", active=True, date_from=now())
|
||
se2 = self.event.subevents.create(name="Future", active=True, date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Disabled", active=False, date_from=now() + datetime.timedelta(days=3))
|
||
self.event.subevents.create(name="Hidden", active=True, is_public=False, date_from=now() + datetime.timedelta(days=3))
|
||
|
||
response = self.client.get('/%s/widget/product_list?style=calendar' % (self.orga.slug,))
|
||
data = json.loads(response.content.decode())
|
||
assert data == {
|
||
'date': '2019-01-01',
|
||
'list_type': 'calendar',
|
||
'meta_filter_fields': [],
|
||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||
'weeks': [
|
||
[None,
|
||
{'date': '2019-01-01',
|
||
'day': 1,
|
||
'events': [{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'continued': False,
|
||
'date_range': 'Tue, Jan. 1, 2019 10:00',
|
||
'event_url': 'http://example.com/ccc/present/',
|
||
'name': 'Present',
|
||
'location': '',
|
||
'subevent': None,
|
||
'time': '10:00'},
|
||
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'continued': False,
|
||
'date_range': 'Tue, Jan. 1, 2019 11:00',
|
||
'event_url': 'http://example.com/ccc/30c3/',
|
||
'name': 'Present',
|
||
'location': '',
|
||
'subevent': se1.pk,
|
||
'time': '11:00'}]},
|
||
{'date': '2019-01-02', 'day': 2, 'events': []},
|
||
{'date': '2019-01-03', 'day': 3, 'events': []},
|
||
{'date': '2019-01-04',
|
||
'day': 4,
|
||
'events': [{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'continued': False,
|
||
'date_range': 'Fri, Jan. 4, 2019 10:00',
|
||
'event_url': 'http://example.com/ccc/future/',
|
||
'name': 'Future',
|
||
'location': '',
|
||
'subevent': None,
|
||
'time': '10:00'},
|
||
{'availability': {'color': 'none', 'text': 'More info', 'reason': 'unknown'},
|
||
'continued': False,
|
||
'date_range': 'Fri, Jan. 4, 2019 11:00',
|
||
'event_url': 'http://example.com/ccc/30c3/',
|
||
'name': 'Future',
|
||
'location': '',
|
||
'subevent': se2.pk,
|
||
'time': '11:00'}]},
|
||
{'date': '2019-01-05', 'day': 5, 'events': []},
|
||
{'date': '2019-01-06', 'day': 6, 'events': []}],
|
||
[{'date': '2019-01-07', 'day': 7, 'events': []},
|
||
{'date': '2019-01-08', 'day': 8, 'events': []},
|
||
{'date': '2019-01-09', 'day': 9, 'events': []},
|
||
{'date': '2019-01-10', 'day': 10, 'events': []},
|
||
{'date': '2019-01-11', 'day': 11, 'events': []},
|
||
{'date': '2019-01-12', 'day': 12, 'events': []},
|
||
{'date': '2019-01-13', 'day': 13, 'events': []}],
|
||
[{'date': '2019-01-14', 'day': 14, 'events': []},
|
||
{'date': '2019-01-15', 'day': 15, 'events': []},
|
||
{'date': '2019-01-16', 'day': 16, 'events': []},
|
||
{'date': '2019-01-17', 'day': 17, 'events': []},
|
||
{'date': '2019-01-18', 'day': 18, 'events': []},
|
||
{'date': '2019-01-19', 'day': 19, 'events': []},
|
||
{'date': '2019-01-20', 'day': 20, 'events': []}],
|
||
[{'date': '2019-01-21', 'day': 21, 'events': []},
|
||
{'date': '2019-01-22', 'day': 22, 'events': []},
|
||
{'date': '2019-01-23', 'day': 23, 'events': []},
|
||
{'date': '2019-01-24', 'day': 24, 'events': []},
|
||
{'date': '2019-01-25', 'day': 25, 'events': []},
|
||
{'date': '2019-01-26', 'day': 26, 'events': []},
|
||
{'date': '2019-01-27', 'day': 27, 'events': []}],
|
||
[{'date': '2019-01-28', 'day': 28, 'events': []},
|
||
{'date': '2019-01-29', 'day': 29, 'events': []},
|
||
{'date': '2019-01-30', 'day': 30, 'events': []},
|
||
{'date': '2019-01-31', 'day': 31, 'events': []},
|
||
None,
|
||
None,
|
||
None]
|
||
]
|
||
}
|