summaryrefslogtreecommitdiff
path: root/tests/regressiontests/forms
diff options
context:
space:
mode:
authorHonza Král <honza.kral@gmail.com>2009-12-28 16:35:23 +0000
committerHonza Král <honza.kral@gmail.com>2009-12-28 16:35:23 +0000
commitf911df19a455246198b0c8c81ab96bf2abec04f8 (patch)
tree0c0bfb72d622994419492db943d9d37857224f97 /tests/regressiontests/forms
parent695de8cc9145e139c2b22e05aa44f5ac04da6f85 (diff)
[soc2009/model-validation] Merget to trunk at r12009
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@12014 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/regressiontests/forms')
-rw-r--r--tests/regressiontests/forms/fields.py19
-rw-r--r--tests/regressiontests/forms/forms.py39
-rw-r--r--tests/regressiontests/forms/localflavor/ca.py44
-rw-r--r--tests/regressiontests/forms/localflavor/se.py332
-rw-r--r--tests/regressiontests/forms/tests.py4
5 files changed, 429 insertions, 9 deletions
diff --git a/tests/regressiontests/forms/fields.py b/tests/regressiontests/forms/fields.py
index eeff56761d..1b96450f63 100644
--- a/tests/regressiontests/forms/fields.py
+++ b/tests/regressiontests/forms/fields.py
@@ -27,18 +27,20 @@ __init__(). For example, CharField has a max_length option.
import datetime
import time
import re
-from unittest import TestCase
import os
+from unittest import TestCase
+
+from django.core.files.uploadedfile import SimpleUploadedFile
from django.forms import *
from django.forms.widgets import RadioFieldRenderer
-from django.core.files.uploadedfile import SimpleUploadedFile
try:
from decimal import Decimal
except ImportError:
from django.utils._decimal import Decimal
+
def fix_os_paths(x):
if isinstance(x, basestring):
return x.replace('\\', '/')
@@ -50,7 +52,8 @@ def fix_os_paths(x):
return x
-class TestFields(TestCase):
+class FieldsTests(TestCase):
+
def assertRaisesErrorWithMessage(self, error, message, callable, *args, **kwargs):
self.assertRaises(error, callable, *args, **kwargs)
try:
@@ -187,7 +190,7 @@ class TestFields(TestCase):
self.assertRaisesErrorWithMessage(ValidationError, "[u'Ensure this value is greater than or equal to 0.5.']", f.clean, '0.4')
self.assertEqual(1.5, f.clean('1.5'))
self.assertEqual(0.5, f.clean('0.5'))
-
+
# DecimalField ################################################################
def test_decimalfield_13(self):
@@ -487,11 +490,11 @@ class TestFields(TestCase):
self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://inv-.-alid.com')
self.assertEqual(u'http://valid-----hyphens.com/', f.clean('http://valid-----hyphens.com'))
- def test_url_regexp_for_performance(self):
+ def test_url_regex_ticket11198(self):
f = URLField()
# hangs "forever" if catastrophic backtracking in ticket:#11198 not fixed
self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://%s' % ("X"*200,))
-
+
# a second test, to make sure the problem is really addressed, even on
# domains that don't fail the domain label length check in the regex
self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid URL.']", f.clean, 'http://%s' % ("X"*60,))
@@ -575,7 +578,7 @@ class TestFields(TestCase):
self.assertEqual(False, f.clean('0'))
self.assertEqual(True, f.clean('Django rocks'))
self.assertEqual(False, f.clean('False'))
-
+
# ChoiceField #################################################################
def test_choicefield_46(self):
@@ -750,7 +753,7 @@ class TestFields(TestCase):
self.assertRaisesErrorWithMessage(ValidationError, "[u'Enter a valid e-mail address.']", f.clean, 'not an e-mail')
self.assertEqual(u'', f.clean(''))
self.assertEqual(u'', f.clean(None))
-
+
# FilePathField ###############################################################
def test_filepathfield_65(self):
diff --git a/tests/regressiontests/forms/forms.py b/tests/regressiontests/forms/forms.py
index bf9623fe77..627f50a6fe 100644
--- a/tests/regressiontests/forms/forms.py
+++ b/tests/regressiontests/forms/forms.py
@@ -1807,4 +1807,43 @@ True
>>> [f.name for f in form.visible_fields()]
['artist', 'name']
+# Hidden initial input gets its own unique id ################################
+
+>>> class MyForm(Form):
+... field1 = CharField(max_length=50, show_hidden_initial=True)
+>>> print MyForm()
+<tr><th><label for="id_field1">Field1:</label></th><td><input id="id_field1" type="text" name="field1" maxlength="50" /><input type="hidden" name="initial-field1" id="initial-id_field1" /></td></tr>
+
+# The error_html_class and required_html_class attributes ####################
+
+>>> p = Person({})
+>>> p.error_css_class = 'error'
+>>> p.required_css_class = 'required'
+
+>>> print p.as_ul()
+<li class="required error"><ul class="errorlist"><li>This field is required.</li></ul><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></li>
+<li class="required"><label for="id_is_cool">Is cool:</label> <select name="is_cool" id="id_is_cool">
+<option value="1" selected="selected">Unknown</option>
+<option value="2">Yes</option>
+<option value="3">No</option>
+</select></li>
+
+>>> print p.as_p()
+<ul class="errorlist"><li>This field is required.</li></ul>
+<p class="required error"><label for="id_name">Name:</label> <input type="text" name="name" id="id_name" /></p>
+<p class="required"><label for="id_is_cool">Is cool:</label> <select name="is_cool" id="id_is_cool">
+<option value="1" selected="selected">Unknown</option>
+<option value="2">Yes</option>
+<option value="3">No</option>
+</select></p>
+
+>>> print p.as_table()
+<tr class="required error"><th><label for="id_name">Name:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="name" id="id_name" /></td></tr>
+<tr class="required"><th><label for="id_is_cool">Is cool:</label></th><td><select name="is_cool" id="id_is_cool">
+<option value="1" selected="selected">Unknown</option>
+<option value="2">Yes</option>
+<option value="3">No</option>
+</select></td></tr>
+
+
"""
diff --git a/tests/regressiontests/forms/localflavor/ca.py b/tests/regressiontests/forms/localflavor/ca.py
index 48171b0558..7f4b3ac89c 100644
--- a/tests/regressiontests/forms/localflavor/ca.py
+++ b/tests/regressiontests/forms/localflavor/ca.py
@@ -60,6 +60,50 @@ ValidationError: [u'Enter a postal code in the format XXX XXX.']
u''
>>> f.clean('')
u''
+>>> f.clean('W2S 2H3')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('T2W 2H7')
+u'T2W 2H7'
+>>> f.clean('T2S 2W7')
+u'T2S 2W7'
+>>> f.clean('Z2S 2H3')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('T2Z 2H7')
+u'T2Z 2H7'
+>>> f.clean('T2S 2Z7')
+u'T2S 2Z7'
+>>> f.clean('F2S 2H3')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('A2S 2D3')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('A2I 2R3')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('A2I 2R3')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('A2Q 2R3')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('U2B 2R3')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
+>>> f.clean('O2B 2R3')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a postal code in the format XXX XXX.']
# CAPhoneNumberField ##########################################################
diff --git a/tests/regressiontests/forms/localflavor/se.py b/tests/regressiontests/forms/localflavor/se.py
new file mode 100644
index 0000000000..44bd953c6e
--- /dev/null
+++ b/tests/regressiontests/forms/localflavor/se.py
@@ -0,0 +1,332 @@
+# -*- coding: utf-8 -*-
+# Tests for the contrib/localflavor/se form fields.
+
+tests = r"""
+# Monkey-patch datetime.date
+>>> import datetime
+>>> class MockDate(datetime.date):
+... def today(cls):
+... return datetime.date(2008, 5, 14)
+... today = classmethod(today)
+...
+>>> olddate = datetime.date
+>>> datetime.date = MockDate
+>>> datetime.date.today()
+MockDate(2008, 5, 14)
+
+
+# SECountySelect #####################################################
+>>> from django.contrib.localflavor.se.forms import SECountySelect
+
+>>> w = SECountySelect()
+>>> w.render('swedish_county', 'E')
+u'<select name="swedish_county">\n<option value="AB">Stockholm</option>\n<option value="AC">V\xe4sterbotten</option>\n<option value="BD">Norrbotten</option>\n<option value="C">Uppsala</option>\n<option value="D">S\xf6dermanland</option>\n<option value="E" selected="selected">\xd6sterg\xf6tland</option>\n<option value="F">J\xf6nk\xf6ping</option>\n<option value="G">Kronoberg</option>\n<option value="H">Kalmar</option>\n<option value="I">Gotland</option>\n<option value="K">Blekinge</option>\n<option value="M">Sk\xe5ne</option>\n<option value="N">Halland</option>\n<option value="O">V\xe4stra G\xf6taland</option>\n<option value="S">V\xe4rmland</option>\n<option value="T">\xd6rebro</option>\n<option value="U">V\xe4stmanland</option>\n<option value="W">Dalarna</option>\n<option value="X">G\xe4vleborg</option>\n<option value="Y">V\xe4sternorrland</option>\n<option value="Z">J\xe4mtland</option>\n</select>'
+
+# SEOrganisationNumberField #######################################
+
+>>> from django.contrib.localflavor.se.forms import SEOrganisationNumberField
+
+>>> f = SEOrganisationNumberField()
+
+# Ordinary personal identity numbers for sole proprietors
+# The same rules as for SEPersonalIdentityField applies here
+>>> f.clean('870512-1989')
+u'198705121989'
+>>> f.clean('19870512-1989')
+u'198705121989'
+>>> f.clean('870512-2128')
+u'198705122128'
+>>> f.clean('081015-6315')
+u'190810156315'
+>>> f.clean('081015+6315')
+u'180810156315'
+>>> f.clean('0810156315')
+u'190810156315'
+
+>>> f.clean('081015 6315')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish organisation number.']
+>>> f.clean('950231-4496')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish organisation number.']
+>>> f.clean('6914104499')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish organisation number.']
+>>> f.clean('950d314496')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish organisation number.']
+>>> f.clean('invalid!!!')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish organisation number.']
+>>> f.clean('870514-1111')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish organisation number.']
+
+
+# Empty values
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+# Co-ordination number checking
+# Co-ordination numbers are not valid organisation numbers
+>>> f.clean('870574-1315')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish organisation number.']
+
+>>> f.clean('870573-1311')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish organisation number.']
+
+# Test some different organisation numbers
+>>> f.clean('556074-7569') # IKEA Linköping
+u'5560747569'
+
+>>> f.clean('556074-3089') # Volvo Personvagnar
+u'5560743089'
+
+>>> f.clean('822001-5476') # LJS (organisation)
+u'8220015476'
+
+>>> f.clean('8220015476') # LJS (organisation)
+u'8220015476'
+
+>>> f.clean('2120000449') # Katedralskolan Linköping (school)
+u'2120000449'
+
+# Faux organisation number, which tests that the checksum can be 0
+>>> f.clean('232518-5060')
+u'2325185060'
+
+>>> f.clean('556074+3089') # Volvo Personvagnar, bad format
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish organisation number.']
+
+
+# Invalid checksum
+>>> f.clean('2120000441')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish organisation number.']
+
+# Valid checksum but invalid organisation type
+f.clean('1120000441')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish organisation number.']
+
+# Empty values with required=False
+>>> f = SEOrganisationNumberField(required=False)
+
+>>> f.clean(None)
+u''
+
+>>> f.clean('')
+u''
+
+
+# SEPersonalIdentityNumberField #######################################
+
+>>> from django.contrib.localflavor.se.forms import SEPersonalIdentityNumberField
+
+>>> f = SEPersonalIdentityNumberField()
+
+# Valid id numbers
+>>> f.clean('870512-1989')
+u'198705121989'
+
+>>> f.clean('870512-2128')
+u'198705122128'
+
+>>> f.clean('19870512-1989')
+u'198705121989'
+
+>>> f.clean('198705121989')
+u'198705121989'
+
+>>> f.clean('081015-6315')
+u'190810156315'
+
+>>> f.clean('0810156315')
+u'190810156315'
+
+# This is a "special-case" in the checksum calculation,
+# where the sum is divisible by 10 (the checksum digit == 0)
+>>> f.clean('8705141060')
+u'198705141060'
+
+# + means that the person is older than 100 years
+>>> f.clean('081015+6315')
+u'180810156315'
+
+# Bogus values
+>>> f.clean('081015 6315')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish personal identity number.']
+
+>>> f.clean('950d314496')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish personal identity number.']
+
+>>> f.clean('invalid!!!')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish personal identity number.']
+
+
+# Invalid dates
+
+# February 31st does not exist
+>>> f.clean('950231-4496')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish personal identity number.']
+
+# Month 14 does not exist
+>>> f.clean('6914104499')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish personal identity number.']
+
+# There are no Swedish personal id numbers where year < 1800
+>>> f.clean('17430309-7135')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish personal identity number.']
+
+# Invalid checksum
+>>> f.clean('870514-1111')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish personal identity number.']
+
+# Empty values
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+# Co-ordination number checking
+>>> f.clean('870574-1315')
+u'198705741315'
+
+>>> f.clean('870574+1315')
+u'188705741315'
+
+>>> f.clean('198705741315')
+u'198705741315'
+
+# Co-ordination number with bad checksum
+>>> f.clean('870573-1311')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish personal identity number.']
+
+
+# Check valid co-ordination numbers, that should not be accepted
+# because of coordination_number=False
+>>> f = SEPersonalIdentityNumberField(coordination_number=False)
+
+>>> f.clean('870574-1315')
+Traceback (most recent call last):
+...
+ValidationError: [u'Co-ordination numbers are not allowed.']
+
+>>> f.clean('870574+1315')
+Traceback (most recent call last):
+...
+ValidationError: [u'Co-ordination numbers are not allowed.']
+
+>>> f.clean('8705741315')
+Traceback (most recent call last):
+...
+ValidationError: [u'Co-ordination numbers are not allowed.']
+
+# Invalid co-ordination numbers should be treated as invalid, and not
+# as co-ordination numbers
+>>> f.clean('870573-1311')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a valid Swedish personal identity number.']
+
+# Empty values with required=False
+>>> f = SEPersonalIdentityNumberField(required=False)
+
+>>> f.clean(None)
+u''
+
+>>> f.clean('')
+u''
+
+# SEPostalCodeField ###############################################
+>>> from django.contrib.localflavor.se.forms import SEPostalCodeField
+>>> f = SEPostalCodeField()
+>>>
+Postal codes can have spaces
+>>> f.clean('589 37')
+u'58937'
+
+... but the dont have to
+>>> f.clean('58937')
+u'58937'
+>>> f.clean('abcasfassadf')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
+
+# Only one space is allowed for separation
+>>> f.clean('589 37')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
+
+# The postal code must not start with 0
+>>> f.clean('01234')
+Traceback (most recent call last):
+...
+ValidationError: [u'Enter a Swedish postal code in the format XXXXX.']
+
+# Empty values
+>>> f.clean('')
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+>>> f.clean(None)
+Traceback (most recent call last):
+...
+ValidationError: [u'This field is required.']
+
+# Empty values, required=False
+>>> f = SEPostalCodeField(required=False)
+>>> f.clean('')
+u''
+>>> f.clean(None)
+u''
+
+# Revert the monkey patching
+>>> datetime.date = olddate
+
+"""
diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py
index ef7326735d..b6b7752f5a 100644
--- a/tests/regressiontests/forms/tests.py
+++ b/tests/regressiontests/forms/tests.py
@@ -21,6 +21,7 @@ from localflavor.jp import tests as localflavor_jp_tests
from localflavor.nl import tests as localflavor_nl_tests
from localflavor.pl import tests as localflavor_pl_tests
from localflavor.ro import tests as localflavor_ro_tests
+from localflavor.se import tests as localflavor_se_tests
from localflavor.sk import tests as localflavor_sk_tests
from localflavor.uk import tests as localflavor_uk_tests
from localflavor.us import tests as localflavor_us_tests
@@ -31,7 +32,7 @@ from widgets import tests as widgets_tests
from formsets import tests as formset_tests
from media import media_tests
-from fields import TestFields
+from fields import FieldsTests
from validators import TestFormWithValidators, TestFieldWithValidators
__test__ = {
@@ -57,6 +58,7 @@ __test__ = {
'localflavor_nl_tests': localflavor_nl_tests,
'localflavor_pl_tests': localflavor_pl_tests,
'localflavor_ro_tests': localflavor_ro_tests,
+ 'localflavor_se_tests': localflavor_se_tests,
'localflavor_sk_tests': localflavor_sk_tests,
'localflavor_uk_tests': localflavor_uk_tests,
'localflavor_us_tests': localflavor_us_tests,