mirror of
https://github.com/pretix/pretix.git
synced 2026-05-08 15:44:02 +00:00
Tests, fixes and creating items
This commit is contained in:
@@ -51,10 +51,24 @@ class Versionable(BaseVersionable):
|
|||||||
earlier_version.version_end_date = forced_version_date
|
earlier_version.version_end_date = forced_version_date
|
||||||
earlier_version.save()
|
earlier_version.save()
|
||||||
|
|
||||||
|
for field in earlier_version._meta.many_to_many:
|
||||||
|
earlier_version.clone_relations_shallow(later_version, field.attname, forced_version_date)
|
||||||
|
|
||||||
|
if hasattr(earlier_version._meta, 'many_to_many_related'):
|
||||||
|
for rel in earlier_version._meta.many_to_many_related:
|
||||||
|
earlier_version.clone_relations_shallow(later_version, rel.via_field_name, forced_version_date)
|
||||||
|
|
||||||
later_version.save()
|
later_version.save()
|
||||||
|
|
||||||
return later_version
|
return later_version
|
||||||
|
|
||||||
|
def clone_relations_shallow(self, clone, manager_field_name, forced_version_date):
|
||||||
|
# Source: the original object, where relations are currently pointing to
|
||||||
|
source = getattr(self, manager_field_name) # returns a VersionedRelatedManager instance
|
||||||
|
# Destination: the clone, where the cloned relations should point to
|
||||||
|
source.through.objects.filter(**{source.source_field.attname: clone.id}).update(**{
|
||||||
|
source.source_field.attname: self.id})
|
||||||
|
|
||||||
|
|
||||||
class UserManager(BaseUserManager):
|
class UserManager(BaseUserManager):
|
||||||
"""
|
"""
|
||||||
@@ -156,11 +170,11 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||||||
return self.identifier
|
return self.identifier
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
if self.identifier is None:
|
if not self.identifier:
|
||||||
if self.event is None:
|
if self.event is None:
|
||||||
self.identifier = self.email.lower()
|
self.identifier = self.email.lower()
|
||||||
else:
|
else:
|
||||||
self.identifier = "%s@%d.event.tixl" % (self.username.lower(), self.event.id)
|
self.identifier = "%s@%s.event.tixl" % (self.username.lower(), self.event.id)
|
||||||
if not self.pk:
|
if not self.pk:
|
||||||
self.identifier = self.identifier.lower()
|
self.identifier = self.identifier.lower()
|
||||||
super().save(*args, **kwargs)
|
super().save(*args, **kwargs)
|
||||||
@@ -179,7 +193,7 @@ class User(AbstractBaseUser, PermissionsMixin):
|
|||||||
elif not self.givenname and self.familyname:
|
elif not self.givenname and self.familyname:
|
||||||
return self.familyname
|
return self.familyname
|
||||||
elif self.familyname and self.givenname:
|
elif self.familyname and self.givenname:
|
||||||
return '%(family)s, %(given)s' % {
|
return _('%(family)s, %(given)s') % {
|
||||||
'family': self.familyname,
|
'family': self.familyname,
|
||||||
'given': self.givenname
|
'given': self.givenname
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ class LocaleDeterminationTest(TestCase):
|
|||||||
language = response['Content-Language']
|
language = response['Content-Language']
|
||||||
self.assertEqual(language, self.TEST_LOCALE)
|
self.assertEqual(language, self.TEST_LOCALE)
|
||||||
|
|
||||||
|
def test_unknown_browser_default(self):
|
||||||
|
c = Client(HTTP_ACCEPT_LANGUAGE='sjn')
|
||||||
|
response = c.get('/control/')
|
||||||
|
language = response['Content-Language']
|
||||||
|
self.assertEqual(language, settings.LANGUAGE_CODE)
|
||||||
|
|
||||||
def test_cookie_settings(self):
|
def test_cookie_settings(self):
|
||||||
c = Client()
|
c = Client()
|
||||||
cookies = c.cookies
|
cookies = c.cookies
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from django.utils.timezone import now
|
|||||||
|
|
||||||
from tixlbase.models import (
|
from tixlbase.models import (
|
||||||
Event, Organizer, Item, ItemVariation,
|
Event, Organizer, Item, ItemVariation,
|
||||||
Property, PropertyValue
|
Property, PropertyValue, User
|
||||||
)
|
)
|
||||||
from tixlbase.types import VariationDict
|
from tixlbase.types import VariationDict
|
||||||
|
|
||||||
@@ -139,3 +139,41 @@ class ItemVariationsTest(TestCase):
|
|||||||
['L', 'blue'],
|
['L', 'blue'],
|
||||||
]))
|
]))
|
||||||
self.assertEqual(num_variations, 1)
|
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.tixl" % (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")
|
||||||
|
|||||||
@@ -2,12 +2,19 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block title %}{{ item.name }} :: {% trans "Item" %}{% endblock %}
|
{% block title %}{{ item.name }} :: {% trans "Item" %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{% trans "Modify item:" %} {{ item.name }}</h1>
|
{% if item.identity %}
|
||||||
<ul class="nav nav-pills">
|
<h1>{% trans "Modify item:" %} {{ item.name }}</h1>
|
||||||
<li {% if "event.item" == url_name %}class="active"{% endif %}><a href="{% url 'control:event.item' organizer=request.event.organizer.slug event=request.event.slug item=item.identity %}">{% trans "General information" %}</a></li>
|
<ul class="nav nav-pills">
|
||||||
<li {% if "event.item.variations" == url_name %}class="active"{% endif %}><a href="{% url 'control:event.item.variations' organizer=request.event.organizer.slug event=request.event.slug item=item.identity %}">{% trans "Variations" %}</a></li>
|
<li {% if "event.item" == url_name %}class="active"{% endif %}><a href="{% url 'control:event.item' organizer=request.event.organizer.slug event=request.event.slug item=item.identity %}">{% trans "General information" %}</a></li>
|
||||||
<li {% if "event.item.restrictions" == url_name %}class="active"{% endif %}><a href="{% url 'control:event.item.restrictions' organizer=request.event.organizer.slug event=request.event.slug item=item.identity %}">{% trans "Restrictions" %}</a></li>
|
<li {% if "event.item.variations" == url_name %}class="active"{% endif %}><a href="{% url 'control:event.item.variations' organizer=request.event.organizer.slug event=request.event.slug item=item.identity %}">{% trans "Variations" %}</a></li>
|
||||||
</ul>
|
<li {% if "event.item.restrictions" == url_name %}class="active"{% endif %}><a href="{% url 'control:event.item.restrictions' organizer=request.event.organizer.slug event=request.event.slug item=item.identity %}">{% trans "Restrictions" %}</a></li>
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<h1>{% trans "Create item" %}</h1>
|
||||||
|
<p>{% blocktrans trimmed %}
|
||||||
|
You will be able to adjust further settings in the next step.
|
||||||
|
{% endblocktrans %}</p>
|
||||||
|
{% endif %}
|
||||||
{% if item.identity and not item.quotas.exists %}
|
{% if item.identity and not item.quotas.exists %}
|
||||||
<div class="alert alert-warning">
|
<div class="alert alert-warning">
|
||||||
{% blocktrans trimmed %}
|
{% blocktrans trimmed %}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
{% block title %}{% trans "Items" %}{% endblock %}
|
{% block title %}{% trans "Items" %}{% endblock %}
|
||||||
{% block inside %}
|
{% block inside %}
|
||||||
<h1>{% trans "Items" %}</h1>
|
<h1>{% trans "Items" %}</h1>
|
||||||
|
<p>
|
||||||
|
<a href="{% url "control:event.items.add" organizer=request.event.organizer.slug event=request.event.slug %}" class="btn btn-default"><i class="fa fa-plus"></i> {% trans "Create new item" %}</a>
|
||||||
|
</p>
|
||||||
<table class="table table-condensed table-hover">
|
<table class="table table-condensed table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -15,7 +18,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td><strong><a href="
|
<td><strong><a href="
|
||||||
{% url "control:event.item" organizer=request.event.organizer.slug event=request.event.slug item=i.identity %}">{{ i.name }}</a></strong></td>
|
{% url "control:event.item" organizer=request.event.organizer.slug event=request.event.slug item=i.identity %}">{{ i.name }}</a></strong></td>
|
||||||
<td>{{ i.category }}</td>
|
<td>{% if i.category %}{{ i.category }}{% endif %}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ urlpatterns += patterns(
|
|||||||
url(r'^settings/$', event.EventUpdate.as_view(), name='event.settings'),
|
url(r'^settings/$', event.EventUpdate.as_view(), name='event.settings'),
|
||||||
url(r'^settings/plugins$', event.EventPlugins.as_view(), name='event.settings.plugins'),
|
url(r'^settings/plugins$', event.EventPlugins.as_view(), name='event.settings.plugins'),
|
||||||
url(r'^items/$', item.ItemList.as_view(), name='event.items'),
|
url(r'^items/$', item.ItemList.as_view(), name='event.items'),
|
||||||
|
url(r'^items/add$', item.ItemCreate.as_view(), name='event.items.add'),
|
||||||
url(r'^items/(?P<item>[0-9a-f-]+)/$', item.ItemUpdateGeneral.as_view(), name='event.item'),
|
url(r'^items/(?P<item>[0-9a-f-]+)/$', item.ItemUpdateGeneral.as_view(), name='event.item'),
|
||||||
url(r'^items/(?P<item>[0-9a-f-]+)/variations$', item.ItemVariations.as_view(),
|
url(r'^items/(?P<item>[0-9a-f-]+)/variations$', item.ItemVariations.as_view(),
|
||||||
name='event.item.variations'),
|
name='event.item.variations'),
|
||||||
|
|||||||
@@ -513,11 +513,12 @@ class QuotaEditorMixin:
|
|||||||
# optimization of tixlbase.models.Versionable.clone_shallow()
|
# optimization of tixlbase.models.Versionable.clone_shallow()
|
||||||
# items = self.object.items.all()
|
# items = self.object.items.all()
|
||||||
# variations = self.object.variations.all()
|
# variations = self.object.variations.all()
|
||||||
|
self.object = form.instance
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
field = form.fields['item_%s' % item.identity]
|
field = form.fields['item_%s' % item.identity]
|
||||||
data = form.cleaned_data['item_%s' % item.identity]
|
data = form.cleaned_data['item_%s' % item.identity]
|
||||||
if isinstance(field, VariationsField):
|
if isinstance(field, VariationsField):
|
||||||
self.object.variations.add(data)
|
self.object.variations.add(*data)
|
||||||
# for v in data:
|
# for v in data:
|
||||||
# if v not in variations:
|
# if v not in variations:
|
||||||
# self.object.variations.add(v)
|
# self.object.variations.add(v)
|
||||||
@@ -613,7 +614,7 @@ class ItemDetailMixin(SingleObjectMixin):
|
|||||||
return self.object
|
return self.object
|
||||||
|
|
||||||
|
|
||||||
class ItemUpdateFormGeneral(VersionedModelForm):
|
class ItemFormGeneral(VersionedModelForm):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@@ -637,8 +638,30 @@ class ItemUpdateFormGeneral(VersionedModelForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ItemCreate(EventPermissionRequiredMixin, CreateView):
|
||||||
|
form_class = ItemFormGeneral
|
||||||
|
template_name = 'tixlcontrol/item/index.html'
|
||||||
|
permission = 'can_change_items'
|
||||||
|
|
||||||
|
def get_success_url(self) -> str:
|
||||||
|
return reverse('control:event.item', kwargs={
|
||||||
|
'organizer': self.request.event.organizer.slug,
|
||||||
|
'event': self.request.event.slug,
|
||||||
|
'item': self.object.identity,
|
||||||
|
}) + '?success=true'
|
||||||
|
|
||||||
|
def get_form_kwargs(self):
|
||||||
|
"""
|
||||||
|
Returns the keyword arguments for instantiating the form.
|
||||||
|
"""
|
||||||
|
newinst = Item(event=self.request.event)
|
||||||
|
kwargs = super().get_form_kwargs()
|
||||||
|
kwargs.update({'instance': newinst})
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
class ItemUpdateGeneral(ItemDetailMixin, EventPermissionRequiredMixin, UpdateView):
|
class ItemUpdateGeneral(ItemDetailMixin, EventPermissionRequiredMixin, UpdateView):
|
||||||
form_class = ItemUpdateFormGeneral
|
form_class = ItemFormGeneral
|
||||||
template_name = 'tixlcontrol/item/index.html'
|
template_name = 'tixlcontrol/item/index.html'
|
||||||
permission = 'can_change_items'
|
permission = 'can_change_items'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user