diff options
Diffstat (limited to 'tests/forms/tests/error_messages.py')
-rw-r--r-- | tests/forms/tests/error_messages.py | 263 |
1 files changed, 263 insertions, 0 deletions
diff --git a/tests/forms/tests/error_messages.py b/tests/forms/tests/error_messages.py new file mode 100644 index 0000000000..b76e122bc0 --- /dev/null +++ b/tests/forms/tests/error_messages.py @@ -0,0 +1,263 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, unicode_literals + +from django.core.files.uploadedfile import SimpleUploadedFile +from django.forms import * +from django.test import TestCase +from django.utils.safestring import mark_safe +from django.utils.encoding import python_2_unicode_compatible + + +class AssertFormErrorsMixin(object): + def assertFormErrors(self, expected, the_callable, *args, **kwargs): + try: + the_callable(*args, **kwargs) + self.fail("Testing the 'clean' method on %s failed to raise a ValidationError.") + except ValidationError as e: + self.assertEqual(e.messages, expected) + +class FormsErrorMessagesTestCase(TestCase, AssertFormErrorsMixin): + def test_charfield(self): + e = { + 'required': 'REQUIRED', + 'min_length': 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s', + 'max_length': 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s', + } + f = CharField(min_length=5, max_length=10, error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['LENGTH 4, MIN LENGTH 5'], f.clean, '1234') + self.assertFormErrors(['LENGTH 11, MAX LENGTH 10'], f.clean, '12345678901') + + def test_integerfield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID', + 'min_value': 'MIN VALUE IS %(limit_value)s', + 'max_value': 'MAX VALUE IS %(limit_value)s', + } + f = IntegerField(min_value=5, max_value=10, error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID'], f.clean, 'abc') + self.assertFormErrors(['MIN VALUE IS 5'], f.clean, '4') + self.assertFormErrors(['MAX VALUE IS 10'], f.clean, '11') + + def test_floatfield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID', + 'min_value': 'MIN VALUE IS %(limit_value)s', + 'max_value': 'MAX VALUE IS %(limit_value)s', + } + f = FloatField(min_value=5, max_value=10, error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID'], f.clean, 'abc') + self.assertFormErrors(['MIN VALUE IS 5'], f.clean, '4') + self.assertFormErrors(['MAX VALUE IS 10'], f.clean, '11') + + def test_decimalfield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID', + 'min_value': 'MIN VALUE IS %(limit_value)s', + 'max_value': 'MAX VALUE IS %(limit_value)s', + 'max_digits': 'MAX DIGITS IS %s', + 'max_decimal_places': 'MAX DP IS %s', + 'max_whole_digits': 'MAX DIGITS BEFORE DP IS %s', + } + f = DecimalField(min_value=5, max_value=10, error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID'], f.clean, 'abc') + self.assertFormErrors(['MIN VALUE IS 5'], f.clean, '4') + self.assertFormErrors(['MAX VALUE IS 10'], f.clean, '11') + + f2 = DecimalField(max_digits=4, decimal_places=2, error_messages=e) + self.assertFormErrors(['MAX DIGITS IS 4'], f2.clean, '123.45') + self.assertFormErrors(['MAX DP IS 2'], f2.clean, '1.234') + self.assertFormErrors(['MAX DIGITS BEFORE DP IS 2'], f2.clean, '123.4') + + def test_datefield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID', + } + f = DateField(error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID'], f.clean, 'abc') + + def test_timefield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID', + } + f = TimeField(error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID'], f.clean, 'abc') + + def test_datetimefield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID', + } + f = DateTimeField(error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID'], f.clean, 'abc') + + def test_regexfield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID', + 'min_length': 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s', + 'max_length': 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s', + } + f = RegexField(r'^\d+$', min_length=5, max_length=10, error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID'], f.clean, 'abcde') + self.assertFormErrors(['LENGTH 4, MIN LENGTH 5'], f.clean, '1234') + self.assertFormErrors(['LENGTH 11, MAX LENGTH 10'], f.clean, '12345678901') + + def test_emailfield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID', + 'min_length': 'LENGTH %(show_value)s, MIN LENGTH %(limit_value)s', + 'max_length': 'LENGTH %(show_value)s, MAX LENGTH %(limit_value)s', + } + f = EmailField(min_length=8, max_length=10, error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID'], f.clean, 'abcdefgh') + self.assertFormErrors(['LENGTH 7, MIN LENGTH 8'], f.clean, 'a@b.com') + self.assertFormErrors(['LENGTH 11, MAX LENGTH 10'], f.clean, 'aye@bee.com') + + def test_filefield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID', + 'missing': 'MISSING', + 'empty': 'EMPTY FILE', + } + f = FileField(error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID'], f.clean, 'abc') + self.assertFormErrors(['EMPTY FILE'], f.clean, SimpleUploadedFile('name', None)) + self.assertFormErrors(['EMPTY FILE'], f.clean, SimpleUploadedFile('name', '')) + + def test_urlfield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID', + } + f = URLField(error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID'], f.clean, 'abc.c') + + def test_booleanfield(self): + e = { + 'required': 'REQUIRED', + } + f = BooleanField(error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + + def test_choicefield(self): + e = { + 'required': 'REQUIRED', + 'invalid_choice': '%(value)s IS INVALID CHOICE', + } + f = ChoiceField(choices=[('a', 'aye')], error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['b IS INVALID CHOICE'], f.clean, 'b') + + def test_multiplechoicefield(self): + e = { + 'required': 'REQUIRED', + 'invalid_choice': '%(value)s IS INVALID CHOICE', + 'invalid_list': 'NOT A LIST', + } + f = MultipleChoiceField(choices=[('a', 'aye')], error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['NOT A LIST'], f.clean, 'b') + self.assertFormErrors(['b IS INVALID CHOICE'], f.clean, ['b']) + + def test_splitdatetimefield(self): + e = { + 'required': 'REQUIRED', + 'invalid_date': 'INVALID DATE', + 'invalid_time': 'INVALID TIME', + } + f = SplitDateTimeField(error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID DATE', 'INVALID TIME'], f.clean, ['a', 'b']) + + def test_ipaddressfield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID IP ADDRESS', + } + f = IPAddressField(error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID IP ADDRESS'], f.clean, '127.0.0') + + def test_generic_ipaddressfield(self): + e = { + 'required': 'REQUIRED', + 'invalid': 'INVALID IP ADDRESS', + } + f = GenericIPAddressField(error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID IP ADDRESS'], f.clean, '127.0.0') + + def test_subclassing_errorlist(self): + class TestForm(Form): + first_name = CharField() + last_name = CharField() + birthday = DateField() + + def clean(self): + raise ValidationError("I like to be awkward.") + + @python_2_unicode_compatible + class CustomErrorList(util.ErrorList): + def __str__(self): + return self.as_divs() + + def as_divs(self): + if not self: return '' + return mark_safe('<div class="error">%s</div>' % ''.join(['<p>%s</p>' % e for e in self])) + + # This form should print errors the default way. + form1 = TestForm({'first_name': 'John'}) + self.assertHTMLEqual(str(form1['last_name'].errors), '<ul class="errorlist"><li>This field is required.</li></ul>') + self.assertHTMLEqual(str(form1.errors['__all__']), '<ul class="errorlist"><li>I like to be awkward.</li></ul>') + + # This one should wrap error groups in the customized way. + form2 = TestForm({'first_name': 'John'}, error_class=CustomErrorList) + self.assertHTMLEqual(str(form2['last_name'].errors), '<div class="error"><p>This field is required.</p></div>') + self.assertHTMLEqual(str(form2.errors['__all__']), '<div class="error"><p>I like to be awkward.</p></div>') + + +class ModelChoiceFieldErrorMessagesTestCase(TestCase, AssertFormErrorsMixin): + def test_modelchoicefield(self): + # Create choices for the model choice field tests below. + from regressiontests.forms.models import ChoiceModel + c1 = ChoiceModel.objects.create(pk=1, name='a') + c2 = ChoiceModel.objects.create(pk=2, name='b') + c3 = ChoiceModel.objects.create(pk=3, name='c') + + # ModelChoiceField + e = { + 'required': 'REQUIRED', + 'invalid_choice': 'INVALID CHOICE', + } + f = ModelChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['INVALID CHOICE'], f.clean, '4') + + # ModelMultipleChoiceField + e = { + 'required': 'REQUIRED', + 'invalid_choice': '%s IS INVALID CHOICE', + 'list': 'NOT A LIST OF VALUES', + } + f = ModelMultipleChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e) + self.assertFormErrors(['REQUIRED'], f.clean, '') + self.assertFormErrors(['NOT A LIST OF VALUES'], f.clean, '3') + self.assertFormErrors(['4 IS INVALID CHOICE'], f.clean, ['4']) |