mirror of
https://github.com/pretix/pretix.git
synced 2026-08-13 11:17:01 +00:00
Data structures and form elements for internationalized data
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
import copy
|
||||
import json
|
||||
from django.conf import settings
|
||||
from django.db.models import TextField, SubfieldBase
|
||||
from django import forms
|
||||
from django.utils import translation
|
||||
|
||||
|
||||
class LazyI18String:
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
if isinstance(self.data, str) and self.data is not None:
|
||||
try:
|
||||
j = json.loads(self.data)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
self.data = j
|
||||
|
||||
def __str__(self):
|
||||
if self.data is None:
|
||||
return ""
|
||||
if isinstance(self.data, dict):
|
||||
lng = translation.get_language()
|
||||
if lng in self.data and self.data[lng]:
|
||||
return self.data[lng]
|
||||
elif settings.LANGUAGE_CODE in self.data and self.data[settings.LANGUAGE_CODE]:
|
||||
return self.data[settings.LANGUAGE_CODE]
|
||||
elif len(self.data):
|
||||
return self.data.items()[0][1]
|
||||
else:
|
||||
return ""
|
||||
else:
|
||||
return str(self.data)
|
||||
|
||||
def __repr__(self):
|
||||
return '<LazyI18nString: %s>' % repr(self.data)
|
||||
|
||||
def __lt__(self, other):
|
||||
return str(self) < str(other)
|
||||
|
||||
|
||||
class I18nWidget(forms.MultiWidget):
|
||||
widget = forms.TextInput
|
||||
|
||||
def langcodes(self):
|
||||
return [l[0] for l in settings.LANGUAGES]
|
||||
|
||||
def __init__(self, attrs=None):
|
||||
widgets = []
|
||||
for lng in self.langcodes():
|
||||
a = copy.copy(attrs) or {}
|
||||
a['data-lang'] = lng
|
||||
widgets.append(self.widget(attrs=a))
|
||||
super().__init__(widgets, attrs)
|
||||
|
||||
def decompress(self, value):
|
||||
data = []
|
||||
for lng in self.langcodes():
|
||||
data.append(
|
||||
value.data[lng]
|
||||
if value is not None and value.data is not None and lng in value.data
|
||||
else None
|
||||
)
|
||||
return data
|
||||
|
||||
|
||||
class I18nTextInput(I18nWidget):
|
||||
widget = forms.TextInput
|
||||
|
||||
|
||||
class I18nTextarea(I18nWidget):
|
||||
widget = forms.Textarea
|
||||
|
||||
|
||||
class I18nFormField(forms.MultiValueField):
|
||||
|
||||
def compress(self, data_list):
|
||||
langcodes = self.langcodes()
|
||||
data = {}
|
||||
for i, value in enumerate(data_list):
|
||||
data[langcodes[i]] = value
|
||||
return LazyI18String(data)
|
||||
|
||||
def langcodes(self):
|
||||
return [l[0] for l in settings.LANGUAGES]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
fields = []
|
||||
defaults = {
|
||||
'widget': self.widget,
|
||||
'max_length': kwargs.pop('max_length', None),
|
||||
}
|
||||
kwargs['required'] = False
|
||||
defaults.update(**kwargs)
|
||||
for lngcode in self.langcodes():
|
||||
defaults['label'] = '%s (%s)' % (defaults.get('label'), lngcode)
|
||||
fields.append(forms.CharField(**defaults))
|
||||
super().__init__(
|
||||
fields=fields, require_all_fields=False, *args, **kwargs
|
||||
)
|
||||
|
||||
|
||||
class I18nFieldMixin:
|
||||
# TODO: Formfield
|
||||
# TODO: Correct null/blank validating
|
||||
form_class = I18nFormField
|
||||
widget = I18nTextInput
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.event = kwargs.pop('event', None)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def to_python(self, value):
|
||||
if isinstance(value, LazyI18String):
|
||||
return value
|
||||
return LazyI18String(value)
|
||||
|
||||
def get_prep_value(self, value):
|
||||
if isinstance(value, LazyI18String):
|
||||
value = value.data
|
||||
if isinstance(value, dict):
|
||||
return json.dumps(value, sort_keys=True)
|
||||
return value
|
||||
|
||||
def get_prep_lookup(self, lookup_type, value):
|
||||
raise TypeError('Lookups on i18n string currently not supported.')
|
||||
|
||||
def formfield(self, **kwargs):
|
||||
defaults = {'form_class': self.form_class, 'widget': self.widget}
|
||||
defaults.update(kwargs)
|
||||
return super().formfield(**defaults)
|
||||
|
||||
|
||||
class I18nCharField(I18nFieldMixin, TextField, metaclass=SubfieldBase):
|
||||
# TODO: Check max length
|
||||
widget = I18nTextInput
|
||||
|
||||
|
||||
class I18nTextField(I18nFieldMixin, TextField, metaclass=SubfieldBase):
|
||||
widget = I18nTextarea
|
||||
@@ -0,0 +1,50 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
import pretix.base.i18n
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('pretixbase', '0023_auto_20150401_0954'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='name',
|
||||
field=pretix.base.i18n.I18nCharField(max_length=200, verbose_name='Name'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='item',
|
||||
name='long_description',
|
||||
field=pretix.base.i18n.I18nTextField(null=True, blank=True, verbose_name='Long description'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='item',
|
||||
name='name',
|
||||
field=pretix.base.i18n.I18nCharField(max_length=255, verbose_name='Item name'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='item',
|
||||
name='short_description',
|
||||
field=pretix.base.i18n.I18nTextField(null=True, blank=True, verbose_name='Short description', help_text='This is shown below the product name in lists.'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='property',
|
||||
name='name',
|
||||
field=pretix.base.i18n.I18nCharField(max_length=250, verbose_name='Property name'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='propertyvalue',
|
||||
name='value',
|
||||
field=pretix.base.i18n.I18nCharField(max_length=250, verbose_name='Value'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='question',
|
||||
name='question',
|
||||
field=pretix.base.i18n.I18nTextField(verbose_name='Question'),
|
||||
),
|
||||
]
|
||||
+16
-13
@@ -15,6 +15,7 @@ from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.template.defaultfilters import date as _date
|
||||
from django.core.validators import RegexValidator
|
||||
from pretix.base.i18n import I18nCharField, I18nTextField
|
||||
from pretix.base.settings import SettingsProxy
|
||||
import six
|
||||
from versions.models import Versionable as BaseVersionable
|
||||
@@ -379,8 +380,10 @@ class Event(Versionable):
|
||||
|
||||
organizer = VersionedForeignKey(Organizer, related_name="events",
|
||||
on_delete=models.PROTECT)
|
||||
name = models.CharField(max_length=200,
|
||||
verbose_name=_("Name"))
|
||||
name = I18nCharField(
|
||||
max_length=200,
|
||||
verbose_name=_("Name"),
|
||||
)
|
||||
slug = models.SlugField(
|
||||
max_length=50, db_index=True,
|
||||
help_text=_(
|
||||
@@ -424,7 +427,7 @@ class Event(Versionable):
|
||||
ordering = ("date_from", "name")
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
return str(self.name)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
obj = super().save(*args, **kwargs)
|
||||
@@ -594,7 +597,7 @@ class Property(Versionable):
|
||||
Event,
|
||||
related_name="properties",
|
||||
)
|
||||
name = models.CharField(
|
||||
name = I18nCharField(
|
||||
max_length=250,
|
||||
verbose_name=_("Property name"),
|
||||
)
|
||||
@@ -604,7 +607,7 @@ class Property(Versionable):
|
||||
verbose_name_plural = _("Product properties")
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
return str(self.name)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
super().delete(*args, **kwargs)
|
||||
@@ -635,7 +638,7 @@ class PropertyValue(Versionable):
|
||||
on_delete=models.CASCADE,
|
||||
related_name="values"
|
||||
)
|
||||
value = models.CharField(
|
||||
value = I18nCharField(
|
||||
max_length=250,
|
||||
verbose_name=_("Value"),
|
||||
)
|
||||
@@ -704,7 +707,7 @@ class Question(Versionable):
|
||||
Event,
|
||||
related_name="questions",
|
||||
)
|
||||
question = models.TextField(
|
||||
question = I18nTextField(
|
||||
verbose_name=_("Question"),
|
||||
)
|
||||
type = models.CharField(
|
||||
@@ -722,7 +725,7 @@ class Question(Versionable):
|
||||
verbose_name_plural = _("Questions")
|
||||
|
||||
def __str__(self):
|
||||
return self.question
|
||||
return str(self.question)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
super().delete(*args, **kwargs)
|
||||
@@ -777,20 +780,20 @@ class Item(Versionable):
|
||||
blank=True, null=True,
|
||||
verbose_name=_("Category"),
|
||||
)
|
||||
name = models.CharField(
|
||||
name = I18nCharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Item name")
|
||||
verbose_name=_("Item name"),
|
||||
)
|
||||
active = models.BooleanField(
|
||||
default=True,
|
||||
verbose_name=_("Active"),
|
||||
)
|
||||
short_description = models.TextField(
|
||||
short_description = I18nTextField(
|
||||
verbose_name=_("Short description"),
|
||||
help_text=_("This is shown below the product name in lists."),
|
||||
null=True, blank=True,
|
||||
)
|
||||
long_description = models.TextField(
|
||||
long_description = I18nTextField(
|
||||
verbose_name=_("Long description"),
|
||||
null=True, blank=True,
|
||||
)
|
||||
@@ -839,7 +842,7 @@ class Item(Versionable):
|
||||
verbose_name_plural = _("Products")
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
return str(self.name)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
@@ -80,7 +80,7 @@ class VariationDict(dict):
|
||||
]
|
||||
|
||||
def __str__(self):
|
||||
return " – ".join([v.value for v in self.ordered_values()])
|
||||
return " – ".join([str(v.value) for v in self.ordered_values()])
|
||||
|
||||
def copy(self) -> "VariationDict":
|
||||
"""
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
{% for line in items.positions %}
|
||||
<div class="row-fluid product-row">
|
||||
<div class="col-md-4 col-xs-6">
|
||||
<strong>{{ line.item }}</strong>
|
||||
<strong>{{ line.item.name }}</strong>
|
||||
{% if line.variation %}
|
||||
– {{ line.variation }}
|
||||
{% endif %}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
EMAIL_PORT = 1025
|
||||
EMAIL_HOST = '127.0.0.1'
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 11 KiB |
@@ -14,7 +14,7 @@
|
||||
<h4 class="panel-title">
|
||||
<a data-toggle="collapse" href="#cp{{ form.pos.identity }}"
|
||||
data-parent="#questions_accordion">
|
||||
<strong>{{ form.pos.item }}</strong>
|
||||
<strong>{{ form.pos.item.name }}</strong>
|
||||
{% if form.pos.variation %}
|
||||
– {{ form.pos.variation }}
|
||||
{% endif %}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{% for line in cart.positions %}
|
||||
<div class="row-fluid cart-row">
|
||||
<div class="col-md-4 col-xs-6">
|
||||
<strong>{{ line.item }}</strong>
|
||||
<strong>{{ line.item.name }}</strong>
|
||||
{% if line.variation %}
|
||||
– {{ line.variation }}
|
||||
{% endif %}
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
{% if item.short_description %}<p>{{ item.short_description }}</p>{% endif %}
|
||||
</div>
|
||||
<div class="col-md-2 col-xs-6 price">
|
||||
{{ event.currency }} {{ item.price|floatformat:2 }}
|
||||
{{ event.currency }} {{ item.price }}
|
||||
{% if item.tax_rate %}
|
||||
<br /><small>{% blocktrans trimmed with rate=item.tax_rate %}
|
||||
incl. {{ rate }}% taxes
|
||||
|
||||
@@ -112,8 +112,8 @@ LOCALE_PATHS = (
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _ # NOQA
|
||||
LANGUAGES = (
|
||||
('de', _('German')),
|
||||
('en', _('English')),
|
||||
('de', _('German')),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -21,21 +21,19 @@ class ItemVariationsTest(TestCase):
|
||||
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')
|
||||
cls.p_size = Property.objects.create(event=cls.event, name='Size')
|
||||
cls.pv_size_s = PropertyValue.objects.create(prop=cls.p_size, value='S')
|
||||
cls.pv_size_m = PropertyValue.objects.create(prop=cls.p_size, value='M')
|
||||
PropertyValue.objects.create(prop=cls.p_size, value='L')
|
||||
cls.p_color = Property.objects.create(event=cls.event, name='Color')
|
||||
cls.pv_color_black = PropertyValue.objects.create(prop=cls.p_color, value='black')
|
||||
PropertyValue.objects.create(prop=cls.p_color, 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)
|
||||
i.properties.add(self.p_size)
|
||||
iv = ItemVariation.objects.create(item=i)
|
||||
pv = PropertyValue.objects.get(prop=p, value='S')
|
||||
iv.values.add(pv)
|
||||
iv.values.add(self.pv_size_s)
|
||||
|
||||
variations = i.get_all_variations()
|
||||
|
||||
@@ -46,16 +44,16 @@ class ItemVariationsTest(TestCase):
|
||||
for v in vd.relevant_values():
|
||||
self.assertIs(type(v), PropertyValue)
|
||||
|
||||
if vd[p.pk] == pv:
|
||||
if vd[self.p_size.pk] == self.pv_size_s:
|
||||
vd1 = vd
|
||||
|
||||
vd2 = VariationDict()
|
||||
vd2[p.pk] = pv
|
||||
vd2[self.p_size.pk] = self.pv_size_s
|
||||
|
||||
self.assertEqual(vd2.identify(), vd1.identify())
|
||||
self.assertEqual(vd2, vd1)
|
||||
|
||||
vd2[p.pk] = PropertyValue.objects.get(prop=p, value='M')
|
||||
vd2[self.p_size.pk] = self.pv_size_m
|
||||
|
||||
self.assertNotEqual(vd2.identify(), vd.identify())
|
||||
self.assertNotEqual(vd2, vd1)
|
||||
@@ -63,7 +61,7 @@ class ItemVariationsTest(TestCase):
|
||||
vd3 = vd2.copy()
|
||||
self.assertEqual(vd3, vd2)
|
||||
|
||||
vd2[p.pk] = pv
|
||||
vd2[self.p_size.pk] = self.pv_size_s
|
||||
self.assertNotEqual(vd3, vd2)
|
||||
|
||||
vd4 = VariationDict()
|
||||
@@ -80,22 +78,21 @@ class ItemVariationsTest(TestCase):
|
||||
self.assertEqual(v[0], {})
|
||||
|
||||
# One property, no variations
|
||||
p = Property.objects.get(event=self.event, name='Size')
|
||||
i.properties.add(p)
|
||||
i.properties.add(self.p_size)
|
||||
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']))
|
||||
self.assertIn(self.p_size.pk, var)
|
||||
self.assertIs(type(var[self.p_size.pk]), PropertyValue)
|
||||
values.append(var[self.p_size.pk].value)
|
||||
self.assertEqual(sorted([str(V) for V in 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'))
|
||||
iv.values.add(self.pv_size_s)
|
||||
v = i.get_all_variations()
|
||||
self.assertIs(type(v), list)
|
||||
self.assertEqual(len(v), 3)
|
||||
@@ -107,16 +104,15 @@ class ItemVariationsTest(TestCase):
|
||||
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']))
|
||||
elif self.p_size.pk in var:
|
||||
self.assertIs(type(var[self.p_size.pk]), PropertyValue)
|
||||
values.append(var[self.p_size.pk].value)
|
||||
self.assertEqual(sorted([str(V) for V in 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'))
|
||||
i.properties.add(self.p_color)
|
||||
iv.values.add(self.pv_color_black)
|
||||
v = i.get_all_variations()
|
||||
self.assertIs(type(v), list)
|
||||
self.assertEqual(len(v), 6)
|
||||
@@ -126,11 +122,11 @@ class ItemVariationsTest(TestCase):
|
||||
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']))
|
||||
values.append(sorted([str(ivv.value) for ivv in iv.values.all()]))
|
||||
self.assertEqual(sorted([str(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()]))
|
||||
values.append(sorted([str(pv.value) for pv in var.values()]))
|
||||
self.assertEqual(sorted(values), sorted([
|
||||
['S', 'black'],
|
||||
['S', 'blue'],
|
||||
|
||||
@@ -104,15 +104,15 @@ class PropertiesTest(ItemFormTest):
|
||||
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.driver.find_element_by_css_selector("#id_name_0").send_keys('Size')
|
||||
self.driver.find_element_by_name("values-0-value_0").send_keys('S')
|
||||
self.driver.find_element_by_name("values-1-value_0").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("#page-wrapper 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"))
|
||||
self.assertEqual("S", self.driver.find_element_by_name("values-0-value_0").get_attribute("value"))
|
||||
self.assertEqual("M", self.driver.find_element_by_name("values-1-value_0").get_attribute("value"))
|
||||
|
||||
@unittest.skipIf('TRAVIS' in os.environ, 'See CategoriesTest.test_sort for details.')
|
||||
def test_update(self):
|
||||
@@ -122,18 +122,18 @@ class PropertiesTest(ItemFormTest):
|
||||
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_element_by_css_selector("#id_name_0").clear()
|
||||
self.driver.find_element_by_css_selector("#id_name_0").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.scroll_into_view(self.driver.find_element_by_name("values-1-value_0"))
|
||||
self.driver.find_element_by_name("values-1-value_0").clear()
|
||||
self.driver.find_element_by_name("values-1-value_0").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_name("values-2-value_0").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"))
|
||||
self.assertEqual("red", self.driver.find_element_by_name("values-0-value_0").get_attribute("value"))
|
||||
self.assertEqual("blue", self.driver.find_element_by_name("values-1-value_0").get_attribute("value"))
|
||||
|
||||
def test_delete(self):
|
||||
c = Property.objects.create(event=self.event1, name="Size")
|
||||
@@ -151,7 +151,7 @@ class QuestionsTest(ItemFormTest):
|
||||
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?')
|
||||
self.driver.find_element_by_name("question_0").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")
|
||||
@@ -162,8 +162,8 @@ class QuestionsTest(ItemFormTest):
|
||||
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.driver.find_element_by_name("question_0").clear()
|
||||
self.driver.find_element_by_name("question_0").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("#page-wrapper table").text)
|
||||
|
||||
@@ -17,7 +17,7 @@ class EventMiddlewareTest(BrowserTest):
|
||||
|
||||
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)
|
||||
self.assertIn(str(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'))
|
||||
|
||||
Reference in New Issue
Block a user