Move tests to directory outside of the main package

This commit is contained in:
Raphael Michel
2015-03-14 00:57:09 +01:00
parent d85f112c33
commit 2fce883230
18 changed files with 5 additions and 6 deletions

0
src/tests/__init__.py Normal file
View File

View File

@@ -0,0 +1,36 @@
import os
import sys
import time
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.conf import settings
from selenium import webdriver
# could use Chrome, Firefox, etc... here
BROWSER = os.environ.get('TEST_BROWSER', 'PhantomJS')
class BrowserTest(StaticLiveServerTestCase):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
settings.DEBUG = ('--debug' in sys.argv)
def setUp(self):
self.driver = getattr(webdriver, BROWSER)()
self.driver.set_window_size(1920, 1080)
self.driver.implicitly_wait(10)
def tearDown(self):
self.driver.quit()
def scroll_into_view(self, element):
"""Scroll element into view"""
y = element.location['y']
self.driver.execute_script('window.scrollTo(0, {0})'.format(y))
def scroll_and_click(self, element):
self.scroll_into_view(element)
time.sleep(0.5)
element.click()

View File

@@ -0,0 +1,49 @@
import random
from django.test import TestCase
from django.core.cache import cache as django_cache
from django.utils.timezone import now
from pretix.base.models import Event, Organizer
class CacheTest(TestCase):
"""
This test case tests the invalidation of the event related
cache.
"""
@classmethod
def setUpTestData(cls):
o = Organizer.objects.create(name='Dummy', slug='dummy')
cls.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy',
date_from=now(),
)
def setUp(self):
self.cache = self.event.get_cache()
randint = random.random()
self.testkey = "test" + str(randint)
def test_interference(self):
django_cache.clear()
self.cache.set(self.testkey, "foo")
self.assertIsNone(django_cache.get(self.testkey))
self.assertIn(self.cache.get(self.testkey), (None, "foo"))
def test_longkey(self):
self.cache.set(self.testkey * 100, "foo")
self.assertEquals(self.cache.get(self.testkey * 100), "foo")
def test_invalidation(self):
self.cache.set(self.testkey, "foo")
self.cache.clear()
self.assertIsNone(self.cache.get(self.testkey))
def test_many(self):
inp = {
'a': 'foo',
'b': 'bar',
}
self.cache.set_many(inp)
self.assertEquals(inp, self.cache.get_many(inp.keys()))

View File

@@ -0,0 +1,72 @@
from django.test import TestCase, Client
from django.utils.timezone import now
from django.conf import settings
from pretix.base.models import Event, Organizer, User
class LocaleDeterminationTest(TestCase):
"""
This test case tests various methods around the properties /
variations concept.
"""
@classmethod
def setUpTestData(cls):
o = Organizer.objects.create(name='Dummy', slug='dummy')
cls.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy',
date_from=now(),
)
cls.TEST_LOCALE = 'de' if settings.LANGUAGE_CODE == 'en' else 'en'
cls.TEST_LOCALE_LONG = 'de-AT' if settings.LANGUAGE_CODE == 'en' else 'en-NZ'
cls.user = User.objects.create_user('dummy@dummy.dummy', 'dummy@dummy.dummy', 'dummy')
def test_global_default(self):
c = Client()
response = c.get('/control/login')
language = response['Content-Language']
self.assertEqual(language, settings.LANGUAGE_CODE)
def test_browser_default(self):
c = Client(HTTP_ACCEPT_LANGUAGE=self.TEST_LOCALE)
response = c.get('/control/login')
language = response['Content-Language']
self.assertEqual(language, self.TEST_LOCALE)
c = Client(HTTP_ACCEPT_LANGUAGE=self.TEST_LOCALE_LONG)
response = c.get('/control/login')
language = response['Content-Language']
self.assertEqual(language, self.TEST_LOCALE)
def test_unknown_browser_default(self):
c = Client(HTTP_ACCEPT_LANGUAGE='sjn')
response = c.get('/control/login')
language = response['Content-Language']
self.assertEqual(language, settings.LANGUAGE_CODE)
def test_cookie_settings(self):
c = Client()
cookies = c.cookies
cookies[settings.LANGUAGE_COOKIE_NAME] = self.TEST_LOCALE
response = c.get('/control/login')
language = response['Content-Language']
self.assertEqual(language, self.TEST_LOCALE)
cookies[settings.LANGUAGE_COOKIE_NAME] = self.TEST_LOCALE_LONG
response = c.get('/control/login')
language = response['Content-Language']
self.assertEqual(language, self.TEST_LOCALE)
def test_user_settings(self):
c = Client()
self.user.locale = self.TEST_LOCALE
self.user.save()
response = c.post('/control/login', {
'email': 'dummy@dummy.dummy',
'password': 'dummy',
})
self.assertEqual(response.status_code, 302)
response = c.get('/control/login')
language = response['Content-Language']
self.assertEqual(language, self.TEST_LOCALE)

View File

@@ -0,0 +1,295 @@
from datetime import timedelta
from django.test import TestCase
from django.utils.timezone import now
from pretix.base.models import (
Event, Organizer, Item, ItemVariation,
Property, PropertyValue, User, Quota,
Order, OrderPosition, CartPosition)
from pretix.base.types import VariationDict
class ItemVariationsTest(TestCase):
"""
This test case tests various methods around the properties /
variations concept.
"""
@classmethod
def setUpTestData(cls):
o = Organizer.objects.create(name='Dummy', slug='dummy')
cls.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy',
date_from=now(),
)
p = Property.objects.create(event=cls.event, name='Size')
PropertyValue.objects.create(prop=p, value='S')
PropertyValue.objects.create(prop=p, value='M')
PropertyValue.objects.create(prop=p, value='L')
p = Property.objects.create(event=cls.event, name='Color')
PropertyValue.objects.create(prop=p, value='black')
PropertyValue.objects.create(prop=p, value='blue')
def test_variationdict(self):
i = Item.objects.create(event=self.event, name='Dummy')
p = Property.objects.get(event=self.event, name='Size')
i.properties.add(p)
iv = ItemVariation.objects.create(item=i)
pv = PropertyValue.objects.get(prop=p, value='S')
iv.values.add(pv)
variations = i.get_all_variations()
for vd in variations:
for i, v in vd.relevant_items():
self.assertIs(type(v), PropertyValue)
for v in vd.relevant_values():
self.assertIs(type(v), PropertyValue)
if vd[p.pk] == pv:
vd1 = vd
vd2 = VariationDict()
vd2[p.pk] = pv
self.assertEqual(vd2.identify(), vd1.identify())
self.assertEqual(vd2, vd1)
vd2[p.pk] = PropertyValue.objects.get(prop=p, value='M')
self.assertNotEqual(vd2.identify(), vd.identify())
self.assertNotEqual(vd2, vd1)
vd3 = vd2.copy()
self.assertEqual(vd3, vd2)
vd2[p.pk] = pv
self.assertNotEqual(vd3, vd2)
vd4 = VariationDict()
vd4[4] = 'b'
vd4[2] = 'a'
self.assertEqual(vd4.ordered_values(), ['a', 'b'])
def test_get_all_variations(self):
i = Item.objects.create(event=self.event, name='Dummy')
# No properties available
v = i.get_all_variations()
self.assertEqual(len(v), 1)
self.assertEqual(v[0], {})
# One property, no variations
p = Property.objects.get(event=self.event, name='Size')
i.properties.add(p)
v = i.get_all_variations()
self.assertIs(type(v), list)
self.assertEqual(len(v), 3)
values = []
for var in v:
self.assertIs(type(var), VariationDict)
self.assertIn(p.pk, var)
self.assertIs(type(var[p.pk]), PropertyValue)
values.append(var[p.pk].value)
self.assertEqual(sorted(values), sorted(['S', 'M', 'L']))
# One property, one variation
iv = ItemVariation.objects.create(item=i)
iv.values.add(PropertyValue.objects.get(prop=p, value='S'))
v = i.get_all_variations()
self.assertIs(type(v), list)
self.assertEqual(len(v), 3)
values = []
num_variations = 0
for var in v:
self.assertIs(type(var), VariationDict)
if 'variation' in var and type(var['variation']) is ItemVariation:
self.assertEqual(iv.pk, var['variation'].pk)
values.append(var['variation'].values.all()[0].value)
num_variations += 1
elif p.pk in var:
self.assertIs(type(var[p.pk]), PropertyValue)
values.append(var[p.pk].value)
self.assertEqual(sorted(values), sorted(['S', 'M', 'L']))
self.assertEqual(num_variations, 1)
# Two properties, one variation
p2 = Property.objects.get(event=self.event, name='Color')
i.properties.add(p2)
iv.values.add(PropertyValue.objects.get(prop=p2, value='black'))
v = i.get_all_variations()
self.assertIs(type(v), list)
self.assertEqual(len(v), 6)
values = []
num_variations = 0
for var in v:
self.assertIs(type(var), VariationDict)
if 'variation' in var:
self.assertEqual(iv.pk, var['variation'].pk)
values.append(sorted([ivv.value for ivv in iv.values.all()]))
self.assertEqual(sorted([ivv.value for ivv in iv.values.all()]), sorted(['S', 'black']))
num_variations += 1
else:
values.append(sorted([pv.value for pv in var.values()]))
self.assertEqual(sorted(values), sorted([
['S', 'black'],
['S', 'blue'],
['M', 'black'],
['M', 'blue'],
['L', 'black'],
['L', 'blue'],
]))
self.assertEqual(num_variations, 1)
class VersionableTestCase(TestCase):
def test_shallow_cone(self):
o = Organizer.objects.create(name='Dummy', slug='dummy')
event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy',
date_from=now(),
)
old = Item.objects.create(event=event, name='Dummy', default_price=14)
prop = Property.objects.create(event=event, name='Size')
old.properties.add(prop)
new = old.clone_shallow()
self.assertIsNone(new.version_end_date)
self.assertIsNotNone(old.version_end_date)
self.assertEqual(new.properties.count(), 0)
self.assertEqual(old.properties.count(), 1)
class UserTestCase(TestCase):
def test_identifier_local(self):
o = Organizer.objects.create(name='Dummy', slug='dummy')
event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy',
date_from=now(),
)
u = User(event=event, username='tester')
u.set_password("test")
u.save()
self.assertEqual(u.identifier, "%s@%s.event.pretix" % (u.username.lower(), event.id))
def test_identifier_global(self):
u = User(email='test@example.com')
u.set_password("test")
u.save()
self.assertEqual(u.identifier, "test@example.com")
class QuotaTestCase(TestCase):
@classmethod
def setUpTestData(cls):
o = Organizer.objects.create(name='Dummy', slug='dummy')
cls.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy',
date_from=now(),
)
def setUp(self):
self.quota = Quota.objects.create(name="Test", size=2, event=self.event)
self.item1 = Item.objects.create(event=self.event, name="Ticket")
self.item2 = Item.objects.create(event=self.event, name="T-Shirt")
p = Property.objects.create(event=self.event, name='Size')
pv1 = PropertyValue.objects.create(prop=p, value='S')
PropertyValue.objects.create(prop=p, value='M')
PropertyValue.objects.create(prop=p, value='L')
self.var1 = ItemVariation.objects.create(item=self.item2)
self.var1.values.add(pv1)
self.item2.properties.add(p)
def test_available(self):
self.quota.items.add(self.item1)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 2))
self.quota.items.add(self.item2)
self.quota.variations.add(self.var1)
try:
self.item2.check_quotas()
self.assertTrue(False)
except:
pass
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 2))
def test_sold_out(self):
self.quota.items.add(self.item1)
order = Order.objects.create(event=self.event, status=Order.STATUS_PAID,
expires=now() + timedelta(days=3),
total=4)
OrderPosition.objects.create(order=order, item=self.item1, price=2)
OrderPosition.objects.create(order=order, item=self.item1, price=2)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_GONE, 0))
self.quota.items.add(self.item2)
self.quota.variations.add(self.var1)
self.quota.size = 3
self.quota.save()
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
order = Order.objects.create(event=self.event, status=Order.STATUS_PAID,
expires=now() + timedelta(days=3),
total=4)
OrderPosition.objects.create(order=order, item=self.item2, variation=self.var1, price=2)
self.assertEqual(self.var1.check_quotas(), (Quota.AVAILABILITY_GONE, 0))
def test_ordered(self):
self.quota.items.add(self.item1)
order = Order.objects.create(event=self.event, status=Order.STATUS_PAID,
expires=now() + timedelta(days=3),
total=4)
OrderPosition.objects.create(order=order, item=self.item1, price=2)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
order = Order.objects.create(event=self.event, status=Order.STATUS_PENDING,
expires=now() + timedelta(days=3),
total=4)
OrderPosition.objects.create(order=order, item=self.item1, price=2)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_ORDERED, 0))
order.expires = now() - timedelta(days=3)
order.save()
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
def test_reserved(self):
self.quota.items.add(self.item1)
self.quota.size = 3
self.quota.save()
order = Order.objects.create(event=self.event, status=Order.STATUS_PAID,
expires=now() + timedelta(days=3),
total=4)
OrderPosition.objects.create(order=order, item=self.item1, price=2)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 2))
order = Order.objects.create(event=self.event, status=Order.STATUS_PENDING,
expires=now() + timedelta(days=3),
total=4)
OrderPosition.objects.create(order=order, item=self.item1, price=2)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
cp = CartPosition.objects.create(event=self.event, item=self.item1, price=2,
expires=now() + timedelta(days=3))
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_RESERVED, 0))
cp.expires = now() - timedelta(days=3)
cp.save()
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
self.quota.items.add(self.item2)
self.quota.variations.add(self.var1)
cp = CartPosition.objects.create(event=self.event, item=self.item2, variation=self.var1,
price=2, expires=now() + timedelta(days=3))
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_RESERVED, 0))
def test_multiple(self):
self.quota.items.add(self.item1)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 2))
quota2 = Quota.objects.create(event=self.event, name="Test 2", size=1)
quota2.items.add(self.item1)
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_OK, 1))
quota2.size = 0
quota2.save()
self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_GONE, 0))

View File

@@ -0,0 +1,57 @@
from django.test import TestCase
from django.utils.timezone import now
from django.conf import settings
from pretix.base.models import Event, Organizer
from pretix.base.plugins import get_all_plugins
from pretix.base.signals import determine_availability
class PluginRegistryTest(TestCase):
"""
This test case performs tests for the plugin registry.
"""
def setUp(self):
o = Organizer.objects.create(name='Dummy', slug='dummy')
self.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy',
date_from=now(),
)
def test_plugin_names(self):
for mod in get_all_plugins():
self.assertIn(mod.module, settings.INSTALLED_APPS)
def test_metadata(self):
for mod in get_all_plugins():
self.assertTrue(hasattr(mod, 'name'))
self.assertTrue(hasattr(mod, 'version'))
self.assertTrue(hasattr(mod, 'type'))
class PluginSignalTest(TestCase):
"""
This test case tests the EventPluginSignal handler
"""
@classmethod
def setUpTestData(cls):
o = Organizer.objects.create(name='Dummy', slug='dummy')
cls.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy',
date_from=now(),
)
def test_no_plugins_active(self):
self.event.plugins = ''
self.event.save()
responses = determine_availability.send(self.event)
self.assertEqual(len(responses), 0)
def test_one_plugin_active(self):
self.event.plugins = 'pretix.plugins.testdummy'
self.event.save()
payload = {'foo': 'bar'}
responses = determine_availability.send(self.event, **payload)
self.assertEqual(len(responses), 1)
self.assertIn('pretix.plugins.testdummy.signals', [r[0].__module__ for r in responses])

View File

@@ -0,0 +1,151 @@
from decimal import Decimal
from django.test import TestCase
from django.utils.timezone import now
from pretix.base.models import Event, Organizer, User
from pretix.base import settings
from pretix.base.settings import SettingsSandbox
class SettingsTestCase(TestCase):
def setUp(self):
settings.DEFAULTS['test_default'] = 'def'
self.organizer = Organizer.objects.create(name='Dummy', slug='dummy')
self.event = Event.objects.create(
organizer=self.organizer, name='Dummy', slug='dummy',
date_from=now(),
)
def test_event_set_explicit(self):
self.event.settings.test = 'foo'
self.assertEqual(self.event.settings.test, 'foo')
# Reload object
self.event = Event.objects.get(identity=self.event.identity)
self.assertEqual(self.event.settings.test, 'foo')
def test_event_set_twice(self):
self.event.settings.test = 'bar'
self.event.settings.test = 'foo'
self.assertEqual(self.event.settings.test, 'foo')
# Reload object
self.event = Event.objects.get(identity=self.event.identity)
self.assertEqual(self.event.settings.test, 'foo')
def test_event_set_on_organizer(self):
self.organizer.settings.test = 'foo'
self.assertEqual(self.organizer.settings.test, 'foo')
self.assertEqual(self.event.settings.test, 'foo')
# Reload object
self.organizer = Organizer.objects.get(identity=self.organizer.identity)
self.event = Event.objects.get(identity=self.event.identity)
self.assertEqual(self.organizer.settings.test, 'foo')
self.assertEqual(self.event.settings.test, 'foo')
def test_override_organizer(self):
self.organizer.settings.test = 'foo'
self.event.settings.test = 'bar'
self.assertEqual(self.organizer.settings.test, 'foo')
self.assertEqual(self.event.settings.test, 'bar')
# Reload object
self.organizer = Organizer.objects.get(identity=self.organizer.identity)
self.event = Event.objects.get(identity=self.event.identity)
self.assertEqual(self.organizer.settings.test, 'foo')
self.assertEqual(self.event.settings.test, 'bar')
def test_default(self):
self.assertEqual(self.organizer.settings.test_default, 'def')
self.assertEqual(self.event.settings.test_default, 'def')
self.assertEqual(self.event.settings.get('nonexistant', default='abc'), 'abc')
def test_item_access(self):
self.event.settings['foo'] = 'abc'
self.assertEqual(self.event.settings['foo'], 'abc')
del self.event.settings['foo']
self.assertIsNone(self.event.settings['foo'])
def test_delete(self):
self.organizer.settings.test = 'foo'
self.event.settings.test = 'bar'
self.assertEqual(self.organizer.settings.test, 'foo')
self.assertEqual(self.event.settings.test, 'bar')
del self.event.settings.test
self.assertEqual(self.event.settings.test, 'foo')
self.event = Event.objects.get(identity=self.event.identity)
self.assertEqual(self.event.settings.test, 'foo')
del self.organizer.settings.test
self.assertIsNone(self.organizer.settings.test)
self.organizer = Organizer.objects.get(identity=self.organizer.identity)
self.assertIsNone(self.organizer.settings.test)
def test_serialize_str(self):
self._test_serialization('ABC', as_type=str)
def test_serialize_float(self):
self._test_serialization(2.3, float)
def test_serialize_int(self):
self._test_serialization(2, int)
def test_serialize_decimal(self):
self._test_serialization(Decimal('2.3'), Decimal)
def test_serialize_dict(self):
self._test_serialization({'a': 'b', 'c': 'd'}, dict)
def test_serialize_list(self):
self._test_serialization([1, 2, 'a'], list)
def test_serialize_bool(self):
self._test_serialization(True, bool)
self._test_serialization(False, bool)
def test_serialize_versionable(self):
self._test_serialization(self.event, Event)
def test_serialize_model(self):
self._test_serialization(User.objects.create_local_user(self.event, 'dummy', 'dummy'), User)
def test_serialize_unknown(self):
class Type:
pass
try:
self._test_serialization(Type(), Type)
self.assertTrue(False, 'No exception thrown!')
except TypeError:
pass
def _test_serialization(self, val, as_type):
self.event.settings.set('test', val)
self.event.settings._flush()
self.assertEqual(self.event.settings.get('test', as_type=as_type), val)
self.assertIsInstance(self.event.settings.get('test', as_type=as_type), as_type)
def test_sandbox(self):
sandbox = SettingsSandbox('testing', 'foo', self.event)
sandbox.set('foo', 'bar')
self.assertEqual(sandbox.get('foo'), 'bar')
self.assertEqual(self.event.settings.get('testing_foo_foo'), 'bar')
self.assertIsNone(self.event.settings.get('foo'), 'bar')
sandbox['bar'] = 'baz'
sandbox.baz = 42
self.event = Event.objects.get(identity=self.event.identity)
sandbox = SettingsSandbox('testing', 'foo', self.event)
self.assertEqual(sandbox['bar'], 'baz')
self.assertEqual(sandbox.baz, '42')
del sandbox.baz
del sandbox['bar']
self.assertIsNone(sandbox.bar)
self.assertIsNone(sandbox['baz'])

View File

View File

@@ -0,0 +1,107 @@
from django.test import TestCase, Client
from pretix.base.models import User
from tests.base import BrowserTest
class LoginFormBrowserTest(BrowserTest):
def setUp(self):
super().setUp()
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy@dummy.dummy', 'dummy')
def test_login(self):
self.driver.implicitly_wait(10)
self.driver.get('%s%s' % (self.live_server_url, '/control/login'))
username_input = self.driver.find_element_by_name("email")
username_input.send_keys('dummy@dummy.dummy')
password_input = self.driver.find_element_by_name("password")
password_input.send_keys('dummy')
self.driver.find_element_by_css_selector('button[type="submit"]').click()
self.driver.find_element_by_class_name("navbar-right")
def test_login_fail(self):
self.driver.implicitly_wait(10)
self.driver.get('%s%s' % (self.live_server_url, '/control/login'))
username_input = self.driver.find_element_by_name("email")
username_input.send_keys('dummy@dummy.dummy')
password_input = self.driver.find_element_by_name("password")
password_input.send_keys('wrong')
self.driver.find_element_by_css_selector('button[type="submit"]').click()
self.driver.find_element_by_class_name("alert-danger")
class LoginFormTest(TestCase):
"""
This test case tests various methods around the properties /
variations concept.
"""
def setUp(self):
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy@dummy.dummy', 'dummy')
def test_wrong_credentials(self):
c = Client()
response = c.post('/control/login', {
'email': 'dummy@dummy.dummy',
'password': 'foo',
})
self.assertEqual(response.status_code, 200)
def test_correct_credentials(self):
c = Client()
response = c.post('/control/login', {
'email': 'dummy@dummy.dummy',
'password': 'dummy',
})
self.assertEqual(response.status_code, 302)
def test_inactive_account(self):
self.user.is_active = False
self.user.save()
c = Client()
response = c.post('/control/login', {
'email': 'dummy@dummy.dummy',
'password': 'dummy',
})
self.assertEqual(response.status_code, 200)
def test_redirect(self):
c = Client()
response = c.post('/control/login?next=/control/events/', {
'email': 'dummy@dummy.dummy',
'password': 'dummy',
})
self.assertEqual(response.status_code, 302)
self.assertIn('/control/events/', response['Location'])
def test_logged_in(self):
c = Client()
response = c.post('/control/login?next=/control/events/', {
'email': 'dummy@dummy.dummy',
'password': 'dummy',
})
self.assertEqual(response.status_code, 302)
self.assertIn('/control/events/', response['Location'])
response = c.get('/control/login')
self.assertEqual(response.status_code, 302)
response = c.get('/control/login?next=/control/events/')
self.assertEqual(response.status_code, 302)
self.assertIn('/control/events/', response['Location'])
def test_logout(self):
c = Client()
response = c.post('/control/login', {
'email': 'dummy@dummy.dummy',
'password': 'dummy',
})
self.assertEqual(response.status_code, 302)
response = c.get('/control/logout')
self.assertEqual(response.status_code, 302)
response = c.get('/control/login')
self.assertEqual(response.status_code, 200)

View File

@@ -0,0 +1,60 @@
import datetime
from pretix.base.models import User, Organizer, Event, OrganizerPermission, EventPermission
from tests.base import BrowserTest
class EventsTest(BrowserTest):
def setUp(self):
super().setUp()
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy@dummy.dummy', 'dummy')
self.orga1 = Organizer.objects.create(name='CCC', slug='ccc')
self.orga2 = Organizer.objects.create(name='MRM', slug='mrm')
self.event1 = Event.objects.create(
organizer=self.orga1, name='30C3', slug='30c3',
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
)
self.event2 = Event.objects.create(
organizer=self.orga1, name='31C3', slug='31c3',
date_from=datetime.datetime(2014, 12, 26, tzinfo=datetime.timezone.utc),
)
self.event3 = Event.objects.create(
organizer=self.orga2, name='MRMCD14', slug='mrmcd14',
date_from=datetime.datetime(2014, 9, 5, tzinfo=datetime.timezone.utc),
)
OrganizerPermission.objects.create(organizer=self.orga1, user=self.user)
EventPermission.objects.create(event=self.event1, user=self.user, can_change_items=True,
can_change_settings=True)
self.driver.implicitly_wait(10)
self.driver.get('%s%s' % (self.live_server_url, '/control/login'))
username_input = self.driver.find_element_by_name("email")
username_input.send_keys('dummy@dummy.dummy')
password_input = self.driver.find_element_by_name("password")
password_input.send_keys('dummy')
self.driver.find_element_by_css_selector('button[type="submit"]').click()
self.driver.find_element_by_class_name("navbar-right")
def test_event_list(self):
self.driver.get('%s%s' % (self.live_server_url, '/control/events/'))
tabletext = self.driver.find_element_by_css_selector(".container .table").text
self.assertIn("30C3", tabletext)
self.assertNotIn("31C3", tabletext)
self.assertNotIn("MRMCD14", tabletext)
def test_settings(self):
self.driver.get('%s/control/event/%s/%s/settings/' % (self.live_server_url, self.orga1.slug,
self.event1.slug))
self.driver.find_element_by_name("date_to").send_keys("2013-12-30 17:00:00")
self.driver.find_element_by_class_name("btn-save").click()
self.driver.find_element_by_class_name("alert-success")
self.assertIn("2013-12-30 17:00:00", self.driver.find_element_by_name("date_to").get_attribute("value"))
def test_plugins(self):
self.driver.get('%s/control/event/%s/%s/settings/plugins' % (self.live_server_url, self.orga1.slug,
self.event1.slug))
self.assertIn("Restriction by time", self.driver.find_element_by_class_name("form-plugins").text)
self.assertIn("Enable", self.driver.find_element_by_name("plugin:pretix.plugins.timerestriction").text)
self.driver.find_element_by_name("plugin:pretix.plugins.timerestriction").click()
self.assertIn("Disable", self.driver.find_element_by_name("plugin:pretix.plugins.timerestriction").text)
self.driver.find_element_by_name("plugin:pretix.plugins.timerestriction").click()
self.assertIn("Enable", self.driver.find_element_by_name("plugin:pretix.plugins.timerestriction").text)

View File

@@ -0,0 +1,227 @@
import os
import time
import datetime
import unittest
from selenium.webdriver.support.select import Select
from pretix.base.models import User, Organizer, Event, OrganizerPermission, EventPermission, ItemCategory, Property, \
PropertyValue, Question, Quota, Item
from tests.base import BrowserTest
class ItemFormTest(BrowserTest):
def setUp(self):
super().setUp()
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy@dummy.dummy', 'dummy')
self.orga1 = Organizer.objects.create(name='CCC', slug='ccc')
self.orga2 = Organizer.objects.create(name='MRM', slug='mrm')
self.event1 = Event.objects.create(
organizer=self.orga1, name='30C3', slug='30c3',
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
)
OrganizerPermission.objects.create(organizer=self.orga1, user=self.user)
EventPermission.objects.create(event=self.event1, user=self.user, can_change_items=True,
can_change_settings=True)
self.driver.implicitly_wait(10)
self.driver.get('%s%s' % (self.live_server_url, '/control/login'))
username_input = self.driver.find_element_by_name("email")
username_input.send_keys('dummy@dummy.dummy')
password_input = self.driver.find_element_by_name("password")
password_input.send_keys('dummy')
self.driver.find_element_by_css_selector('button[type="submit"]').click()
self.driver.find_element_by_class_name("navbar-right")
class CategoriesTest(ItemFormTest):
def test_create(self):
self.driver.get('%s/control/event/%s/%s/categories/add' % (
self.live_server_url, self.orga1.slug, self.event1.slug
))
self.driver.find_element_by_name("name").send_keys('Entry tickets')
self.driver.find_element_by_class_name("btn-save").click()
self.driver.find_element_by_class_name("alert-success")
self.assertIn("Entry tickets", self.driver.find_element_by_css_selector(".container table").text)
def test_update(self):
c = ItemCategory.objects.create(event=self.event1, name="Entry tickets")
self.driver.get('%s/control/event/%s/%s/categories/%s/' % (
self.live_server_url, self.orga1.slug, self.event1.slug, c.identity
))
self.driver.find_element_by_name("name").clear()
self.driver.find_element_by_name("name").send_keys('T-Shirts')
self.scroll_and_click(self.driver.find_element_by_class_name("btn-save"))
self.driver.find_element_by_class_name("alert-success")
self.assertIn("T-Shirts", self.driver.find_element_by_css_selector(".container table").text)
self.assertNotIn("Entry tickets", self.driver.find_element_by_css_selector(".container table").text)
@unittest.skipIf('TRAVIS' in os.environ, 'See docstring for details.')
def test_sort(self):
"""
For unknown reasons, the first scoll_and_click() call sometimes results in the following exception
selenium.common.exceptions.ElementNotVisibleException:
Message: {"errorMessage":"Element is not currently visible and may not be manipulated", …}
This exception does not occur on either of my machines, but only when being run in Travis CI.
Raphael Michel, 2015-02-08
"""
ItemCategory.objects.create(event=self.event1, name="Entry tickets", position=0)
ItemCategory.objects.create(event=self.event1, name="T-Shirts", position=1)
self.driver.get('%s/control/event/%s/%s/categories/' % (
self.live_server_url, self.orga1.slug, self.event1.slug
))
self.assertIn("Entry tickets",
self.driver.find_element_by_css_selector("table > tbody > tr:nth-child(1)").text)
self.assertIn("T-Shirts",
self.driver.find_element_by_css_selector("table > tbody > tr:nth-child(2)").text)
self.scroll_and_click(self.driver.find_element_by_css_selector("table > tbody > tr:nth-child(1) a[href*='down']"))
time.sleep(1)
self.assertIn("Entry tickets",
self.driver.find_element_by_css_selector("table > tbody > tr:nth-child(2)").text)
self.assertIn("T-Shirts",
self.driver.find_element_by_css_selector("table > tbody > tr:nth-child(1)").text)
self.scroll_and_click(self.driver.find_element_by_css_selector("table > tbody > tr:nth-child(2) a[href*='up']"))
time.sleep(1)
self.assertIn("Entry tickets",
self.driver.find_element_by_css_selector("table > tbody > tr:nth-child(1)").text)
self.assertIn("T-Shirts",
self.driver.find_element_by_css_selector("table > tbody > tr:nth-child(2)").text)
def test_delete(self):
c = ItemCategory.objects.create(event=self.event1, name="Entry tickets")
self.driver.get('%s/control/event/%s/%s/categories/%s/delete' % (
self.live_server_url, self.orga1.slug, self.event1.slug, c.identity
))
self.driver.find_element_by_class_name("btn-danger").click()
self.driver.find_element_by_class_name("alert-success")
self.assertNotIn("Entry tickets", self.driver.find_element_by_css_selector(".container table").text)
class PropertiesTest(ItemFormTest):
def test_create(self):
self.driver.get('%s/control/event/%s/%s/properties/add' % (
self.live_server_url, self.orga1.slug, self.event1.slug
))
self.driver.find_element_by_css_selector("#id_name").send_keys('Size')
self.driver.find_element_by_name("values-0-value").send_keys('S')
self.driver.find_element_by_name("values-1-value").send_keys('M')
self.scroll_and_click(self.driver.find_element_by_class_name("btn-save"))
self.driver.find_element_by_class_name("alert-success")
self.assertIn("Size", self.driver.find_element_by_css_selector(".container table").text)
self.driver.find_element_by_partial_link_text("Size").click()
self.assertEqual("S", self.driver.find_element_by_name("values-0-value").get_attribute("value"))
self.assertEqual("M", self.driver.find_element_by_name("values-1-value").get_attribute("value"))
@unittest.skipIf('TRAVIS' in os.environ, 'See CategoriesTest.test_sort for details.')
def test_update(self):
c = Property.objects.create(event=self.event1, name="Size")
PropertyValue.objects.create(prop=c, position=0, value="S")
PropertyValue.objects.create(prop=c, position=1, value="M")
self.driver.get('%s/control/event/%s/%s/properties/%s/' % (
self.live_server_url, self.orga1.slug, self.event1.slug, c.identity
))
self.driver.find_element_by_css_selector("#id_name").clear()
self.driver.find_element_by_css_selector("#id_name").send_keys('Color')
self.driver.find_elements_by_css_selector("div.form-group button.btn-danger")[0].click()
self.scroll_into_view(self.driver.find_element_by_name("values-1-value"))
self.driver.find_element_by_name("values-1-value").clear()
self.driver.find_element_by_name("values-1-value").send_keys('red')
self.driver.find_element_by_css_selector("button[data-formset-add]").click()
self.driver.find_element_by_name("values-2-value").send_keys('blue')
self.driver.find_element_by_class_name("btn-save").click()
self.driver.find_element_by_class_name("alert-success")
self.assertEqual("red", self.driver.find_element_by_name("values-0-value").get_attribute("value"))
self.assertEqual("blue", self.driver.find_element_by_name("values-1-value").get_attribute("value"))
def test_delete(self):
c = Property.objects.create(event=self.event1, name="Size")
self.driver.get('%s/control/event/%s/%s/properties/%s/delete' % (
self.live_server_url, self.orga1.slug, self.event1.slug, c.identity
))
self.driver.find_element_by_class_name("btn-danger").click()
self.driver.find_element_by_class_name("alert-success")
self.assertNotIn("Size", self.driver.find_element_by_css_selector(".container table").text)
class QuestionsTest(ItemFormTest):
def test_create(self):
self.driver.get('%s/control/event/%s/%s/questions/add' % (
self.live_server_url, self.orga1.slug, self.event1.slug
))
self.driver.find_element_by_name("question").send_keys('What is your shoe size?')
Select(self.driver.find_element_by_name("type")).select_by_value('N')
self.driver.find_element_by_class_name("btn-save").click()
self.driver.find_element_by_class_name("alert-success")
self.assertIn("shoe size", self.driver.find_element_by_css_selector(".container table").text)
def test_update(self):
c = Question.objects.create(event=self.event1, question="What is your shoe size?", type="N", required=True)
self.driver.get('%s/control/event/%s/%s/questions/%s/' % (
self.live_server_url, self.orga1.slug, self.event1.slug, c.identity
))
self.driver.find_element_by_name("question").clear()
self.driver.find_element_by_name("question").send_keys('How old are you?')
self.scroll_and_click(self.driver.find_element_by_class_name("btn-save"))
self.driver.find_element_by_class_name("alert-success")
self.assertIn("How old", self.driver.find_element_by_css_selector(".container table").text)
self.assertNotIn("shoe size", self.driver.find_element_by_css_selector(".container table").text)
c = Question.objects.current.get(identity=c.identity)
self.assertTrue(c.required)
def test_delete(self):
c = Question.objects.create(event=self.event1, question="What is your shoe size?", type="N", required=True)
self.driver.get('%s/control/event/%s/%s/questions/%s/delete' % (
self.live_server_url, self.orga1.slug, self.event1.slug, c.identity
))
self.driver.find_element_by_class_name("btn-danger").click()
self.driver.find_element_by_class_name("alert-success")
self.assertNotIn("shoe size", self.driver.find_element_by_css_selector(".container table").text)
class QuotaTest(ItemFormTest):
def test_create(self):
self.driver.get('%s/control/event/%s/%s/quotas/add' % (
self.live_server_url, self.orga1.slug, self.event1.slug
))
self.driver.find_element_by_name("name").send_keys('Full house')
self.driver.find_element_by_name("size").send_keys('500')
self.driver.find_element_by_class_name("btn-save").click()
self.driver.find_element_by_class_name("alert-success")
self.assertIn("Full house", self.driver.find_element_by_css_selector(".container table").text)
def test_update(self):
c = Quota.objects.create(event=self.event1, name="Full house", size=500)
item1 = Item.objects.create(event=self.event1, name="Standard")
item2 = Item.objects.create(event=self.event1, name="Business")
prop1 = Property.objects.create(event=self.event1, name="Level")
item2.properties.add(prop1)
PropertyValue.objects.create(prop=prop1, value="Silver")
PropertyValue.objects.create(prop=prop1, value="Gold")
self.driver.get('%s/control/event/%s/%s/quotas/%s/' % (
self.live_server_url, self.orga1.slug, self.event1.slug, c.identity
))
self.driver.find_element_by_name("size").clear()
self.driver.find_element_by_name("size").send_keys('350')
self.scroll_and_click(self.driver.find_element_by_css_selector('.panel-group .panel:nth-child(1) .panel-title a'))
time.sleep(1)
self.scroll_and_click(self.driver.find_element_by_name("item_%s" % item1.identity))
self.driver.find_element_by_css_selector('.panel-group .panel:nth-child(2) .panel-title a').click()
time.sleep(1)
self.scroll_and_click(self.driver.find_elements_by_css_selector("input[name=item_%s]" % item2.identity)[1])
self.scroll_and_click(self.driver.find_element_by_class_name("btn-save"))
self.driver.find_element_by_class_name("alert-success")
self.assertIn("350", self.driver.find_element_by_css_selector(".container table").text)
self.assertNotIn("500", self.driver.find_element_by_css_selector(".container table").text)
def test_delete(self):
c = Quota.objects.create(event=self.event1, name="Full house", size=500)
self.driver.get('%s/control/event/%s/%s/quotas/%s/delete' % (
self.live_server_url, self.orga1.slug, self.event1.slug, c.identity
))
self.driver.find_element_by_class_name("btn-danger").click()
self.driver.find_element_by_class_name("alert-success")
self.assertNotIn("Full house", self.driver.find_element_by_css_selector(".container table").text)

View File

@@ -0,0 +1,69 @@
from django.test import TestCase, Client
from django.utils.timezone import now
from pretix.base.models import Event, Organizer, User, EventPermission
class PermissionMiddlewareTest(TestCase):
"""
This test case tests various methods around the properties /
variations concept.
"""
def setUp(self):
o = Organizer.objects.create(name='Dummy', slug='dummy')
self.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy',
date_from=now(),
)
self.user = User.objects.create_user('dummy@dummy.dummy', 'dummy@dummy.dummy', 'dummy')
def test_logged_out(self):
c = Client()
response = c.get('/control/login')
self.assertEqual(response.status_code, 200)
response = c.get('/control/events/')
self.assertEqual(response.status_code, 302)
def test_wrong_event(self):
c = Client()
response = c.post('/control/login', {
'email': 'dummy@dummy.dummy',
'password': 'dummy',
})
self.assertEqual(response.status_code, 302)
response = c.get('/control/event/dummy/dummy/settings/')
self.assertIn(response.status_code, (403, 404))
def test_wrong_event_permission(self):
EventPermission.objects.create(
event=self.event, user=self.user,
can_change_settings=False,
can_change_items=True,
)
c = Client()
response = c.post('/control/login', {
'email': 'dummy@dummy.dummy',
'password': 'dummy',
})
self.assertEqual(response.status_code, 302)
response = c.get('/control/event/dummy/dummy/settings/')
self.assertIn(response.status_code, (403, 404))
def test_correct(self):
EventPermission.objects.create(
event=self.event, user=self.user,
can_change_settings=True,
can_change_items=True,
)
c = Client()
response = c.post('/control/login', {
'email': 'dummy@dummy.dummy',
'password': 'dummy',
})
self.assertEqual(response.status_code, 302)
response = c.get('/control/event/dummy/dummy/settings/')
self.assertEqual(response.status_code, 200)

View File

View File

@@ -0,0 +1,286 @@
from datetime import timedelta
from django.test import TestCase
from django.utils.timezone import now
from pretix.base.models import (
Event, Organizer, Item, Property, PropertyValue, ItemVariation
)
# Do NOT use relative imports here
from pretix.plugins.timerestriction import signals
from pretix.plugins.timerestriction.models import TimeRestriction
class TimeRestrictionTest(TestCase):
"""
This test case tests the various aspects of the time restriction
plugin
"""
@classmethod
def setUpTestData(cls):
o = Organizer.objects.create(name='Dummy', slug='dummy')
cls.event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy',
date_from=now(),
)
cls.item = Item.objects.create(event=cls.event, name='Dummy', default_price=14)
cls.property = Property.objects.create(event=cls.event, name='Size')
cls.value1 = PropertyValue.objects.create(prop=cls.property, value='S')
cls.value2 = PropertyValue.objects.create(prop=cls.property, value='M')
cls.value3 = PropertyValue.objects.create(prop=cls.property, value='L')
cls.variation1 = ItemVariation.objects.create(item=cls.item)
cls.variation1.values.add(cls.value1)
cls.variation2 = ItemVariation.objects.create(item=cls.item)
cls.variation2.values.add(cls.value2)
cls.variation3 = ItemVariation.objects.create(item=cls.item)
cls.variation3.values.add(cls.value3)
def test_nothing(self):
result = signals.availability_handler(
None, item=self.item,
variations=self.item.get_all_variations(),
context=None, cache=self.event.get_cache()
)
self.assertEqual(len(result), 1)
self.assertTrue('available' not in result[0] or result[0]['available'] is True)
def test_simple_case_available(self):
r = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=3),
timeframe_to=now() + timedelta(days=3),
event=self.event,
price=12
)
r.item = self.item
r.save()
result = signals.availability_handler(
self.event, item=self.item,
variations=self.item.get_all_variations(),
context=None, cache=self.event.get_cache()
)
self.assertEqual(len(result), 1)
self.assertIn('available', result[0])
self.assertTrue(result[0]['available'])
self.assertEqual(result[0]['price'], 12)
def test_cached_result(self):
r = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=3),
timeframe_to=now() + timedelta(days=3),
event=self.event,
price=12
)
r.item = self.item
r.save()
result = signals.availability_handler(
self.event, item=self.item,
variations=self.item.get_all_variations(),
context=None, cache=self.event.get_cache()
)
self.assertEqual(len(result), 1)
self.assertIn('available', result[0])
self.assertTrue(result[0]['available'])
self.assertEqual(result[0]['price'], 12)
result = signals.availability_handler(
self.event, item=self.item,
variations=self.item.get_all_variations(),
context=None, cache=self.event.get_cache()
)
self.assertEqual(len(result), 1)
self.assertIn('available', result[0])
self.assertTrue(result[0]['available'])
self.assertEqual(result[0]['price'], 12)
def test_simple_case_unavailable(self):
r = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=5),
timeframe_to=now() - timedelta(days=3),
event=self.event,
price=12
)
r.item = self.item
r.save()
result = signals.availability_handler(
self.event, item=self.item,
variations=self.item.get_all_variations(),
context=None, cache=self.event.get_cache()
)
self.assertEqual(len(result), 1)
self.assertIn('available', result[0])
self.assertFalse(result[0]['available'])
def test_multiple_overlapping_now(self):
r1 = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=5),
timeframe_to=now() + timedelta(days=3),
event=self.event,
price=12
)
r1.item = self.item
r1.save()
r2 = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=3),
timeframe_to=now() + timedelta(days=5),
event=self.event,
price=8
)
r2.item = self.item
r2.save()
result = signals.availability_handler(
self.event, item=self.item,
variations=self.item.get_all_variations(),
context=None, cache=self.event.get_cache()
)
self.assertEqual(len(result), 1)
self.assertIn('available', result[0])
self.assertTrue(result[0]['available'])
self.assertEqual(result[0]['price'], 8)
def test_multiple_overlapping_tomorrow(self):
r1 = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=5),
timeframe_to=now() + timedelta(days=5),
event=self.event,
price=12
)
r1.item = self.item
r1.save()
r2 = TimeRestriction.objects.create(
timeframe_from=now() + timedelta(days=1),
timeframe_to=now() + timedelta(days=7),
event=self.event,
price=8
)
r2.item = self.item
r2.save()
result = signals.availability_handler(
self.event, item=self.item,
variations=self.item.get_all_variations(),
context=None, cache=self.event.get_cache()
)
self.assertEqual(len(result), 1)
self.assertIn('available', result[0])
self.assertTrue(result[0]['available'])
self.assertEqual(result[0]['price'], 12)
def test_multiple_distinct_available(self):
r1 = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=5),
timeframe_to=now() + timedelta(days=2),
event=self.event,
price=12
)
r1.item = self.item
r1.save()
r2 = TimeRestriction.objects.create(
timeframe_from=now() + timedelta(days=4),
timeframe_to=now() + timedelta(days=7),
event=self.event,
price=8
)
r2.item = self.item
r2.save()
result = signals.availability_handler(
self.event, item=self.item,
variations=self.item.get_all_variations(),
context=None, cache=self.event.get_cache()
)
self.assertEqual(len(result), 1)
self.assertIn('available', result[0])
self.assertTrue(result[0]['available'])
self.assertEqual(result[0]['price'], 12)
def test_multiple_distinct_unavailable(self):
r1 = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=5),
timeframe_to=now() - timedelta(days=1),
event=self.event,
price=12
)
r1.item = self.item
r1.save()
r2 = TimeRestriction.objects.create(
timeframe_from=now() + timedelta(days=4),
timeframe_to=now() + timedelta(days=7),
event=self.event,
price=8
)
r2.item = self.item
r2.save()
result = signals.availability_handler(
self.event, item=self.item,
variations=self.item.get_all_variations(),
context=None, cache=self.event.get_cache()
)
self.assertEqual(len(result), 1)
self.assertIn('available', result[0])
self.assertFalse(result[0]['available'])
def test_variation_specific(self):
self.item.properties.add(self.property)
r1 = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=5),
timeframe_to=now() + timedelta(days=1),
event=self.event,
price=12
)
r1.item = self.item
r1.save()
r1.variations.add(self.variation1)
result = signals.availability_handler(
self.event, item=self.item,
variations=self.item.get_all_variations(),
context=None, cache=self.event.get_cache()
)
self.assertEqual(len(result), 3)
for v in result:
if 'variation' in v and v['variation'].pk == self.variation1.pk:
self.assertTrue(v['available'])
self.assertEqual(v['price'], 12)
else:
self.assertFalse(v['available'])
def test_variation_specifics(self):
self.item.properties.add(self.property)
r1 = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=5),
timeframe_to=now() + timedelta(days=1),
event=self.event,
price=12
)
r1.item = self.item
r1.save()
r1.variations.add(self.variation1)
r2 = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=5),
timeframe_to=now() + timedelta(days=1),
event=self.event,
price=8
)
r2.item = self.item
r2.save()
r2.variations.add(self.variation1)
r3 = TimeRestriction.objects.create(
timeframe_from=now() - timedelta(days=5),
timeframe_to=now() - timedelta(days=1),
event=self.event,
price=8
)
r3.item = self.item
r3.save()
r3.variations.add(self.variation3)
result = signals.availability_handler(
self.event, item=self.item,
variations=self.item.get_all_variations(),
context=None, cache=self.event.get_cache()
)
self.assertEqual(len(result), 3)
for v in result:
if 'variation' in v and v['variation'].pk == self.variation1.pk:
self.assertTrue(v['available'])
self.assertEqual(v['price'], 8)
else:
self.assertFalse(v['available'])

View File

View File

@@ -0,0 +1,410 @@
import datetime
import time
from bs4 import BeautifulSoup
from django.test import TestCase
from django.utils.timezone import now
from datetime import timedelta
from pretix.base.models import Item, Organizer, Event, ItemCategory, Quota, Property, PropertyValue, ItemVariation, User, \
CartPosition
from tests.base import BrowserTest
class CartTestMixin:
def setUp(self):
super().setUp()
self.orga = Organizer.objects.create(name='CCC', slug='ccc')
self.event = Event.objects.create(
organizer=self.orga, name='30C3', slug='30c3',
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc)
)
self.user = User.objects.create_local_user(self.event, 'demo', 'demo')
self.category = ItemCategory.objects.create(event=self.event, name="Everything", position=0)
self.quota_shirts = Quota.objects.create(event=self.event, name='Shirts', size=2)
self.shirt = Item.objects.create(event=self.event, name='T-Shirt', category=self.category, default_price=12)
prop1 = Property.objects.create(event=self.event, name="Color")
self.shirt.properties.add(prop1)
val1 = PropertyValue.objects.create(prop=prop1, value="Red", position=0)
val2 = PropertyValue.objects.create(prop=prop1, value="Black", position=1)
self.quota_shirts.items.add(self.shirt)
self.shirt_red = ItemVariation.objects.create(item=self.shirt, default_price=14)
self.shirt_red.values.add(val1)
var2 = ItemVariation.objects.create(item=self.shirt)
var2.values.add(val2)
self.quota_shirts.variations.add(self.shirt_red)
self.quota_shirts.variations.add(var2)
self.quota_tickets = Quota.objects.create(event=self.event, name='Tickets', size=5)
self.ticket = Item.objects.create(event=self.event, name='Early-bird ticket',
category=self.category, default_price=23)
self.quota_tickets.items.add(self.ticket)
class CartBrowserTest(CartTestMixin, BrowserTest):
def test_not_logged_in(self):
self.driver.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
# add the entry ticket to cart
self.driver.find_element_by_css_selector('input[type=number][name=item_%s]' % self.ticket.identity).send_keys('1')
self.scroll_and_click(self.driver.find_element_by_css_selector('.checkout-button-row button'))
# should redirect to login page
self.driver.find_element_by_name('username')
def test_simple_login(self):
self.driver.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
# add the entry ticket to cart
self.driver.find_element_by_css_selector('input[type=number][name=item_%s]' % self.ticket.identity).send_keys('1')
self.scroll_and_click(self.driver.find_element_by_css_selector('.checkout-button-row button'))
# should redirect to login page
# open the login accordion
self.scroll_and_click(self.driver.find_element_by_css_selector('a[href*=loginForm]'))
time.sleep(1)
# enter login details
self.driver.find_element_by_css_selector('#loginForm input[name=username]').send_keys('demo')
self.driver.find_element_by_css_selector('#loginForm input[name=password]').send_keys('demo')
self.scroll_and_click(self.driver.find_element_by_css_selector('#loginForm button.btn-primary'))
# should display our ticket
self.assertIn('Early-bird', self.driver.find_element_by_css_selector('.cart-row:first-child').text)
def test_local_registration(self):
self.driver.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
# add the entry ticket to cart
self.driver.find_element_by_css_selector('input[type=number][name=item_%s]' % self.ticket.identity).send_keys('1')
self.scroll_and_click(self.driver.find_element_by_css_selector('.checkout-button-row button'))
# should redirect to login page
# open the login accordion
self.scroll_and_click(self.driver.find_element_by_css_selector('a[href*=localRegistrationForm]'))
time.sleep(1)
# enter login details
self.driver.find_element_by_css_selector('#localRegistrationForm input[name=username]').send_keys('demo2')
self.driver.find_element_by_css_selector('#localRegistrationForm input[name=email]').send_keys('demo@demo.demo')
self.driver.find_element_by_css_selector('#localRegistrationForm input[name=password]').send_keys('demo')
self.driver.find_element_by_css_selector('#localRegistrationForm input[name=password_repeat]').send_keys('demo')
self.scroll_and_click(self.driver.find_element_by_css_selector('#localRegistrationForm button.btn-primary'))
# should display our ticket
self.assertIn('Early-bird', self.driver.find_element_by_css_selector('.cart-row:first-child').text)
def test_global_registration(self):
self.driver.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
# add the entry ticket to cart
self.driver.find_element_by_css_selector('input[type=number][name=item_%s]' % self.ticket.identity).send_keys('1')
self.scroll_and_click(self.driver.find_element_by_css_selector('.checkout-button-row button'))
# should redirect to login page
# open the login accordion
self.scroll_and_click(self.driver.find_element_by_css_selector('a[href*=globalRegistrationForm]'))
time.sleep(1)
# enter login details
self.driver.find_element_by_css_selector('#globalRegistrationForm input[name=email]').send_keys('demo@example.com')
self.driver.find_element_by_css_selector('#globalRegistrationForm input[name=password]').send_keys('demo')
self.driver.find_element_by_css_selector('#globalRegistrationForm input[name=password_repeat]').send_keys('demo')
self.scroll_and_click(self.driver.find_element_by_css_selector('#globalRegistrationForm button.btn-primary'))
# should display our ticket
self.assertIn('Early-bird', self.driver.find_element_by_css_selector('.cart-row:first-child').text)
class CartTest(CartTestMixin, TestCase):
def setUp(self):
super().setUp()
self.assertTrue(self.client.login(username='demo@%s.event.pretix' % self.event.identity, password='demo'))
def test_simple(self):
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '1'
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
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)
objs = list(CartPosition.objects.filter(user=self.user, event=self.event))
self.assertEqual(len(objs), 1)
self.assertEqual(objs[0].item, self.ticket)
self.assertIsNone(objs[0].variation)
self.assertEqual(objs[0].price, 23)
def test_variation(self):
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'variation_' + self.shirt.identity + '_' + self.shirt_red.identity: '1'
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('Shirt', doc.select('.cart .cart-row')[0].select('strong')[0].text)
self.assertIn('Red', doc.select('.cart .cart-row')[0].text)
self.assertIn('1', doc.select('.cart .cart-row')[0].select('.count')[0].text)
self.assertIn('14', doc.select('.cart .cart-row')[0].select('.price')[0].text)
self.assertIn('14', doc.select('.cart .cart-row')[0].select('.price')[1].text)
objs = list(CartPosition.objects.filter(user=self.user, event=self.event))
self.assertEqual(len(objs), 1)
self.assertEqual(objs[0].item, self.shirt)
self.assertEqual(objs[0].variation, self.shirt_red)
self.assertEqual(objs[0].price, 14)
def test_count(self):
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '2'
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('Early-bird', doc.select('.cart .cart-row')[0].select('strong')[0].text)
self.assertIn('2', 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('46', doc.select('.cart .cart-row')[0].select('.price')[1].text)
objs = list(CartPosition.objects.filter(user=self.user, event=self.event))
self.assertEqual(len(objs), 2)
for obj in objs:
self.assertEqual(obj.item, self.ticket)
self.assertIsNone(obj.variation)
self.assertEqual(obj.price, 23)
def test_multiple(self):
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '2',
'variation_' + self.shirt.identity + '_' + self.shirt_red.identity: '1'
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('Early-bird', doc.select('.cart')[0].text)
self.assertIn('Shirt', doc.select('.cart')[0].text)
objs = list(CartPosition.objects.filter(user=self.user, event=self.event))
self.assertEqual(len(objs), 3)
self.assertIn(self.shirt, [obj.item for obj in objs])
self.assertIn(self.shirt_red, [obj.variation for obj in objs])
self.assertIn(self.ticket, [obj.item for obj in objs])
def test_fuzzy_input(self):
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: 'a',
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('numbers only', doc.select('.alert-danger')[0].text)
self.assertFalse(CartPosition.objects.filter(user=self.user, event=self.event).exists())
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('did not select any items', doc.select('.alert-warning')[0].text)
self.assertFalse(CartPosition.objects.filter(user=self.user, event=self.event).exists())
def test_wrong_event(self):
event2 = Event.objects.create(
organizer=self.orga, name='MRMCD', slug='mrmcd',
date_from=datetime.datetime(2014, 9, 6, tzinfo=datetime.timezone.utc)
)
shirt2 = Item.objects.create(event=event2, name='T-Shirt', default_price=12)
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_' + shirt2.identity: '1',
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('not available', doc.select('.alert-danger')[0].text)
self.assertFalse(CartPosition.objects.filter(user=self.user, event=self.event).exists())
def test_no_quota(self):
shirt2 = Item.objects.create(event=self.event, name='T-Shirt', default_price=12)
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_' + shirt2.identity: '1',
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('no longer available', doc.select('.alert-danger')[0].text)
self.assertFalse(CartPosition.objects.filter(user=self.user, event=self.event).exists())
def test_max_items(self):
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
self.event.settings.max_items_per_order = 5
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '5',
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('more than', doc.select('.alert-danger')[0].text)
self.assertEqual(CartPosition.objects.filter(user=self.user, event=self.event).count(), 1)
def test_quota_full(self):
self.quota_tickets.size = 0
self.quota_tickets.save()
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '1',
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('no longer available', doc.select('.alert-danger')[0].text)
self.assertFalse(CartPosition.objects.filter(user=self.user, event=self.event).exists())
def test_quota_partly(self):
self.quota_tickets.size = 1
self.quota_tickets.save()
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '2'
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('no longer available', doc.select('.alert-danger')[0].text)
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)
objs = list(CartPosition.objects.filter(user=self.user, event=self.event))
self.assertEqual(len(objs), 1)
self.assertEqual(objs[0].item, self.ticket)
self.assertIsNone(objs[0].variation)
self.assertEqual(objs[0].price, 23)
def test_renew_in_time(self):
cp = CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
}, follow=True)
cp = CartPosition.objects.current.get(identity=cp.identity)
self.assertGreater(cp.expires, now())
def test_renew_expired_successfully(self):
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() - timedelta(minutes=10)
)
self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
}, follow=True)
objs = list(CartPosition.objects.current.filter(user=self.user, event=self.event))
self.assertEqual(len(objs), 1)
self.assertEqual(objs[0].item, self.ticket)
self.assertIsNone(objs[0].variation)
self.assertEqual(objs[0].price, 23)
self.assertGreater(objs[0].expires, now())
def test_renew_expired_failed(self):
self.quota_tickets.size = 0
self.quota_tickets.save()
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() - timedelta(minutes=10)
)
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
}, follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('no longer available', doc.select('.alert-danger')[0].text)
self.assertFalse(CartPosition.objects.current.filter(user=self.user, event=self.event).exists())
def test_restriction_failed(self):
self.event.plugins = 'pretix.plugins.testdummy'
self.event.save()
self.event.settings.testdummy_available = 'yes'
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '1',
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
objs = list(CartPosition.objects.current.filter(user=self.user, event=self.event))
self.assertEqual(len(objs), 1)
self.assertEqual(objs[0].item, self.ticket)
self.assertIsNone(objs[0].variation)
self.assertEqual(objs[0].price, 23)
def test_restriction_ok(self):
self.event.plugins = 'pretix.plugins.testdummy'
self.event.save()
self.event.settings.testdummy_available = 'no'
response = self.client.post('/%s/%s/cart/add' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '1',
}, follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('no longer available', doc.select('.alert-danger')[0].text)
self.assertFalse(CartPosition.objects.filter(user=self.user, event=self.event).exists())
def test_remove_simple(self):
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
response = self.client.post('/%s/%s/cart/remove' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '1',
}, follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('updated', doc.select('.alert-success')[0].text)
self.assertFalse(CartPosition.objects.current.filter(user=self.user, event=self.event).exists())
def test_remove_variation(self):
CartPosition.objects.create(
event=self.event, user=self.user, item=self.shirt, variation=self.shirt_red,
price=14, expires=now() + timedelta(minutes=10)
)
response = self.client.post('/%s/%s/cart/remove' % (self.orga.slug, self.event.slug), {
'variation_' + self.shirt.identity + '_' + self.shirt_red.identity: '1',
}, follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('updated', doc.select('.alert-success')[0].text)
self.assertFalse(CartPosition.objects.current.filter(user=self.user, event=self.event).exists())
def test_remove_one_of_multiple(self):
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
response = self.client.post('/%s/%s/cart/remove' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '1',
}, follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('updated', doc.select('.alert-success')[0].text)
self.assertEqual(CartPosition.objects.current.filter(user=self.user, event=self.event).count(), 1)
def test_remove_multiple(self):
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
response = self.client.post('/%s/%s/cart/remove' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '2',
}, follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('updated', doc.select('.alert-success')[0].text)
self.assertFalse(CartPosition.objects.current.filter(user=self.user, event=self.event).exists())
def test_remove_most_expensive(self):
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=20, expires=now() + timedelta(minutes=10)
)
response = self.client.post('/%s/%s/cart/remove' % (self.orga.slug, self.event.slug), {
'item_' + self.ticket.identity: '1',
}, follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertIn('updated', doc.select('.alert-success')[0].text)
objs = list(CartPosition.objects.current.filter(user=self.user, event=self.event))
self.assertEqual(len(objs), 1)
self.assertEqual(objs[0].item, self.ticket)
self.assertIsNone(objs[0].variation)
self.assertEqual(objs[0].price, 20)

View File

@@ -0,0 +1,210 @@
import datetime
from unittest import expectedFailure
from bs4 import BeautifulSoup
from django.test import TestCase
from django.utils.timezone import now
from datetime import timedelta
from pretix.base.models import Item, Organizer, Event, ItemCategory, Quota, Property, PropertyValue, ItemVariation, User, \
CartPosition, Question
class CheckoutTestCase(TestCase):
def setUp(self):
super().setUp()
self.orga = Organizer.objects.create(name='CCC', slug='ccc')
self.event = Event.objects.create(
organizer=self.orga, name='30C3', slug='30c3',
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
plugins='pretix.plugins.stripe,pretix.plugins.banktransfer'
)
self.user = User.objects.create_local_user(self.event, 'demo', 'demo')
self.category = ItemCategory.objects.create(event=self.event, name="Everything", position=0)
self.quota_shirts = Quota.objects.create(event=self.event, name='Shirts', size=2)
self.shirt = Item.objects.create(event=self.event, name='T-Shirt', category=self.category, default_price=12)
prop1 = Property.objects.create(event=self.event, name="Color")
self.shirt.properties.add(prop1)
val1 = PropertyValue.objects.create(prop=prop1, value="Red", position=0)
val2 = PropertyValue.objects.create(prop=prop1, value="Black", position=1)
self.quota_shirts.items.add(self.shirt)
self.shirt_red = ItemVariation.objects.create(item=self.shirt, default_price=14)
self.shirt_red.values.add(val1)
var2 = ItemVariation.objects.create(item=self.shirt)
var2.values.add(val2)
self.quota_shirts.variations.add(self.shirt_red)
self.quota_shirts.variations.add(var2)
self.quota_tickets = Quota.objects.create(event=self.event, name='Tickets', size=5)
self.ticket = Item.objects.create(event=self.event, name='Early-bird ticket',
category=self.category, default_price=23, admission=True)
self.quota_tickets.items.add(self.ticket)
self.assertTrue(self.client.login(username='demo@%s.event.pretix' % self.event.identity, password='demo'))
def test_empty_cart(self):
response = self.client.get('/%s/%s/checkout' % (self.orga.slug, self.event.slug), follow=True)
self.assertRedirects(response, '/%s/%s/' % (self.orga.slug, self.event.slug),
target_status_code=200)
def test_no_questions(self):
self.event.settings.set('attendee_names_asked', False)
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=20, expires=now() + timedelta(minutes=10)
)
response = self.client.get('/%s/%s/checkout' % (self.orga.slug, self.event.slug), follow=True)
self.assertRedirects(response, '/%s/%s/checkout/payment' % (self.orga.slug, self.event.slug),
target_status_code=200)
def test_questions(self):
self.event.settings.set('attendee_names_asked', False)
q1 = Question.objects.create(
event=self.event, question='Age', type=Question.TYPE_NUMBER,
required=True
)
q2 = Question.objects.create(
event=self.event, question='How have you heard from us?', type=Question.TYPE_STRING,
required=False
)
self.ticket.questions.add(q1)
self.ticket.questions.add(q2)
cr1 = CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
cr2 = CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=20, expires=now() + timedelta(minutes=10)
)
response = self.client.get('/%s/%s/checkout' % (self.orga.slug, self.event.slug), follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertEqual(len(doc.select('input[name=%s-question_%s]' % (cr1.identity, q1.identity))), 1)
self.assertEqual(len(doc.select('input[name=%s-question_%s]' % (cr2.identity, q1.identity))), 1)
self.assertEqual(len(doc.select('input[name=%s-question_%s]' % (cr1.identity, q2.identity))), 1)
self.assertEqual(len(doc.select('input[name=%s-question_%s]' % (cr2.identity, q2.identity))), 1)
# Not all required fields filled out, expect failure
response = self.client.post('/%s/%s/checkout' % (self.orga.slug, self.event.slug), {
'%s-question_%s' % (cr1.identity, q1.identity): '42',
'%s-question_%s' % (cr2.identity, q1.identity): '',
'%s-question_%s' % (cr1.identity, q2.identity): 'Internet',
'%s-question_%s' % (cr2.identity, q2.identity): '',
}, follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertGreaterEqual(len(doc.select('.has-error')), 1)
# Corrected request
response = self.client.post('/%s/%s/checkout' % (self.orga.slug, self.event.slug), {
'%s-question_%s' % (cr1.identity, q1.identity): '42',
'%s-question_%s' % (cr2.identity, q1.identity): '23',
'%s-question_%s' % (cr1.identity, q2.identity): 'Internet',
'%s-question_%s' % (cr2.identity, q2.identity): '',
}, follow=True)
self.assertRedirects(response, '/%s/%s/checkout/payment' % (self.orga.slug, self.event.slug),
target_status_code=200)
cr1 = CartPosition.objects.current.get(identity=cr1.identity)
cr2 = CartPosition.objects.current.get(identity=cr2.identity)
self.assertEqual(cr1.answers.filter(question=q1).count(), 1)
self.assertEqual(cr2.answers.filter(question=q1).count(), 1)
self.assertEqual(cr1.answers.filter(question=q2).count(), 1)
self.assertFalse(cr2.answers.filter(question=q2).exists())
@expectedFailure
def test_boolean_required_question(self):
"""
Expected to fail. See https://github.com/pretix/pretix/issues/19
"""
self.event.settings.set('attendee_names_asked', False)
q1 = Question.objects.create(
event=self.event, question='Breakfast', type=Question.TYPE_BOOLEAN,
required=True
)
self.ticket.questions.add(q1)
cr1 = CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
response = self.client.get('/%s/%s/checkout' % (self.orga.slug, self.event.slug), follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertEqual(len(doc.select('input[name=%s-question_%s]' % (cr1.identity, q1.identity))), 1)
response = self.client.post('/%s/%s/checkout' % (self.orga.slug, self.event.slug), {
'%s-question_%s' % (cr1.identity, q1.identity): '',
}, follow=True)
self.assertRedirects(response, '/%s/%s/checkout/payment' % (self.orga.slug, self.event.slug),
target_status_code=200)
cr1 = CartPosition.objects.current.get(identity=cr1.identity)
self.assertEqual(cr1.answers.filter(question=q1).count(), 1)
self.assertEqual(cr1.answers.get(question=q1).value, 'False')
def test_attendee_name_required(self):
self.event.settings.set('attendee_names_asked', True)
self.event.settings.set('attendee_names_required', True)
cr1 = CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
response = self.client.get('/%s/%s/checkout' % (self.orga.slug, self.event.slug), follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertEqual(len(doc.select('input[name=%s-attendee_name]' % cr1.identity)), 1)
# Not all required fields filled out, expect failure
response = self.client.post('/%s/%s/checkout' % (self.orga.slug, self.event.slug), {
'%s-attendee_name' % cr1.identity: '',
}, follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertGreaterEqual(len(doc.select('.has-error')), 1)
# Corrected request
response = self.client.post('/%s/%s/checkout' % (self.orga.slug, self.event.slug), {
'%s-attendee_name' % cr1.identity: 'Peter',
}, follow=True)
self.assertRedirects(response, '/%s/%s/checkout/payment' % (self.orga.slug, self.event.slug),
target_status_code=200)
cr1 = CartPosition.objects.current.get(identity=cr1.identity)
self.assertEqual(cr1.attendee_name, 'Peter')
def test_attendee_name_optional(self):
self.event.settings.set('attendee_names_asked', True)
self.event.settings.set('atendee_names_required', False)
cr1 = CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
response = self.client.get('/%s/%s/checkout' % (self.orga.slug, self.event.slug), follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertEqual(len(doc.select('input[name=%s-attendee_name]' % cr1.identity)), 1)
# Not all required fields filled out, expect failure
response = self.client.post('/%s/%s/checkout' % (self.orga.slug, self.event.slug), {
'%s-attendee_name' % cr1.identity: '',
}, follow=True)
self.assertRedirects(response, '/%s/%s/checkout/payment' % (self.orga.slug, self.event.slug),
target_status_code=200)
cr1 = CartPosition.objects.current.get(identity=cr1.identity)
self.assertIsNone(cr1.attendee_name)
def test_payment(self):
# TODO: Test for payment method fees
self.event.settings.set('payment_stripe__enabled', True)
self.event.settings.set('payment_banktransfer__enabled', True)
CartPosition.objects.create(
event=self.event, user=self.user, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
response = self.client.get('/%s/%s/checkout/payment' % (self.orga.slug, self.event.slug), follow=True)
doc = BeautifulSoup(response.rendered_content)
self.assertEqual(len(doc.select('input[name=payment]')), 2)
response = self.client.post('/%s/%s/checkout/payment' % (self.orga.slug, self.event.slug), {
'payment': 'banktransfer'
}, follow=True)
self.assertRedirects(response, '/%s/%s/checkout/confirm' % (self.orga.slug, self.event.slug),
target_status_code=200)

View File

@@ -0,0 +1,119 @@
import datetime
from pretix.base.models import Item, Organizer, Event, ItemCategory, Quota, Property, PropertyValue, ItemVariation
from tests.base import BrowserTest
class EventMiddlewareTest(BrowserTest):
def setUp(self):
super().setUp()
self.orga = Organizer.objects.create(name='CCC', slug='ccc')
self.event = Event.objects.create(
organizer=self.orga, name='30C3', slug='30c3',
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
)
self.driver.implicitly_wait(10)
def test_event_header(self):
self.driver.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
self.assertIn(self.event.name, self.driver.find_element_by_css_selector("h1").text)
def test_not_found(self):
resp = self.client.get('%s/%s/%s/' % (self.live_server_url, 'foo', 'bar'))
self.assertEqual(resp.status_code, 404)
class ItemDisplayTest(BrowserTest):
def setUp(self):
super().setUp()
self.orga = Organizer.objects.create(name='CCC', slug='ccc')
self.event = Event.objects.create(
organizer=self.orga, name='30C3', slug='30c3',
date_from=datetime.datetime(2013, 12, 26, tzinfo=datetime.timezone.utc),
)
self.driver.implicitly_wait(10)
def test_without_category(self):
q = Quota.objects.create(event=self.event, name='Quota', size=2)
item = Item.objects.create(event=self.event, name='Early-bird ticket')
q.items.add(item)
self.driver.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
self.assertIn("Early-bird", self.driver.find_element_by_css_selector("section .product-row:first-child").text)
def test_simple_with_category(self):
c = ItemCategory.objects.create(event=self.event, name="Entry tickets", position=0)
q = Quota.objects.create(event=self.event, name='Quota', size=2)
item = Item.objects.create(event=self.event, name='Early-bird ticket', category=c)
q.items.add(item)
self.driver.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
self.assertIn("Entry tickets", self.driver.find_element_by_css_selector("section:nth-of-type(1) h3").text)
self.assertIn("Early-bird",
self.driver.find_element_by_css_selector("section:nth-of-type(1) div:nth-of-type(1)").text)
def test_simple_without_quota(self):
c = ItemCategory.objects.create(event=self.event, name="Entry tickets", position=0)
Item.objects.create(event=self.event, name='Early-bird ticket', category=c)
resp = self.client.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
self.assertNotIn("Early-bird", resp.rendered_content)
def test_no_variations_in_quota(self):
c = ItemCategory.objects.create(event=self.event, name="Entry tickets", position=0)
q = Quota.objects.create(event=self.event, name='Quota', size=2)
item = Item.objects.create(event=self.event, name='Early-bird ticket', category=c)
prop1 = Property.objects.create(event=self.event, name="Color")
item.properties.add(prop1)
PropertyValue.objects.create(prop=prop1, value="Red")
PropertyValue.objects.create(prop=prop1, value="Black")
q.items.add(item)
self.driver.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
resp = self.client.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
self.assertNotIn("Early-bird", resp.rendered_content)
def test_one_variation_in_quota(self):
c = ItemCategory.objects.create(event=self.event, name="Entry tickets", position=0)
q = Quota.objects.create(event=self.event, name='Quota', size=2)
item = Item.objects.create(event=self.event, name='Early-bird ticket', category=c)
prop1 = Property.objects.create(event=self.event, name="Color")
item.properties.add(prop1)
val1 = PropertyValue.objects.create(prop=prop1, value="Red")
PropertyValue.objects.create(prop=prop1, value="Black")
q.items.add(item)
var1 = ItemVariation.objects.create(item=item)
var1.values.add(val1)
q.variations.add(var1)
self.driver.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
self.assertIn("Early-bird",
self.driver.find_element_by_css_selector("section:nth-of-type(1) div:nth-of-type(1)").text)
self.assertIn("Red",
self.driver.find_element_by_css_selector("section:nth-of-type(1)").text)
self.assertNotIn("Black",
self.driver.find_element_by_css_selector("section:nth-of-type(1)").text)
def test_variation_prices_in_quota(self):
c = ItemCategory.objects.create(event=self.event, name="Entry tickets", position=0)
q = Quota.objects.create(event=self.event, name='Quota', size=2)
item = Item.objects.create(event=self.event, name='Early-bird ticket', category=c, default_price=12)
prop1 = Property.objects.create(event=self.event, name="Color")
item.properties.add(prop1)
val1 = PropertyValue.objects.create(prop=prop1, value="Red", position=0)
val2 = PropertyValue.objects.create(prop=prop1, value="Black", position=1)
q.items.add(item)
var1 = ItemVariation.objects.create(item=item, default_price=14)
var1.values.add(val1)
var2 = ItemVariation.objects.create(item=item)
var2.values.add(val2)
q.variations.add(var1)
q.variations.add(var2)
self.driver.get('%s/%s/%s/' % (self.live_server_url, self.orga.slug, self.event.slug))
self.assertIn("Early-bird",
self.driver.find_element_by_css_selector("section:nth-of-type(1) div:nth-of-type(1)").text)
self.assertIn("Red",
self.driver.find_elements_by_css_selector("section:nth-of-type(1) div.variation")[0].text)
self.assertIn("14.00",
self.driver.find_elements_by_css_selector("section:nth-of-type(1) div.variation")[0].text)
self.assertIn("Black",
self.driver.find_elements_by_css_selector("section:nth-of-type(1) div.variation")[1].text)
self.assertIn("12.00",
self.driver.find_elements_by_css_selector("section:nth-of-type(1) div.variation")[1].text)