diff --git a/src/pretix/base/payment.py b/src/pretix/base/payment.py index c166de11ca..b66a60c717 100644 --- a/src/pretix/base/payment.py +++ b/src/pretix/base/payment.py @@ -41,14 +41,14 @@ class BasePaymentProvider: """ A human-readable name for this payment provider """ - raise NotImplementedError + raise NotImplementedError() # NOQA @property def identifier(self) -> str: """ A unique identifier for this payment provider """ - raise NotImplementedError() + raise NotImplementedError() # NOQA @property def settings_form_fields(self) -> dict: @@ -58,7 +58,7 @@ class BasePaymentProvider: We suggest returning a collections.OrderedDict object instead of a dict. """ - raise NotImplementedError() + raise NotImplementedError() # NOQA @property def checkout_form_fields(self) -> dict: @@ -103,7 +103,7 @@ class BasePaymentProvider: Returns the HTML that should be displayed when the user selected this provider on the 'confirm order' page. """ - raise NotImplementedError() + raise NotImplementedError() # NOQA def checkout_prepare(self, request, total) -> "bool|HttpResponse": """ @@ -134,7 +134,7 @@ class BasePaymentProvider: True, if the user's session is valid and all data your payment provider requires in future steps is present. """ - raise NotImplementedError() + raise NotImplementedError() # NOQA def checkout_perform(self, request, order) -> str: """ @@ -162,7 +162,7 @@ class BasePaymentProvider: :param order: The order object """ - raise NotImplementedError() + raise NotImplementedError() # NOQA def order_paid_render(self, request, order) -> str: """ diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index 97019616f9..ab600997f4 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -35,6 +35,9 @@ class SettingsProxy: self._cached_obj[setting.key] = setting return self._cached_obj + def _flush(self): + self._cached_obj = None + def _unserialize(self, value, as_type): if isinstance(value, as_type): return value @@ -62,7 +65,7 @@ class SettingsProxy: elif isinstance(value, int) or isinstance(value, float) \ or isinstance(value, bool) or isinstance(value, decimal.Decimal): return str(value) - elif isinstance(value, list) or isinstance(value, bool): + elif isinstance(value, list) or isinstance(value, dict): return json.dumps(value) elif isinstance(value, Versionable): return value.identity diff --git a/src/pretix/base/tests/test_models.py b/src/pretix/base/tests/test_models.py index e49bf6279d..a180addf06 100644 --- a/src/pretix/base/tests/test_models.py +++ b/src/pretix/base/tests/test_models.py @@ -7,7 +7,6 @@ from pretix.base.models import ( Property, PropertyValue, User, Quota, Order, OrderPosition, CartPosition) from pretix.base.types import VariationDict -from pretix.base import settings class ItemVariationsTest(TestCase): @@ -294,67 +293,3 @@ class QuotaTestCase(TestCase): quota2.size = 0 quota2.save() self.assertEqual(self.item1.check_quotas(), (Quota.AVAILABILITY_GONE, 0)) - - -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_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') - - 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) diff --git a/src/pretix/base/tests/test_settings.py b/src/pretix/base/tests/test_settings.py new file mode 100644 index 0000000000..0632518f04 --- /dev/null +++ b/src/pretix/base/tests/test_settings.py @@ -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'])