Tests, fixes and creating items

This commit is contained in:
Raphael Michel
2015-01-11 17:47:43 +01:00
parent dacb81af47
commit 59eac8987a
7 changed files with 106 additions and 14 deletions

View File

@@ -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
} }

View File

@@ -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

View File

@@ -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")

View File

@@ -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 %}

View File

@@ -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>

View File

@@ -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'),

View File

@@ -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'