summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAndrew Godwin <andrew@aeracode.org>2012-10-26 08:41:13 +0100
committerAndrew Godwin <andrew@aeracode.org>2012-10-26 08:41:13 +0100
commit6a632e04578776e877adc5e2dc53f008c890a0d4 (patch)
treeaa47200fb63adf44609066a45601bd3b8768ec1c /tests
parenta589fdff81ab36c57ff0a1003e60ee0dd55f3a88 (diff)
parentfabe9c9e5f0a437b5389faaf469ce53091abd3cf (diff)
Merge branch 'master' into schema-alteration
Conflicts: django/db/backends/__init__.py django/db/models/fields/related.py django/db/models/options.py
Diffstat (limited to 'tests')
-rw-r--r--tests/.coveragerc5
-rw-r--r--tests/modeltests/basic/tests.py3
-rw-r--r--tests/modeltests/delete/models.py20
-rw-r--r--tests/modeltests/delete/tests.py101
-rw-r--r--tests/modeltests/invalid_models/invalid_models/models.py125
-rw-r--r--tests/modeltests/invalid_models/tests.py13
-rw-r--r--tests/modeltests/model_forms/tests.py5
-rw-r--r--tests/modeltests/proxy_models/tests.py38
-rw-r--r--tests/modeltests/test_client/models.py4
-rw-r--r--tests/modeltests/timezones/tests.py62
-rw-r--r--tests/modeltests/validators/tests.py26
-rw-r--r--tests/regressiontests/admin_changelist/tests.py10
-rw-r--r--tests/regressiontests/admin_custom_urls/fixtures/actions.json7
-rw-r--r--tests/regressiontests/admin_custom_urls/models.py37
-rw-r--r--tests/regressiontests/admin_custom_urls/tests.py60
-rw-r--r--tests/regressiontests/admin_inlines/models.py3
-rw-r--r--tests/regressiontests/admin_inlines/tests.py12
-rw-r--r--tests/regressiontests/admin_scripts/tests.py39
-rw-r--r--tests/regressiontests/admin_util/models.py3
-rw-r--r--tests/regressiontests/admin_util/tests.py13
-rw-r--r--tests/regressiontests/admin_views/tests.py185
-rw-r--r--tests/regressiontests/aggregation_regress/tests.py11
-rw-r--r--tests/regressiontests/backends/tests.py7
-rw-r--r--tests/regressiontests/bulk_create/tests.py46
-rw-r--r--tests/regressiontests/cache/tests.py26
-rw-r--r--tests/regressiontests/comment_tests/tests/feed_tests.py21
-rw-r--r--tests/regressiontests/comment_tests/urls.py1
-rw-r--r--tests/regressiontests/conditional_processing/models.py29
-rw-r--r--tests/regressiontests/delete_regress/models.py8
-rw-r--r--tests/regressiontests/delete_regress/tests.py103
-rw-r--r--tests/regressiontests/dispatch/tests/test_dispatcher.py11
-rw-r--r--tests/regressiontests/expressions_regress/tests.py22
-rw-r--r--tests/regressiontests/file_storage/tests.py19
-rw-r--r--tests/regressiontests/file_uploads/tests.py42
-rw-r--r--tests/regressiontests/fixtures_regress/fixtures/sequence_extra.json13
-rw-r--r--tests/regressiontests/fixtures_regress/tests.py32
-rw-r--r--tests/regressiontests/forms/models.py6
-rw-r--r--tests/regressiontests/forms/tests/extra.py9
-rw-r--r--tests/regressiontests/forms/tests/fields.py40
-rw-r--r--tests/regressiontests/forms/tests/formsets.py10
-rw-r--r--tests/regressiontests/forms/tests/input_formats.py58
-rw-r--r--tests/regressiontests/forms/tests/models.py23
-rw-r--r--tests/regressiontests/forms/tests/widgets.py6
-rw-r--r--tests/regressiontests/generic_views/dates.py50
-rw-r--r--tests/regressiontests/handlers/tests.py10
-rw-r--r--tests/regressiontests/http_utils/__init__.py (renamed from tests/regressiontests/localflavor/ar/__init__.py)0
-rw-r--r--tests/regressiontests/http_utils/models.py (renamed from tests/regressiontests/localflavor/at/__init__.py)0
-rw-r--r--tests/regressiontests/http_utils/tests.py45
-rw-r--r--tests/regressiontests/httpwrappers/abc.txt1
-rw-r--r--tests/regressiontests/httpwrappers/tests.py184
-rw-r--r--tests/regressiontests/i18n/commands/extraction.py15
-rw-r--r--tests/regressiontests/i18n/commands/templates/test.html5
-rw-r--r--tests/regressiontests/i18n/tests.py274
-rw-r--r--tests/regressiontests/localflavor/ar/tests.py103
-rw-r--r--tests/regressiontests/localflavor/at/tests.py49
-rw-r--r--tests/regressiontests/localflavor/au/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/au/forms.py11
-rw-r--r--tests/regressiontests/localflavor/au/models.py14
-rw-r--r--tests/regressiontests/localflavor/au/tests.py108
-rw-r--r--tests/regressiontests/localflavor/be/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/be/tests.py81
-rw-r--r--tests/regressiontests/localflavor/br/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/br/tests.py146
-rw-r--r--tests/regressiontests/localflavor/ca/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/ca/tests.py115
-rw-r--r--tests/regressiontests/localflavor/ch/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/ch/tests.py76
-rw-r--r--tests/regressiontests/localflavor/cl/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/cl/tests.py58
-rw-r--r--tests/regressiontests/localflavor/cn/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/cn/tests.py113
-rw-r--r--tests/regressiontests/localflavor/co/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/co/tests.py45
-rw-r--r--tests/regressiontests/localflavor/cz/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/cz/tests.py80
-rw-r--r--tests/regressiontests/localflavor/de/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/de/tests.py51
-rw-r--r--tests/regressiontests/localflavor/ec/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/ec/tests.py36
-rw-r--r--tests/regressiontests/localflavor/es/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/es/tests.py173
-rw-r--r--tests/regressiontests/localflavor/fi/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/fi/tests.py383
-rw-r--r--tests/regressiontests/localflavor/fr/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/fr/tests.py152
-rw-r--r--tests/regressiontests/localflavor/gb/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/gb/tests.py32
-rw-r--r--tests/regressiontests/localflavor/hk/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/hk/forms.py11
-rw-r--r--tests/regressiontests/localflavor/hk/tests.py35
-rw-r--r--tests/regressiontests/localflavor/hr/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/hr/tests.py192
-rw-r--r--tests/regressiontests/localflavor/id/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/id/tests.py195
-rw-r--r--tests/regressiontests/localflavor/ie/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/ie/tests.py45
-rw-r--r--tests/regressiontests/localflavor/il/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/il/tests.py41
-rw-r--r--tests/regressiontests/localflavor/in_/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/in_/tests.py178
-rw-r--r--tests/regressiontests/localflavor/is_/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/is_/tests.py200
-rw-r--r--tests/regressiontests/localflavor/it/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/it/tests.py71
-rw-r--r--tests/regressiontests/localflavor/jp/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/jp/tests.py75
-rw-r--r--tests/regressiontests/localflavor/kw/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/kw/tests.py17
-rw-r--r--tests/regressiontests/localflavor/mk/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/mk/forms.py11
-rw-r--r--tests/regressiontests/localflavor/mk/models.py15
-rw-r--r--tests/regressiontests/localflavor/mk/tests.py308
-rw-r--r--tests/regressiontests/localflavor/mx/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/mx/forms.py11
-rw-r--r--tests/regressiontests/localflavor/mx/models.py13
-rw-r--r--tests/regressiontests/localflavor/mx/mx.py0
-rw-r--r--tests/regressiontests/localflavor/mx/tests.py198
-rw-r--r--tests/regressiontests/localflavor/nl/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/nl/tests.py64
-rw-r--r--tests/regressiontests/localflavor/pl/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/pl/tests.py480
-rw-r--r--tests/regressiontests/localflavor/pt/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/pt/tests.py33
-rw-r--r--tests/regressiontests/localflavor/py/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/py/tests.py55
-rw-r--r--tests/regressiontests/localflavor/ro/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/ro/tests.py144
-rw-r--r--tests/regressiontests/localflavor/ru/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/ru/tests.py150
-rw-r--r--tests/regressiontests/localflavor/se/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/se/tests.py166
-rw-r--r--tests/regressiontests/localflavor/si/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/si/tests.py557
-rw-r--r--tests/regressiontests/localflavor/sk/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/sk/tests.py118
-rw-r--r--tests/regressiontests/localflavor/tests.py42
-rw-r--r--tests/regressiontests/localflavor/tr/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/tr/tests.py75
-rw-r--r--tests/regressiontests/localflavor/us/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/us/forms.py11
-rw-r--r--tests/regressiontests/localflavor/us/models.py15
-rw-r--r--tests/regressiontests/localflavor/us/tests.py286
-rw-r--r--tests/regressiontests/localflavor/uy/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/uy/tests.py53
-rw-r--r--tests/regressiontests/localflavor/za/__init__.py0
-rw-r--r--tests/regressiontests/localflavor/za/tests.py31
-rw-r--r--tests/regressiontests/logging_tests/logconfig.py8
-rw-r--r--tests/regressiontests/logging_tests/tests.py72
-rw-r--r--tests/regressiontests/mail/tests.py5
-rw-r--r--tests/regressiontests/managers_regress/models.py13
-rw-r--r--tests/regressiontests/managers_regress/tests.py168
-rw-r--r--tests/regressiontests/middleware/tests.py43
-rw-r--r--tests/regressiontests/model_fields/models.py5
-rw-r--r--tests/regressiontests/model_fields/tests.py40
-rw-r--r--tests/regressiontests/multiple_database/tests.py18
-rw-r--r--tests/regressiontests/one_to_one_regress/tests.py40
-rw-r--r--tests/regressiontests/queries/tests.py7
-rw-r--r--tests/regressiontests/requests/tests.py267
-rw-r--r--tests/regressiontests/servers/tests.py8
-rw-r--r--tests/regressiontests/servers/urls.py3
-rw-r--r--tests/regressiontests/servers/views.py6
-rw-r--r--tests/regressiontests/syndication/feeds.py8
-rw-r--r--tests/regressiontests/syndication/tests.py8
-rw-r--r--tests/regressiontests/syndication/urls.py1
-rw-r--r--tests/regressiontests/templates/tests.py14
-rw-r--r--tests/regressiontests/test_client_regress/tests.py22
-rw-r--r--tests/regressiontests/test_utils/tests.py42
-rw-r--r--tests/regressiontests/urlpatterns_reverse/namespace_urls.py1
-rw-r--r--tests/regressiontests/urlpatterns_reverse/tests.py5
-rw-r--r--tests/regressiontests/urlpatterns_reverse/views.py5
-rw-r--r--tests/regressiontests/utils/datastructures.py25
-rw-r--r--tests/regressiontests/utils/dateformat.py5
-rw-r--r--tests/regressiontests/utils/html.py2
-rw-r--r--tests/regressiontests/utils/http.py29
-rw-r--r--tests/regressiontests/utils/numberformat.py47
-rw-r--r--tests/regressiontests/utils/tests.py3
-rw-r--r--tests/regressiontests/views/tests/__init__.py2
-rw-r--r--tests/regressiontests/views/tests/debug.py3
-rw-r--r--tests/regressiontests/views/tests/defaults.py22
-rw-r--r--tests/regressiontests/views/tests/static.py55
-rw-r--r--tests/templates/404.html1
-rw-r--r--tests/templates/500.html1
182 files changed, 2206 insertions, 6418 deletions
diff --git a/tests/.coveragerc b/tests/.coveragerc
new file mode 100644
index 0000000000..b979e94c58
--- /dev/null
+++ b/tests/.coveragerc
@@ -0,0 +1,5 @@
+[run]
+omit = runtests,test_sqlite,regressiontests*,modeltests*,*/django/contrib/*/tests*,*/django/utils/unittest*,*/django/utils/simplejson*,*/django/utils/importlib.py,*/django/test/_doctest.py,*/django/core/servers/fastcgi.py,*/django/utils/autoreload.py,*/django/utils/dictconfig.py
+
+[html]
+directory = coverage_html
diff --git a/tests/modeltests/basic/tests.py b/tests/modeltests/basic/tests.py
index 6ec9ca03af..ebd70d14d9 100644
--- a/tests/modeltests/basic/tests.py
+++ b/tests/modeltests/basic/tests.py
@@ -259,9 +259,8 @@ class ModelTest(TestCase):
"datetime.datetime(2005, 7, 28, 0, 0)"])
# dates() requires valid arguments.
- six.assertRaisesRegex(self,
+ self.assertRaises(
TypeError,
- "dates\(\) takes at least 3 arguments \(1 given\)",
Article.objects.dates,
)
diff --git a/tests/modeltests/delete/models.py b/tests/modeltests/delete/models.py
index e0cec426ea..65d4e6f725 100644
--- a/tests/modeltests/delete/models.py
+++ b/tests/modeltests/delete/models.py
@@ -95,7 +95,7 @@ class MRNull(models.Model):
class Avatar(models.Model):
- pass
+ desc = models.TextField(null=True)
class User(models.Model):
@@ -108,3 +108,21 @@ class HiddenUser(models.Model):
class HiddenUserProfile(models.Model):
user = models.ForeignKey(HiddenUser)
+
+class M2MTo(models.Model):
+ pass
+
+class M2MFrom(models.Model):
+ m2m = models.ManyToManyField(M2MTo)
+
+class Parent(models.Model):
+ pass
+
+class Child(Parent):
+ pass
+
+class Base(models.Model):
+ pass
+
+class RelToBase(models.Model):
+ base = models.ForeignKey(Base, on_delete=models.DO_NOTHING)
diff --git a/tests/modeltests/delete/tests.py b/tests/modeltests/delete/tests.py
index 26f2fd52c1..20b815c33d 100644
--- a/tests/modeltests/delete/tests.py
+++ b/tests/modeltests/delete/tests.py
@@ -1,11 +1,12 @@
from __future__ import absolute_import
-from django.db import models, IntegrityError
+from django.db import models, IntegrityError, connection
from django.test import TestCase, skipUnlessDBFeature, skipIfDBFeature
from django.utils.six.moves import xrange
from .models import (R, RChild, S, T, U, A, M, MR, MRNull,
- create_a, get_default_r, User, Avatar, HiddenUser, HiddenUserProfile)
+ create_a, get_default_r, User, Avatar, HiddenUser, HiddenUserProfile,
+ M2MTo, M2MFrom, Parent, Child, Base)
class OnDeleteTests(TestCase):
@@ -74,6 +75,16 @@ class OnDeleteTests(TestCase):
self.assertEqual(replacement_r, a.donothing)
models.signals.pre_delete.disconnect(check_do_nothing)
+ def test_do_nothing_qscount(self):
+ """
+ Test that a models.DO_NOTHING relation doesn't trigger a query.
+ """
+ b = Base.objects.create()
+ with self.assertNumQueries(1):
+ # RelToBase should not be queried.
+ b.delete()
+ self.assertEqual(Base.objects.count(), 0)
+
def test_inheritance_cascade_up(self):
child = RChild.objects.create()
child.delete()
@@ -229,16 +240,34 @@ class DeletionTests(TestCase):
# 1 query to delete the avatar
# The important thing is that when we can defer constraint checks there
# is no need to do an UPDATE on User.avatar to null it out.
+
+ # Attach a signal to make sure we will not do fast_deletes.
+ calls = []
+ def noop(*args, **kwargs):
+ calls.append('')
+ models.signals.post_delete.connect(noop, sender=User)
+
self.assertNumQueries(3, a.delete)
self.assertFalse(User.objects.exists())
self.assertFalse(Avatar.objects.exists())
+ self.assertEqual(len(calls), 1)
+ models.signals.post_delete.disconnect(noop, sender=User)
@skipIfDBFeature("can_defer_constraint_checks")
def test_cannot_defer_constraint_checks(self):
u = User.objects.create(
avatar=Avatar.objects.create()
)
+ # Attach a signal to make sure we will not do fast_deletes.
+ calls = []
+ def noop(*args, **kwargs):
+ calls.append('')
+ models.signals.post_delete.connect(noop, sender=User)
+
a = Avatar.objects.get(pk=u.avatar_id)
+ # The below doesn't make sense... Why do we need to null out
+ # user.avatar if we are going to delete the user immediately after it,
+ # and there are no more cascades.
# 1 query to find the users for the avatar.
# 1 query to delete the user
# 1 query to null out user.avatar, because we can't defer the constraint
@@ -246,6 +275,8 @@ class DeletionTests(TestCase):
self.assertNumQueries(4, a.delete)
self.assertFalse(User.objects.exists())
self.assertFalse(Avatar.objects.exists())
+ self.assertEqual(len(calls), 1)
+ models.signals.post_delete.disconnect(noop, sender=User)
def test_hidden_related(self):
r = R.objects.create()
@@ -254,3 +285,69 @@ class DeletionTests(TestCase):
r.delete()
self.assertEqual(HiddenUserProfile.objects.count(), 0)
+
+class FastDeleteTests(TestCase):
+
+ def test_fast_delete_fk(self):
+ u = User.objects.create(
+ avatar=Avatar.objects.create()
+ )
+ a = Avatar.objects.get(pk=u.avatar_id)
+ # 1 query to fast-delete the user
+ # 1 query to delete the avatar
+ self.assertNumQueries(2, a.delete)
+ self.assertFalse(User.objects.exists())
+ self.assertFalse(Avatar.objects.exists())
+
+ def test_fast_delete_m2m(self):
+ t = M2MTo.objects.create()
+ f = M2MFrom.objects.create()
+ f.m2m.add(t)
+ # 1 to delete f, 1 to fast-delete m2m for f
+ self.assertNumQueries(2, f.delete)
+
+ def test_fast_delete_revm2m(self):
+ t = M2MTo.objects.create()
+ f = M2MFrom.objects.create()
+ f.m2m.add(t)
+ # 1 to delete t, 1 to fast-delete t's m_set
+ self.assertNumQueries(2, f.delete)
+
+ def test_fast_delete_qs(self):
+ u1 = User.objects.create()
+ u2 = User.objects.create()
+ self.assertNumQueries(1, User.objects.filter(pk=u1.pk).delete)
+ self.assertEqual(User.objects.count(), 1)
+ self.assertTrue(User.objects.filter(pk=u2.pk).exists())
+
+ def test_fast_delete_joined_qs(self):
+ a = Avatar.objects.create(desc='a')
+ User.objects.create(avatar=a)
+ u2 = User.objects.create()
+ expected_queries = 1 if connection.features.update_can_self_select else 2
+ self.assertNumQueries(expected_queries,
+ User.objects.filter(avatar__desc='a').delete)
+ self.assertEqual(User.objects.count(), 1)
+ self.assertTrue(User.objects.filter(pk=u2.pk).exists())
+
+ def test_fast_delete_inheritance(self):
+ c = Child.objects.create()
+ p = Parent.objects.create()
+ # 1 for self, 1 for parent
+ # However, this doesn't work as child.parent access creates a query,
+ # and this means we will be generating extra queries (a lot for large
+ # querysets). This is not a fast-delete problem.
+ # self.assertNumQueries(2, c.delete)
+ c.delete()
+ self.assertFalse(Child.objects.exists())
+ self.assertEqual(Parent.objects.count(), 1)
+ self.assertEqual(Parent.objects.filter(pk=p.pk).count(), 1)
+ # 1 for self delete, 1 for fast delete of empty "child" qs.
+ self.assertNumQueries(2, p.delete)
+ self.assertFalse(Parent.objects.exists())
+ # 1 for self delete, 1 for fast delete of empty "child" qs.
+ c = Child.objects.create()
+ p = c.parent_ptr
+ self.assertNumQueries(2, p.delete)
+ self.assertFalse(Parent.objects.exists())
+ self.assertFalse(Child.objects.exists())
diff --git a/tests/modeltests/invalid_models/invalid_models/models.py b/tests/modeltests/invalid_models/invalid_models/models.py
index b2ba253c5d..ccb6396352 100644
--- a/tests/modeltests/invalid_models/invalid_models/models.py
+++ b/tests/modeltests/invalid_models/invalid_models/models.py
@@ -21,11 +21,12 @@ class FieldErrors(models.Model):
decimalfield5 = models.DecimalField(max_digits=10, decimal_places=10)
filefield = models.FileField()
choices = models.CharField(max_length=10, choices='bad')
- choices2 = models.CharField(max_length=10, choices=[(1,2,3),(1,2,3)])
+ choices2 = models.CharField(max_length=10, choices=[(1, 2, 3), (1, 2, 3)])
index = models.CharField(max_length=10, db_index='bad')
field_ = models.CharField(max_length=10)
nullbool = models.BooleanField(null=True)
+
class Target(models.Model):
tgt_safe = models.CharField(max_length=10)
clash1 = models.CharField(max_length=10)
@@ -33,12 +34,14 @@ class Target(models.Model):
clash1_set = models.CharField(max_length=10)
+
class Clash1(models.Model):
src_safe = models.CharField(max_length=10)
foreign = models.ForeignKey(Target)
m2m = models.ManyToManyField(Target)
+
class Clash2(models.Model):
src_safe = models.CharField(max_length=10)
@@ -48,6 +51,7 @@ class Clash2(models.Model):
m2m_1 = models.ManyToManyField(Target, related_name='id')
m2m_2 = models.ManyToManyField(Target, related_name='src_safe')
+
class Target2(models.Model):
clash3 = models.CharField(max_length=10)
foreign_tgt = models.ForeignKey(Target)
@@ -56,6 +60,7 @@ class Target2(models.Model):
m2m_tgt = models.ManyToManyField(Target)
clashm2m_set = models.ManyToManyField(Target)
+
class Clash3(models.Model):
src_safe = models.CharField(max_length=10)
@@ -65,12 +70,15 @@ class Clash3(models.Model):
m2m_1 = models.ManyToManyField(Target2, related_name='foreign_tgt')
m2m_2 = models.ManyToManyField(Target2, related_name='m2m_tgt')
+
class ClashForeign(models.Model):
foreign = models.ForeignKey(Target2)
+
class ClashM2M(models.Model):
m2m = models.ManyToManyField(Target2)
+
class SelfClashForeign(models.Model):
src_safe = models.CharField(max_length=10)
selfclashforeign = models.CharField(max_length=10)
@@ -79,6 +87,7 @@ class SelfClashForeign(models.Model):
foreign_1 = models.ForeignKey("SelfClashForeign", related_name='id')
foreign_2 = models.ForeignKey("SelfClashForeign", related_name='src_safe')
+
class ValidM2M(models.Model):
src_safe = models.CharField(max_length=10)
validm2m = models.CharField(max_length=10)
@@ -94,6 +103,7 @@ class ValidM2M(models.Model):
m2m_3 = models.ManyToManyField('self')
m2m_4 = models.ManyToManyField('self')
+
class SelfClashM2M(models.Model):
src_safe = models.CharField(max_length=10)
selfclashm2m = models.CharField(max_length=10)
@@ -108,120 +118,148 @@ class SelfClashM2M(models.Model):
m2m_3 = models.ManyToManyField('self', symmetrical=False)
m2m_4 = models.ManyToManyField('self', symmetrical=False)
+
class Model(models.Model):
"But it's valid to call a model Model."
- year = models.PositiveIntegerField() #1960
- make = models.CharField(max_length=10) #Aston Martin
- name = models.CharField(max_length=10) #DB 4 GT
+ year = models.PositiveIntegerField() # 1960
+ make = models.CharField(max_length=10) # Aston Martin
+ name = models.CharField(max_length=10) # DB 4 GT
+
class Car(models.Model):
colour = models.CharField(max_length=5)
model = models.ForeignKey(Model)
+
class MissingRelations(models.Model):
rel1 = models.ForeignKey("Rel1")
rel2 = models.ManyToManyField("Rel2")
+
class MissingManualM2MModel(models.Model):
name = models.CharField(max_length=5)
missing_m2m = models.ManyToManyField(Model, through="MissingM2MModel")
+
class Person(models.Model):
name = models.CharField(max_length=5)
+
class Group(models.Model):
name = models.CharField(max_length=5)
primary = models.ManyToManyField(Person, through="Membership", related_name="primary")
secondary = models.ManyToManyField(Person, through="Membership", related_name="secondary")
tertiary = models.ManyToManyField(Person, through="RelationshipDoubleFK", related_name="tertiary")
+
class GroupTwo(models.Model):
name = models.CharField(max_length=5)
primary = models.ManyToManyField(Person, through="Membership")
secondary = models.ManyToManyField(Group, through="MembershipMissingFK")
+
class Membership(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
not_default_or_null = models.CharField(max_length=5)
+
class MembershipMissingFK(models.Model):
person = models.ForeignKey(Person)
+
class PersonSelfRefM2M(models.Model):
name = models.CharField(max_length=5)
friends = models.ManyToManyField('self', through="Relationship")
too_many_friends = models.ManyToManyField('self', through="RelationshipTripleFK")
+
class PersonSelfRefM2MExplicit(models.Model):
name = models.CharField(max_length=5)
friends = models.ManyToManyField('self', through="ExplicitRelationship", symmetrical=True)
+
class Relationship(models.Model):
first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set")
second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set")
date_added = models.DateTimeField()
+
class ExplicitRelationship(models.Model):
first = models.ForeignKey(PersonSelfRefM2MExplicit, related_name="rel_from_set")
second = models.ForeignKey(PersonSelfRefM2MExplicit, related_name="rel_to_set")
date_added = models.DateTimeField()
+
class RelationshipTripleFK(models.Model):
first = models.ForeignKey(PersonSelfRefM2M, related_name="rel_from_set_2")
second = models.ForeignKey(PersonSelfRefM2M, related_name="rel_to_set_2")
third = models.ForeignKey(PersonSelfRefM2M, related_name="too_many_by_far")
date_added = models.DateTimeField()
+
class RelationshipDoubleFK(models.Model):
first = models.ForeignKey(Person, related_name="first_related_name")
second = models.ForeignKey(Person, related_name="second_related_name")
third = models.ForeignKey(Group, related_name="rel_to_set")
date_added = models.DateTimeField()
+
class AbstractModel(models.Model):
name = models.CharField(max_length=10)
+
class Meta:
abstract = True
+
class AbstractRelationModel(models.Model):
fk1 = models.ForeignKey('AbstractModel')
fk2 = models.ManyToManyField('AbstractModel')
+
class UniqueM2M(models.Model):
""" Model to test for unique ManyToManyFields, which are invalid. """
unique_people = models.ManyToManyField(Person, unique=True)
+
class NonUniqueFKTarget1(models.Model):
""" Model to test for non-unique FK target in yet-to-be-defined model: expect an error """
tgt = models.ForeignKey('FKTarget', to_field='bad')
+
class UniqueFKTarget1(models.Model):
""" Model to test for unique FK target in yet-to-be-defined model: expect no error """
tgt = models.ForeignKey('FKTarget', to_field='good')
+
class FKTarget(models.Model):
bad = models.IntegerField()
good = models.IntegerField(unique=True)
+
class NonUniqueFKTarget2(models.Model):
""" Model to test for non-unique FK target in previously seen model: expect an error """
tgt = models.ForeignKey(FKTarget, to_field='bad')
+
class UniqueFKTarget2(models.Model):
""" Model to test for unique FK target in previously seen model: expect no error """
tgt = models.ForeignKey(FKTarget, to_field='good')
+
class NonExistingOrderingWithSingleUnderscore(models.Model):
class Meta:
ordering = ("does_not_exist",)
+
class InvalidSetNull(models.Model):
fk = models.ForeignKey('self', on_delete=models.SET_NULL)
+
class InvalidSetDefault(models.Model):
fk = models.ForeignKey('self', on_delete=models.SET_DEFAULT)
+
class UnicodeForeignKeys(models.Model):
"""Foreign keys which can translate to ascii should be OK, but fail if
they're not."""
@@ -232,9 +270,11 @@ class UnicodeForeignKeys(models.Model):
# when adding the errors in core/management/validation.py
#bad = models.ForeignKey('★')
+
class PrimaryKeyNull(models.Model):
my_pk_field = models.IntegerField(primary_key=True, null=True)
+
class OrderByPKModel(models.Model):
"""
Model to test that ordering by pk passes validation.
@@ -245,6 +285,77 @@ class OrderByPKModel(models.Model):
class Meta:
ordering = ('pk',)
+
+class SwappableModel(models.Model):
+ """A model that can be, but isn't swapped out.
+
+ References to this model *shoudln't* raise any validation error.
+ """
+ name = models.CharField(max_length=100)
+
+ class Meta:
+ swappable = 'TEST_SWAPPABLE_MODEL'
+
+
+class SwappedModel(models.Model):
+ """A model that is swapped out.
+
+ References to this model *should* raise a validation error.
+ Requires TEST_SWAPPED_MODEL to be defined in the test environment;
+ this is guaranteed by the test runner using @override_settings.
+
+ The foreign keys and m2m relations on this model *shouldn't*
+ install related accessors, so there shouldn't be clashes with
+ the equivalent names on the replacement.
+ """
+ name = models.CharField(max_length=100)
+
+ foreign = models.ForeignKey(Target, related_name='swappable_fk_set')
+ m2m = models.ManyToManyField(Target, related_name='swappable_m2m_set')
+
+ class Meta:
+ swappable = 'TEST_SWAPPED_MODEL'
+
+
+class ReplacementModel(models.Model):
+ """A replacement model for swapping purposes."""
+ name = models.CharField(max_length=100)
+
+ foreign = models.ForeignKey(Target, related_name='swappable_fk_set')
+ m2m = models.ManyToManyField(Target, related_name='swappable_m2m_set')
+
+
+class BadSwappableValue(models.Model):
+ """A model that can be swapped out; during testing, the swappable
+ value is not of the format app.model
+ """
+ name = models.CharField(max_length=100)
+
+ class Meta:
+ swappable = 'TEST_SWAPPED_MODEL_BAD_VALUE'
+
+
+class BadSwappableModel(models.Model):
+ """A model that can be swapped out; during testing, the swappable
+ value references an unknown model.
+ """
+ name = models.CharField(max_length=100)
+
+ class Meta:
+ swappable = 'TEST_SWAPPED_MODEL_BAD_MODEL'
+
+
+class HardReferenceModel(models.Model):
+ fk_1 = models.ForeignKey(SwappableModel, related_name='fk_hardref1')
+ fk_2 = models.ForeignKey('invalid_models.SwappableModel', related_name='fk_hardref2')
+ fk_3 = models.ForeignKey(SwappedModel, related_name='fk_hardref3')
+ fk_4 = models.ForeignKey('invalid_models.SwappedModel', related_name='fk_hardref4')
+ m2m_1 = models.ManyToManyField(SwappableModel, related_name='m2m_hardref1')
+ m2m_2 = models.ManyToManyField('invalid_models.SwappableModel', related_name='m2m_hardref2')
+ m2m_3 = models.ManyToManyField(SwappedModel, related_name='m2m_hardref3')
+ m2m_4 = models.ManyToManyField('invalid_models.SwappedModel', related_name='m2m_hardref4')
+
+
model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "max_length" attribute that is a positive integer.
invalid_models.fielderrors: "charfield2": CharFields require a "max_length" attribute that is a positive integer.
invalid_models.fielderrors: "charfield3": CharFields require a "max_length" attribute that is a positive integer.
@@ -353,6 +464,12 @@ invalid_models.nonuniquefktarget2: Field 'bad' under model 'FKTarget' must have
invalid_models.nonexistingorderingwithsingleunderscore: "ordering" refers to "does_not_exist", a field that doesn't exist.
invalid_models.invalidsetnull: 'fk' specifies on_delete=SET_NULL, but cannot be null.
invalid_models.invalidsetdefault: 'fk' specifies on_delete=SET_DEFAULT, but has no default value.
+invalid_models.hardreferencemodel: 'fk_3' defines a relation with the model 'invalid_models.SwappedModel', which has been swapped out. Update the relation to point at settings.TEST_SWAPPED_MODEL.
+invalid_models.hardreferencemodel: 'fk_4' defines a relation with the model 'invalid_models.SwappedModel', which has been swapped out. Update the relation to point at settings.TEST_SWAPPED_MODEL.
+invalid_models.hardreferencemodel: 'm2m_3' defines a relation with the model 'invalid_models.SwappedModel', which has been swapped out. Update the relation to point at settings.TEST_SWAPPED_MODEL.
+invalid_models.hardreferencemodel: 'm2m_4' defines a relation with the model 'invalid_models.SwappedModel', which has been swapped out. Update the relation to point at settings.TEST_SWAPPED_MODEL.
+invalid_models.badswappablevalue: TEST_SWAPPED_MODEL_BAD_VALUE is not of the form 'app_label.app_name'.
+invalid_models.badswappablemodel: Model has been swapped out for 'not_an_app.Target' which has not been installed or is abstract.
"""
if not connection.features.interprets_empty_strings_as_nulls:
diff --git a/tests/modeltests/invalid_models/tests.py b/tests/modeltests/invalid_models/tests.py
index e1fc68743e..5f6224c45d 100644
--- a/tests/modeltests/invalid_models/tests.py
+++ b/tests/modeltests/invalid_models/tests.py
@@ -4,6 +4,7 @@ import sys
from django.core.management.validation import get_validation_errors
from django.db.models.loading import cache, load_app
+from django.test.utils import override_settings
from django.utils import unittest
from django.utils.six import StringIO
@@ -31,14 +32,22 @@ class InvalidModelTestCase(unittest.TestCase):
cache._get_models_cache = {}
sys.stdout = self.old_stdout
+ # Technically, this isn't an override -- TEST_SWAPPED_MODEL must be
+ # set to *something* in order for the test to work. However, it's
+ # easier to set this up as an override than to require every developer
+ # to specify a value in their test settings.
+ @override_settings(
+ TEST_SWAPPED_MODEL='invalid_models.ReplacementModel',
+ TEST_SWAPPED_MODEL_BAD_VALUE='not-a-model',
+ TEST_SWAPPED_MODEL_BAD_MODEL='not_an_app.Target',
+ )
def test_invalid_models(self):
-
try:
module = load_app("modeltests.invalid_models.invalid_models")
except Exception:
self.fail('Unable to load invalid model module')
- count = get_validation_errors(self.stdout, module)
+ get_validation_errors(self.stdout, module)
self.stdout.seek(0)
error_log = self.stdout.read()
actual = error_log.split('\n')
diff --git a/tests/modeltests/model_forms/tests.py b/tests/modeltests/model_forms/tests.py
index 038ce32287..947d0cf3c3 100644
--- a/tests/modeltests/model_forms/tests.py
+++ b/tests/modeltests/model_forms/tests.py
@@ -8,6 +8,7 @@ from django import forms
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.validators import ValidationError
from django.db import connection
+from django.db.models.query import EmptyQuerySet
from django.forms.models import model_to_dict
from django.utils.unittest import skipUnless
from django.test import TestCase
@@ -1035,8 +1036,8 @@ class OldFormForXTests(TestCase):
f.clean([c6.id])
f = forms.ModelMultipleChoiceField(Category.objects.all(), required=False)
- self.assertEqual(f.clean([]), [])
- self.assertEqual(f.clean(()), [])
+ self.assertIsInstance(f.clean([]), EmptyQuerySet)
+ self.assertIsInstance(f.clean(()), EmptyQuerySet)
with self.assertRaises(ValidationError):
f.clean(['10'])
with self.assertRaises(ValidationError):
diff --git a/tests/modeltests/proxy_models/tests.py b/tests/modeltests/proxy_models/tests.py
index 7ec86e9b22..d1c95467ee 100644
--- a/tests/modeltests/proxy_models/tests.py
+++ b/tests/modeltests/proxy_models/tests.py
@@ -1,10 +1,13 @@
from __future__ import absolute_import, unicode_literals
+import copy
+from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core import management
from django.core.exceptions import FieldError
from django.db import models, DEFAULT_DB_ALIAS
from django.db.models import signals
+from django.db.models.loading import cache
from django.test import TestCase
@@ -13,6 +16,7 @@ from .models import (MyPerson, Person, StatusPerson, LowerStatusPerson,
Country, State, StateProxy, TrackerUser, BaseUser, Bug, ProxyTrackerUser,
Improvement, ProxyProxyBug, ProxyBug, ProxyImprovement)
+
class ProxyModelTests(TestCase):
def test_same_manager_queries(self):
"""
@@ -91,7 +95,7 @@ class ProxyModelTests(TestCase):
)
self.assertRaises(Person.MultipleObjectsReturned,
MyPersonProxy.objects.get,
- id__lt=max_id+1
+ id__lt=max_id + 1
)
self.assertRaises(Person.DoesNotExist,
StatusPerson.objects.get,
@@ -104,7 +108,7 @@ class ProxyModelTests(TestCase):
self.assertRaises(Person.MultipleObjectsReturned,
StatusPerson.objects.get,
- id__lt=max_id+1
+ id__lt=max_id + 1
)
def test_abc(self):
@@ -138,10 +142,40 @@ class ProxyModelTests(TestCase):
def build_new_fields():
class NoNewFields(Person):
newfield = models.BooleanField()
+
class Meta:
proxy = True
self.assertRaises(FieldError, build_new_fields)
+ def test_swappable(self):
+ try:
+ # This test adds dummy applications to the app cache. These
+ # need to be removed in order to prevent bad interactions
+ # with the flush operation in other tests.
+ old_app_models = copy.deepcopy(cache.app_models)
+ old_app_store = copy.deepcopy(cache.app_store)
+
+ settings.TEST_SWAPPABLE_MODEL = 'proxy_models.AlternateModel'
+
+ class SwappableModel(models.Model):
+
+ class Meta:
+ swappable = 'TEST_SWAPPABLE_MODEL'
+
+ class AlternateModel(models.Model):
+ pass
+
+ # You can't proxy a swapped model
+ with self.assertRaises(TypeError):
+ class ProxyModel(SwappableModel):
+
+ class Meta:
+ proxy = True
+ finally:
+ del settings.TEST_SWAPPABLE_MODEL
+ cache.app_models = old_app_models
+ cache.app_store = old_app_store
+
def test_myperson_manager(self):
Person.objects.create(name="fred")
Person.objects.create(name="wilma")
diff --git a/tests/modeltests/test_client/models.py b/tests/modeltests/test_client/models.py
index 1d9c999f21..0f3cba7e88 100644
--- a/tests/modeltests/test_client/models.py
+++ b/tests/modeltests/test_client/models.py
@@ -215,7 +215,7 @@ class ClientTest(TestCase):
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "Invalid POST Template")
- self.assertFormError(response, 'form', 'email', 'Enter a valid e-mail address.')
+ self.assertFormError(response, 'form', 'email', 'Enter a valid email address.')
def test_valid_form_with_template(self):
"POST valid data to a form using multiple templates"
@@ -263,7 +263,7 @@ class ClientTest(TestCase):
self.assertTemplateUsed(response, 'base.html')
self.assertTemplateNotUsed(response, "Invalid POST Template")
- self.assertFormError(response, 'form', 'email', 'Enter a valid e-mail address.')
+ self.assertFormError(response, 'form', 'email', 'Enter a valid email address.')
def test_unknown_page(self):
"GET an invalid URL"
diff --git a/tests/modeltests/timezones/tests.py b/tests/modeltests/timezones/tests.py
index 4621f0a60c..2fdf6733a0 100644
--- a/tests/modeltests/timezones/tests.py
+++ b/tests/modeltests/timezones/tests.py
@@ -5,6 +5,7 @@ import os
import sys
import time
import warnings
+from xml.dom.minidom import parseString
try:
import pytz
@@ -492,27 +493,40 @@ class SerializationTests(TestCase):
# returns a naive datetime object in UTC (http://pyyaml.org/ticket/202).
# Tests are adapted to take these quirks into account.
+ def assert_python_contains_datetime(self, objects, dt):
+ self.assertEqual(objects[0]['fields']['dt'], dt)
+
+ def assert_json_contains_datetime(self, json, dt):
+ self.assertIn('"fields": {"dt": "%s"}' % dt, json)
+
+ def assert_xml_contains_datetime(self, xml, dt):
+ field = parseString(xml).getElementsByTagName('field')[0]
+ self.assertXMLEqual(field.childNodes[0].wholeText, dt)
+
+ def assert_yaml_contains_datetime(self, yaml, dt):
+ self.assertIn("- fields: {dt: !!timestamp '%s'}" % dt, yaml)
+
def test_naive_datetime(self):
dt = datetime.datetime(2011, 9, 1, 13, 20, 30)
data = serializers.serialize('python', [Event(dt=dt)])
- self.assertEqual(data[0]['fields']['dt'], dt)
+ self.assert_python_contains_datetime(data, dt)
obj = next(serializers.deserialize('python', data)).object
self.assertEqual(obj.dt, dt)
data = serializers.serialize('json', [Event(dt=dt)])
- self.assertIn('"fields": {"dt": "2011-09-01T13:20:30"}', data)
+ self.assert_json_contains_datetime(data, "2011-09-01T13:20:30")
obj = next(serializers.deserialize('json', data)).object
self.assertEqual(obj.dt, dt)
data = serializers.serialize('xml', [Event(dt=dt)])
- self.assertIn('<field type="DateTimeField" name="dt">2011-09-01T13:20:30</field>', data)
+ self.assert_xml_contains_datetime(data, "2011-09-01T13:20:30")
obj = next(serializers.deserialize('xml', data)).object
self.assertEqual(obj.dt, dt)
if 'yaml' in serializers.get_serializer_formats():
data = serializers.serialize('yaml', [Event(dt=dt)])
- self.assertIn("- fields: {dt: !!timestamp '2011-09-01 13:20:30'}", data)
+ self.assert_yaml_contains_datetime(data, "2011-09-01 13:20:30")
obj = next(serializers.deserialize('yaml', data)).object
self.assertEqual(obj.dt, dt)
@@ -520,23 +534,23 @@ class SerializationTests(TestCase):
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, 405060)
data = serializers.serialize('python', [Event(dt=dt)])
- self.assertEqual(data[0]['fields']['dt'], dt)
+ self.assert_python_contains_datetime(data, dt)
obj = next(serializers.deserialize('python', data)).object
self.assertEqual(obj.dt, dt)
data = serializers.serialize('json', [Event(dt=dt)])
- self.assertIn('"fields": {"dt": "2011-09-01T13:20:30.405"}', data)
+ self.assert_json_contains_datetime(data, "2011-09-01T13:20:30.405")
obj = next(serializers.deserialize('json', data)).object
self.assertEqual(obj.dt, dt.replace(microsecond=405000))
data = serializers.serialize('xml', [Event(dt=dt)])
- self.assertIn('<field type="DateTimeField" name="dt">2011-09-01T13:20:30.405060</field>', data)
+ self.assert_xml_contains_datetime(data, "2011-09-01T13:20:30.405060")
obj = next(serializers.deserialize('xml', data)).object
self.assertEqual(obj.dt, dt)
if 'yaml' in serializers.get_serializer_formats():
data = serializers.serialize('yaml', [Event(dt=dt)])
- self.assertIn("- fields: {dt: !!timestamp '2011-09-01 13:20:30.405060'}", data)
+ self.assert_yaml_contains_datetime(data, "2011-09-01 13:20:30.405060")
obj = next(serializers.deserialize('yaml', data)).object
self.assertEqual(obj.dt, dt)
@@ -544,23 +558,23 @@ class SerializationTests(TestCase):
dt = datetime.datetime(2011, 9, 1, 17, 20, 30, 405060, tzinfo=ICT)
data = serializers.serialize('python', [Event(dt=dt)])
- self.assertEqual(data[0]['fields']['dt'], dt)
+ self.assert_python_contains_datetime(data, dt)
obj = next(serializers.deserialize('python', data)).object
self.assertEqual(obj.dt, dt)
data = serializers.serialize('json', [Event(dt=dt)])
- self.assertIn('"fields": {"dt": "2011-09-01T17:20:30.405+07:00"}', data)
+ self.assert_json_contains_datetime(data, "2011-09-01T17:20:30.405+07:00")
obj = next(serializers.deserialize('json', data)).object
self.assertEqual(obj.dt, dt.replace(microsecond=405000))
data = serializers.serialize('xml', [Event(dt=dt)])
- self.assertIn('<field type="DateTimeField" name="dt">2011-09-01T17:20:30.405060+07:00</field>', data)
+ self.assert_xml_contains_datetime(data, "2011-09-01T17:20:30.405060+07:00")
obj = next(serializers.deserialize('xml', data)).object
self.assertEqual(obj.dt, dt)
if 'yaml' in serializers.get_serializer_formats():
data = serializers.serialize('yaml', [Event(dt=dt)])
- self.assertIn("- fields: {dt: !!timestamp '2011-09-01 17:20:30.405060+07:00'}", data)
+ self.assert_yaml_contains_datetime(data, "2011-09-01 17:20:30.405060+07:00")
obj = next(serializers.deserialize('yaml', data)).object
self.assertEqual(obj.dt.replace(tzinfo=UTC), dt)
@@ -568,23 +582,23 @@ class SerializationTests(TestCase):
dt = datetime.datetime(2011, 9, 1, 10, 20, 30, tzinfo=UTC)
data = serializers.serialize('python', [Event(dt=dt)])
- self.assertEqual(data[0]['fields']['dt'], dt)
+ self.assert_python_contains_datetime(data, dt)
obj = next(serializers.deserialize('python', data)).object
self.assertEqual(obj.dt, dt)
data = serializers.serialize('json', [Event(dt=dt)])
- self.assertIn('"fields": {"dt": "2011-09-01T10:20:30Z"}', data)
+ self.assert_json_contains_datetime(data, "2011-09-01T10:20:30Z")
obj = next(serializers.deserialize('json', data)).object
self.assertEqual(obj.dt, dt)
data = serializers.serialize('xml', [Event(dt=dt)])
- self.assertIn('<field type="DateTimeField" name="dt">2011-09-01T10:20:30+00:00</field>', data)
+ self.assert_xml_contains_datetime(data, "2011-09-01T10:20:30+00:00")
obj = next(serializers.deserialize('xml', data)).object
self.assertEqual(obj.dt, dt)
if 'yaml' in serializers.get_serializer_formats():
data = serializers.serialize('yaml', [Event(dt=dt)])
- self.assertIn("- fields: {dt: !!timestamp '2011-09-01 10:20:30+00:00'}", data)
+ self.assert_yaml_contains_datetime(data, "2011-09-01 10:20:30+00:00")
obj = next(serializers.deserialize('yaml', data)).object
self.assertEqual(obj.dt.replace(tzinfo=UTC), dt)
@@ -592,23 +606,23 @@ class SerializationTests(TestCase):
dt = datetime.datetime(2011, 9, 1, 13, 20, 30, tzinfo=EAT)
data = serializers.serialize('python', [Event(dt=dt)])
- self.assertEqual(data[0]['fields']['dt'], dt)
+ self.assert_python_contains_datetime(data, dt)
obj = next(serializers.deserialize('python', data)).object
self.assertEqual(obj.dt, dt)
data = serializers.serialize('json', [Event(dt=dt)])
- self.assertIn('"fields": {"dt": "2011-09-01T13:20:30+03:00"}', data)
+ self.assert_json_contains_datetime(data, "2011-09-01T13:20:30+03:00")
obj = next(serializers.deserialize('json', data)).object
self.assertEqual(obj.dt, dt)
data = serializers.serialize('xml', [Event(dt=dt)])
- self.assertIn('<field type="DateTimeField" name="dt">2011-09-01T13:20:30+03:00</field>', data)
+ self.assert_xml_contains_datetime(data, "2011-09-01T13:20:30+03:00")
obj = next(serializers.deserialize('xml', data)).object
self.assertEqual(obj.dt, dt)
if 'yaml' in serializers.get_serializer_formats():
data = serializers.serialize('yaml', [Event(dt=dt)])
- self.assertIn("- fields: {dt: !!timestamp '2011-09-01 13:20:30+03:00'}", data)
+ self.assert_yaml_contains_datetime(data, "2011-09-01 13:20:30+03:00")
obj = next(serializers.deserialize('yaml', data)).object
self.assertEqual(obj.dt.replace(tzinfo=UTC), dt)
@@ -616,23 +630,23 @@ class SerializationTests(TestCase):
dt = datetime.datetime(2011, 9, 1, 17, 20, 30, tzinfo=ICT)
data = serializers.serialize('python', [Event(dt=dt)])
- self.assertEqual(data[0]['fields']['dt'], dt)
+ self.assert_python_contains_datetime(data, dt)
obj = next(serializers.deserialize('python', data)).object
self.assertEqual(obj.dt, dt)
data = serializers.serialize('json', [Event(dt=dt)])
- self.assertIn('"fields": {"dt": "2011-09-01T17:20:30+07:00"}', data)
+ self.assert_json_contains_datetime(data, "2011-09-01T17:20:30+07:00")
obj = next(serializers.deserialize('json', data)).object
self.assertEqual(obj.dt, dt)
data = serializers.serialize('xml', [Event(dt=dt)])
- self.assertIn('<field type="DateTimeField" name="dt">2011-09-01T17:20:30+07:00</field>', data)
+ self.assert_xml_contains_datetime(data, "2011-09-01T17:20:30+07:00")
obj = next(serializers.deserialize('xml', data)).object
self.assertEqual(obj.dt, dt)
if 'yaml' in serializers.get_serializer_formats():
data = serializers.serialize('yaml', [Event(dt=dt)])
- self.assertIn("- fields: {dt: !!timestamp '2011-09-01 17:20:30+07:00'}", data)
+ self.assert_yaml_contains_datetime(data, "2011-09-01 17:20:30+07:00")
obj = next(serializers.deserialize('yaml', data)).object
self.assertEqual(obj.dt.replace(tzinfo=UTC), dt)
diff --git a/tests/modeltests/validators/tests.py b/tests/modeltests/validators/tests.py
index 018be6ae59..0174a606df 100644
--- a/tests/modeltests/validators/tests.py
+++ b/tests/modeltests/validators/tests.py
@@ -26,13 +26,23 @@ TEST_DATA = (
(validate_email, 'email@here.com', None),
(validate_email, 'weirder-email@here.and.there.com', None),
(validate_email, 'email@[127.0.0.1]', None),
+ (validate_email, 'example@valid-----hyphens.com', None),
+ (validate_email, 'example@valid-with-hyphens.com', None),
+ (validate_email, 'test@domain.with.idn.tld.उदाहरण.परीक्षा', None),
(validate_email, None, ValidationError),
(validate_email, '', ValidationError),
(validate_email, 'abc', ValidationError),
+ (validate_email, 'abc@', ValidationError),
+ (validate_email, 'abc@bar', ValidationError),
(validate_email, 'a @x.cz', ValidationError),
+ (validate_email, 'abc@.com', ValidationError),
(validate_email, 'something@@somewhere.com', ValidationError),
(validate_email, 'email@127.0.0.1', ValidationError),
+ (validate_email, 'example@invalid-.com', ValidationError),
+ (validate_email, 'example@-invalid.com', ValidationError),
+ (validate_email, 'example@inv-.alid-.com', ValidationError),
+ (validate_email, 'example@inv-.-alid.com', ValidationError),
# Quoted-string format (CR not allowed)
(validate_email, '"\\\011"@here.com', None),
(validate_email, '"\\\012"@here.com', ValidationError),
@@ -162,11 +172,23 @@ def create_simple_test_method(validator, expected, value, num):
if expected is not None and issubclass(expected, Exception):
test_mask = 'test_%s_raises_error_%d'
def test_func(self):
- self.assertRaises(expected, validator, value)
+ # assertRaises not used, so as to be able to produce an error message
+ # containing the tested value
+ try:
+ validator(value)
+ except expected:
+ pass
+ else:
+ self.fail("%s not raised when validating '%s'" % (
+ expected.__name__, value))
else:
test_mask = 'test_%s_%d'
def test_func(self):
- self.assertEqual(expected, validator(value))
+ try:
+ self.assertEqual(expected, validator(value))
+ except ValidationError as e:
+ self.fail("Validation of '%s' failed. Error message was: %s" % (
+ value, str(e)))
if isinstance(validator, types.FunctionType):
val_name = validator.__name__
else:
diff --git a/tests/regressiontests/admin_changelist/tests.py b/tests/regressiontests/admin_changelist/tests.py
index be88c9a161..2b1c1a9bcf 100644
--- a/tests/regressiontests/admin_changelist/tests.py
+++ b/tests/regressiontests/admin_changelist/tests.py
@@ -6,6 +6,7 @@ from django.contrib import admin
from django.contrib.admin.options import IncorrectLookupParameters
from django.contrib.admin.views.main import ChangeList, SEARCH_VAR, ALL_VAR
from django.contrib.auth.models import User
+from django.core.urlresolvers import reverse
from django.template import Context, Template
from django.test import TestCase
from django.test.client import RequestFactory
@@ -65,7 +66,8 @@ class ChangeListTests(TestCase):
template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
context = Context({'cl': cl})
table_output = template.render(context)
- row_html = '<tbody><tr class="row1"><th><a href="%d/">name</a></th><td class="nowrap">(None)</td></tr></tbody>' % new_child.id
+ link = reverse('admin:admin_changelist_child_change', args=(new_child.id,))
+ row_html = '<tbody><tr class="row1"><th><a href="%s">name</a></th><td class="nowrap">(None)</td></tr></tbody>' % link
self.assertFalse(table_output.find(row_html) == -1,
'Failed to find expected row element: %s' % table_output)
@@ -87,7 +89,8 @@ class ChangeListTests(TestCase):
template = Template('{% load admin_list %}{% spaceless %}{% result_list cl %}{% endspaceless %}')
context = Context({'cl': cl})
table_output = template.render(context)
- row_html = '<tbody><tr class="row1"><th><a href="%d/">name</a></th><td class="nowrap">Parent object</td></tr></tbody>' % new_child.id
+ link = reverse('admin:admin_changelist_child_change', args=(new_child.id,))
+ row_html = '<tbody><tr class="row1"><th><a href="%s">name</a></th><td class="nowrap">Parent object</td></tr></tbody>' % link
self.assertFalse(table_output.find(row_html) == -1,
'Failed to find expected row element: %s' % table_output)
@@ -425,7 +428,8 @@ class ChangeListTests(TestCase):
request = self._mocked_authenticated_request('/child/', superuser)
response = m.changelist_view(request)
for i in range(1, 10):
- self.assertContains(response, '<a href="%s/">%s</a>' % (i, i))
+ link = reverse('admin:admin_changelist_child_change', args=(i,))
+ self.assertContains(response, '<a href="%s">%s</a>' % (link, i))
list_display = m.get_list_display(request)
list_display_links = m.get_list_display_links(request, list_display)
diff --git a/tests/regressiontests/admin_custom_urls/fixtures/actions.json b/tests/regressiontests/admin_custom_urls/fixtures/actions.json
index a63cf8135c..7c6341d71d 100644
--- a/tests/regressiontests/admin_custom_urls/fixtures/actions.json
+++ b/tests/regressiontests/admin_custom_urls/fixtures/actions.json
@@ -40,12 +40,5 @@
"fields": {
"description": "An action with a name suspected of being a XSS attempt"
}
- },
- {
- "pk": "The name of an action",
- "model": "admin_custom_urls.action",
- "fields": {
- "description": "A generic action"
- }
}
]
diff --git a/tests/regressiontests/admin_custom_urls/models.py b/tests/regressiontests/admin_custom_urls/models.py
index a5b4983b09..b9b3285463 100644
--- a/tests/regressiontests/admin_custom_urls/models.py
+++ b/tests/regressiontests/admin_custom_urls/models.py
@@ -50,3 +50,40 @@ class ActionAdmin(admin.ModelAdmin):
admin.site.register(Action, ActionAdmin)
+
+
+class Person(models.Model):
+ nick = models.CharField(max_length=20)
+
+
+class PersonAdmin(admin.ModelAdmin):
+ """A custom ModelAdmin that customizes the deprecated post_url_continue
+ argument to response_add()"""
+ def response_add(self, request, obj, post_url_continue='../%s/continue/',
+ continue_url=None, add_url=None, hasperm_url=None,
+ noperm_url=None):
+ return super(PersonAdmin, self).response_add(request, obj,
+ post_url_continue,
+ continue_url, add_url,
+ hasperm_url, noperm_url)
+
+
+admin.site.register(Person, PersonAdmin)
+
+
+class City(models.Model):
+ name = models.CharField(max_length=20)
+
+
+class CityAdmin(admin.ModelAdmin):
+ """A custom ModelAdmin that redirects to the changelist when the user
+ presses the 'Save and add another' button when adding a model instance."""
+ def response_add(self, request, obj,
+ add_another_url='admin:admin_custom_urls_city_changelist',
+ **kwargs):
+ return super(CityAdmin, self).response_add(request, obj,
+ add_another_url=add_another_url,
+ **kwargs)
+
+
+admin.site.register(City, CityAdmin)
diff --git a/tests/regressiontests/admin_custom_urls/tests.py b/tests/regressiontests/admin_custom_urls/tests.py
index 64ff9f6692..87c72e2e71 100644
--- a/tests/regressiontests/admin_custom_urls/tests.py
+++ b/tests/regressiontests/admin_custom_urls/tests.py
@@ -1,11 +1,14 @@
from __future__ import absolute_import, unicode_literals
+import warnings
+
+from django.contrib.admin.util import quote
from django.core.urlresolvers import reverse
from django.template.response import TemplateResponse
from django.test import TestCase
from django.test.utils import override_settings
-from .models import Action
+from .models import Action, Person, City
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
@@ -67,7 +70,7 @@ class AdminCustomUrlsTest(TestCase):
# Ditto, but use reverse() to build the URL
url = reverse('admin:%s_action_change' % Action._meta.app_label,
- args=('add',))
+ args=(quote('add'),))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Change action')
@@ -75,19 +78,50 @@ class AdminCustomUrlsTest(TestCase):
# Should correctly get the change_view for the model instance with the
# funny-looking PK (the one wth a 'path/to/html/document.html' value)
url = reverse('admin:%s_action_change' % Action._meta.app_label,
- args=("path/to/html/document.html",))
+ args=(quote("path/to/html/document.html"),))
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Change action')
self.assertContains(response, 'value="path/to/html/document.html"')
- def testChangeViewHistoryButton(self):
- url = reverse('admin:%s_action_change' % Action._meta.app_label,
- args=('The name of an action',))
- response = self.client.get(url)
- self.assertEqual(response.status_code, 200)
- expected_link = reverse('admin:%s_action_history' %
- Action._meta.app_label,
- args=('The name of an action',))
- self.assertContains(response, '<a href="%s" class="historylink"' %
- expected_link)
+
+@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
+class CustomUrlsWorkflowTests(TestCase):
+ fixtures = ['users.json']
+
+ def setUp(self):
+ self.client.login(username='super', password='secret')
+
+ def tearDown(self):
+ self.client.logout()
+
+ def test_old_argument_deprecation(self):
+ """Test reporting of post_url_continue deprecation."""
+ post_data = {
+ 'nick': 'johndoe',
+ }
+ cnt = Person.objects.count()
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter("always")
+ response = self.client.post(reverse('admin:admin_custom_urls_person_add'), post_data)
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(Person.objects.count(), cnt + 1)
+ # We should get a DeprecationWarning
+ self.assertEqual(len(w), 1)
+ self.assertTrue(isinstance(w[0].message, DeprecationWarning))
+
+ def test_custom_add_another_redirect(self):
+ """Test customizability of post-object-creation redirect URL."""
+ post_data = {
+ 'name': 'Rome',
+ '_addanother': '1',
+ }
+ cnt = City.objects.count()
+ with warnings.catch_warnings(record=True) as w:
+ # POST to the view whose post-object-creation redir URL argument we
+ # are customizing (object creation)
+ response = self.client.post(reverse('admin:admin_custom_urls_city_add'), post_data)
+ self.assertEqual(City.objects.count(), cnt + 1)
+ # Check that it redirected to the URL we set
+ self.assertRedirects(response, reverse('admin:admin_custom_urls_city_changelist'))
+ self.assertEqual(len(w), 0) # We should get no DeprecationWarning
diff --git a/tests/regressiontests/admin_inlines/models.py b/tests/regressiontests/admin_inlines/models.py
index 5b703a7481..b004d5f85a 100644
--- a/tests/regressiontests/admin_inlines/models.py
+++ b/tests/regressiontests/admin_inlines/models.py
@@ -57,6 +57,9 @@ class Inner(models.Model):
holder = models.ForeignKey(Holder)
readonly = models.CharField("Inner readonly label", max_length=1)
+ def get_absolute_url(self):
+ return '/inner/'
+
class Holder2(models.Model):
dummy = models.IntegerField()
diff --git a/tests/regressiontests/admin_inlines/tests.py b/tests/regressiontests/admin_inlines/tests.py
index 57f45ab0ff..5bb6077bff 100644
--- a/tests/regressiontests/admin_inlines/tests.py
+++ b/tests/regressiontests/admin_inlines/tests.py
@@ -148,6 +148,18 @@ class TestInline(TestCase):
'<input id="id_-2-0-name" type="text" class="vTextField" '
'name="-2-0-name" maxlength="100" />', html=True)
+ @override_settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True)
+ def test_localize_pk_shortcut(self):
+ """
+ Ensure that the "View on Site" link is correct for locales that use
+ thousand separators
+ """
+ holder = Holder.objects.create(pk=123456789, dummy=42)
+ inner = Inner.objects.create(pk=987654321, holder=holder, dummy=42, readonly='')
+ response = self.client.get('/admin/admin_inlines/holder/%i/' % holder.id)
+ inner_shortcut = 'r/%s/%s/'%(ContentType.objects.get_for_model(inner).pk, inner.pk)
+ self.assertContains(response, inner_shortcut)
+
def test_custom_pk_shortcut(self):
"""
Ensure that the "View on Site" link is correct for models with a
diff --git a/tests/regressiontests/admin_scripts/tests.py b/tests/regressiontests/admin_scripts/tests.py
index 6028eac846..3bb8bb0b50 100644
--- a/tests/regressiontests/admin_scripts/tests.py
+++ b/tests/regressiontests/admin_scripts/tests.py
@@ -982,13 +982,11 @@ class ManageMultipleSettings(AdminScriptTestCase):
self.assertNoOutput(err)
self.assertOutput(out, "EXECUTE:NoArgsCommand")
+
class ManageSettingsWithImportError(AdminScriptTestCase):
"""Tests for manage.py when using the default settings.py file
with an import error. Ticket #14130.
"""
- def setUp(self):
- self.write_settings_with_import_error('settings.py')
-
def tearDown(self):
self.remove_settings('settings.py')
@@ -1004,11 +1002,27 @@ class ManageSettingsWithImportError(AdminScriptTestCase):
settings_file.write('# The next line will cause an import error:\nimport foo42bar\n')
def test_builtin_command(self):
- "import error: manage.py builtin commands shows useful diagnostic info when settings with import errors is provided"
+ """
+ import error: manage.py builtin commands shows useful diagnostic info
+ when settings with import errors is provided
+ """
+ self.write_settings_with_import_error('settings.py')
args = ['sqlall', 'admin_scripts']
out, err = self.run_manage(args)
self.assertNoOutput(out)
- self.assertOutput(err, "No module named foo42bar")
+ self.assertOutput(err, "No module named")
+ self.assertOutput(err, "foo42bar")
+
+ def test_builtin_command_with_attribute_error(self):
+ """
+ manage.py builtin commands does not swallow attribute errors from bad settings (#18845)
+ """
+ self.write_settings('settings.py', sdict={'BAD_VAR': 'INSTALLED_APPS.crash'})
+ args = ['collectstatic', 'admin_scripts']
+ out, err = self.run_manage(args)
+ self.assertNoOutput(out)
+ self.assertOutput(err, "AttributeError: 'list' object has no attribute 'crash'")
+
class ManageValidate(AdminScriptTestCase):
def tearDown(self):
@@ -1020,7 +1034,8 @@ class ManageValidate(AdminScriptTestCase):
args = ['validate']
out, err = self.run_manage(args)
self.assertNoOutput(out)
- self.assertOutput(err, 'No module named admin_scriptz')
+ self.assertOutput(err, 'No module named')
+ self.assertOutput(err, 'admin_scriptz')
def test_broken_app(self):
"manage.py validate reports an ImportError if an app's models.py raises one on import"
@@ -1590,3 +1605,15 @@ class StartProject(LiveServerTestCase, AdminScriptTestCase):
with codecs.open(path, 'r', 'utf-8') as f:
self.assertEqual(f.read(),
'Some non-ASCII text for testing ticket #18091:\nüäö €\n')
+
+
+class DiffSettings(AdminScriptTestCase):
+ """Tests for diffsettings management command."""
+ def test_basic(self):
+ "Runs without error and emits settings diff."
+ self.write_settings('settings_to_diff.py', sdict={'FOO': '"bar"'})
+ args = ['diffsettings', '--settings=settings_to_diff']
+ out, err = self.run_manage(args)
+ self.remove_settings('settings_to_diff.py')
+ self.assertNoOutput(err)
+ self.assertOutput(out, "FOO = 'bar' ###")
diff --git a/tests/regressiontests/admin_util/models.py b/tests/regressiontests/admin_util/models.py
index b3504a1fa4..32a6cd6291 100644
--- a/tests/regressiontests/admin_util/models.py
+++ b/tests/regressiontests/admin_util/models.py
@@ -39,3 +39,6 @@ class Guest(models.Model):
class Meta:
verbose_name = "awesome guest"
+
+class EventGuide(models.Model):
+ event = models.ForeignKey(Event, on_delete=models.DO_NOTHING)
diff --git a/tests/regressiontests/admin_util/tests.py b/tests/regressiontests/admin_util/tests.py
index d04740ce95..ef8a91d1db 100644
--- a/tests/regressiontests/admin_util/tests.py
+++ b/tests/regressiontests/admin_util/tests.py
@@ -17,7 +17,7 @@ from django.utils.formats import localize
from django.utils.safestring import mark_safe
from django.utils import six
-from .models import Article, Count, Event, Location
+from .models import Article, Count, Event, Location, EventGuide
class NestedObjectsTests(TestCase):
@@ -71,6 +71,17 @@ class NestedObjectsTests(TestCase):
# Should not require additional queries to populate the nested graph.
self.assertNumQueries(2, self._collect, 0)
+ def test_on_delete_do_nothing(self):
+ """
+ Check that the nested collector doesn't query for DO_NOTHING objects.
+ """
+ n = NestedObjects(using=DEFAULT_DB_ALIAS)
+ objs = [Event.objects.create()]
+ EventGuide.objects.create(event=objs[0])
+ with self.assertNumQueries(2):
+ # One for Location, one for Guest, and no query for EventGuide
+ n.collect(objs)
+
class UtilTests(unittest.TestCase):
def test_values_from_lookup_field(self):
"""
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
index 36fea59f2e..72dc6a3f97 100644
--- a/tests/regressiontests/admin_views/tests.py
+++ b/tests/regressiontests/admin_views/tests.py
@@ -52,6 +52,7 @@ from .models import (Article, BarAccount, CustomArticle, EmptyModel, FooAccount,
ERROR_MESSAGE = "Please enter the correct username and password \
for a staff account. Note that both fields are case-sensitive."
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminViewBasicTest(TestCase):
fixtures = ['admin-views-users.xml', 'admin-views-colors.xml',
@@ -141,7 +142,7 @@ class AdminViewBasicTest(TestCase):
"article_set-MAX_NUM_FORMS": "0",
}
response = self.client.post('/test_admin/%s/admin_views/section/add/' % self.urlbit, post_data)
- self.assertEqual(response.status_code, 302) # redirect somewhere
+ self.assertEqual(response.status_code, 302) # redirect somewhere
def testPopupAddPost(self):
"""
@@ -205,7 +206,7 @@ class AdminViewBasicTest(TestCase):
A smoke test to ensure POST on edit_view works.
"""
response = self.client.post('/test_admin/%s/admin_views/section/1/' % self.urlbit, self.inline_post_data)
- self.assertEqual(response.status_code, 302) # redirect somewhere
+ self.assertEqual(response.status_code, 302) # redirect somewhere
def testEditSaveAs(self):
"""
@@ -221,7 +222,7 @@ class AdminViewBasicTest(TestCase):
"article_set-5-section": "1",
})
response = self.client.post('/test_admin/%s/admin_views/section/1/' % self.urlbit, post_data)
- self.assertEqual(response.status_code, 302) # redirect somewhere
+ self.assertEqual(response.status_code, 302) # redirect somewhere
def testChangeListSortingCallable(self):
"""
@@ -260,19 +261,21 @@ class AdminViewBasicTest(TestCase):
p1 = Person.objects.create(name="Chris", gender=1, alive=True)
p2 = Person.objects.create(name="Chris", gender=2, alive=True)
p3 = Person.objects.create(name="Bob", gender=1, alive=True)
- link = '<a href="%s/'
+ link1 = reverse('admin:admin_views_person_change', args=(p1.pk,))
+ link2 = reverse('admin:admin_views_person_change', args=(p2.pk,))
+ link3 = reverse('admin:admin_views_person_change', args=(p3.pk,))
# Sort by name, gender
# This hard-codes the URL because it'll fail if it runs against the
# 'admin2' custom admin (which doesn't have the Person model).
response = self.client.get('/test_admin/admin/admin_views/person/', {'o': '1.2'})
- self.assertContentBefore(response, link % p3.id, link % p1.id)
- self.assertContentBefore(response, link % p1.id, link % p2.id)
+ self.assertContentBefore(response, link3, link1)
+ self.assertContentBefore(response, link1, link2)
# Sort by gender descending, name
response = self.client.get('/test_admin/admin/admin_views/person/', {'o': '-2.1'})
- self.assertContentBefore(response, link % p2.id, link % p3.id)
- self.assertContentBefore(response, link % p3.id, link % p1.id)
+ self.assertContentBefore(response, link2, link3)
+ self.assertContentBefore(response, link3, link1)
def testChangeListSortingPreserveQuerySetOrdering(self):
"""
@@ -284,37 +287,41 @@ class AdminViewBasicTest(TestCase):
p1 = Person.objects.create(name="Amy", gender=1, alive=True, age=80)
p2 = Person.objects.create(name="Bob", gender=1, alive=True, age=70)
p3 = Person.objects.create(name="Chris", gender=2, alive=False, age=60)
- link = '<a href="%s/'
+ link1 = reverse('admin:admin_views_person_change', args=(p1.pk,))
+ link2 = reverse('admin:admin_views_person_change', args=(p2.pk,))
+ link3 = reverse('admin:admin_views_person_change', args=(p3.pk,))
# This hard-codes the URL because it'll fail if it runs against the
# 'admin2' custom admin (which doesn't have the Person model).
response = self.client.get('/test_admin/admin/admin_views/person/', {})
- self.assertContentBefore(response, link % p3.id, link % p2.id)
- self.assertContentBefore(response, link % p2.id, link % p1.id)
+ self.assertContentBefore(response, link3, link2)
+ self.assertContentBefore(response, link2, link1)
def testChangeListSortingModelMeta(self):
# Test ordering on Model Meta is respected
l1 = Language.objects.create(iso='ur', name='Urdu')
l2 = Language.objects.create(iso='ar', name='Arabic')
- link = '<a href="%s/'
+ link1 = reverse('admin:admin_views_language_change', args=(quote(l1.pk),))
+ link2 = reverse('admin:admin_views_language_change', args=(quote(l2.pk),))
response = self.client.get('/test_admin/admin/admin_views/language/', {})
- self.assertContentBefore(response, link % l2.pk, link % l1.pk)
+ self.assertContentBefore(response, link2, link1)
# Test we can override with query string
- response = self.client.get('/test_admin/admin/admin_views/language/', {'o':'-1'})
- self.assertContentBefore(response, link % l1.pk, link % l2.pk)
+ response = self.client.get('/test_admin/admin/admin_views/language/', {'o': '-1'})
+ self.assertContentBefore(response, link1, link2)
def testChangeListSortingOverrideModelAdmin(self):
# Test ordering on Model Admin is respected, and overrides Model Meta
dt = datetime.datetime.now()
p1 = Podcast.objects.create(name="A", release_date=dt)
p2 = Podcast.objects.create(name="B", release_date=dt - datetime.timedelta(10))
+ link1 = reverse('admin:admin_views_podcast_change', args=(p1.pk,))
+ link2 = reverse('admin:admin_views_podcast_change', args=(p2.pk,))
- link = '<a href="%s/'
response = self.client.get('/test_admin/admin/admin_views/podcast/', {})
- self.assertContentBefore(response, link % p1.pk, link % p2.pk)
+ self.assertContentBefore(response, link1, link2)
def testMultipleSortSameField(self):
# Check that we get the columns we expect if we have two columns
@@ -322,14 +329,16 @@ class AdminViewBasicTest(TestCase):
dt = datetime.datetime.now()
p1 = Podcast.objects.create(name="A", release_date=dt)
p2 = Podcast.objects.create(name="B", release_date=dt - datetime.timedelta(10))
+ link1 = reverse('admin:admin_views_podcast_change', args=(quote(p1.pk),))
+ link2 = reverse('admin:admin_views_podcast_change', args=(quote(p2.pk),))
- link = '<a href="%s/'
response = self.client.get('/test_admin/admin/admin_views/podcast/', {})
- self.assertContentBefore(response, link % p1.pk, link % p2.pk)
+ self.assertContentBefore(response, link1, link2)
p1 = ComplexSortedPerson.objects.create(name="Bob", age=10)
p2 = ComplexSortedPerson.objects.create(name="Amy", age=20)
- link = '<a href="%s/'
+ link1 = reverse('admin:admin_views_complexsortedperson_change', args=(p1.pk,))
+ link2 = reverse('admin:admin_views_complexsortedperson_change', args=(p2.pk,))
response = self.client.get('/test_admin/admin/admin_views/complexsortedperson/', {})
# Should have 5 columns (including action checkbox col)
@@ -342,7 +351,7 @@ class AdminViewBasicTest(TestCase):
self.assertContentBefore(response, 'Name', 'Colored name')
# Check sorting - should be by name
- self.assertContentBefore(response, link % p2.id, link % p1.id)
+ self.assertContentBefore(response, link2, link1)
def testSortIndicatorsAdminOrder(self):
"""
@@ -350,13 +359,13 @@ class AdminViewBasicTest(TestCase):
kinds of 'ordering' fields: field names, method on the model
admin and model itself, and other callables. See #17252.
"""
- models = [(AdminOrderedField, 'adminorderedfield' ),
+ models = [(AdminOrderedField, 'adminorderedfield'),
(AdminOrderedModelMethod, 'adminorderedmodelmethod'),
(AdminOrderedAdminMethod, 'adminorderedadminmethod'),
- (AdminOrderedCallable, 'adminorderedcallable' )]
+ (AdminOrderedCallable, 'adminorderedcallable')]
for model, url in models:
- a1 = model.objects.create(stuff='The Last Item', order=3)
- a2 = model.objects.create(stuff='The First Item', order=1)
+ a1 = model.objects.create(stuff='The Last Item', order=3)
+ a2 = model.objects.create(stuff='The First Item', order=1)
a3 = model.objects.create(stuff='The Middle Item', order=2)
response = self.client.get('/test_admin/admin/admin_views/%s/' % url, {})
self.assertEqual(response.status_code, 200)
@@ -461,10 +470,12 @@ class AdminViewBasicTest(TestCase):
for rows corresponding to instances of a model in which a named group
has been used in the choices option of a field.
"""
+ link1 = reverse('admin:admin_views_fabric_change', args=(1,), current_app=self.urlbit)
+ link2 = reverse('admin:admin_views_fabric_change', args=(2,), current_app=self.urlbit)
response = self.client.get('/test_admin/%s/admin_views/fabric/' % self.urlbit)
fail_msg = "Changelist table isn't showing the right human-readable values set by a model field 'choices' option named group."
- self.assertContains(response, '<a href="1/">Horizontal</a>', msg_prefix=fail_msg, html=True)
- self.assertContains(response, '<a href="2/">Vertical</a>', msg_prefix=fail_msg, html=True)
+ self.assertContains(response, '<a href="%s">Horizontal</a>' % link1, msg_prefix=fail_msg, html=True)
+ self.assertContains(response, '<a href="%s">Vertical</a>' % link2, msg_prefix=fail_msg, html=True)
def testNamedGroupFieldChoicesFilter(self):
"""
@@ -661,7 +672,6 @@ class AdminJavaScriptTest(TestCase):
'<script type="text/javascript">document.getElementById("id_start_date_0").focus();</script>'
)
-
def test_js_minified_only_if_debug_is_false(self):
"""
Ensure that the minified versions of the JS files are only used when
@@ -699,7 +709,7 @@ class AdminJavaScriptTest(TestCase):
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class SaveAsTests(TestCase):
urls = "regressiontests.admin_views.urls"
- fixtures = ['admin-views-users.xml','admin-views-person.xml']
+ fixtures = ['admin-views-users.xml', 'admin-views-person.xml']
def setUp(self):
self.client.login(username='super', password='secret')
@@ -709,7 +719,7 @@ class SaveAsTests(TestCase):
def test_save_as_duplication(self):
"""Ensure save as actually creates a new person"""
- post_data = {'_saveasnew':'', 'name':'John M', 'gender':1, 'age': 42}
+ post_data = {'_saveasnew': '', 'name': 'John M', 'gender': 1, 'age': 42}
response = self.client.post('/test_admin/admin/admin_views/person/1/', post_data)
self.assertEqual(len(Person.objects.filter(name='John M')), 1)
self.assertEqual(len(Person.objects.filter(id=1)), 1)
@@ -722,10 +732,11 @@ class SaveAsTests(TestCase):
"""
response = self.client.get('/test_admin/admin/admin_views/person/1/')
self.assertTrue(response.context['save_as'])
- post_data = {'_saveasnew':'', 'name':'John M', 'gender':3, 'alive':'checked'}
+ post_data = {'_saveasnew': '', 'name': 'John M', 'gender': 3, 'alive': 'checked'}
response = self.client.post('/test_admin/admin/admin_views/person/1/', post_data)
self.assertEqual(response.context['form_url'], '/test_admin/admin/admin_views/person/add/')
+
class CustomModelAdminTest(AdminViewBasicTest):
urls = "regressiontests.admin_views.urls"
urlbit = "admin2"
@@ -781,11 +792,13 @@ class CustomModelAdminTest(AdminViewBasicTest):
response = self.client.get('/test_admin/%s/my_view/' % self.urlbit)
self.assertEqual(response.content, b"Django is a magical pony!")
+
def get_perm(Model, perm):
"""Return the permission object, for the Model"""
ct = ContentType.objects.get_for_model(Model)
return Permission.objects.get(content_type=ct, codename=perm)
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminViewPermissionsTest(TestCase):
"""Tests for Admin Views Permissions."""
@@ -884,17 +897,17 @@ class AdminViewPermissionsTest(TestCase):
self.assertFalse(login.context)
self.client.get('/test_admin/admin/logout/')
- # Test if user enters e-mail address
+ # Test if user enters email address
response = self.client.get('/test_admin/admin/')
self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/', self.super_email_login)
- self.assertContains(login, "Your e-mail address is not your username")
+ self.assertContains(login, ERROR_MESSAGE)
# only correct passwords get a username hint
login = self.client.post('/test_admin/admin/', self.super_email_bad_login)
self.assertContains(login, ERROR_MESSAGE)
new_user = User(username='jondoe', password='secret', email='super@example.com')
new_user.save()
- # check to ensure if there are multiple e-mail addresses a user doesn't get a 500
+ # check to ensure if there are multiple email addresses a user doesn't get a 500
login = self.client.post('/test_admin/admin/', self.super_email_login)
self.assertContains(login, ERROR_MESSAGE)
@@ -949,7 +962,7 @@ class AdminViewPermissionsTest(TestCase):
def testAddView(self):
"""Test add view restricts access and actually adds items."""
- add_dict = {'title' : 'Døm ikke',
+ add_dict = {'title': 'Døm ikke',
'content': '<p>great article</p>',
'date_0': '2008-03-18', 'date_1': '10:54:39',
'section': 1}
@@ -1004,7 +1017,7 @@ class AdminViewPermissionsTest(TestCase):
def testChangeView(self):
"""Change view should restrict access and allow users to edit items."""
- change_dict = {'title' : 'Ikke fordømt',
+ change_dict = {'title': 'Ikke fordømt',
'content': '<p>edited article</p>',
'date_0': '2008-03-18', 'date_1': '10:54:39',
'section': 1}
@@ -1336,6 +1349,7 @@ class AdminViewDeletedObjectsTest(TestCase):
response = self.client.get('/test_admin/admin/admin_views/plot/%s/delete/' % quote(3))
self.assertContains(response, should_contain)
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminViewStringPrimaryKeyTest(TestCase):
urls = "regressiontests.admin_views.urls"
@@ -1371,9 +1385,12 @@ class AdminViewStringPrimaryKeyTest(TestCase):
self.assertEqual(response.status_code, 200)
def test_changelist_to_changeform_link(self):
- "The link from the changelist referring to the changeform of the object should be quoted"
- response = self.client.get('/test_admin/admin/admin_views/modelwithstringprimarykey/')
- should_contain = """<th><a href="%s/">%s</a></th></tr>""" % (escape(quote(self.pk)), escape(self.pk))
+ "Link to the changeform of the object in changelist should use reverse() and be quoted -- #18072"
+ prefix = '/test_admin/admin/admin_views/modelwithstringprimarykey/'
+ response = self.client.get(prefix)
+ # this URL now comes through reverse(), thus iri_to_uri encoding
+ pk_final_url = escape(iri_to_uri(quote(self.pk)))
+ should_contain = """<th><a href="%s%s/">%s</a></th>""" % (prefix, pk_final_url, escape(self.pk))
self.assertContains(response, should_contain)
def test_recentactions_link(self):
@@ -1387,7 +1404,7 @@ class AdminViewStringPrimaryKeyTest(TestCase):
response = self.client.get('/test_admin/admin/')
should_contain = """<a href="admin_views/modelwithstringprimarykey/%s/">%s</a>""" % (escape(quote(self.pk)), escape(self.pk))
self.assertContains(response, should_contain)
- should_contain = "Model with string primary key" # capitalized in Recent Actions
+ should_contain = "Model with string primary key" # capitalized in Recent Actions
self.assertContains(response, should_contain)
logentry = LogEntry.objects.get(content_type__name__iexact=should_contain)
# http://code.djangoproject.com/ticket/10275
@@ -1441,6 +1458,18 @@ class AdminViewStringPrimaryKeyTest(TestCase):
should_contain = '/%s/" class="viewsitelink">' % model.pk
self.assertContains(response, should_contain)
+ def test_change_view_history_link(self):
+ """Object history button link should work and contain the pk value quoted."""
+ url = reverse('admin:%s_modelwithstringprimarykey_change' %
+ ModelWithStringPrimaryKey._meta.app_label,
+ args=(quote(self.pk),))
+ response = self.client.get(url)
+ self.assertEqual(response.status_code, 200)
+ expected_link = reverse('admin:%s_modelwithstringprimarykey_history' %
+ ModelWithStringPrimaryKey._meta.app_label,
+ args=(quote(self.pk),))
+ self.assertContains(response, '<a href="%s" class="historylink"' % expected_link)
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class SecureViewTests(TestCase):
@@ -1497,7 +1526,7 @@ class SecureViewTests(TestCase):
def test_secure_view_shows_login_if_not_logged_in(self):
"Ensure that we see the login form"
- response = self.client.get('/test_admin/admin/secure-view/' )
+ response = self.client.get('/test_admin/admin/secure-view/')
self.assertTemplateUsed(response, 'admin/login.html')
def test_secure_view_login_successfully_redirects_to_original_url(self):
@@ -1527,17 +1556,17 @@ class SecureViewTests(TestCase):
# make sure the view removes test cookie
self.assertEqual(self.client.session.test_cookie_worked(), False)
- # Test if user enters e-mail address
+ # Test if user enters email address
response = self.client.get('/test_admin/admin/secure-view/')
self.assertEqual(response.status_code, 200)
login = self.client.post('/test_admin/admin/secure-view/', self.super_email_login)
- self.assertContains(login, "Your e-mail address is not your username")
+ self.assertContains(login, ERROR_MESSAGE)
# only correct passwords get a username hint
login = self.client.post('/test_admin/admin/secure-view/', self.super_email_bad_login)
self.assertContains(login, ERROR_MESSAGE)
new_user = User(username='jondoe', password='secret', email='super@example.com')
new_user.save()
- # check to ensure if there are multiple e-mail addresses a user doesn't get a 500
+ # check to ensure if there are multiple email addresses a user doesn't get a 500
login = self.client.post('/test_admin/admin/secure-view/', self.super_email_login)
self.assertContains(login, ERROR_MESSAGE)
@@ -1601,6 +1630,7 @@ class SecureViewTests(TestCase):
self.assertEqual(response.status_code, 302)
self.assertEqual(response['Location'], 'http://example.com/users/super/')
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminViewUnicodeTest(TestCase):
urls = "regressiontests.admin_views.urls"
@@ -1643,7 +1673,7 @@ class AdminViewUnicodeTest(TestCase):
}
response = self.client.post('/test_admin/admin/admin_views/book/1/', post_data)
- self.assertEqual(response.status_code, 302) # redirect somewhere
+ self.assertEqual(response.status_code, 302) # redirect somewhere
def testUnicodeDelete(self):
"""
@@ -2010,7 +2040,7 @@ class AdminViewListEditable(TestCase):
story1 = Story.objects.create(title='The adventures of Guido', content='Once upon a time in Djangoland...')
story2 = Story.objects.create(title='Crouching Tiger, Hidden Python', content='The Python was sneaking into...')
response = self.client.get('/test_admin/admin/admin_views/story/')
- self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table.
+ self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table.
self.assertContains(response, 'id="id_form-1-id"', 1)
self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" />\n</div>' % (story2.id, story1.id), html=True)
self.assertContains(response, '<td>%d</td>' % story1.id, 1)
@@ -2023,12 +2053,14 @@ class AdminViewListEditable(TestCase):
"""
story1 = OtherStory.objects.create(title='The adventures of Guido', content='Once upon a time in Djangoland...')
story2 = OtherStory.objects.create(title='Crouching Tiger, Hidden Python', content='The Python was sneaking into...')
+ link1 = reverse('admin:admin_views_otherstory_change', args=(story1.pk,))
+ link2 = reverse('admin:admin_views_otherstory_change', args=(story2.pk,))
response = self.client.get('/test_admin/admin/admin_views/otherstory/')
- self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table.
+ self.assertContains(response, 'id="id_form-0-id"', 1) # Only one hidden field, in a separate place than the table.
self.assertContains(response, 'id="id_form-1-id"', 1)
self.assertContains(response, '<div class="hiddenfields">\n<input type="hidden" name="form-0-id" value="%d" id="id_form-0-id" /><input type="hidden" name="form-1-id" value="%d" id="id_form-1-id" />\n</div>' % (story2.id, story1.id), html=True)
- self.assertContains(response, '<th><a href="%d/">%d</a></th>' % (story1.id, story1.id), 1)
- self.assertContains(response, '<th><a href="%d/">%d</a></th>' % (story2.id, story2.id), 1)
+ self.assertContains(response, '<th><a href="%s">%d</a></th>' % (link1, story1.id), 1)
+ self.assertContains(response, '<th><a href="%s">%d</a></th>' % (link2, story2.id), 1)
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
@@ -2082,7 +2114,7 @@ class AdminSearchTest(TestCase):
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminInheritedInlinesTest(TestCase):
urls = "regressiontests.admin_views.urls"
- fixtures = ['admin-views-users.xml',]
+ fixtures = ['admin-views-users.xml']
def setUp(self):
self.client.login(username='super', password='secret')
@@ -2119,7 +2151,7 @@ class AdminInheritedInlinesTest(TestCase):
}
response = self.client.post('/test_admin/admin/admin_views/persona/add/', post_data)
- self.assertEqual(response.status_code, 302) # redirect somewhere
+ self.assertEqual(response.status_code, 302) # redirect somewhere
self.assertEqual(Persona.objects.count(), 1)
self.assertEqual(FooAccount.objects.count(), 1)
self.assertEqual(BarAccount.objects.count(), 1)
@@ -2166,6 +2198,7 @@ class AdminInheritedInlinesTest(TestCase):
self.assertEqual(BarAccount.objects.all()[0].username, "%s-1" % bar_user)
self.assertEqual(Persona.objects.all()[0].accounts.count(), 2)
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminActionsTest(TestCase):
urls = "regressiontests.admin_views.urls"
@@ -2181,7 +2214,7 @@ class AdminActionsTest(TestCase):
"Tests a custom action defined in a ModelAdmin method"
action_data = {
ACTION_CHECKBOX_NAME: [1],
- 'action' : 'mail_admin',
+ 'action': 'mail_admin',
'index': 0,
}
response = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data)
@@ -2192,12 +2225,12 @@ class AdminActionsTest(TestCase):
"Tests the default delete action defined as a ModelAdmin method"
action_data = {
ACTION_CHECKBOX_NAME: [1, 2],
- 'action' : 'delete_selected',
+ 'action': 'delete_selected',
'index': 0,
}
delete_confirmation_data = {
ACTION_CHECKBOX_NAME: [1, 2],
- 'action' : 'delete_selected',
+ 'action': 'delete_selected',
'post': 'yes',
}
confirmation = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data)
@@ -2221,12 +2254,12 @@ class AdminActionsTest(TestCase):
subscriber.save()
action_data = {
ACTION_CHECKBOX_NAME: [9999, 2],
- 'action' : 'delete_selected',
+ 'action': 'delete_selected',
'index': 0,
}
response = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data)
self.assertTemplateUsed(response, 'admin/delete_selected_confirmation.html')
- self.assertContains(response, 'value="9999"') # Instead of 9,999
+ self.assertContains(response, 'value="9999"') # Instead of 9,999
self.assertContains(response, 'value="2"')
settings.USE_THOUSAND_SEPARATOR = self.old_USE_THOUSAND_SEPARATOR
settings.USE_L10N = self.old_USE_L10N
@@ -2243,7 +2276,7 @@ class AdminActionsTest(TestCase):
action_data = {
ACTION_CHECKBOX_NAME: [q1.pk, q2.pk],
- 'action' : 'delete_selected',
+ 'action': 'delete_selected',
'index': 0,
}
@@ -2257,7 +2290,7 @@ class AdminActionsTest(TestCase):
"Tests a custom action defined in a function"
action_data = {
ACTION_CHECKBOX_NAME: [1],
- 'action' : 'external_mail',
+ 'action': 'external_mail',
'index': 0,
}
response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data)
@@ -2268,7 +2301,7 @@ class AdminActionsTest(TestCase):
"Tests a custom action defined in a function"
action_data = {
ACTION_CHECKBOX_NAME: [1],
- 'action' : 'redirect_to',
+ 'action': 'redirect_to',
'index': 0,
}
response = self.client.post('/test_admin/admin/admin_views/externalsubscriber/', action_data)
@@ -2282,7 +2315,7 @@ class AdminActionsTest(TestCase):
"""
action_data = {
ACTION_CHECKBOX_NAME: [1],
- 'action' : 'external_mail',
+ 'action': 'external_mail',
'index': 0,
}
url = '/test_admin/admin/admin_views/externalsubscriber/?o=1'
@@ -2347,7 +2380,7 @@ class AdminActionsTest(TestCase):
"""
action_data = {
ACTION_CHECKBOX_NAME: [],
- 'action' : 'delete_selected',
+ 'action': 'delete_selected',
'index': 0,
}
response = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data)
@@ -2361,7 +2394,7 @@ class AdminActionsTest(TestCase):
"""
action_data = {
ACTION_CHECKBOX_NAME: [1, 2],
- 'action' : '',
+ 'action': '',
'index': 0,
}
response = self.client.post('/test_admin/admin/admin_views/subscriber/', action_data)
@@ -2405,7 +2438,7 @@ class TestCustomChangeList(TestCase):
# Insert some data
post_data = {"name": "First Gadget"}
response = self.client.post('/test_admin/%s/admin_views/gadget/add/' % self.urlbit, post_data)
- self.assertEqual(response.status_code, 302) # redirect somewhere
+ self.assertEqual(response.status_code, 302) # redirect somewhere
# Hit the page once to get messages out of the queue message list
response = self.client.get('/test_admin/%s/admin_views/gadget/' % self.urlbit)
# Ensure that that data is still not visible on the page
@@ -2433,6 +2466,7 @@ class TestInlineNotEditable(TestCase):
response = self.client.get('/test_admin/admin/admin_views/parent/add/')
self.assertEqual(response.status_code, 200)
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminCustomQuerysetTest(TestCase):
urls = "regressiontests.admin_views.urls"
@@ -2489,6 +2523,7 @@ class AdminCustomQuerysetTest(TestCase):
# Message should contain non-ugly model name. Instance representation is set by model's __unicode__()
self.assertContains(response, '<li class="info">The cover letter &quot;John Doe II&quot; was changed successfully.</li>', html=True)
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminInlineFileUploadTest(TestCase):
urls = "regressiontests.admin_views.urls"
@@ -2629,7 +2664,7 @@ class AdminInlineTests(TestCase):
result = self.client.login(username='super', password='secret')
self.assertEqual(result, True)
- self.collector = Collector(pk=1,name='John Fowles')
+ self.collector = Collector(pk=1, name='John Fowles')
self.collector.save()
def tearDown(self):
@@ -2955,14 +2990,14 @@ class PrePopulatedTest(TestCase):
self.assertNotContains(response, "field['dependency_ids'].push('#id_title');")
self.assertNotContains(response, "id: '#id_prepopulatedsubpost_set-0-subslug',")
- @override_settings(USE_THOUSAND_SEPARATOR = True, USE_L10N = True)
+ @override_settings(USE_THOUSAND_SEPARATOR=True, USE_L10N=True)
def test_prepopulated_maxlength_localized(self):
"""
Regression test for #15938: if USE_THOUSAND_SEPARATOR is set, make sure
that maxLength (in the JavaScript) is rendered without separators.
"""
response = self.client.get('/test_admin/admin/admin_views/prepopulatedpostlargeslug/add/')
- self.assertContains(response, "maxLength: 1000") # instead of 1,000
+ self.assertContains(response, "maxLength: 1000") # instead of 1,000
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
@@ -3008,8 +3043,8 @@ class SeleniumPrePopulatedFirefoxTests(AdminSeleniumWebDriverTestCase):
self.selenium.find_element_by_css_selector('#id_relatedprepopulated_set-1-name').send_keys(' now you haVe anöther sŤāÇkeð inline with a very ... loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooog text... ')
slug1 = self.selenium.find_element_by_css_selector('#id_relatedprepopulated_set-1-slug1').get_attribute('value')
slug2 = self.selenium.find_element_by_css_selector('#id_relatedprepopulated_set-1-slug2').get_attribute('value')
- self.assertEqual(slug1, 'now-you-have-another-stacked-inline-very-loooooooo') # 50 characters maximum for slug1 field
- self.assertEqual(slug2, 'option-two-now-you-have-another-stacked-inline-very-looooooo') # 60 characters maximum for slug2 field
+ self.assertEqual(slug1, 'now-you-have-another-stacked-inline-very-loooooooo') # 50 characters maximum for slug1 field
+ self.assertEqual(slug2, 'option-two-now-you-have-another-stacked-inline-very-looooooo') # 60 characters maximum for slug2 field
# Tabular inlines ----------------------------------------------------
# Initial inline
@@ -3060,7 +3095,7 @@ class SeleniumPrePopulatedFirefoxTests(AdminSeleniumWebDriverTestCase):
slug2='option-one-here-stacked-inline',
)
RelatedPrepopulated.objects.get(
- name=' now you haVe anöther sŤāÇkeð inline with a very ... loooooooooooooooooo', # 75 characters in name field
+ name=' now you haVe anöther sŤāÇkeð inline with a very ... loooooooooooooooooo', # 75 characters in name field
pubdate='1999-01-25',
status='option two',
slug1='now-you-have-another-stacked-inline-very-loooooooo',
@@ -3085,6 +3120,7 @@ class SeleniumPrePopulatedFirefoxTests(AdminSeleniumWebDriverTestCase):
class SeleniumPrePopulatedChromeTests(SeleniumPrePopulatedFirefoxTests):
webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver'
+
class SeleniumPrePopulatedIETests(SeleniumPrePopulatedFirefoxTests):
webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver'
@@ -3145,7 +3181,7 @@ class ReadonlyTest(TestCase):
p = Post.objects.get()
self.assertEqual(p.posted, datetime.date.today())
- data["posted"] = "10-8-1990" # some date that's not today
+ data["posted"] = "10-8-1990" # some date that's not today
response = self.client.post('/test_admin/admin/admin_views/post/add/', data)
self.assertEqual(response.status_code, 302)
self.assertEqual(Post.objects.count(), 2)
@@ -3187,7 +3223,7 @@ class RawIdFieldsTest(TestCase):
response = self.client.get('/test_admin/admin/admin_views/sketch/add/')
# Find the link
m = re.search(br'<a href="([^"]*)"[^>]* id="lookup_id_inquisition"', response.content)
- self.assertTrue(m) # Got a match
+ self.assertTrue(m) # Got a match
popup_url = m.groups()[0].decode().replace("&amp;", "&")
# Handle relative links
@@ -3197,6 +3233,7 @@ class RawIdFieldsTest(TestCase):
self.assertContains(response2, "Spain")
self.assertNotContains(response2, "England")
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class UserAdminTest(TestCase):
"""
@@ -3351,7 +3388,7 @@ class CSSTest(TestCase):
self.assertContains(response, 'class="form-row field-awesomeness_level"')
self.assertContains(response, 'class="form-row field-coolness"')
self.assertContains(response, 'class="form-row field-value"')
- self.assertContains(response, 'class="form-row"') # The lambda function
+ self.assertContains(response, 'class="form-row"') # The lambda function
# The tabular inline
self.assertContains(response, '<td class="field-url">')
@@ -3363,6 +3400,7 @@ try:
except ImportError:
docutils = None
+
@unittest.skipUnless(docutils, "no docutils installed.")
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminDocsTest(TestCase):
@@ -3421,7 +3459,7 @@ class ValidXHTMLTests(TestCase):
@override_settings(
TEMPLATE_CONTEXT_PROCESSORS=filter(
- lambda t:t!='django.core.context_processors.i18n',
+ lambda t: t != 'django.core.context_processors.i18n',
global_settings.TEMPLATE_CONTEXT_PROCESSORS),
USE_I18N=False,
)
@@ -3558,6 +3596,7 @@ class DateHierarchyTests(TestCase):
self.assert_non_localized_year(response, 2003)
self.assert_non_localized_year(response, 2005)
+
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminCustomSaveRelatedTests(TestCase):
"""
diff --git a/tests/regressiontests/aggregation_regress/tests.py b/tests/regressiontests/aggregation_regress/tests.py
index b9f3ab27eb..af0f421502 100644
--- a/tests/regressiontests/aggregation_regress/tests.py
+++ b/tests/regressiontests/aggregation_regress/tests.py
@@ -878,3 +878,14 @@ class AggregationTests(TestCase):
connection.ops.convert_values(testData, testField),
testData
)
+
+ def test_annotate_joins(self):
+ """
+ Test that the base table's join isn't promoted to LOUTER. This could
+ cause the query generation to fail if there is an exclude() for fk-field
+ in the query, too. Refs #19087.
+ """
+ qs = Book.objects.annotate(n=Count('pk'))
+ self.assertIs(qs.query.alias_map['aggregation_regress_book'].join_type, None)
+ # Check that the query executes without problems.
+ self.assertEqual(len(qs.exclude(publisher=-1)), 6)
diff --git a/tests/regressiontests/backends/tests.py b/tests/regressiontests/backends/tests.py
index cfa298253c..d284cfaac8 100644
--- a/tests/regressiontests/backends/tests.py
+++ b/tests/regressiontests/backends/tests.py
@@ -666,13 +666,6 @@ class ThreadTests(TestCase):
self.assertEqual(len(exceptions), 0)
-class BackendLoadingTests(TestCase):
- def test_old_style_backends_raise_useful_exception(self):
- six.assertRaisesRegex(self, ImproperlyConfigured,
- "Try using django.db.backends.sqlite3 instead",
- load_backend, 'sqlite3')
-
-
class MySQLPKZeroTests(TestCase):
"""
Zero as id for AutoField should raise exception in MySQL, because MySQL
diff --git a/tests/regressiontests/bulk_create/tests.py b/tests/regressiontests/bulk_create/tests.py
index 33108ea9b0..5d61242b9b 100644
--- a/tests/regressiontests/bulk_create/tests.py
+++ b/tests/regressiontests/bulk_create/tests.py
@@ -3,7 +3,7 @@ from __future__ import absolute_import
from operator import attrgetter
from django.db import connection
-from django.test import TestCase, skipIfDBFeature
+from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
from django.test.utils import override_settings
from .models import Country, Restaurant, Pizzeria, State, TwoFields
@@ -29,6 +29,7 @@ class BulkCreateTests(TestCase):
self.assertEqual(created, [])
self.assertEqual(Country.objects.count(), 4)
+ @skipUnlessDBFeature('has_bulk_insert')
def test_efficiency(self):
with self.assertNumQueries(1):
Country.objects.bulk_create(self.data)
@@ -50,6 +51,16 @@ class BulkCreateTests(TestCase):
], attrgetter("name"))
def test_non_auto_increment_pk(self):
+ State.objects.bulk_create([
+ State(two_letter_code=s)
+ for s in ["IL", "NY", "CA", "ME"]
+ ])
+ self.assertQuerysetEqual(State.objects.order_by("two_letter_code"), [
+ "CA", "IL", "ME", "NY",
+ ], attrgetter("two_letter_code"))
+
+ @skipUnlessDBFeature('has_bulk_insert')
+ def test_non_auto_increment_pk_efficiency(self):
with self.assertNumQueries(1):
State.objects.bulk_create([
State(two_letter_code=s)
@@ -77,13 +88,21 @@ class BulkCreateTests(TestCase):
TwoFields.objects.bulk_create([
TwoFields(f1=i, f2=i+1) for i in range(0, 1001)
])
- self.assertTrue(len(connection.queries) < 10)
self.assertEqual(TwoFields.objects.count(), 1001)
self.assertEqual(
TwoFields.objects.filter(f1__gte=450, f1__lte=550).count(),
101)
self.assertEqual(TwoFields.objects.filter(f2__gte=901).count(), 101)
+ @skipUnlessDBFeature('has_bulk_insert')
+ def test_large_batch_efficiency(self):
+ with override_settings(DEBUG=True):
+ connection.queries = []
+ TwoFields.objects.bulk_create([
+ TwoFields(f1=i, f2=i+1) for i in range(0, 1001)
+ ])
+ self.assertTrue(len(connection.queries) < 10)
+
def test_large_batch_mixed(self):
"""
Test inserting a large batch with objects having primary key set
@@ -94,7 +113,6 @@ class BulkCreateTests(TestCase):
TwoFields.objects.bulk_create([
TwoFields(id=i if i % 2 == 0 else None, f1=i, f2=i+1)
for i in range(100000, 101000)])
- self.assertTrue(len(connection.queries) < 10)
self.assertEqual(TwoFields.objects.count(), 1000)
# We can't assume much about the ID's created, except that the above
# created IDs must exist.
@@ -102,7 +120,29 @@ class BulkCreateTests(TestCase):
self.assertEqual(TwoFields.objects.filter(id__in=id_range).count(), 500)
self.assertEqual(TwoFields.objects.exclude(id__in=id_range).count(), 500)
+ @skipUnlessDBFeature('has_bulk_insert')
+ def test_large_batch_mixed_efficiency(self):
+ """
+ Test inserting a large batch with objects having primary key set
+ mixed together with objects without PK set.
+ """
+ with override_settings(DEBUG=True):
+ connection.queries = []
+ TwoFields.objects.bulk_create([
+ TwoFields(id=i if i % 2 == 0 else None, f1=i, f2=i+1)
+ for i in range(100000, 101000)])
+ self.assertTrue(len(connection.queries) < 10)
+
def test_explicit_batch_size(self):
+ objs = [TwoFields(f1=i, f2=i) for i in range(0, 4)]
+ TwoFields.objects.bulk_create(objs, 2)
+ self.assertEqual(TwoFields.objects.count(), len(objs))
+ TwoFields.objects.all().delete()
+ TwoFields.objects.bulk_create(objs, len(objs))
+ self.assertEqual(TwoFields.objects.count(), len(objs))
+
+ @skipUnlessDBFeature('has_bulk_insert')
+ def test_explicit_batch_size_efficiency(self):
objs = [TwoFields(f1=i, f2=i) for i in range(0, 100)]
with self.assertNumQueries(2):
TwoFields.objects.bulk_create(objs, 50)
diff --git a/tests/regressiontests/cache/tests.py b/tests/regressiontests/cache/tests.py
index de27bc9476..a6eff8950b 100644
--- a/tests/regressiontests/cache/tests.py
+++ b/tests/regressiontests/cache/tests.py
@@ -19,7 +19,8 @@ from django.core.cache import get_cache
from django.core.cache.backends.base import (CacheKeyWarning,
InvalidCacheBackendError)
from django.db import router
-from django.http import HttpResponse, HttpRequest, QueryDict
+from django.http import (HttpResponse, HttpRequest, StreamingHttpResponse,
+ QueryDict)
from django.middleware.cache import (FetchFromCacheMiddleware,
UpdateCacheMiddleware, CacheMiddleware)
from django.template import Template
@@ -1416,6 +1417,29 @@ class CacheI18nTest(TestCase):
# reset the language
translation.deactivate()
+ @override_settings(
+ CACHE_MIDDLEWARE_KEY_PREFIX="test",
+ CACHE_MIDDLEWARE_SECONDS=60,
+ USE_ETAGS=True,
+ )
+ def test_middleware_with_streaming_response(self):
+ # cache with non empty request.GET
+ request = self._get_request_cache(query_string='foo=baz&other=true')
+
+ # first access, cache must return None
+ get_cache_data = FetchFromCacheMiddleware().process_request(request)
+ self.assertEqual(get_cache_data, None)
+
+ # pass streaming response through UpdateCacheMiddleware.
+ content = 'Check for cache with QUERY_STRING and streaming content'
+ response = StreamingHttpResponse(content)
+ UpdateCacheMiddleware().process_response(request, response)
+
+ # second access, cache must still return None, because we can't cache
+ # streaming response.
+ get_cache_data = FetchFromCacheMiddleware().process_request(request)
+ self.assertEqual(get_cache_data, None)
+
@override_settings(
CACHES={
diff --git a/tests/regressiontests/comment_tests/tests/feed_tests.py b/tests/regressiontests/comment_tests/tests/feed_tests.py
index b15ec0c7b8..1ec316eab8 100644
--- a/tests/regressiontests/comment_tests/tests/feed_tests.py
+++ b/tests/regressiontests/comment_tests/tests/feed_tests.py
@@ -1,12 +1,32 @@
from __future__ import absolute_import
+from django.conf import settings
+from django.contrib.comments.models import Comment
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.sites.models import Site
+
from . import CommentTestCase
+from ..models import Article
class CommentFeedTests(CommentTestCase):
urls = 'regressiontests.comment_tests.urls'
feed_url = '/rss/comments/'
+ def setUp(self):
+ site_2 = Site.objects.create(id=settings.SITE_ID+1,
+ domain="example2.com", name="example2.com")
+ # A comment for another site
+ c5 = Comment.objects.create(
+ content_type = ContentType.objects.get_for_model(Article),
+ object_pk = "1",
+ user_name = "Joe Somebody",
+ user_email = "jsomebody@example.com",
+ user_url = "http://example.com/~joe/",
+ comment = "A comment for the second site.",
+ site = site_2,
+ )
+
def test_feed(self):
response = self.client.get(self.feed_url)
self.assertEqual(response.status_code, 200)
@@ -15,3 +35,4 @@ class CommentFeedTests(CommentTestCase):
self.assertContains(response, '<title>example.com comments</title>')
self.assertContains(response, '<link>http://example.com/</link>')
self.assertContains(response, '</rss>')
+ self.assertNotContains(response, "A comment for the second site.")
diff --git a/tests/regressiontests/comment_tests/urls.py b/tests/regressiontests/comment_tests/urls.py
index b2f676786f..0a7e8b5fdf 100644
--- a/tests/regressiontests/comment_tests/urls.py
+++ b/tests/regressiontests/comment_tests/urls.py
@@ -15,6 +15,7 @@ urlpatterns = patterns('',
url(r'^flag/(\d+)/$', views.custom_flag_comment),
url(r'^delete/(\d+)/$', views.custom_delete_comment),
url(r'^approve/(\d+)/$', views.custom_approve_comment),
+ url(r'^cr/(\d+)/(.+)/$', 'django.contrib.contenttypes.views.shortcut', name='comments-url-redirect'),
)
urlpatterns += patterns('',
diff --git a/tests/regressiontests/conditional_processing/models.py b/tests/regressiontests/conditional_processing/models.py
index d0838e153d..b47fdf6fb5 100644
--- a/tests/regressiontests/conditional_processing/models.py
+++ b/tests/regressiontests/conditional_processing/models.py
@@ -4,8 +4,6 @@ from __future__ import unicode_literals
from datetime import datetime
from django.test import TestCase
-from django.utils import unittest
-from django.utils.http import parse_etags, quote_etag, parse_http_date
FULL_RESPONSE = 'Test conditional get response'
@@ -129,30 +127,3 @@ class ConditionalGet(TestCase):
self.client.defaults['HTTP_IF_NONE_MATCH'] = r'"\"'
response = self.client.get('/condition/etag/')
self.assertFullResponse(response, check_last_modified=False)
-
-
-class ETagProcessing(unittest.TestCase):
- def testParsing(self):
- etags = parse_etags(r'"", "etag", "e\"t\"ag", "e\\tag", W/"weak"')
- self.assertEqual(etags, ['', 'etag', 'e"t"ag', r'e\tag', 'weak'])
-
- def testQuoting(self):
- quoted_etag = quote_etag(r'e\t"ag')
- self.assertEqual(quoted_etag, r'"e\\t\"ag"')
-
-
-class HttpDateProcessing(unittest.TestCase):
- def testParsingRfc1123(self):
- parsed = parse_http_date('Sun, 06 Nov 1994 08:49:37 GMT')
- self.assertEqual(datetime.utcfromtimestamp(parsed),
- datetime(1994, 11, 6, 8, 49, 37))
-
- def testParsingRfc850(self):
- parsed = parse_http_date('Sunday, 06-Nov-94 08:49:37 GMT')
- self.assertEqual(datetime.utcfromtimestamp(parsed),
- datetime(1994, 11, 6, 8, 49, 37))
-
- def testParsingAsctime(self):
- parsed = parse_http_date('Sun Nov 6 08:49:37 1994')
- self.assertEqual(datetime.utcfromtimestamp(parsed),
- datetime(1994, 11, 6, 8, 49, 37))
diff --git a/tests/regressiontests/delete_regress/models.py b/tests/regressiontests/delete_regress/models.py
index 5db253f713..dbe383fb41 100644
--- a/tests/regressiontests/delete_regress/models.py
+++ b/tests/regressiontests/delete_regress/models.py
@@ -2,7 +2,6 @@ from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.db import models
-
class Award(models.Model):
name = models.CharField(max_length=25)
object_id = models.PositiveIntegerField()
@@ -93,3 +92,10 @@ class FooPhoto(models.Model):
class FooFileProxy(FooFile):
class Meta:
proxy = True
+
+class OrgUnit(models.Model):
+ name = models.CharField(max_length=64, unique=True)
+
+class Login(models.Model):
+ description = models.CharField(max_length=32)
+ orgunit = models.ForeignKey(OrgUnit)
diff --git a/tests/regressiontests/delete_regress/tests.py b/tests/regressiontests/delete_regress/tests.py
index 32feae2ded..f94bb2f20c 100644
--- a/tests/regressiontests/delete_regress/tests.py
+++ b/tests/regressiontests/delete_regress/tests.py
@@ -3,12 +3,13 @@ from __future__ import absolute_import
import datetime
from django.conf import settings
-from django.db import backend, transaction, DEFAULT_DB_ALIAS
+from django.db import backend, transaction, DEFAULT_DB_ALIAS, models
from django.test import TestCase, TransactionTestCase, skipUnlessDBFeature
from .models import (Book, Award, AwardNote, Person, Child, Toy, PlayedWith,
PlayedWithNote, Email, Researcher, Food, Eaten, Policy, Version, Location,
- Item, Image, File, Photo, FooFile, FooImage, FooPhoto, FooFileProxy)
+ Item, Image, File, Photo, FooFile, FooImage, FooPhoto, FooFileProxy, Login,
+ OrgUnit)
# Can't run this test under SQLite, because you can't
@@ -139,17 +140,24 @@ class DeleteCascadeTransactionTests(TransactionTestCase):
eaten = Eaten.objects.create(food=apple, meal="lunch")
apple.delete()
+ self.assertFalse(Food.objects.exists())
+ self.assertFalse(Eaten.objects.exists())
+
class LargeDeleteTests(TestCase):
def test_large_deletes(self):
"Regression for #13309 -- if the number of objects > chunk size, deletion still occurs"
for x in range(300):
track = Book.objects.create(pagecount=x+100)
+ # attach a signal to make sure we will not fast-delete
+ def noop(*args, **kwargs):
+ pass
+ models.signals.post_delete.connect(noop, sender=Book)
Book.objects.all().delete()
+ models.signals.post_delete.disconnect(noop, sender=Book)
self.assertEqual(Book.objects.count(), 0)
-
class ProxyDeleteTest(TestCase):
"""
Tests on_delete behavior for proxy models.
@@ -258,3 +266,92 @@ class ProxyDeleteTest(TestCase):
Image.objects.all().delete()
self.assertEqual(len(FooFileProxy.objects.all()), 0)
+
+ def test_19187_values(self):
+ with self.assertRaises(TypeError):
+ Image.objects.values().delete()
+ with self.assertRaises(TypeError):
+ Image.objects.values_list().delete()
+
+class Ticket19102Tests(TestCase):
+ """
+ Test different queries which alter the SELECT clause of the query. We
+ also must be using a subquery for the deletion (that is, the original
+ query has a join in it). The deletion should be done as "fast-path"
+ deletion (that is, just one query for the .delete() call).
+
+ Note that .values() is not tested here on purpose. .values().delete()
+ doesn't work for non fast-path deletes at all.
+ """
+ def setUp(self):
+ self.o1 = OrgUnit.objects.create(name='o1')
+ self.o2 = OrgUnit.objects.create(name='o2')
+ self.l1 = Login.objects.create(description='l1', orgunit=self.o1)
+ self.l2 = Login.objects.create(description='l2', orgunit=self.o2)
+
+ @skipUnlessDBFeature("update_can_self_select")
+ def test_ticket_19102_annotate(self):
+ with self.assertNumQueries(1):
+ Login.objects.order_by('description').filter(
+ orgunit__name__isnull=False
+ ).annotate(
+ n=models.Count('description')
+ ).filter(
+ n=1, pk=self.l1.pk
+ ).delete()
+ self.assertFalse(Login.objects.filter(pk=self.l1.pk).exists())
+ self.assertTrue(Login.objects.filter(pk=self.l2.pk).exists())
+
+ @skipUnlessDBFeature("update_can_self_select")
+ def test_ticket_19102_extra(self):
+ with self.assertNumQueries(1):
+ Login.objects.order_by('description').filter(
+ orgunit__name__isnull=False
+ ).extra(
+ select={'extraf':'1'}
+ ).filter(
+ pk=self.l1.pk
+ ).delete()
+ self.assertFalse(Login.objects.filter(pk=self.l1.pk).exists())
+ self.assertTrue(Login.objects.filter(pk=self.l2.pk).exists())
+
+ @skipUnlessDBFeature("update_can_self_select")
+ @skipUnlessDBFeature('can_distinct_on_fields')
+ def test_ticket_19102_distinct_on(self):
+ # Both Login objs should have same description so that only the one
+ # having smaller PK will be deleted.
+ Login.objects.update(description='description')
+ with self.assertNumQueries(1):
+ Login.objects.distinct('description').order_by('pk').filter(
+ orgunit__name__isnull=False
+ ).delete()
+ # Assumed that l1 which is created first has smaller PK.
+ self.assertFalse(Login.objects.filter(pk=self.l1.pk).exists())
+ self.assertTrue(Login.objects.filter(pk=self.l2.pk).exists())
+
+ @skipUnlessDBFeature("update_can_self_select")
+ def test_ticket_19102_select_related(self):
+ with self.assertNumQueries(1):
+ Login.objects.filter(
+ pk=self.l1.pk
+ ).filter(
+ orgunit__name__isnull=False
+ ).order_by(
+ 'description'
+ ).select_related('orgunit').delete()
+ self.assertFalse(Login.objects.filter(pk=self.l1.pk).exists())
+ self.assertTrue(Login.objects.filter(pk=self.l2.pk).exists())
+
+ @skipUnlessDBFeature("update_can_self_select")
+ def test_ticket_19102_defer(self):
+ with self.assertNumQueries(1):
+ Login.objects.filter(
+ pk=self.l1.pk
+ ).filter(
+ orgunit__name__isnull=False
+ ).order_by(
+ 'description'
+ ).only('id').delete()
+ self.assertFalse(Login.objects.filter(pk=self.l1.pk).exists())
+ self.assertTrue(Login.objects.filter(pk=self.l2.pk).exists())
+
diff --git a/tests/regressiontests/dispatch/tests/test_dispatcher.py b/tests/regressiontests/dispatch/tests/test_dispatcher.py
index 5f7094d5fa..5f8f92acaf 100644
--- a/tests/regressiontests/dispatch/tests/test_dispatcher.py
+++ b/tests/regressiontests/dispatch/tests/test_dispatcher.py
@@ -126,6 +126,17 @@ class DispatcherTests(unittest.TestCase):
a_signal.disconnect(receiver_3)
self._testIsClean(a_signal)
+ def test_has_listeners(self):
+ self.assertFalse(a_signal.has_listeners())
+ self.assertFalse(a_signal.has_listeners(sender=object()))
+ receiver_1 = Callable()
+ a_signal.connect(receiver_1)
+ self.assertTrue(a_signal.has_listeners())
+ self.assertTrue(a_signal.has_listeners(sender=object()))
+ a_signal.disconnect(receiver_1)
+ self.assertFalse(a_signal.has_listeners())
+ self.assertFalse(a_signal.has_listeners(sender=object()))
+
class ReceiverTestCase(unittest.TestCase):
"""
diff --git a/tests/regressiontests/expressions_regress/tests.py b/tests/regressiontests/expressions_regress/tests.py
index 80ddfadbe7..508a497151 100644
--- a/tests/regressiontests/expressions_regress/tests.py
+++ b/tests/regressiontests/expressions_regress/tests.py
@@ -128,7 +128,7 @@ class ExpressionOperatorTests(TestCase):
def test_lefthand_bitwise_and(self):
# LH Bitwise ands on integers
- Number.objects.filter(pk=self.n.pk).update(integer=F('integer') & 56)
+ Number.objects.filter(pk=self.n.pk).update(integer=F('integer').bitand(56))
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 40)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
@@ -136,7 +136,7 @@ class ExpressionOperatorTests(TestCase):
@skipUnlessDBFeature('supports_bitwise_or')
def test_lefthand_bitwise_or(self):
# LH Bitwise or on integers
- Number.objects.filter(pk=self.n.pk).update(integer=F('integer') | 48)
+ Number.objects.filter(pk=self.n.pk).update(integer=F('integer').bitor(48))
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 58)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
@@ -181,20 +181,6 @@ class ExpressionOperatorTests(TestCase):
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 27)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
- def test_right_hand_bitwise_and(self):
- # RH Bitwise ands on integers
- Number.objects.filter(pk=self.n.pk).update(integer=15 & F('integer'))
-
- self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 10)
- self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
-
- @skipUnlessDBFeature('supports_bitwise_or')
- def test_right_hand_bitwise_or(self):
- # RH Bitwise or on integers
- Number.objects.filter(pk=self.n.pk).update(integer=15 | F('integer'))
-
- self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 47)
- self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
class FTimeDeltaTests(TestCase):
@@ -385,7 +371,7 @@ class FTimeDeltaTests(TestCase):
def test_delta_invalid_op_and(self):
raised = False
try:
- r = repr(Experiment.objects.filter(end__lt=F('start')&self.deltas[0]))
+ r = repr(Experiment.objects.filter(end__lt=F('start').bitand(self.deltas[0])))
except TypeError:
raised = True
self.assertTrue(raised, "TypeError not raised on attempt to binary and a datetime with a timedelta.")
@@ -393,7 +379,7 @@ class FTimeDeltaTests(TestCase):
def test_delta_invalid_op_or(self):
raised = False
try:
- r = repr(Experiment.objects.filter(end__lt=F('start')|self.deltas[0]))
+ r = repr(Experiment.objects.filter(end__lt=F('start').bitor(self.deltas[0])))
except TypeError:
raised = True
self.assertTrue(raised, "TypeError not raised on attempt to binary or a datetime with a timedelta.")
diff --git a/tests/regressiontests/file_storage/tests.py b/tests/regressiontests/file_storage/tests.py
index 281041e651..595b65d9f1 100644
--- a/tests/regressiontests/file_storage/tests.py
+++ b/tests/regressiontests/file_storage/tests.py
@@ -4,6 +4,7 @@ from __future__ import absolute_import, unicode_literals
import errno
import os
import shutil
+import sys
import tempfile
import time
from datetime import datetime, timedelta
@@ -23,6 +24,7 @@ from django.core.files.uploadedfile import UploadedFile
from django.test import SimpleTestCase
from django.utils import six
from django.utils import unittest
+from django.test.utils import override_settings
from ..servers.tests import LiveServerBase
# Try to import PIL in either of the two ways it can end up installed.
@@ -76,7 +78,7 @@ class GetStorageClassTests(SimpleTestCase):
six.assertRaisesRegex(self,
ImproperlyConfigured,
('Error importing storage module django.core.files.non_existing_'
- 'storage: "No module named .*non_existing_storage"'),
+ 'storage: "No module named .*non_existing_storage'),
get_storage_class,
'django.core.files.non_existing_storage.NonExistingStorage'
)
@@ -433,22 +435,29 @@ class FileSaveRaceConditionTest(unittest.TestCase):
self.storage.delete('conflict')
self.storage.delete('conflict_1')
+@unittest.skipIf(sys.platform.startswith('win'), "Windows only partially supports umasks and chmod.")
class FileStoragePermissions(unittest.TestCase):
def setUp(self):
- self.old_perms = settings.FILE_UPLOAD_PERMISSIONS
- settings.FILE_UPLOAD_PERMISSIONS = 0o666
+ self.umask = 0o027
+ self.old_umask = os.umask(self.umask)
self.storage_dir = tempfile.mkdtemp()
self.storage = FileSystemStorage(self.storage_dir)
def tearDown(self):
- settings.FILE_UPLOAD_PERMISSIONS = self.old_perms
shutil.rmtree(self.storage_dir)
+ os.umask(self.old_umask)
+ @override_settings(FILE_UPLOAD_PERMISSIONS=0o654)
def test_file_upload_permissions(self):
name = self.storage.save("the_file", ContentFile("data"))
actual_mode = os.stat(self.storage.path(name))[0] & 0o777
- self.assertEqual(actual_mode, 0o666)
+ self.assertEqual(actual_mode, 0o654)
+ @override_settings(FILE_UPLOAD_PERMISSIONS=None)
+ def test_file_upload_default_permissions(self):
+ fname = self.storage.save("some_file", ContentFile("data"))
+ mode = os.stat(self.storage.path(fname))[0] & 0o777
+ self.assertEqual(mode, 0o666 & ~self.umask)
class FileStoragePathParsing(unittest.TestCase):
def setUp(self):
diff --git a/tests/regressiontests/file_uploads/tests.py b/tests/regressiontests/file_uploads/tests.py
index 2a1ec7db21..918f77d73c 100644
--- a/tests/regressiontests/file_uploads/tests.py
+++ b/tests/regressiontests/file_uploads/tests.py
@@ -62,22 +62,20 @@ class FileUploadTests(TestCase):
def test_base64_upload(self):
test_string = "This data will be transmitted base64-encoded."
- payload = "\r\n".join([
+ payload = client.FakePayload("\r\n".join([
'--' + client.BOUNDARY,
'Content-Disposition: form-data; name="file"; filename="test.txt"',
'Content-Type: application/octet-stream',
'Content-Transfer-Encoding: base64',
- '',
- base64.b64encode(force_bytes(test_string)).decode('ascii'),
- '--' + client.BOUNDARY + '--',
- '',
- ]).encode('utf-8')
+ '',]))
+ payload.write(b"\r\n" + base64.b64encode(force_bytes(test_string)) + b"\r\n")
+ payload.write('--' + client.BOUNDARY + '--\r\n')
r = {
'CONTENT_LENGTH': len(payload),
'CONTENT_TYPE': client.MULTIPART_CONTENT,
'PATH_INFO': "/file_uploads/echo_content/",
'REQUEST_METHOD': 'POST',
- 'wsgi.input': client.FakePayload(payload),
+ 'wsgi.input': payload,
}
response = self.client.request(**r)
received = json.loads(response.content.decode('utf-8'))
@@ -126,27 +124,23 @@ class FileUploadTests(TestCase):
"../..\\hax0rd.txt" # Relative path, mixed.
]
- payload = []
+ payload = client.FakePayload()
for i, name in enumerate(scary_file_names):
- payload.extend([
+ payload.write('\r\n'.join([
'--' + client.BOUNDARY,
'Content-Disposition: form-data; name="file%s"; filename="%s"' % (i, name),
'Content-Type: application/octet-stream',
'',
- 'You got pwnd.'
- ])
- payload.extend([
- '--' + client.BOUNDARY + '--',
- '',
- ])
+ 'You got pwnd.\r\n'
+ ]))
+ payload.write('\r\n--' + client.BOUNDARY + '--\r\n')
- payload = "\r\n".join(payload).encode('utf-8')
r = {
'CONTENT_LENGTH': len(payload),
'CONTENT_TYPE': client.MULTIPART_CONTENT,
'PATH_INFO': "/file_uploads/echo/",
'REQUEST_METHOD': 'POST',
- 'wsgi.input': client.FakePayload(payload),
+ 'wsgi.input': payload,
}
response = self.client.request(**r)
@@ -159,7 +153,7 @@ class FileUploadTests(TestCase):
def test_filename_overflow(self):
"""File names over 256 characters (dangerous on some platforms) get fixed up."""
name = "%s.txt" % ("f"*500)
- payload = "\r\n".join([
+ payload = client.FakePayload("\r\n".join([
'--' + client.BOUNDARY,
'Content-Disposition: form-data; name="file"; filename="%s"' % name,
'Content-Type: application/octet-stream',
@@ -167,13 +161,13 @@ class FileUploadTests(TestCase):
'Oops.'
'--' + client.BOUNDARY + '--',
'',
- ]).encode('utf-8')
+ ]))
r = {
'CONTENT_LENGTH': len(payload),
'CONTENT_TYPE': client.MULTIPART_CONTENT,
'PATH_INFO': "/file_uploads/echo/",
'REQUEST_METHOD': 'POST',
- 'wsgi.input': client.FakePayload(payload),
+ 'wsgi.input': payload,
}
got = json.loads(self.client.request(**r).content.decode('utf-8'))
self.assertTrue(len(got['file']) < 256, "Got a long file name (%s characters)." % len(got['file']))
@@ -184,7 +178,7 @@ class FileUploadTests(TestCase):
attempt to read beyond the end of the stream, and simply will handle
the part that can be parsed gracefully.
"""
- payload = "\r\n".join([
+ payload_str = "\r\n".join([
'--' + client.BOUNDARY,
'Content-Disposition: form-data; name="file"; filename="foo.txt"',
'Content-Type: application/octet-stream',
@@ -192,14 +186,14 @@ class FileUploadTests(TestCase):
'file contents'
'--' + client.BOUNDARY + '--',
'',
- ]).encode('utf-8')
- payload = payload[:-10]
+ ])
+ payload = client.FakePayload(payload_str[:-10])
r = {
'CONTENT_LENGTH': len(payload),
'CONTENT_TYPE': client.MULTIPART_CONTENT,
'PATH_INFO': '/file_uploads/echo/',
'REQUEST_METHOD': 'POST',
- 'wsgi.input': client.FakePayload(payload),
+ 'wsgi.input': payload,
}
got = json.loads(self.client.request(**r).content.decode('utf-8'))
self.assertEqual(got, {})
diff --git a/tests/regressiontests/fixtures_regress/fixtures/sequence_extra.json b/tests/regressiontests/fixtures_regress/fixtures/sequence_extra.json
new file mode 100644
index 0000000000..03c0f36696
--- /dev/null
+++ b/tests/regressiontests/fixtures_regress/fixtures/sequence_extra.json
@@ -0,0 +1,13 @@
+[
+ {
+ "pk": "1",
+ "model": "fixtures_regress.animal",
+ "fields": {
+ "name": "Lion",
+ "extra_name": "Super Lion",
+ "latin_name": "Panthera leo",
+ "count": 3,
+ "weight": 1.2
+ }
+ }
+]
diff --git a/tests/regressiontests/fixtures_regress/tests.py b/tests/regressiontests/fixtures_regress/tests.py
index d675372c7a..55363bc5b7 100644
--- a/tests/regressiontests/fixtures_regress/tests.py
+++ b/tests/regressiontests/fixtures_regress/tests.py
@@ -5,6 +5,7 @@ from __future__ import absolute_import, unicode_literals
import os
import re
+from django.core.serializers.base import DeserializationError
from django.core import management
from django.core.management.base import CommandError
from django.core.management.commands.dumpdata import sort_dependencies
@@ -22,6 +23,7 @@ from .models import (Animal, Stuff, Absolute, Parent, Child, Article, Widget,
class TestFixtures(TestCase):
+
def animal_pre_save_check(self, signal, sender, instance, **kwargs):
self.pre_save_checks.append(
(
@@ -54,6 +56,34 @@ class TestFixtures(TestCase):
animal.save()
self.assertGreater(animal.id, 1)
+ def test_loaddata_not_found_fields_not_ignore(self):
+ """
+ Test for ticket #9279 -- Error is raised for entries in
+ the serialised data for fields that have been removed
+ from the database when not ignored.
+ """
+ with self.assertRaises(DeserializationError):
+ management.call_command(
+ 'loaddata',
+ 'sequence_extra',
+ verbosity=0
+ )
+
+ def test_loaddata_not_found_fields_ignore(self):
+ """
+ Test for ticket #9279 -- Ignores entries in
+ the serialised data for fields that have been removed
+ from the database.
+ """
+ management.call_command(
+ 'loaddata',
+ 'sequence_extra',
+ ignore=True,
+ verbosity=0,
+ commit=False
+ )
+ self.assertEqual(Animal.specimens.all()[0].name, 'Lion')
+
@skipIfDBFeature('interprets_empty_strings_as_nulls')
def test_pretty_print_xml(self):
"""
@@ -129,7 +159,7 @@ class TestFixtures(TestCase):
Test that failing serializer import raises the proper error
"""
with six.assertRaisesRegex(self, ImportError,
- "No module named unexistent.path"):
+ r"No module named.*unexistent"):
management.call_command(
'loaddata',
'bad_fixture1.unkn',
diff --git a/tests/regressiontests/forms/models.py b/tests/regressiontests/forms/models.py
index 2f3ee9fa31..6e9c269356 100644
--- a/tests/regressiontests/forms/models.py
+++ b/tests/regressiontests/forms/models.py
@@ -63,6 +63,12 @@ class ChoiceFieldModel(models.Model):
multi_choice_int = models.ManyToManyField(ChoiceOptionModel, blank=False, related_name='multi_choice_int',
default=lambda: [1])
+class OptionalMultiChoiceModel(models.Model):
+ multi_choice = models.ManyToManyField(ChoiceOptionModel, blank=False, related_name='not_relevant',
+ default=lambda: ChoiceOptionModel.objects.filter(name='default'))
+ multi_choice_optional = models.ManyToManyField(ChoiceOptionModel, blank=True, null=True,
+ related_name='not_relevant2')
+
class FileModel(models.Model):
file = models.FileField(storage=temp_storage, upload_to='tests')
diff --git a/tests/regressiontests/forms/tests/extra.py b/tests/regressiontests/forms/tests/extra.py
index 2ab5d40942..07acb29741 100644
--- a/tests/regressiontests/forms/tests/extra.py
+++ b/tests/regressiontests/forms/tests/extra.py
@@ -3,11 +3,11 @@ from __future__ import absolute_import, unicode_literals
import datetime
-from django.conf import settings
from django.forms import *
from django.forms.extras import SelectDateWidget
from django.forms.util import ErrorList
from django.test import TestCase
+from django.test.utils import override_settings
from django.utils import six
from django.utils import translation
from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible
@@ -613,7 +613,7 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
data = dict(email='invalid')
f = CommentForm(data, auto_id=False, error_class=DivErrorList)
self.assertHTMLEqual(f.as_p(), """<p>Name: <input type="text" name="name" maxlength="50" /></p>
-<div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
+<div class="errorlist"><div class="error">Enter a valid email address.</div></div>
<p>Email: <input type="text" name="email" value="invalid" /></p>
<div class="errorlist"><div class="error">This field is required.</div></div>
<p>Comment: <input type="text" name="comment" /></p>""")
@@ -642,17 +642,14 @@ class FormsExtraTestCase(TestCase, AssertFormErrorsMixin):
self.assertFalse(b.has_changed())
-
+@override_settings(USE_L10N=True)
class FormsExtraL10NTestCase(TestCase):
def setUp(self):
super(FormsExtraL10NTestCase, self).setUp()
- self.old_use_l10n = getattr(settings, 'USE_L10N', False)
- settings.USE_L10N = True
translation.activate('nl')
def tearDown(self):
translation.deactivate()
- settings.USE_L10N = self.old_use_l10n
super(FormsExtraL10NTestCase, self).tearDown()
def test_l10n(self):
diff --git a/tests/regressiontests/forms/tests/fields.py b/tests/regressiontests/forms/tests/fields.py
index 197ce1abd9..1027afceb1 100644
--- a/tests/regressiontests/forms/tests/fields.py
+++ b/tests/regressiontests/forms/tests/fields.py
@@ -356,6 +356,11 @@ class FieldsTests(SimpleTestCase):
self.assertEqual(datetime.date(2006, 10, 25), f.clean(' 25 October 2006 '))
self.assertRaisesMessage(ValidationError, "'Enter a valid date.'", f.clean, ' ')
+ def test_datefield_5(self):
+ # Test null bytes (#18982)
+ f = DateField()
+ self.assertRaisesMessage(ValidationError, "'Enter a valid date.'", f.clean, 'a\x00b')
+
# TimeField ###################################################################
def test_timefield_1(self):
@@ -496,46 +501,33 @@ class FieldsTests(SimpleTestCase):
self.assertRaisesMessage(ValidationError, "'Enter a valid value.'", f.clean, 'abcd')
# EmailField ##################################################################
+ # See also modeltests/validators tests for validate_email specific tests
def test_emailfield_1(self):
f = EmailField()
self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, '')
self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, None)
self.assertEqual('person@example.com', f.clean('person@example.com'))
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'foo')
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'foo@')
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'foo@bar')
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'example@invalid-.com')
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'example@-invalid.com')
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'example@inv-.alid-.com')
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'example@inv-.-alid.com')
- self.assertEqual('example@valid-----hyphens.com', f.clean('example@valid-----hyphens.com'))
- self.assertEqual('example@valid-with-hyphens.com', f.clean('example@valid-with-hyphens.com'))
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'example@.com')
- self.assertEqual('local@domain.with.idn.xyz\xe4\xf6\xfc\xdfabc.part.com', f.clean('local@domain.with.idn.xyzäöüßabc.part.com'))
+ self.assertRaisesMessage(ValidationError, "'Enter a valid email address.'", f.clean, 'foo')
+ self.assertEqual('local@domain.with.idn.xyz\xe4\xf6\xfc\xdfabc.part.com',
+ f.clean('local@domain.with.idn.xyzäöüßabc.part.com'))
def test_email_regexp_for_performance(self):
f = EmailField()
# Check for runaway regex security problem. This will take for-freeking-ever
# if the security fix isn't in place.
- self.assertRaisesMessage(
- ValidationError,
- "'Enter a valid e-mail address.'",
- f.clean,
- 'viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058'
- )
+ addr = 'viewx3dtextx26qx3d@yahoo.comx26latlngx3d15854521645943074058'
+ self.assertEqual(addr, f.clean(addr))
- def test_emailfield_2(self):
+ def test_emailfield_not_required(self):
f = EmailField(required=False)
self.assertEqual('', f.clean(''))
self.assertEqual('', f.clean(None))
self.assertEqual('person@example.com', f.clean('person@example.com'))
self.assertEqual('example@example.com', f.clean(' example@example.com \t \t '))
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'foo')
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'foo@')
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'foo@bar')
+ self.assertRaisesMessage(ValidationError, "'Enter a valid email address.'", f.clean, 'foo')
- def test_emailfield_3(self):
+ def test_emailfield_min_max_length(self):
f = EmailField(min_length=10, max_length=15)
self.assertRaisesMessage(ValidationError, "'Ensure this value has at least 10 characters (it has 9).'", f.clean, 'a@foo.com')
self.assertEqual('alf@foo.com', f.clean('alf@foo.com'))
@@ -921,7 +913,7 @@ class FieldsTests(SimpleTestCase):
f = ComboField(fields=[CharField(max_length=20), EmailField()])
self.assertEqual('test@example.com', f.clean('test@example.com'))
self.assertRaisesMessage(ValidationError, "'Ensure this value has at most 20 characters (it has 28).'", f.clean, 'longemailaddress@example.com')
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'not an e-mail')
+ self.assertRaisesMessage(ValidationError, "'Enter a valid email address.'", f.clean, 'not an email')
self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, '')
self.assertRaisesMessage(ValidationError, "'This field is required.'", f.clean, None)
@@ -929,7 +921,7 @@ class FieldsTests(SimpleTestCase):
f = ComboField(fields=[CharField(max_length=20), EmailField()], required=False)
self.assertEqual('test@example.com', f.clean('test@example.com'))
self.assertRaisesMessage(ValidationError, "'Ensure this value has at most 20 characters (it has 28).'", f.clean, 'longemailaddress@example.com')
- self.assertRaisesMessage(ValidationError, "'Enter a valid e-mail address.'", f.clean, 'not an e-mail')
+ self.assertRaisesMessage(ValidationError, "'Enter a valid email address.'", f.clean, 'not an email')
self.assertEqual('', f.clean(''))
self.assertEqual('', f.clean(None))
diff --git a/tests/regressiontests/forms/tests/formsets.py b/tests/regressiontests/forms/tests/formsets.py
index 3decd1f085..b3ceee551b 100644
--- a/tests/regressiontests/forms/tests/formsets.py
+++ b/tests/regressiontests/forms/tests/formsets.py
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.forms import Form, CharField, IntegerField, ValidationError, DateField
from django.forms.formsets import formset_factory, BaseFormSet
+from django.forms.util import ErrorList
from django.test import TestCase
@@ -847,6 +848,15 @@ class FormsFormsetTestCase(TestCase):
self.assertTrue(formset)
+ def test_formset_error_class(self):
+ # Regression tests for #16479 -- formsets form use ErrorList instead of supplied error_class
+ class CustomErrorList(ErrorList):
+ pass
+
+ formset = FavoriteDrinksFormSet(error_class=CustomErrorList)
+ self.assertEqual(formset.forms[0].error_class, CustomErrorList)
+
+
data = {
'choices-TOTAL_FORMS': '1', # the number of forms rendered
'choices-INITIAL_FORMS': '0', # the number of forms with initial data
diff --git a/tests/regressiontests/forms/tests/input_formats.py b/tests/regressiontests/forms/tests/input_formats.py
index e362620ddb..d591804b9d 100644
--- a/tests/regressiontests/forms/tests/input_formats.py
+++ b/tests/regressiontests/forms/tests/input_formats.py
@@ -1,25 +1,17 @@
from datetime import time, date, datetime
from django import forms
-from django.conf import settings
+from django.test.utils import override_settings
from django.utils.translation import activate, deactivate
from django.utils.unittest import TestCase
+@override_settings(TIME_INPUT_FORMATS=["%I:%M:%S %p", "%I:%M %p"], USE_L10N=True)
class LocalizedTimeTests(TestCase):
def setUp(self):
- self.old_TIME_INPUT_FORMATS = settings.TIME_INPUT_FORMATS
- self.old_USE_L10N = settings.USE_L10N
-
- settings.TIME_INPUT_FORMATS = ["%I:%M:%S %p", "%I:%M %p"]
- settings.USE_L10N = True
-
activate('de')
def tearDown(self):
- settings.TIME_INPUT_FORMATS = self.old_TIME_INPUT_FORMATS
- settings.USE_L10N = self.old_USE_L10N
-
deactivate()
def test_timeField(self):
@@ -113,14 +105,8 @@ class LocalizedTimeTests(TestCase):
self.assertEqual(text, "13:30:00")
+@override_settings(TIME_INPUT_FORMATS=["%I:%M:%S %p", "%I:%M %p"])
class CustomTimeInputFormatsTests(TestCase):
- def setUp(self):
- self.old_TIME_INPUT_FORMATS = settings.TIME_INPUT_FORMATS
- settings.TIME_INPUT_FORMATS = ["%I:%M:%S %p", "%I:%M %p"]
-
- def tearDown(self):
- settings.TIME_INPUT_FORMATS = self.old_TIME_INPUT_FORMATS
-
def test_timeField(self):
"TimeFields can parse dates in the default format"
f = forms.TimeField()
@@ -302,20 +288,12 @@ class SimpleTimeFormatTests(TestCase):
self.assertEqual(text, "13:30:00")
+@override_settings(DATE_INPUT_FORMATS=["%d/%m/%Y", "%d-%m-%Y"], USE_L10N=True)
class LocalizedDateTests(TestCase):
def setUp(self):
- self.old_DATE_INPUT_FORMATS = settings.DATE_INPUT_FORMATS
- self.old_USE_L10N = settings.USE_L10N
-
- settings.DATE_INPUT_FORMATS = ["%d/%m/%Y", "%d-%m-%Y"]
- settings.USE_L10N = True
-
activate('de')
def tearDown(self):
- settings.DATE_INPUT_FORMATS = self.old_DATE_INPUT_FORMATS
- settings.USE_L10N = self.old_USE_L10N
-
deactivate()
def test_dateField(self):
@@ -410,14 +388,9 @@ class LocalizedDateTests(TestCase):
text = f.widget._format_value(result)
self.assertEqual(text, "21.12.2010")
-class CustomDateInputFormatsTests(TestCase):
- def setUp(self):
- self.old_DATE_INPUT_FORMATS = settings.DATE_INPUT_FORMATS
- settings.DATE_INPUT_FORMATS = ["%d.%m.%Y", "%d-%m-%Y"]
-
- def tearDown(self):
- settings.DATE_INPUT_FORMATS = self.old_DATE_INPUT_FORMATS
+@override_settings(DATE_INPUT_FORMATS=["%d.%m.%Y", "%d-%m-%Y"])
+class CustomDateInputFormatsTests(TestCase):
def test_dateField(self):
"DateFields can parse dates in the default format"
f = forms.DateField()
@@ -597,20 +570,13 @@ class SimpleDateFormatTests(TestCase):
text = f.widget._format_value(result)
self.assertEqual(text, "2010-12-21")
+
+@override_settings(DATETIME_INPUT_FORMATS=["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"], USE_L10N=True)
class LocalizedDateTimeTests(TestCase):
def setUp(self):
- self.old_DATETIME_INPUT_FORMATS = settings.DATETIME_INPUT_FORMATS
- self.old_USE_L10N = settings.USE_L10N
-
- settings.DATETIME_INPUT_FORMATS = ["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"]
- settings.USE_L10N = True
-
activate('de')
def tearDown(self):
- settings.DATETIME_INPUT_FORMATS = self.old_DATETIME_INPUT_FORMATS
- settings.USE_L10N = self.old_USE_L10N
-
deactivate()
def test_dateTimeField(self):
@@ -706,14 +672,8 @@ class LocalizedDateTimeTests(TestCase):
self.assertEqual(text, "21.12.2010 13:30:00")
+@override_settings(DATETIME_INPUT_FORMATS=["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"])
class CustomDateTimeInputFormatsTests(TestCase):
- def setUp(self):
- self.old_DATETIME_INPUT_FORMATS = settings.DATETIME_INPUT_FORMATS
- settings.DATETIME_INPUT_FORMATS = ["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"]
-
- def tearDown(self):
- settings.DATETIME_INPUT_FORMATS = self.old_DATETIME_INPUT_FORMATS
-
def test_dateTimeField(self):
"DateTimeFields can parse dates in the default format"
f = forms.DateTimeField()
diff --git a/tests/regressiontests/forms/tests/models.py b/tests/regressiontests/forms/tests/models.py
index c351509cee..be75643b28 100644
--- a/tests/regressiontests/forms/tests/models.py
+++ b/tests/regressiontests/forms/tests/models.py
@@ -11,7 +11,7 @@ from django.test import TestCase
from django.utils import six
from ..models import (ChoiceOptionModel, ChoiceFieldModel, FileModel, Group,
- BoundaryModel, Defaults)
+ BoundaryModel, Defaults, OptionalMultiChoiceModel)
class ChoiceFieldForm(ModelForm):
@@ -19,6 +19,11 @@ class ChoiceFieldForm(ModelForm):
model = ChoiceFieldModel
+class OptionalMultiChoiceModelForm(ModelForm):
+ class Meta:
+ model = OptionalMultiChoiceModel
+
+
class FileForm(Form):
file1 = FileField()
@@ -34,6 +39,21 @@ class TestTicket12510(TestCase):
field = ModelChoiceField(Group.objects.order_by('-name'))
self.assertEqual('a', field.clean(self.groups[0].pk).name)
+
+class TestTicket14567(TestCase):
+ """
+ Check that the return values of ModelMultipleChoiceFields are QuerySets
+ """
+ def test_empty_queryset_return(self):
+ "If a model's ManyToManyField has blank=True and is saved with no data, a queryset is returned."
+ form = OptionalMultiChoiceModelForm({'multi_choice_optional': '', 'multi_choice': ['1']})
+ self.assertTrue(form.is_valid())
+ # Check that the empty value is a QuerySet
+ self.assertTrue(isinstance(form.cleaned_data['multi_choice_optional'], models.query.QuerySet))
+ # While we're at it, test whether a QuerySet is returned if there *is* a value.
+ self.assertTrue(isinstance(form.cleaned_data['multi_choice'], models.query.QuerySet))
+
+
class ModelFormCallableModelDefault(TestCase):
def test_no_empty_option(self):
"If a model's ForeignKey has blank=False and a default, no empty option is created (Refs #10792)."
@@ -103,7 +123,6 @@ class ModelFormCallableModelDefault(TestCase):
<input type="hidden" name="initial-multi_choice_int" value="3" id="initial-id_multi_choice_int_1" /> <span class="helptext"> Hold down "Control", or "Command" on a Mac, to select more than one.</span></p>""")
-
class FormsModelTestCase(TestCase):
def test_unicode_filename(self):
# FileModel with unicode filename and data #########################
diff --git a/tests/regressiontests/forms/tests/widgets.py b/tests/regressiontests/forms/tests/widgets.py
index 104144b288..4bdd3f76ea 100644
--- a/tests/regressiontests/forms/tests/widgets.py
+++ b/tests/regressiontests/forms/tests/widgets.py
@@ -4,7 +4,6 @@ from __future__ import unicode_literals
import copy
import datetime
-from django.conf import settings
from django.core.files.uploadedfile import SimpleUploadedFile
from django.forms import *
from django.forms.widgets import RadioFieldRenderer
@@ -13,6 +12,7 @@ from django.utils.safestring import mark_safe
from django.utils import six
from django.utils.translation import activate, deactivate
from django.test import TestCase
+from django.test.utils import override_settings
from django.utils.encoding import python_2_unicode_compatible
@@ -989,16 +989,14 @@ class NullBooleanSelectLazyForm(Form):
"""Form to test for lazy evaluation. Refs #17190"""
bool = BooleanField(widget=NullBooleanSelect())
+@override_settings(USE_L10N=True)
class FormsI18NWidgetsTestCase(TestCase):
def setUp(self):
super(FormsI18NWidgetsTestCase, self).setUp()
- self.old_use_l10n = getattr(settings, 'USE_L10N', False)
- settings.USE_L10N = True
activate('de-at')
def tearDown(self):
deactivate()
- settings.USE_L10N = self.old_use_l10n
super(FormsI18NWidgetsTestCase, self).tearDown()
def test_splitdatetime(self):
diff --git a/tests/regressiontests/generic_views/dates.py b/tests/regressiontests/generic_views/dates.py
index c2fa71b376..0c565daf9f 100644
--- a/tests/regressiontests/generic_views/dates.py
+++ b/tests/regressiontests/generic_views/dates.py
@@ -23,29 +23,30 @@ requires_tz_support = skipUnless(TZ_SUPPORT,
"time zone, but your operating system isn't able to do that.")
+def _make_books(n, base_date):
+ for i in range(n):
+ b = Book.objects.create(
+ name='Book %d' % i,
+ slug='book-%d' % i,
+ pages=100+i,
+ pubdate=base_date - datetime.timedelta(days=i))
+
class ArchiveIndexViewTests(TestCase):
fixtures = ['generic-views-test-data.json']
urls = 'regressiontests.generic_views.urls'
- def _make_books(self, n, base_date):
- for i in range(n):
- b = Book.objects.create(
- name='Book %d' % i,
- slug='book-%d' % i,
- pages=100+i,
- pubdate=base_date - datetime.timedelta(days=1))
def test_archive_view(self):
res = self.client.get('/dates/books/')
self.assertEqual(res.status_code, 200)
- self.assertEqual(res.context['date_list'], Book.objects.dates('pubdate', 'year')[::-1])
+ self.assertEqual(list(res.context['date_list']), list(Book.objects.dates('pubdate', 'year', 'DESC')))
self.assertEqual(list(res.context['latest']), list(Book.objects.all()))
self.assertTemplateUsed(res, 'generic_views/book_archive.html')
def test_archive_view_context_object_name(self):
res = self.client.get('/dates/books/context_object_name/')
self.assertEqual(res.status_code, 200)
- self.assertEqual(res.context['date_list'], Book.objects.dates('pubdate', 'year')[::-1])
+ self.assertEqual(list(res.context['date_list']), list(Book.objects.dates('pubdate', 'year', 'DESC')))
self.assertEqual(list(res.context['thingies']), list(Book.objects.all()))
self.assertFalse('latest' in res.context)
self.assertTemplateUsed(res, 'generic_views/book_archive.html')
@@ -65,14 +66,14 @@ class ArchiveIndexViewTests(TestCase):
def test_archive_view_template(self):
res = self.client.get('/dates/books/template_name/')
self.assertEqual(res.status_code, 200)
- self.assertEqual(res.context['date_list'], Book.objects.dates('pubdate', 'year')[::-1])
+ self.assertEqual(list(res.context['date_list']), list(Book.objects.dates('pubdate', 'year', 'DESC')))
self.assertEqual(list(res.context['latest']), list(Book.objects.all()))
self.assertTemplateUsed(res, 'generic_views/list.html')
def test_archive_view_template_suffix(self):
res = self.client.get('/dates/books/template_name_suffix/')
self.assertEqual(res.status_code, 200)
- self.assertEqual(res.context['date_list'], Book.objects.dates('pubdate', 'year')[::-1])
+ self.assertEqual(list(res.context['date_list']), list(Book.objects.dates('pubdate', 'year', 'DESC')))
self.assertEqual(list(res.context['latest']), list(Book.objects.all()))
self.assertTemplateUsed(res, 'generic_views/book_detail.html')
@@ -82,13 +83,13 @@ class ArchiveIndexViewTests(TestCase):
def test_archive_view_by_month(self):
res = self.client.get('/dates/books/by_month/')
self.assertEqual(res.status_code, 200)
- self.assertEqual(res.context['date_list'], Book.objects.dates('pubdate', 'month')[::-1])
+ self.assertEqual(list(res.context['date_list']), list(Book.objects.dates('pubdate', 'month', 'DESC')))
def test_paginated_archive_view(self):
- self._make_books(20, base_date=datetime.date.today())
+ _make_books(20, base_date=datetime.date.today())
res = self.client.get('/dates/books/paginated/')
self.assertEqual(res.status_code, 200)
- self.assertEqual(res.context['date_list'], Book.objects.dates('pubdate', 'year')[::-1])
+ self.assertEqual(list(res.context['date_list']), list(Book.objects.dates('pubdate', 'year', 'DESC')))
self.assertEqual(list(res.context['latest']), list(Book.objects.all()[0:10]))
self.assertTemplateUsed(res, 'generic_views/book_archive.html')
@@ -99,7 +100,7 @@ class ArchiveIndexViewTests(TestCase):
def test_paginated_archive_view_does_not_load_entire_table(self):
# Regression test for #18087
- self._make_books(20, base_date=datetime.date.today())
+ _make_books(20, base_date=datetime.date.today())
# 1 query for years list + 1 query for books
with self.assertNumQueries(2):
self.client.get('/dates/books/')
@@ -124,6 +125,13 @@ class ArchiveIndexViewTests(TestCase):
res = self.client.get('/dates/booksignings/')
self.assertEqual(res.status_code, 200)
+ def test_date_list_order(self):
+ """date_list should be sorted descending in index"""
+ _make_books(5, base_date=datetime.date(2011, 12, 25))
+ res = self.client.get('/dates/books/')
+ self.assertEqual(res.status_code, 200)
+ self.assertEqual(list(res.context['date_list']), list(reversed(sorted(res.context['date_list']))))
+
class YearArchiveViewTests(TestCase):
fixtures = ['generic-views-test-data.json']
@@ -202,6 +210,12 @@ class YearArchiveViewTests(TestCase):
res = self.client.get('/dates/booksignings/2008/')
self.assertEqual(res.status_code, 200)
+ def test_date_list_order(self):
+ """date_list should be sorted ascending in year view"""
+ _make_books(10, base_date=datetime.date(2011, 12, 25))
+ res = self.client.get('/dates/books/2011/')
+ self.assertEqual(list(res.context['date_list']), list(sorted(res.context['date_list'])))
+
class MonthArchiveViewTests(TestCase):
fixtures = ['generic-views-test-data.json']
@@ -322,6 +336,12 @@ class MonthArchiveViewTests(TestCase):
res = self.client.get('/dates/booksignings/2008/apr/')
self.assertEqual(res.status_code, 200)
+ def test_date_list_order(self):
+ """date_list should be sorted ascending in month view"""
+ _make_books(10, base_date=datetime.date(2011, 12, 25))
+ res = self.client.get('/dates/books/2011/dec/')
+ self.assertEqual(list(res.context['date_list']), list(sorted(res.context['date_list'])))
+
class WeekArchiveViewTests(TestCase):
fixtures = ['generic-views-test-data.json']
diff --git a/tests/regressiontests/handlers/tests.py b/tests/regressiontests/handlers/tests.py
index 34863b6493..8676a448d9 100644
--- a/tests/regressiontests/handlers/tests.py
+++ b/tests/regressiontests/handlers/tests.py
@@ -1,27 +1,23 @@
-from django.conf import settings
from django.core.handlers.wsgi import WSGIHandler
from django.test import RequestFactory
+from django.test.utils import override_settings
from django.utils import unittest
-
class HandlerTests(unittest.TestCase):
+ # Mangle settings so the handler will fail
+ @override_settings(MIDDLEWARE_CLASSES=42)
def test_lock_safety(self):
"""
Tests for bug #11193 (errors inside middleware shouldn't leave
the initLock locked).
"""
- # Mangle settings so the handler will fail
- old_middleware_classes = settings.MIDDLEWARE_CLASSES
- settings.MIDDLEWARE_CLASSES = 42
# Try running the handler, it will fail in load_middleware
handler = WSGIHandler()
self.assertEqual(handler.initLock.locked(), False)
with self.assertRaises(Exception):
handler(None, None)
self.assertEqual(handler.initLock.locked(), False)
- # Reset settings
- settings.MIDDLEWARE_CLASSES = old_middleware_classes
def test_bad_path_info(self):
"""Tests for bug #15672 ('request' referenced before assignment)"""
diff --git a/tests/regressiontests/localflavor/ar/__init__.py b/tests/regressiontests/http_utils/__init__.py
index e69de29bb2..e69de29bb2 100644
--- a/tests/regressiontests/localflavor/ar/__init__.py
+++ b/tests/regressiontests/http_utils/__init__.py
diff --git a/tests/regressiontests/localflavor/at/__init__.py b/tests/regressiontests/http_utils/models.py
index e69de29bb2..e69de29bb2 100644
--- a/tests/regressiontests/localflavor/at/__init__.py
+++ b/tests/regressiontests/http_utils/models.py
diff --git a/tests/regressiontests/http_utils/tests.py b/tests/regressiontests/http_utils/tests.py
new file mode 100644
index 0000000000..7dfd24d721
--- /dev/null
+++ b/tests/regressiontests/http_utils/tests.py
@@ -0,0 +1,45 @@
+from __future__ import unicode_literals
+
+from django.http import HttpRequest, HttpResponse, StreamingHttpResponse
+from django.http.utils import conditional_content_removal
+from django.test import TestCase
+
+
+class HttpUtilTests(TestCase):
+
+ def test_conditional_content_removal(self):
+ """
+ Tests that content is removed from regular and streaming responses with
+ a status_code of 100-199, 204, 304 or a method of "HEAD".
+ """
+ req = HttpRequest()
+
+ # Do nothing for 200 responses.
+ res = HttpResponse('abc')
+ conditional_content_removal(req, res)
+ self.assertEqual(res.content, b'abc')
+
+ res = StreamingHttpResponse(['abc'])
+ conditional_content_removal(req, res)
+ self.assertEqual(b''.join(res), b'abc')
+
+ # Strip content for some status codes.
+ for status_code in (100, 150, 199, 204, 304):
+ res = HttpResponse('abc', status=status_code)
+ conditional_content_removal(req, res)
+ self.assertEqual(res.content, b'')
+
+ res = StreamingHttpResponse(['abc'], status=status_code)
+ conditional_content_removal(req, res)
+ self.assertEqual(b''.join(res), b'')
+
+ # Strip content for HEAD requests.
+ req.method = 'HEAD'
+
+ res = HttpResponse('abc')
+ conditional_content_removal(req, res)
+ self.assertEqual(res.content, b'')
+
+ res = StreamingHttpResponse(['abc'])
+ conditional_content_removal(req, res)
+ self.assertEqual(b''.join(res), b'')
diff --git a/tests/regressiontests/httpwrappers/abc.txt b/tests/regressiontests/httpwrappers/abc.txt
new file mode 100644
index 0000000000..6bac42b3ad
--- /dev/null
+++ b/tests/regressiontests/httpwrappers/abc.txt
@@ -0,0 +1 @@
+random content
diff --git a/tests/regressiontests/httpwrappers/tests.py b/tests/regressiontests/httpwrappers/tests.py
index 4c6aed1b97..553b6ecff4 100644
--- a/tests/regressiontests/httpwrappers/tests.py
+++ b/tests/regressiontests/httpwrappers/tests.py
@@ -2,12 +2,14 @@
from __future__ import unicode_literals
import copy
+import os
import pickle
+import warnings
from django.core.exceptions import SuspiciousOperation
from django.http import (QueryDict, HttpResponse, HttpResponseRedirect,
HttpResponsePermanentRedirect, HttpResponseNotAllowed,
- HttpResponseNotModified,
+ HttpResponseNotModified, StreamingHttpResponse,
SimpleCookie, BadHeaderError,
parse_cookie)
from django.test import TestCase
@@ -127,10 +129,14 @@ class QueryDictTests(unittest.TestCase):
self.assertTrue(q.has_key('foo'))
self.assertTrue('foo' in q)
- self.assertEqual(list(six.iteritems(q)), [('foo', 'another'), ('name', 'john')])
- self.assertEqual(list(six.iterlists(q)), [('foo', ['bar', 'baz', 'another']), ('name', ['john'])])
- self.assertEqual(list(six.iterkeys(q)), ['foo', 'name'])
- self.assertEqual(list(six.itervalues(q)), ['another', 'john'])
+ self.assertEqual(sorted(list(six.iteritems(q))),
+ [('foo', 'another'), ('name', 'john')])
+ self.assertEqual(sorted(list(six.iterlists(q))),
+ [('foo', ['bar', 'baz', 'another']), ('name', ['john'])])
+ self.assertEqual(sorted(list(six.iterkeys(q))),
+ ['foo', 'name'])
+ self.assertEqual(sorted(list(six.itervalues(q))),
+ ['another', 'john'])
self.assertEqual(len(q), 2)
q.update({'foo': 'hello'})
@@ -312,23 +318,61 @@ class HttpResponseTests(unittest.TestCase):
r.content = [1, 2, 3]
self.assertEqual(r.content, b'123')
- #test retrieval explicitly using iter and odd inputs
+ #test retrieval explicitly using iter (deprecated) and odd inputs
r = HttpResponse()
r.content = ['1', '2', 3, '\u079e']
- my_iter = r.__iter__()
- result = list(my_iter)
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter("always", PendingDeprecationWarning)
+ my_iter = iter(r)
+ self.assertEqual(w[0].category, PendingDeprecationWarning)
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter("always", PendingDeprecationWarning)
+ result = list(my_iter)
+ self.assertEqual(w[0].category, PendingDeprecationWarning)
#'\xde\x9e' == unichr(1950).encode('utf-8')
self.assertEqual(result, [b'1', b'2', b'3', b'\xde\x9e'])
self.assertEqual(r.content, b'123\xde\x9e')
#with Content-Encoding header
- r = HttpResponse([1,1,2,4,8])
+ r = HttpResponse()
r['Content-Encoding'] = 'winning'
- self.assertEqual(r.content, b'11248')
- r.content = ['\u079e',]
- self.assertRaises(UnicodeEncodeError,
+ r.content = [b'abc', b'def']
+ self.assertEqual(r.content, b'abcdef')
+ r.content = ['\u079e']
+ self.assertRaises(TypeError if six.PY3 else UnicodeEncodeError,
getattr, r, 'content')
+ # .content can safely be accessed multiple times.
+ r = HttpResponse(iter(['hello', 'world']))
+ self.assertEqual(r.content, r.content)
+ self.assertEqual(r.content, b'helloworld')
+ # accessing the iterator works (once) after accessing .content
+ self.assertEqual(b''.join(r), b'helloworld')
+ self.assertEqual(b''.join(r), b'')
+ # accessing .content still works
+ self.assertEqual(r.content, b'helloworld')
+
+ # XXX accessing .content doesn't work if the response was iterated first
+ # XXX change this when the deprecation completes in HttpResponse
+ r = HttpResponse(iter(['hello', 'world']))
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", PendingDeprecationWarning)
+ self.assertEqual(b''.join(r), b'helloworld')
+ self.assertEqual(r.content, b'') # not the expected result!
+
+ # additional content can be written to the response.
+ r = HttpResponse(iter(['hello', 'world']))
+ self.assertEqual(r.content, b'helloworld')
+ r.write('!')
+ self.assertEqual(r.content, b'helloworld!')
+
+ def test_iterator_isnt_rewound(self):
+ # Regression test for #13222
+ r = HttpResponse('abc')
+ i = iter(r)
+ self.assertEqual(list(i), [b'abc'])
+ self.assertEqual(list(i), [])
+
def test_file_interface(self):
r = HttpResponse()
r.write(b"hello")
@@ -337,7 +381,9 @@ class HttpResponseTests(unittest.TestCase):
self.assertEqual(r.tell(), 17)
r = HttpResponse(['abc'])
- self.assertRaises(Exception, r.write, 'def')
+ r.write('def')
+ self.assertEqual(r.tell(), 6)
+ self.assertEqual(r.content, b'abcdef')
def test_unsafe_redirect(self):
bad_urls = [
@@ -351,7 +397,6 @@ class HttpResponseTests(unittest.TestCase):
self.assertRaises(SuspiciousOperation,
HttpResponsePermanentRedirect, url)
-
class HttpResponseSubclassesTests(TestCase):
def test_redirect(self):
response = HttpResponseRedirect('/redirected/')
@@ -379,6 +424,115 @@ class HttpResponseSubclassesTests(TestCase):
content_type='text/html')
self.assertContains(response, 'Only the GET method is allowed', status_code=405)
+class StreamingHttpResponseTests(TestCase):
+ def test_streaming_response(self):
+ r = StreamingHttpResponse(iter(['hello', 'world']))
+
+ # iterating over the response itself yields bytestring chunks.
+ chunks = list(r)
+ self.assertEqual(chunks, [b'hello', b'world'])
+ for chunk in chunks:
+ self.assertIsInstance(chunk, six.binary_type)
+
+ # and the response can only be iterated once.
+ self.assertEqual(list(r), [])
+
+ # even when a sequence that can be iterated many times, like a list,
+ # is given as content.
+ r = StreamingHttpResponse(['abc', 'def'])
+ self.assertEqual(list(r), [b'abc', b'def'])
+ self.assertEqual(list(r), [])
+
+ # streaming responses don't have a `content` attribute.
+ self.assertFalse(hasattr(r, 'content'))
+
+ # and you can't accidentally assign to a `content` attribute.
+ with self.assertRaises(AttributeError):
+ r.content = 'xyz'
+
+ # but they do have a `streaming_content` attribute.
+ self.assertTrue(hasattr(r, 'streaming_content'))
+
+ # that exists so we can check if a response is streaming, and wrap or
+ # replace the content iterator.
+ r.streaming_content = iter(['abc', 'def'])
+ r.streaming_content = (chunk.upper() for chunk in r.streaming_content)
+ self.assertEqual(list(r), [b'ABC', b'DEF'])
+
+ # coercing a streaming response to bytes doesn't return a complete HTTP
+ # message like a regular response does. it only gives us the headers.
+ r = StreamingHttpResponse(iter(['hello', 'world']))
+ self.assertEqual(
+ six.binary_type(r), b'Content-Type: text/html; charset=utf-8')
+
+ # and this won't consume its content.
+ self.assertEqual(list(r), [b'hello', b'world'])
+
+ # additional content cannot be written to the response.
+ r = StreamingHttpResponse(iter(['hello', 'world']))
+ with self.assertRaises(Exception):
+ r.write('!')
+
+ # and we can't tell the current position.
+ with self.assertRaises(Exception):
+ r.tell()
+
+class FileCloseTests(TestCase):
+ def test_response(self):
+ filename = os.path.join(os.path.dirname(__file__), 'abc.txt')
+
+ # file isn't closed until we close the response.
+ file1 = open(filename)
+ r = HttpResponse(file1)
+ self.assertFalse(file1.closed)
+ r.close()
+ self.assertTrue(file1.closed)
+
+ # don't automatically close file when we finish iterating the response.
+ file1 = open(filename)
+ r = HttpResponse(file1)
+ self.assertFalse(file1.closed)
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", PendingDeprecationWarning)
+ list(r)
+ self.assertFalse(file1.closed)
+ r.close()
+ self.assertTrue(file1.closed)
+
+ # when multiple file are assigned as content, make sure they are all
+ # closed with the response.
+ file1 = open(filename)
+ file2 = open(filename)
+ r = HttpResponse(file1)
+ r.content = file2
+ self.assertFalse(file1.closed)
+ self.assertFalse(file2.closed)
+ r.close()
+ self.assertTrue(file1.closed)
+ self.assertTrue(file2.closed)
+
+ def test_streaming_response(self):
+ filename = os.path.join(os.path.dirname(__file__), 'abc.txt')
+
+ # file isn't closed until we close the response.
+ file1 = open(filename)
+ r = StreamingHttpResponse(file1)
+ self.assertFalse(file1.closed)
+ r.close()
+ self.assertTrue(file1.closed)
+
+ # when multiple file are assigned as content, make sure they are all
+ # closed with the response.
+ file1 = open(filename)
+ file2 = open(filename)
+ r = StreamingHttpResponse(file1)
+ r.streaming_content = file2
+ self.assertFalse(file1.closed)
+ self.assertFalse(file2.closed)
+ r.close()
+ self.assertTrue(file1.closed)
+ self.assertTrue(file2.closed)
+
class CookieTests(unittest.TestCase):
def test_encode(self):
"""
@@ -419,7 +573,7 @@ class CookieTests(unittest.TestCase):
"""
Test that a repeated non-standard name doesn't affect all cookies. Ticket #15852
"""
- self.assertTrue('good_cookie' in parse_cookie('a,=b; a,=c; good_cookie=yes').keys())
+ self.assertTrue('good_cookie' in parse_cookie('a:=b; a:=c; good_cookie=yes').keys())
def test_httponly_after_load(self):
"""
diff --git a/tests/regressiontests/i18n/commands/extraction.py b/tests/regressiontests/i18n/commands/extraction.py
index 29d9e277ff..ca2c3cc026 100644
--- a/tests/regressiontests/i18n/commands/extraction.py
+++ b/tests/regressiontests/i18n/commands/extraction.py
@@ -156,6 +156,21 @@ class BasicExtractorTests(ExtractorTests):
self.assertTrue('msgctxt "Special blocktrans context #4"' in po_contents)
self.assertTrue("Translatable literal #8d" in po_contents)
+ def test_context_in_single_quotes(self):
+ os.chdir(self.test_dir)
+ management.call_command('makemessages', locale=LOCALE, verbosity=0)
+ self.assertTrue(os.path.exists(self.PO_FILE))
+ with open(self.PO_FILE, 'r') as fp:
+ po_contents = fp.read()
+ # {% trans %}
+ self.assertTrue('msgctxt "Context wrapped in double quotes"' in po_contents)
+ self.assertTrue('msgctxt "Context wrapped in single quotes"' in po_contents)
+
+ # {% blocktrans %}
+ self.assertTrue('msgctxt "Special blocktrans context wrapped in double quotes"' in po_contents)
+ self.assertTrue('msgctxt "Special blocktrans context wrapped in single quotes"' in po_contents)
+
+
class JavascriptExtractorTests(ExtractorTests):
PO_FILE='locale/%s/LC_MESSAGES/djangojs.po' % LOCALE
diff --git a/tests/regressiontests/i18n/commands/templates/test.html b/tests/regressiontests/i18n/commands/templates/test.html
index 5789346984..e7d7f3ca53 100644
--- a/tests/regressiontests/i18n/commands/templates/test.html
+++ b/tests/regressiontests/i18n/commands/templates/test.html
@@ -77,3 +77,8 @@ continued here.{% endcomment %}
{% trans "Shouldn't double escape this sequence %% either" context "ctx1" %}
{% trans "Looks like a str fmt spec %s but shouldn't be interpreted as such" %}
{% trans "Looks like a str fmt spec % o but shouldn't be interpreted as such" %}
+
+{% trans "Translatable literal with context wrapped in single quotes" context 'Context wrapped in single quotes' as var %}
+{% trans "Translatable literal with context wrapped in double quotes" context "Context wrapped in double quotes" as var %}
+{% blocktrans context 'Special blocktrans context wrapped in single quotes' %}Translatable literal with context wrapped in single quotes{% endblocktrans %}
+{% blocktrans context "Special blocktrans context wrapped in double quotes" %}Translatable literal with context wrapped in double quotes{% endblocktrans %} \ No newline at end of file
diff --git a/tests/regressiontests/i18n/tests.py b/tests/regressiontests/i18n/tests.py
index bce3d617d2..4054f85ef0 100644
--- a/tests/regressiontests/i18n/tests.py
+++ b/tests/regressiontests/i18n/tests.py
@@ -23,7 +23,7 @@ from django.utils import six
from django.utils.six import PY3
from django.utils.translation import (ugettext, ugettext_lazy, activate,
deactivate, gettext_lazy, pgettext, npgettext, to_locale,
- get_language_info, get_language, get_language_from_request)
+ get_language_info, get_language, get_language_from_request, trans_real)
from .commands.tests import can_run_extraction_tests, can_run_compilation_tests
@@ -45,6 +45,9 @@ from .patterns.tests import (URLRedirectWithoutTrailingSlashTests,
here = os.path.dirname(os.path.abspath(__file__))
+extended_locale_paths = settings.LOCALE_PATHS + (
+ os.path.join(here, 'other', 'locale'),
+)
class TranslationTests(TestCase):
@@ -86,139 +89,129 @@ class TranslationTests(TestCase):
s2 = pickle.loads(pickle.dumps(s1))
self.assertEqual(six.text_type(s2), "test")
+ @override_settings(LOCALE_PATHS=extended_locale_paths)
def test_pgettext(self):
- # Reset translation catalog to include other/locale/de
- extended_locale_paths = settings.LOCALE_PATHS + (
- os.path.join(here, 'other', 'locale'),
- )
- with self.settings(LOCALE_PATHS=extended_locale_paths):
- from django.utils.translation import trans_real
- trans_real._active = local()
- trans_real._translations = {}
- with translation.override('de'):
- self.assertEqual(pgettext("unexisting", "May"), "May")
- self.assertEqual(pgettext("month name", "May"), "Mai")
- self.assertEqual(pgettext("verb", "May"), "Kann")
- self.assertEqual(npgettext("search", "%d result", "%d results", 4) % 4, "4 Resultate")
+ trans_real._active = local()
+ trans_real._translations = {}
+ with translation.override('de'):
+ self.assertEqual(pgettext("unexisting", "May"), "May")
+ self.assertEqual(pgettext("month name", "May"), "Mai")
+ self.assertEqual(pgettext("verb", "May"), "Kann")
+ self.assertEqual(npgettext("search", "%d result", "%d results", 4) % 4, "4 Resultate")
+ @override_settings(LOCALE_PATHS=extended_locale_paths)
def test_template_tags_pgettext(self):
"""
Ensure that message contexts are taken into account the {% trans %} and
{% blocktrans %} template tags.
Refs #14806.
"""
- # Reset translation catalog to include other/locale/de
- extended_locale_paths = settings.LOCALE_PATHS + (
- os.path.join(here, 'other', 'locale'),
- )
- with self.settings(LOCALE_PATHS=extended_locale_paths):
- from django.utils.translation import trans_real
- trans_real._active = local()
- trans_real._translations = {}
- with translation.override('de'):
+ trans_real._active = local()
+ trans_real._translations = {}
+ with translation.override('de'):
- # {% trans %} -----------------------------------
+ # {% trans %} -----------------------------------
- # Inexisting context...
- t = Template('{% load i18n %}{% trans "May" context "unexisting" %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, 'May')
+ # Inexisting context...
+ t = Template('{% load i18n %}{% trans "May" context "unexisting" %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, 'May')
- # Existing context...
- # Using a literal
- t = Template('{% load i18n %}{% trans "May" context "month name" %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, 'Mai')
- t = Template('{% load i18n %}{% trans "May" context "verb" %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, 'Kann')
+ # Existing context...
+ # Using a literal
+ t = Template('{% load i18n %}{% trans "May" context "month name" %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, 'Mai')
+ t = Template('{% load i18n %}{% trans "May" context "verb" %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, 'Kann')
- # Using a variable
- t = Template('{% load i18n %}{% trans "May" context message_context %}')
- rendered = t.render(Context({'message_context': 'month name'}))
- self.assertEqual(rendered, 'Mai')
- t = Template('{% load i18n %}{% trans "May" context message_context %}')
- rendered = t.render(Context({'message_context': 'verb'}))
- self.assertEqual(rendered, 'Kann')
+ # Using a variable
+ t = Template('{% load i18n %}{% trans "May" context message_context %}')
+ rendered = t.render(Context({'message_context': 'month name'}))
+ self.assertEqual(rendered, 'Mai')
+ t = Template('{% load i18n %}{% trans "May" context message_context %}')
+ rendered = t.render(Context({'message_context': 'verb'}))
+ self.assertEqual(rendered, 'Kann')
- # Using a filter
- t = Template('{% load i18n %}{% trans "May" context message_context|lower %}')
- rendered = t.render(Context({'message_context': 'MONTH NAME'}))
- self.assertEqual(rendered, 'Mai')
- t = Template('{% load i18n %}{% trans "May" context message_context|lower %}')
- rendered = t.render(Context({'message_context': 'VERB'}))
- self.assertEqual(rendered, 'Kann')
+ # Using a filter
+ t = Template('{% load i18n %}{% trans "May" context message_context|lower %}')
+ rendered = t.render(Context({'message_context': 'MONTH NAME'}))
+ self.assertEqual(rendered, 'Mai')
+ t = Template('{% load i18n %}{% trans "May" context message_context|lower %}')
+ rendered = t.render(Context({'message_context': 'VERB'}))
+ self.assertEqual(rendered, 'Kann')
- # Using 'as'
- t = Template('{% load i18n %}{% trans "May" context "month name" as var %}Value: {{ var }}')
- rendered = t.render(Context())
- self.assertEqual(rendered, 'Value: Mai')
- t = Template('{% load i18n %}{% trans "May" as var context "verb" %}Value: {{ var }}')
- rendered = t.render(Context())
- self.assertEqual(rendered, 'Value: Kann')
+ # Using 'as'
+ t = Template('{% load i18n %}{% trans "May" context "month name" as var %}Value: {{ var }}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, 'Value: Mai')
+ t = Template('{% load i18n %}{% trans "May" as var context "verb" %}Value: {{ var }}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, 'Value: Kann')
- # Mis-uses
- self.assertRaises(TemplateSyntaxError, Template, '{% load i18n %}{% trans "May" context as var %}{{ var }}')
- self.assertRaises(TemplateSyntaxError, Template, '{% load i18n %}{% trans "May" as var context %}{{ var }}')
+ # Mis-uses
+ self.assertRaises(TemplateSyntaxError, Template, '{% load i18n %}{% trans "May" context as var %}{{ var }}')
+ self.assertRaises(TemplateSyntaxError, Template, '{% load i18n %}{% trans "May" as var context %}{{ var }}')
- # {% blocktrans %} ------------------------------
+ # {% blocktrans %} ------------------------------
- # Inexisting context...
- t = Template('{% load i18n %}{% blocktrans context "unexisting" %}May{% endblocktrans %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, 'May')
+ # Inexisting context...
+ t = Template('{% load i18n %}{% blocktrans context "unexisting" %}May{% endblocktrans %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, 'May')
- # Existing context...
- # Using a literal
- t = Template('{% load i18n %}{% blocktrans context "month name" %}May{% endblocktrans %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, 'Mai')
- t = Template('{% load i18n %}{% blocktrans context "verb" %}May{% endblocktrans %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, 'Kann')
+ # Existing context...
+ # Using a literal
+ t = Template('{% load i18n %}{% blocktrans context "month name" %}May{% endblocktrans %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, 'Mai')
+ t = Template('{% load i18n %}{% blocktrans context "verb" %}May{% endblocktrans %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, 'Kann')
- # Using a variable
- t = Template('{% load i18n %}{% blocktrans context message_context %}May{% endblocktrans %}')
- rendered = t.render(Context({'message_context': 'month name'}))
- self.assertEqual(rendered, 'Mai')
- t = Template('{% load i18n %}{% blocktrans context message_context %}May{% endblocktrans %}')
- rendered = t.render(Context({'message_context': 'verb'}))
- self.assertEqual(rendered, 'Kann')
+ # Using a variable
+ t = Template('{% load i18n %}{% blocktrans context message_context %}May{% endblocktrans %}')
+ rendered = t.render(Context({'message_context': 'month name'}))
+ self.assertEqual(rendered, 'Mai')
+ t = Template('{% load i18n %}{% blocktrans context message_context %}May{% endblocktrans %}')
+ rendered = t.render(Context({'message_context': 'verb'}))
+ self.assertEqual(rendered, 'Kann')
- # Using a filter
- t = Template('{% load i18n %}{% blocktrans context message_context|lower %}May{% endblocktrans %}')
- rendered = t.render(Context({'message_context': 'MONTH NAME'}))
- self.assertEqual(rendered, 'Mai')
- t = Template('{% load i18n %}{% blocktrans context message_context|lower %}May{% endblocktrans %}')
- rendered = t.render(Context({'message_context': 'VERB'}))
- self.assertEqual(rendered, 'Kann')
+ # Using a filter
+ t = Template('{% load i18n %}{% blocktrans context message_context|lower %}May{% endblocktrans %}')
+ rendered = t.render(Context({'message_context': 'MONTH NAME'}))
+ self.assertEqual(rendered, 'Mai')
+ t = Template('{% load i18n %}{% blocktrans context message_context|lower %}May{% endblocktrans %}')
+ rendered = t.render(Context({'message_context': 'VERB'}))
+ self.assertEqual(rendered, 'Kann')
- # Using 'count'
- t = Template('{% load i18n %}{% blocktrans count number=1 context "super search" %}{{ number }} super result{% plural %}{{ number }} super results{% endblocktrans %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, '1 Super-Ergebnis')
- t = Template('{% load i18n %}{% blocktrans count number=2 context "super search" %}{{ number }} super result{% plural %}{{ number }} super results{% endblocktrans %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, '2 Super-Ergebnisse')
- t = Template('{% load i18n %}{% blocktrans context "other super search" count number=1 %}{{ number }} super result{% plural %}{{ number }} super results{% endblocktrans %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, '1 anderen Super-Ergebnis')
- t = Template('{% load i18n %}{% blocktrans context "other super search" count number=2 %}{{ number }} super result{% plural %}{{ number }} super results{% endblocktrans %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, '2 andere Super-Ergebnisse')
+ # Using 'count'
+ t = Template('{% load i18n %}{% blocktrans count number=1 context "super search" %}{{ number }} super result{% plural %}{{ number }} super results{% endblocktrans %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, '1 Super-Ergebnis')
+ t = Template('{% load i18n %}{% blocktrans count number=2 context "super search" %}{{ number }} super result{% plural %}{{ number }} super results{% endblocktrans %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, '2 Super-Ergebnisse')
+ t = Template('{% load i18n %}{% blocktrans context "other super search" count number=1 %}{{ number }} super result{% plural %}{{ number }} super results{% endblocktrans %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, '1 anderen Super-Ergebnis')
+ t = Template('{% load i18n %}{% blocktrans context "other super search" count number=2 %}{{ number }} super result{% plural %}{{ number }} super results{% endblocktrans %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, '2 andere Super-Ergebnisse')
- # Using 'with'
- t = Template('{% load i18n %}{% blocktrans with num_comments=5 context "comment count" %}There are {{ num_comments }} comments{% endblocktrans %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, 'Es gibt 5 Kommentare')
- t = Template('{% load i18n %}{% blocktrans with num_comments=5 context "other comment count" %}There are {{ num_comments }} comments{% endblocktrans %}')
- rendered = t.render(Context())
- self.assertEqual(rendered, 'Andere: Es gibt 5 Kommentare')
+ # Using 'with'
+ t = Template('{% load i18n %}{% blocktrans with num_comments=5 context "comment count" %}There are {{ num_comments }} comments{% endblocktrans %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, 'Es gibt 5 Kommentare')
+ t = Template('{% load i18n %}{% blocktrans with num_comments=5 context "other comment count" %}There are {{ num_comments }} comments{% endblocktrans %}')
+ rendered = t.render(Context())
+ self.assertEqual(rendered, 'Andere: Es gibt 5 Kommentare')
- # Mis-uses
- self.assertRaises(TemplateSyntaxError, Template, '{% load i18n %}{% blocktrans context with month="May" %}{{ month }}{% endblocktrans %}')
- self.assertRaises(TemplateSyntaxError, Template, '{% load i18n %}{% blocktrans context %}{% endblocktrans %}')
- self.assertRaises(TemplateSyntaxError, Template, '{% load i18n %}{% blocktrans count number=2 context %}{{ number }} super result{% plural %}{{ number }} super results{% endblocktrans %}')
+ # Mis-uses
+ self.assertRaises(TemplateSyntaxError, Template, '{% load i18n %}{% blocktrans context with month="May" %}{{ month }}{% endblocktrans %}')
+ self.assertRaises(TemplateSyntaxError, Template, '{% load i18n %}{% blocktrans context %}{% endblocktrans %}')
+ self.assertRaises(TemplateSyntaxError, Template, '{% load i18n %}{% blocktrans count number=2 context %}{{ number }} super result{% plural %}{{ number }} super results{% endblocktrans %}')
def test_string_concat(self):
@@ -247,8 +240,7 @@ class TranslationTests(TestCase):
Translations on files with mac or dos end of lines will be converted
to unix eof in .po catalogs, and they have to match when retrieved
"""
- from django.utils.translation.trans_real import translation as Trans
- ca_translation = Trans('ca')
+ ca_translation = trans_real.translation('ca')
ca_translation._catalog['Mac\nEOF\n'] = 'Catalan Mac\nEOF\n'
ca_translation._catalog['Win\nEOF\n'] = 'Catalan Win\nEOF\n'
with translation.override('ca', deactivate=True):
@@ -267,9 +259,8 @@ class TranslationTests(TestCase):
"""
Test the to_language function
"""
- from django.utils.translation.trans_real import to_language
- self.assertEqual(to_language('en_US'), 'en-us')
- self.assertEqual(to_language('sr_Lat'), 'sr-lat')
+ self.assertEqual(trans_real.to_language('en_US'), 'en-us')
+ self.assertEqual(trans_real.to_language('sr_Lat'), 'sr-lat')
@override_settings(LOCALE_PATHS=(os.path.join(here, 'other', 'locale'),))
def test_bad_placeholder_1(self):
@@ -278,7 +269,6 @@ class TranslationTests(TestCase):
(%(person)s is translated as %(personne)s in fr.po)
Refs #16516.
"""
- from django.template import Template, Context
with translation.override('fr'):
t = Template('{% load i18n %}{% blocktrans %}My name is {{ person }}.{% endblocktrans %}')
rendered = t.render(Context({'person': 'James'}))
@@ -291,7 +281,6 @@ class TranslationTests(TestCase):
(%(person) misses a 's' in fr.po, causing the string formatting to fail)
Refs #18393.
"""
- from django.template import Template, Context
with translation.override('fr'):
t = Template('{% load i18n %}{% blocktrans %}My other name is {{ person }}.{% endblocktrans %}')
rendered = t.render(Context({'person': 'James'}))
@@ -710,11 +699,11 @@ class MiscTests(TestCase):
values according to the spec (and that we extract all the pieces in
the right order).
"""
- from django.utils.translation.trans_real import parse_accept_lang_header
- p = parse_accept_lang_header
+ p = trans_real.parse_accept_lang_header
# Good headers.
self.assertEqual([('de', 1.0)], p('de'))
self.assertEqual([('en-AU', 1.0)], p('en-AU'))
+ self.assertEqual([('es-419', 1.0)], p('es-419'))
self.assertEqual([('*', 1.0)], p('*;q=1.00'))
self.assertEqual([('en-AU', 0.123)], p('en-AU;q=0.123'))
self.assertEqual([('en-au', 0.5)], p('en-au;q=0.5'))
@@ -739,6 +728,7 @@ class MiscTests(TestCase):
self.assertEqual([], p('da, en-gb;q=0.8, en;q=0.7,#'))
self.assertEqual([], p('de;q=2.0'))
self.assertEqual([], p('de;q=0.a'))
+ self.assertEqual([], p('12-345'))
self.assertEqual([], p(''))
def test_parse_literal_http_header(self):
@@ -809,7 +799,7 @@ class MiscTests(TestCase):
self.assertEqual(g(r), 'zh-cn')
def test_get_language_from_path_real(self):
- from django.utils.translation.trans_real import get_language_from_path as g
+ g = trans_real.get_language_from_path
self.assertEqual(g('/pl/'), 'pl')
self.assertEqual(g('/pl'), 'pl')
self.assertEqual(g('/xyz/'), None)
@@ -820,23 +810,33 @@ class MiscTests(TestCase):
self.assertEqual(g('/pl'), None)
self.assertEqual(g('/xyz/'), None)
+ @override_settings(LOCALE_PATHS=extended_locale_paths)
def test_percent_in_translatable_block(self):
- extended_locale_paths = settings.LOCALE_PATHS + (
- os.path.join(here, 'other', 'locale'),
- )
- with self.settings(LOCALE_PATHS=extended_locale_paths):
- t_sing = Template("{% load i18n %}{% blocktrans %}The result was {{ percent }}%{% endblocktrans %}")
- t_plur = Template("{% load i18n %}{% blocktrans count num as number %}{{ percent }}% represents {{ num }} object{% plural %}{{ percent }}% represents {{ num }} objects{% endblocktrans %}")
- with translation.override('de'):
- self.assertEqual(t_sing.render(Context({'percent': 42})), 'Das Ergebnis war 42%')
- self.assertEqual(t_plur.render(Context({'percent': 42, 'num': 1})), '42% stellt 1 Objekt dar')
- self.assertEqual(t_plur.render(Context({'percent': 42, 'num': 4})), '42% stellt 4 Objekte dar')
+ t_sing = Template("{% load i18n %}{% blocktrans %}The result was {{ percent }}%{% endblocktrans %}")
+ t_plur = Template("{% load i18n %}{% blocktrans count num as number %}{{ percent }}% represents {{ num }} object{% plural %}{{ percent }}% represents {{ num }} objects{% endblocktrans %}")
+ with translation.override('de'):
+ self.assertEqual(t_sing.render(Context({'percent': 42})), 'Das Ergebnis war 42%')
+ self.assertEqual(t_plur.render(Context({'percent': 42, 'num': 1})), '42% stellt 1 Objekt dar')
+ self.assertEqual(t_plur.render(Context({'percent': 42, 'num': 4})), '42% stellt 4 Objekte dar')
+
+ @override_settings(LOCALE_PATHS=extended_locale_paths)
+ def test_percent_formatting_in_blocktrans(self):
+ """
+ Test that using Python's %-formatting is properly escaped in blocktrans,
+ singular or plural
+ """
+ t_sing = Template("{% load i18n %}{% blocktrans %}There are %(num_comments)s comments{% endblocktrans %}")
+ t_plur = Template("{% load i18n %}{% blocktrans count num as number %}%(percent)s% represents {{ num }} object{% plural %}%(percent)s% represents {{ num }} objects{% endblocktrans %}")
+ with translation.override('de'):
+ # Strings won't get translated as they don't match after escaping %
+ self.assertEqual(t_sing.render(Context({'num_comments': 42})), 'There are %(num_comments)s comments')
+ self.assertEqual(t_plur.render(Context({'percent': 42, 'num': 1})), '%(percent)s% represents 1 object')
+ self.assertEqual(t_plur.render(Context({'percent': 42, 'num': 4})), '%(percent)s% represents 4 objects')
class ResolutionOrderI18NTests(TestCase):
def setUp(self):
- from django.utils.translation import trans_real
# Okay, this is brutal, but we have no other choice to fully reset
# the translation framework
trans_real._active = local()
@@ -865,17 +865,9 @@ class AppResolutionOrderI18NTests(ResolutionOrderI18NTests):
def test_app_translation(self):
self.assertUgettext('Date/time', 'APP')
+@override_settings(LOCALE_PATHS=extended_locale_paths)
class LocalePathsResolutionOrderI18NTests(ResolutionOrderI18NTests):
- def setUp(self):
- self.old_locale_paths = settings.LOCALE_PATHS
- settings.LOCALE_PATHS += (os.path.join(here, 'other', 'locale'),)
- super(LocalePathsResolutionOrderI18NTests, self).setUp()
-
- def tearDown(self):
- settings.LOCALE_PATHS = self.old_locale_paths
- super(LocalePathsResolutionOrderI18NTests, self).tearDown()
-
def test_locale_paths_translation(self):
self.assertUgettext('Time', 'LOCALE_PATHS')
diff --git a/tests/regressiontests/localflavor/ar/tests.py b/tests/regressiontests/localflavor/ar/tests.py
deleted file mode 100644
index 0bc228eae9..0000000000
--- a/tests/regressiontests/localflavor/ar/tests.py
+++ /dev/null
@@ -1,103 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.ar.forms import (ARProvinceSelect,
- ARPostalCodeField, ARDNIField, ARCUITField)
-
-from django.test import SimpleTestCase
-
-
-class ARLocalFlavorTests(SimpleTestCase):
- def test_ARProvinceSelect(self):
- f = ARProvinceSelect()
- out = '''<select name="provincias">
-<option value="B">Buenos Aires</option>
-<option value="K">Catamarca</option>
-<option value="H">Chaco</option>
-<option value="U">Chubut</option>
-<option value="C">Ciudad Aut\xf3noma de Buenos Aires</option>
-<option value="X">C\xf3rdoba</option>
-<option value="W">Corrientes</option>
-<option value="E">Entre R\xedos</option>
-<option value="P">Formosa</option>
-<option value="Y">Jujuy</option>
-<option value="L">La Pampa</option>
-<option value="F">La Rioja</option>
-<option value="M">Mendoza</option>
-<option value="N">Misiones</option>
-<option value="Q">Neuqu\xe9n</option>
-<option value="R">R\xedo Negro</option>
-<option value="A" selected="selected">Salta</option>
-<option value="J">San Juan</option>
-<option value="D">San Luis</option>
-<option value="Z">Santa Cruz</option>
-<option value="S">Santa Fe</option>
-<option value="G">Santiago del Estero</option>
-<option value="V">Tierra del Fuego, Ant\xe1rtida e Islas del Atl\xe1ntico Sur</option>
-<option value="T">Tucum\xe1n</option>
-</select>'''
- self.assertHTMLEqual(f.render('provincias', 'A'), out)
-
- def test_ARPostalCodeField(self):
- error_format = ['Enter a postal code in the format NNNN or ANNNNAAA.']
- error_atmost = ['Ensure this value has at most 8 characters (it has 9).']
- error_atleast = ['Ensure this value has at least 4 characters (it has 3).']
- valid = {
- '5000': '5000',
- 'C1064AAB': 'C1064AAB',
- 'c1064AAB': 'C1064AAB',
- 'C1064aab': 'C1064AAB',
- '4400': '4400',
- 'C1064AAB': 'C1064AAB',
- }
- invalid = {
- 'C1064AABB': error_atmost + error_format,
- 'C1064AA': error_format,
- 'C1064AB': error_format,
- '106AAB': error_format,
- '500': error_atleast + error_format,
- '5PPP': error_format,
- }
- self.assertFieldOutput(ARPostalCodeField, valid, invalid)
-
- def test_ARDNIField(self):
- error_length = ['This field requires 7 or 8 digits.']
- error_digitsonly = ['This field requires only numbers.']
- valid = {
- '20123456': '20123456',
- '20.123.456': '20123456',
- '20123456': '20123456',
- '20.123.456': '20123456',
- '20.123456': '20123456',
- '9123456': '9123456',
- '9.123.456': '9123456',
- }
- invalid = {
- '101234566': error_length,
- 'W0123456': error_digitsonly,
- '10,123,456': error_digitsonly,
- }
- self.assertFieldOutput(ARDNIField, valid, invalid)
-
- def test_ARCUITField(self):
- error_format = ['Enter a valid CUIT in XX-XXXXXXXX-X or XXXXXXXXXXXX format.']
- error_invalid = ['Invalid CUIT.']
- error_legal_type = ['Invalid legal type. Type must be 27, 20, 23 or 30.']
- valid = {
- '20-10123456-9': '20-10123456-9',
- '20-10123456-9': '20-10123456-9',
- '27-10345678-4': '27-10345678-4',
- '20101234569': '20-10123456-9',
- '27103456784': '27-10345678-4',
- '30011111110': '30-01111111-0',
- }
- invalid = {
- '2-10123456-9': error_format,
- '210123456-9': error_format,
- '20-10123456': error_format,
- '20-10123456-': error_format,
- '20-10123456-5': error_invalid,
- '27-10345678-1': error_invalid,
- '27-10345678-1': error_invalid,
- '11211111110': error_legal_type,
- }
- self.assertFieldOutput(ARCUITField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/at/tests.py b/tests/regressiontests/localflavor/at/tests.py
deleted file mode 100644
index 9123ba4e88..0000000000
--- a/tests/regressiontests/localflavor/at/tests.py
+++ /dev/null
@@ -1,49 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.at.forms import (ATZipCodeField, ATStateSelect,
- ATSocialSecurityNumberField)
-
-from django.test import SimpleTestCase
-
-
-class ATLocalFlavorTests(SimpleTestCase):
- def test_ATStateSelect(self):
- f = ATStateSelect()
- out = '''<select name="bundesland">
-<option value="BL">Burgenland</option>
-<option value="KA">Carinthia</option>
-<option value="NO">Lower Austria</option>
-<option value="OO">Upper Austria</option>
-<option value="SA">Salzburg</option>
-<option value="ST">Styria</option>
-<option value="TI">Tyrol</option>
-<option value="VO">Vorarlberg</option>
-<option value="WI" selected="selected">Vienna</option>
-</select>'''
- self.assertHTMLEqual(f.render('bundesland', 'WI'), out)
-
- def test_ATZipCodeField(self):
- error_format = ['Enter a zip code in the format XXXX.']
- valid = {
- '1150': '1150',
- '4020': '4020',
- '8020': '8020',
- }
- invalid = {
- '0000' : error_format,
- '0123' : error_format,
- '111222': error_format,
- 'eeffee': error_format,
- }
- self.assertFieldOutput(ATZipCodeField, valid, invalid)
-
- def test_ATSocialSecurityNumberField(self):
- error_format = ['Enter a valid Austrian Social Security Number in XXXX XXXXXX format.']
- valid = {
- '1237 010180': '1237 010180',
- }
- invalid = {
- '1237 010181': error_format,
- '12370 010180': error_format,
- }
- self.assertFieldOutput(ATSocialSecurityNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/au/__init__.py b/tests/regressiontests/localflavor/au/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/au/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/au/forms.py b/tests/regressiontests/localflavor/au/forms.py
deleted file mode 100644
index aec00694fe..0000000000
--- a/tests/regressiontests/localflavor/au/forms.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from __future__ import absolute_import
-
-from django.forms import ModelForm
-
-from .models import AustralianPlace
-
-
-class AustralianPlaceForm(ModelForm):
- """ Form for storing an Australian place. """
- class Meta:
- model = AustralianPlace
diff --git a/tests/regressiontests/localflavor/au/models.py b/tests/regressiontests/localflavor/au/models.py
deleted file mode 100644
index 39061c5bb3..0000000000
--- a/tests/regressiontests/localflavor/au/models.py
+++ /dev/null
@@ -1,14 +0,0 @@
-from django.contrib.localflavor.au.models import AUStateField, AUPostCodeField
-from django.db import models
-
-class AustralianPlace(models.Model):
- state = AUStateField(blank=True)
- state_required = AUStateField()
- state_default = AUStateField(default="NSW", blank=True)
- postcode = AUPostCodeField(blank=True)
- postcode_required = AUPostCodeField()
- postcode_default = AUPostCodeField(default="2500", blank=True)
- name = models.CharField(max_length=20)
-
- class Meta:
- app_label = 'localflavor'
diff --git a/tests/regressiontests/localflavor/au/tests.py b/tests/regressiontests/localflavor/au/tests.py
deleted file mode 100644
index 69472f0935..0000000000
--- a/tests/regressiontests/localflavor/au/tests.py
+++ /dev/null
@@ -1,108 +0,0 @@
-from __future__ import absolute_import, unicode_literals
-
-import re
-
-from django.test import SimpleTestCase
-from django.contrib.localflavor.au.forms import (AUPostCodeField,
- AUPhoneNumberField, AUStateSelect)
-
-from .forms import AustralianPlaceForm
-
-
-SELECTED_OPTION_PATTERN = r'<option value="%s" selected="selected">'
-BLANK_OPTION_PATTERN = r'<option value="">'
-INPUT_VALUE_PATTERN = r'<input[^>]*value="%s"[^>]*>'
-
-
-class AULocalflavorTests(SimpleTestCase):
-
- def setUp(self):
- self.form = AustralianPlaceForm(
- {'state':'WA',
- 'state_required':'QLD',
- 'name':'dummy',
- 'postcode':'1234',
- 'postcode_required':'4321',
- })
-
- def test_get_display_methods(self):
- """ Ensure get_*_display() methods are added to model instances. """
- place = self.form.save()
- self.assertEqual(place.get_state_display(), 'Western Australia')
- self.assertEqual(place.get_state_required_display(), 'Queensland')
-
- def test_default_values(self):
- """ Ensure that default values are selected in forms. """
- form = AustralianPlaceForm()
- self.assertTrue(re.search(SELECTED_OPTION_PATTERN % 'NSW',
- str(form['state_default'])))
- self.assertTrue(re.search(INPUT_VALUE_PATTERN % '2500',
- str(form['postcode_default'])))
-
- def test_required(self):
- """ Test that required AUStateFields throw appropriate errors. """
- form = AustralianPlaceForm({'state':'NSW', 'name':'Wollongong'})
- self.assertFalse(form.is_valid())
- self.assertEqual(
- form.errors['state_required'], ['This field is required.'])
- self.assertEqual(
- form.errors['postcode_required'], ['This field is required.'])
-
- def test_field_blank_option(self):
- """ Test that the empty option is there. """
- self.assertTrue(re.search(BLANK_OPTION_PATTERN,
- str(self.form['state'])))
-
- def test_selected_values(self):
- """ Ensure selected states match the initial values provided. """
- self.assertTrue(re.search(SELECTED_OPTION_PATTERN % 'WA',
- str(self.form['state'])))
- self.assertTrue(re.search(SELECTED_OPTION_PATTERN % 'QLD',
- str(self.form['state_required'])))
- self.assertTrue(re.search(INPUT_VALUE_PATTERN % '1234',
- str(self.form['postcode'])))
- self.assertTrue(re.search(INPUT_VALUE_PATTERN % '4321',
- str(self.form['postcode_required'])))
-
- def test_AUStateSelect(self):
- f = AUStateSelect()
- out = '''<select name="state">
-<option value="ACT">Australian Capital Territory</option>
-<option value="NSW" selected="selected">New South Wales</option>
-<option value="NT">Northern Territory</option>
-<option value="QLD">Queensland</option>
-<option value="SA">South Australia</option>
-<option value="TAS">Tasmania</option>
-<option value="VIC">Victoria</option>
-<option value="WA">Western Australia</option>
-</select>'''
- self.assertHTMLEqual(f.render('state', 'NSW'), out)
-
- def test_AUPostCodeField(self):
- error_format = ['Enter a 4 digit postcode.']
- valid = {
- '1234': '1234',
- '2000': '2000',
- }
- invalid = {
- 'abcd': error_format,
- '20001': ['Ensure this value has at most 4 characters (it has 5).'] + error_format,
- }
- self.assertFieldOutput(AUPostCodeField, valid, invalid)
-
- def test_AUPhoneNumberField(self):
- error_format = ['Phone numbers must contain 10 digits.']
- valid = {
- '1234567890': '1234567890',
- '0213456789': '0213456789',
- '02 13 45 67 89': '0213456789',
- '(02) 1345 6789': '0213456789',
- '(02) 1345-6789': '0213456789',
- '(02)1345-6789': '0213456789',
- '0408 123 456': '0408123456',
- }
- invalid = {
- '123': error_format,
- '1800DJANGO': error_format,
- }
- self.assertFieldOutput(AUPhoneNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/be/__init__.py b/tests/regressiontests/localflavor/be/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/be/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/be/tests.py b/tests/regressiontests/localflavor/be/tests.py
deleted file mode 100644
index 69f77eb35f..0000000000
--- a/tests/regressiontests/localflavor/be/tests.py
+++ /dev/null
@@ -1,81 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.be.forms import (BEPostalCodeField,
- BEPhoneNumberField, BERegionSelect, BEProvinceSelect)
-
-from django.test import SimpleTestCase
-
-
-class BELocalFlavorTests(SimpleTestCase):
- def test_BEPostalCodeField(self):
- error_format = ['Enter a valid postal code in the range and format 1XXX - 9XXX.']
- valid = {
- '1451': '1451',
- '2540': '2540',
- }
- invalid = {
- '0287': error_format,
- '14309': error_format,
- '873': error_format,
- '35 74': error_format,
- '859A': error_format,
- }
- self.assertFieldOutput(BEPostalCodeField, valid, invalid)
-
- def test_BEPhoneNumberField(self):
- error_format = [
- ('Enter a valid phone number in one of the formats 0x xxx xx xx, '
- '0xx xx xx xx, 04xx xx xx xx, 0x/xxx.xx.xx, 0xx/xx.xx.xx, '
- '04xx/xx.xx.xx, 0x.xxx.xx.xx, 0xx.xx.xx.xx, 04xx.xx.xx.xx, '
- '0xxxxxxxx or 04xxxxxxxx.')
- ]
- valid = {
- '01 234 56 78': '01 234 56 78',
- '01/234.56.78': '01/234.56.78',
- '01.234.56.78': '01.234.56.78',
- '012 34 56 78': '012 34 56 78',
- '012/34.56.78': '012/34.56.78',
- '012.34.56.78': '012.34.56.78',
- '0412 34 56 78': '0412 34 56 78',
- '0412/34.56.78': '0412/34.56.78',
- '0412.34.56.78': '0412.34.56.78',
- '012345678': '012345678',
- '0412345678': '0412345678',
- }
- invalid = {
- '01234567': error_format,
- '12/345.67.89': error_format,
- '012/345.678.90': error_format,
- '012/34.56.789': error_format,
- '0123/45.67.89': error_format,
- '012/345 678 90': error_format,
- '012/34 56 789': error_format,
- '012.34 56 789': error_format,
- }
- self.assertFieldOutput(BEPhoneNumberField, valid, invalid)
-
- def test_BERegionSelect(self):
- f = BERegionSelect()
- out = '''<select name="regions">
-<option value="BRU">Brussels Capital Region</option>
-<option value="VLG" selected="selected">Flemish Region</option>
-<option value="WAL">Wallonia</option>
-</select>'''
- self.assertHTMLEqual(f.render('regions', 'VLG'), out)
-
- def test_BEProvinceSelect(self):
- f = BEProvinceSelect()
- out = '''<select name="provinces">
-<option value="VAN">Antwerp</option>
-<option value="BRU">Brussels</option>
-<option value="VOV">East Flanders</option>
-<option value="VBR">Flemish Brabant</option>
-<option value="WHT">Hainaut</option>
-<option value="WLG" selected="selected">Liege</option>
-<option value="VLI">Limburg</option>
-<option value="WLX">Luxembourg</option>
-<option value="WNA">Namur</option>
-<option value="WBR">Walloon Brabant</option>
-<option value="VWV">West Flanders</option>
-</select>'''
- self.assertHTMLEqual(f.render('provinces', 'WLG'), out)
diff --git a/tests/regressiontests/localflavor/br/__init__.py b/tests/regressiontests/localflavor/br/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/br/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/br/tests.py b/tests/regressiontests/localflavor/br/tests.py
deleted file mode 100644
index abee2d7336..0000000000
--- a/tests/regressiontests/localflavor/br/tests.py
+++ /dev/null
@@ -1,146 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.br.forms import (BRZipCodeField,
- BRCNPJField, BRCPFField, BRPhoneNumberField, BRStateSelect,
- BRStateChoiceField)
-
-from django.test import SimpleTestCase
-
-
-class BRLocalFlavorTests(SimpleTestCase):
- def test_BRZipCodeField(self):
- error_format = ['Enter a zip code in the format XXXXX-XXX.']
- valid = {
- '12345-123': '12345-123',
- }
- invalid = {
- '12345_123': error_format,
- '1234-123': error_format,
- 'abcde-abc': error_format,
- '12345-': error_format,
- '-123': error_format,
- }
- self.assertFieldOutput(BRZipCodeField, valid, invalid)
-
- def test_BRCNPJField(self):
- error_format = ['Invalid CNPJ number.']
- error_numbersonly = ['This field requires only numbers.']
- valid = {
- '64.132.916/0001-88': '64.132.916/0001-88',
- '64-132-916/0001-88': '64-132-916/0001-88',
- '64132916/0001-88': '64132916/0001-88',
- }
- invalid = {
- '12-345-678/9012-10': error_format,
- '12.345.678/9012-10': error_format,
- '12345678/9012-10': error_format,
- '64.132.916/0001-XX': error_numbersonly,
- }
- self.assertFieldOutput(BRCNPJField, valid, invalid)
-
- def test_BRCPFField(self):
- error_format = ['Invalid CPF number.']
- error_numbersonly = ['This field requires only numbers.']
- error_atmost_chars = ['Ensure this value has at most 14 characters (it has 15).']
- error_atleast_chars = ['Ensure this value has at least 11 characters (it has 10).']
- error_atmost = ['This field requires at most 11 digits or 14 characters.']
- valid = {
- '663.256.017-26': '663.256.017-26',
- '66325601726': '66325601726',
- '375.788.573-20': '375.788.573-20',
- '84828509895': '84828509895',
- }
- invalid = {
- '489.294.654-54': error_format,
- '295.669.575-98': error_format,
- '539.315.127-22': error_format,
- '375.788.573-XX': error_numbersonly,
- '375.788.573-000': error_atmost_chars,
- '123.456.78': error_atleast_chars,
- '123456789555': error_atmost,
- }
- self.assertFieldOutput(BRCPFField, valid, invalid)
-
- def test_BRPhoneNumberField(self):
- # TODO: this doesn't test for any invalid inputs.
- valid = {
- '41-3562-3464': '41-3562-3464',
- '4135623464': '41-3562-3464',
- '41 3562-3464': '41-3562-3464',
- '41 3562 3464': '41-3562-3464',
- '(41) 3562 3464': '41-3562-3464',
- '41.3562.3464': '41-3562-3464',
- '41.3562-3464': '41-3562-3464',
- ' (41) 3562.3464': '41-3562-3464',
- }
- invalid = {}
- self.assertFieldOutput(BRPhoneNumberField, valid, invalid)
-
- def test_BRStateSelect(self):
- f = BRStateSelect()
- out = '''<select name="states">
-<option value="AC">Acre</option>
-<option value="AL">Alagoas</option>
-<option value="AP">Amap\xe1</option>
-<option value="AM">Amazonas</option>
-<option value="BA">Bahia</option>
-<option value="CE">Cear\xe1</option>
-<option value="DF">Distrito Federal</option>
-<option value="ES">Esp\xedrito Santo</option>
-<option value="GO">Goi\xe1s</option>
-<option value="MA">Maranh\xe3o</option>
-<option value="MT">Mato Grosso</option>
-<option value="MS">Mato Grosso do Sul</option>
-<option value="MG">Minas Gerais</option>
-<option value="PA">Par\xe1</option>
-<option value="PB">Para\xedba</option>
-<option value="PR" selected="selected">Paran\xe1</option>
-<option value="PE">Pernambuco</option>
-<option value="PI">Piau\xed</option>
-<option value="RJ">Rio de Janeiro</option>
-<option value="RN">Rio Grande do Norte</option>
-<option value="RS">Rio Grande do Sul</option>
-<option value="RO">Rond\xf4nia</option>
-<option value="RR">Roraima</option>
-<option value="SC">Santa Catarina</option>
-<option value="SP">S\xe3o Paulo</option>
-<option value="SE">Sergipe</option>
-<option value="TO">Tocantins</option>
-</select>'''
- self.assertHTMLEqual(f.render('states', 'PR'), out)
-
- def test_BRStateChoiceField(self):
- error_invalid = ['Select a valid brazilian state. That state is not one of the available states.']
- valid = {
- 'AC': 'AC',
- 'AL': 'AL',
- 'AP': 'AP',
- 'AM': 'AM',
- 'BA': 'BA',
- 'CE': 'CE',
- 'DF': 'DF',
- 'ES': 'ES',
- 'GO': 'GO',
- 'MA': 'MA',
- 'MT': 'MT',
- 'MS': 'MS',
- 'MG': 'MG',
- 'PA': 'PA',
- 'PB': 'PB',
- 'PR': 'PR',
- 'PE': 'PE',
- 'PI': 'PI',
- 'RJ': 'RJ',
- 'RN': 'RN',
- 'RS': 'RS',
- 'RO': 'RO',
- 'RR': 'RR',
- 'SC': 'SC',
- 'SP': 'SP',
- 'SE': 'SE',
- 'TO': 'TO',
- }
- invalid = {
- 'pr': error_invalid,
- }
- self.assertFieldOutput(BRStateChoiceField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/ca/__init__.py b/tests/regressiontests/localflavor/ca/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/ca/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/ca/tests.py b/tests/regressiontests/localflavor/ca/tests.py
deleted file mode 100644
index 8f0eb9c702..0000000000
--- a/tests/regressiontests/localflavor/ca/tests.py
+++ /dev/null
@@ -1,115 +0,0 @@
-from __future__ import unicode_literals
-
-import warnings
-
-from django.contrib.localflavor.ca.forms import (CAPostalCodeField,
- CAPhoneNumberField, CAProvinceField, CAProvinceSelect,
- CASocialInsuranceNumberField)
-
-from django.test import SimpleTestCase
-
-
-class CALocalFlavorTests(SimpleTestCase):
- def setUp(self):
- self.save_warnings_state()
- warnings.filterwarnings(
- "ignore",
- category=RuntimeWarning,
- module='django.contrib.localflavor.ca.ca_provinces'
- )
-
- def tearDown(self):
- self.restore_warnings_state()
-
- def test_CAProvinceSelect(self):
- f = CAProvinceSelect()
- out = '''<select name="province">
-<option value="AB" selected="selected">Alberta</option>
-<option value="BC">British Columbia</option>
-<option value="MB">Manitoba</option>
-<option value="NB">New Brunswick</option>
-<option value="NL">Newfoundland and Labrador</option>
-<option value="NT">Northwest Territories</option>
-<option value="NS">Nova Scotia</option>
-<option value="NU">Nunavut</option>
-<option value="ON">Ontario</option>
-<option value="PE">Prince Edward Island</option>
-<option value="QC">Quebec</option>
-<option value="SK">Saskatchewan</option>
-<option value="YT">Yukon</option>
-</select>'''
- self.assertHTMLEqual(f.render('province', 'AB'), out)
-
- def test_CAPostalCodeField(self):
- error_format = ['Enter a postal code in the format XXX XXX.']
- valid = {
- 'T2S 2H7': 'T2S 2H7',
- 'T2S 2W7': 'T2S 2W7',
- 'T2S 2Z7': 'T2S 2Z7',
- 'T2Z 2H7': 'T2Z 2H7',
- 'T2S2H7' : 'T2S 2H7',
- 't2s 2h7': 'T2S 2H7',
- 't2s2h7' : 'T2S 2H7',
- 't2s 2H7': 'T2S 2H7',
- ' t2s 2H7 ': 'T2S 2H7',
- }
- invalid = {
- 'T2S 2H' : error_format,
- '2T6 H8I': error_format,
- 'T2S2H' : error_format,
- 't2s h8i': error_format,
- 90210 : error_format,
- 'W2S 2H3': error_format,
- 'Z2S 2H3': error_format,
- 'F2S 2H3': error_format,
- 'A2S 2D3': error_format,
- 'A2I 2R3': error_format,
- 'A2Q 2R3': error_format,
- 'U2B 2R3': error_format,
- 'O2B 2R3': error_format,
- }
- self.assertFieldOutput(CAPostalCodeField, valid, invalid)
-
- def test_CAPhoneNumberField(self):
- error_format = ['Phone numbers must be in XXX-XXX-XXXX format.']
- valid = {
- '403-555-1212': '403-555-1212',
- '4035551212': '403-555-1212',
- '403 555-1212': '403-555-1212',
- '(403) 555-1212': '403-555-1212',
- '403 555 1212': '403-555-1212',
- '403.555.1212': '403-555-1212',
- '403.555-1212': '403-555-1212',
- ' (403) 555.1212 ': '403-555-1212',
- }
- invalid = {
- '555-1212': error_format,
- '403-55-1212': error_format,
- }
- self.assertFieldOutput(CAPhoneNumberField, valid, invalid)
-
- def test_CAProvinceField(self):
- error_format = ['Enter a Canadian province or territory.']
- valid = {
- 'ab': 'AB',
- 'BC': 'BC',
- 'nova scotia': 'NS',
- ' manitoba ': 'MB',
- 'pq': 'QC',
- }
- invalid = {
- 'T2S 2H7': error_format,
- }
- self.assertFieldOutput(CAProvinceField, valid, invalid)
-
- def test_CASocialInsuranceField(self):
- error_format = ['Enter a valid Canadian Social Insurance number in XXX-XXX-XXX format.']
- valid = {
- '046-454-286': '046-454-286',
- }
- invalid = {
- '046-454-287': error_format,
- '046 454 286': error_format,
- '046-44-286': error_format,
- }
- self.assertFieldOutput(CASocialInsuranceNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/ch/__init__.py b/tests/regressiontests/localflavor/ch/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/ch/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/ch/tests.py b/tests/regressiontests/localflavor/ch/tests.py
deleted file mode 100644
index f3491855a2..0000000000
--- a/tests/regressiontests/localflavor/ch/tests.py
+++ /dev/null
@@ -1,76 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.ch.forms import (CHZipCodeField,
- CHPhoneNumberField, CHIdentityCardNumberField, CHStateSelect)
-
-from django.test import SimpleTestCase
-
-
-class CHLocalFlavorTests(SimpleTestCase):
- def test_CHStateSelect(self):
- f = CHStateSelect()
- out = '''<select name="state">
-<option value="AG" selected="selected">Aargau</option>
-<option value="AI">Appenzell Innerrhoden</option>
-<option value="AR">Appenzell Ausserrhoden</option>
-<option value="BS">Basel-Stadt</option>
-<option value="BL">Basel-Land</option>
-<option value="BE">Berne</option>
-<option value="FR">Fribourg</option>
-<option value="GE">Geneva</option>
-<option value="GL">Glarus</option>
-<option value="GR">Graubuenden</option>
-<option value="JU">Jura</option>
-<option value="LU">Lucerne</option>
-<option value="NE">Neuchatel</option>
-<option value="NW">Nidwalden</option>
-<option value="OW">Obwalden</option>
-<option value="SH">Schaffhausen</option>
-<option value="SZ">Schwyz</option>
-<option value="SO">Solothurn</option>
-<option value="SG">St. Gallen</option>
-<option value="TG">Thurgau</option>
-<option value="TI">Ticino</option>
-<option value="UR">Uri</option>
-<option value="VS">Valais</option>
-<option value="VD">Vaud</option>
-<option value="ZG">Zug</option>
-<option value="ZH">Zurich</option>
-</select>'''
- self.assertHTMLEqual(f.render('state', 'AG'), out)
-
- def test_CHZipCodeField(self):
- error_format = ['Enter a zip code in the format XXXX.']
- valid = {
- '1234': '1234',
- '0000': '0000',
- }
- invalid = {
- '800x': error_format,
- '80 00': error_format,
- }
- self.assertFieldOutput(CHZipCodeField, valid, invalid)
-
- def test_CHPhoneNumberField(self):
- error_format = ['Phone numbers must be in 0XX XXX XX XX format.']
- valid = {
- '012 345 67 89': '012 345 67 89',
- '0123456789': '012 345 67 89',
- }
- invalid = {
- '01234567890': error_format,
- '1234567890': error_format,
- }
- self.assertFieldOutput(CHPhoneNumberField, valid, invalid)
-
- def test_CHIdentityCardNumberField(self):
- error_format = ['Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format.']
- valid = {
- 'C1234567<0': 'C1234567<0',
- '2123456700': '2123456700',
- }
- invalid = {
- 'C1234567<1': error_format,
- '2123456701': error_format,
- }
- self.assertFieldOutput(CHIdentityCardNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/cl/__init__.py b/tests/regressiontests/localflavor/cl/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/cl/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/cl/tests.py b/tests/regressiontests/localflavor/cl/tests.py
deleted file mode 100644
index 47cae6bd48..0000000000
--- a/tests/regressiontests/localflavor/cl/tests.py
+++ /dev/null
@@ -1,58 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.cl.forms import CLRutField, CLRegionSelect
-
-from django.test import SimpleTestCase
-
-
-class CLLocalFlavorTests(SimpleTestCase):
- def test_CLRegionSelect(self):
- f = CLRegionSelect()
- out = '''<select name="foo">
-<option value="RM">Regi\xf3n Metropolitana de Santiago</option>
-<option value="I">Regi\xf3n de Tarapac\xe1</option>
-<option value="II">Regi\xf3n de Antofagasta</option>
-<option value="III">Regi\xf3n de Atacama</option>
-<option value="IV">Regi\xf3n de Coquimbo</option>
-<option value="V">Regi\xf3n de Valpara\xedso</option>
-<option value="VI">Regi\xf3n del Libertador Bernardo O&#39;Higgins</option>
-<option value="VII">Regi\xf3n del Maule</option>
-<option value="VIII">Regi\xf3n del B\xedo B\xedo</option>
-<option value="IX">Regi\xf3n de la Araucan\xeda</option>
-<option value="X">Regi\xf3n de los Lagos</option>
-<option value="XI">Regi\xf3n de Ays\xe9n del General Carlos Ib\xe1\xf1ez del Campo</option>
-<option value="XII">Regi\xf3n de Magallanes y la Ant\xe1rtica Chilena</option>
-<option value="XIV">Regi\xf3n de Los R\xedos</option>
-<option value="XV">Regi\xf3n de Arica-Parinacota</option>
-</select>'''
- self.assertHTMLEqual(f.render('foo', 'bar'), out)
-
- def test_CLRutField(self):
- error_invalid = ['The Chilean RUT is not valid.']
- error_format = ['Enter a valid Chilean RUT. The format is XX.XXX.XXX-X.']
- valid = {
- '11-6': '11-6',
- '116': '11-6',
- '767484100': '76.748.410-0',
- '78.412.790-7': '78.412.790-7',
- '8.334.6043': '8.334.604-3',
- '76793310-K': '76.793.310-K',
- '76793310-k': '76.793.310-K',
- }
- invalid = {
- '11.111.111-0': error_invalid,
- '111': error_invalid,
- }
- self.assertFieldOutput(CLRutField, valid, invalid)
-
- # deal with special "Strict Mode".
- invalid = {
- '11-6': error_format,
- '767484100': error_format,
- '8.334.6043': error_format,
- '76793310-K': error_format,
- '11.111.111-0': error_invalid
- }
- self.assertFieldOutput(CLRutField,
- {}, invalid, field_kwargs={"strict": True}
- )
diff --git a/tests/regressiontests/localflavor/cn/__init__.py b/tests/regressiontests/localflavor/cn/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/cn/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/cn/tests.py b/tests/regressiontests/localflavor/cn/tests.py
deleted file mode 100644
index 24bcc6e392..0000000000
--- a/tests/regressiontests/localflavor/cn/tests.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Tests for contrib/localflavor/ CN Form Fields
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.cn.forms import (CNProvinceSelect,
- CNPostCodeField, CNIDCardField, CNPhoneNumberField, CNCellNumberField)
-from django.test import SimpleTestCase
-
-class CNLocalFlavorTests(SimpleTestCase):
- def test_CNProvinceSelect(self):
- f = CNProvinceSelect()
- correct_output = '''<select name="provinces">
-<option value="anhui">\u5b89\u5fbd</option>
-<option value="beijing">\u5317\u4eac</option>
-<option value="chongqing">\u91cd\u5e86</option>
-<option value="fujian">\u798f\u5efa</option>
-<option value="gansu">\u7518\u8083</option>
-<option value="guangdong">\u5e7f\u4e1c</option>
-<option value="guangxi">\u5e7f\u897f\u58ee\u65cf\u81ea\u6cbb\u533a</option>
-<option value="guizhou">\u8d35\u5dde</option>
-<option value="hainan">\u6d77\u5357</option>
-<option value="hebei">\u6cb3\u5317</option>
-<option value="heilongjiang">\u9ed1\u9f99\u6c5f</option>
-<option value="henan">\u6cb3\u5357</option>
-<option value="hongkong">\u9999\u6e2f</option>
-<option value="hubei" selected="selected">\u6e56\u5317</option>
-<option value="hunan">\u6e56\u5357</option>
-<option value="jiangsu">\u6c5f\u82cf</option>
-<option value="jiangxi">\u6c5f\u897f</option>
-<option value="jilin">\u5409\u6797</option>
-<option value="liaoning">\u8fbd\u5b81</option>
-<option value="macao">\u6fb3\u95e8</option>
-<option value="neimongol">\u5185\u8499\u53e4\u81ea\u6cbb\u533a</option>
-<option value="ningxia">\u5b81\u590f\u56de\u65cf\u81ea\u6cbb\u533a</option>
-<option value="qinghai">\u9752\u6d77</option>
-<option value="shaanxi">\u9655\u897f</option>
-<option value="shandong">\u5c71\u4e1c</option>
-<option value="shanghai">\u4e0a\u6d77</option>
-<option value="shanxi">\u5c71\u897f</option>
-<option value="sichuan">\u56db\u5ddd</option>
-<option value="taiwan">\u53f0\u6e7e</option>
-<option value="tianjin">\u5929\u6d25</option>
-<option value="xinjiang">\u65b0\u7586\u7ef4\u543e\u5c14\u81ea\u6cbb\u533a</option>
-<option value="xizang">\u897f\u85cf\u81ea\u6cbb\u533a</option>
-<option value="yunnan">\u4e91\u5357</option>
-<option value="zhejiang">\u6d59\u6c5f</option>
-</select>'''
- self.assertHTMLEqual(f.render('provinces', 'hubei'), correct_output)
-
- def test_CNPostCodeField(self):
- error_format = ['Enter a post code in the format XXXXXX.']
- valid = {
- '091209': '091209'
- }
- invalid = {
- '09120': error_format,
- '09120916': error_format
- }
- self.assertFieldOutput(CNPostCodeField, valid, invalid)
-
- def test_CNIDCardField(self):
- valid = {
- # A valid 1st generation ID Card Number.
- '110101491001001': '110101491001001',
- # A valid 2nd generation ID Card number.
- '11010119491001001X': '11010119491001001X',
- # Another valid 2nd gen ID Number with a case change
- '11010119491001001x': '11010119491001001X'
- }
-
- wrong_format = ['ID Card Number consists of 15 or 18 digits.']
- wrong_location = ['Invalid ID Card Number: Wrong location code']
- wrong_bday = ['Invalid ID Card Number: Wrong birthdate']
- wrong_checksum = ['Invalid ID Card Number: Wrong checksum']
-
- invalid = {
- 'abcdefghijklmnop': wrong_format,
- '1010101010101010': wrong_format,
- '010101491001001' : wrong_location, # 1st gen, 01 is invalid
- '110101491041001' : wrong_bday, # 1st gen. There wasn't day 41
- '92010119491001001X': wrong_location, # 2nd gen, 92 is invalid
- '91010119491301001X': wrong_bday, # 2nd gen, 19491301 is invalid date
- '910101194910010014': wrong_checksum #2nd gen
- }
- self.assertFieldOutput(CNIDCardField, valid, invalid)
-
- def test_CNPhoneNumberField(self):
- error_format = ['Enter a valid phone number.']
- valid = {
- '010-12345678': '010-12345678',
- '010-1234567': '010-1234567',
- '0101-12345678': '0101-12345678',
- '0101-1234567': '0101-1234567',
- '010-12345678-020':'010-12345678-020'
- }
- invalid = {
- '01x-12345678': error_format,
- '12345678': error_format,
- '01123-12345678': error_format,
- '010-123456789': error_format,
- '010-12345678-': error_format
- }
- self.assertFieldOutput(CNPhoneNumberField, valid, invalid)
-
- def test_CNCellNumberField(self):
- error_format = ['Enter a valid cell number.']
- valid = {
- '13012345678': '13012345678',
- }
- invalid = {
- '130123456789': error_format,
- '14012345678': error_format
- }
- self.assertFieldOutput(CNCellNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/co/__init__.py b/tests/regressiontests/localflavor/co/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/co/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/co/tests.py b/tests/regressiontests/localflavor/co/tests.py
deleted file mode 100644
index 68b20c4308..0000000000
--- a/tests/regressiontests/localflavor/co/tests.py
+++ /dev/null
@@ -1,45 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.co.forms import CODepartmentSelect
-
-from django.test import SimpleTestCase
-
-class COLocalFlavorTests(SimpleTestCase):
- def test_CODepartmentSelect(self):
- d = CODepartmentSelect()
- out = """<select name="department">
-<option value="AMA">Amazonas</option>
-<option value="ANT">Antioquia</option>
-<option value="ARA">Arauca</option>
-<option value="ATL">Atl\xe1ntico</option>
-<option value="DC">Bogot\xe1</option>
-<option value="BOL">Bol\xedvar</option>
-<option value="BOY">Boyac\xe1</option>
-<option value="CAL">Caldas</option>
-<option value="CAQ">Caquet\xe1</option>
-<option value="CAS">Casanare</option>
-<option value="CAU">Cauca</option>
-<option value="CES">Cesar</option>
-<option value="CHO">Choc\xf3</option>
-<option value="COR" selected="selected">C\xf3rdoba</option>
-<option value="CUN">Cundinamarca</option>
-<option value="GUA">Guain\xeda</option>
-<option value="GUV">Guaviare</option>
-<option value="HUI">Huila</option>
-<option value="LAG">La Guajira</option>
-<option value="MAG">Magdalena</option>
-<option value="MET">Meta</option>
-<option value="NAR">Nari\xf1o</option>
-<option value="NSA">Norte de Santander</option>
-<option value="PUT">Putumayo</option>
-<option value="QUI">Quind\xedo</option>
-<option value="RIS">Risaralda</option>
-<option value="SAP">San Andr\xe9s and Providencia</option>
-<option value="SAN">Santander</option>
-<option value="SUC">Sucre</option>
-<option value="TOL">Tolima</option>
-<option value="VAC">Valle del Cauca</option>
-<option value="VAU">Vaup\xe9s</option>
-<option value="VID">Vichada</option>
-</select>"""
- self.assertHTMLEqual(d.render('department', 'COR'), out)
diff --git a/tests/regressiontests/localflavor/cz/__init__.py b/tests/regressiontests/localflavor/cz/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/cz/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/cz/tests.py b/tests/regressiontests/localflavor/cz/tests.py
deleted file mode 100644
index e4cc05e0c6..0000000000
--- a/tests/regressiontests/localflavor/cz/tests.py
+++ /dev/null
@@ -1,80 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.cz.forms import (CZPostalCodeField,
- CZRegionSelect, CZBirthNumberField, CZICNumberField)
-
-from django.core.exceptions import ValidationError
-from django.test import SimpleTestCase
-
-
-class CZLocalFlavorTests(SimpleTestCase):
- def test_CZRegionSelect(self):
- f = CZRegionSelect()
- out = '''<select name="regions">
-<option value="PR">Prague</option>
-<option value="CE">Central Bohemian Region</option>
-<option value="SO">South Bohemian Region</option>
-<option value="PI">Pilsen Region</option>
-<option value="CA">Carlsbad Region</option>
-<option value="US">Usti Region</option>
-<option value="LB">Liberec Region</option>
-<option value="HK">Hradec Region</option>
-<option value="PA">Pardubice Region</option>
-<option value="VY">Vysocina Region</option>
-<option value="SM">South Moravian Region</option>
-<option value="OL">Olomouc Region</option>
-<option value="ZL">Zlin Region</option>
-<option value="MS">Moravian-Silesian Region</option>
-</select>'''
- self.assertHTMLEqual(f.render('regions', 'TT'), out)
-
- def test_CZPostalCodeField(self):
- error_format = ['Enter a postal code in the format XXXXX or XXX XX.']
- valid = {
- '91909': '91909',
- '917 01': '91701',
- '12345': '12345',
- }
- invalid = {
- '84545x': error_format,
- '123456': error_format,
- '1234': error_format,
- '123 4': error_format,
- }
- self.assertFieldOutput(CZPostalCodeField, valid, invalid)
-
- def test_CZBirthNumberField(self):
- error_format = ['Enter a birth number in the format XXXXXX/XXXX or XXXXXXXXXX.']
- error_invalid = ['Enter a valid birth number.']
- valid = {
- '880523/1237': '880523/1237',
- '8805231237': '8805231237',
- '880523/000': '880523/000',
- '880523000': '880523000',
- '882101/0011': '882101/0011',
- }
- invalid = {
- '123456/12': error_format,
- '123456/12345': error_format,
- '12345612': error_format,
- '12345612345': error_format,
- '880523/1239': error_invalid,
- '8805231239': error_invalid,
- '990101/0011': error_invalid,
- }
- self.assertFieldOutput(CZBirthNumberField, valid, invalid)
-
- def test_CZICNumberField(self):
- error_invalid = ['Enter a valid IC number.']
- valid ={
- '12345679': '12345679',
- '12345601': '12345601',
- '12345661': '12345661',
- '12345610': '12345610',
- }
- invalid = {
- '1234567': error_invalid,
- '12345660': error_invalid,
- '12345600': error_invalid,
- }
- self.assertFieldOutput(CZICNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/de/__init__.py b/tests/regressiontests/localflavor/de/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/de/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/de/tests.py b/tests/regressiontests/localflavor/de/tests.py
deleted file mode 100644
index bdf0bcf44f..0000000000
--- a/tests/regressiontests/localflavor/de/tests.py
+++ /dev/null
@@ -1,51 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.de.forms import (DEZipCodeField, DEStateSelect,
- DEIdentityCardNumberField)
-
-from django.test import SimpleTestCase
-
-
-class DELocalFlavorTests(SimpleTestCase):
- def test_DEStateSelect(self):
- f = DEStateSelect()
- out = '''<select name="states">
-<option value="BW">Baden-Wuerttemberg</option>
-<option value="BY">Bavaria</option>
-<option value="BE">Berlin</option>
-<option value="BB">Brandenburg</option>
-<option value="HB">Bremen</option>
-<option value="HH">Hamburg</option>
-<option value="HE">Hessen</option>
-<option value="MV">Mecklenburg-Western Pomerania</option>
-<option value="NI">Lower Saxony</option>
-<option value="NW">North Rhine-Westphalia</option>
-<option value="RP">Rhineland-Palatinate</option>
-<option value="SL">Saarland</option>
-<option value="SN">Saxony</option>
-<option value="ST">Saxony-Anhalt</option>
-<option value="SH">Schleswig-Holstein</option>
-<option value="TH" selected="selected">Thuringia</option>
-</select>'''
- self.assertHTMLEqual(f.render('states', 'TH'), out)
-
- def test_DEZipCodeField(self):
- error_format = ['Enter a zip code in the format XXXXX.']
- valid = {
- '99423': '99423',
- }
- invalid = {
- ' 99423': error_format,
- }
- self.assertFieldOutput(DEZipCodeField, valid, invalid)
-
- def test_DEIdentityCardNumberField(self):
- error_format = ['Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format.']
- valid = {
- '7549313035D-6004103-0903042-0': '7549313035D-6004103-0903042-0',
- '9786324830D 6104243 0910271 2': '9786324830D-6104243-0910271-2',
- }
- invalid = {
- '0434657485D-6407276-0508137-9': error_format,
- }
- self.assertFieldOutput(DEIdentityCardNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/ec/__init__.py b/tests/regressiontests/localflavor/ec/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/ec/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/ec/tests.py b/tests/regressiontests/localflavor/ec/tests.py
deleted file mode 100644
index c72d77e558..0000000000
--- a/tests/regressiontests/localflavor/ec/tests.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.ec.forms import ECProvinceSelect
-
-from django.test import SimpleTestCase
-
-class ECLocalFlavorTests(SimpleTestCase):
- def test_ECProvinceSelect(self):
- p = ECProvinceSelect()
- out = """<select name="province">
-<option value="A">Azuay</option>
-<option value="B">Bol\xedvar</option>
-<option value="F">Ca\xf1ar</option>
-<option value="C">Carchi</option>
-<option value="H">Chimborazo</option>
-<option value="X">Cotopaxi</option>
-<option value="O">El Oro</option>
-<option value="E">Esmeraldas</option>
-<option value="W">Gal\xe1pagos</option>
-<option value="G">Guayas</option>
-<option value="I">Imbabura</option>
-<option value="L">Loja</option>
-<option value="R">Los R\xedos</option>
-<option value="M">Manab\xed</option>
-<option value="S">Morona Santiago</option>
-<option value="N">Napo</option>
-<option value="D">Orellana</option>
-<option value="Y">Pastaza</option>
-<option value="P">Pichincha</option>
-<option value="SE">Santa Elena</option>
-<option value="SD">Santo Domingo de los Ts\xe1chilas</option>
-<option value="U" selected="selected">Sucumb\xedos</option>
-<option value="T">Tungurahua</option>
-<option value="Z">Zamora Chinchipe</option>
-</select>"""
- self.assertHTMLEqual(p.render('province', 'U'), out)
diff --git a/tests/regressiontests/localflavor/es/__init__.py b/tests/regressiontests/localflavor/es/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/es/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/es/tests.py b/tests/regressiontests/localflavor/es/tests.py
deleted file mode 100644
index 3fc072cffc..0000000000
--- a/tests/regressiontests/localflavor/es/tests.py
+++ /dev/null
@@ -1,173 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.es.forms import (ESPostalCodeField, ESPhoneNumberField,
- ESIdentityCardNumberField, ESCCCField, ESRegionSelect, ESProvinceSelect)
-
-from django.test import SimpleTestCase
-
-
-class ESLocalFlavorTests(SimpleTestCase):
- def test_ESRegionSelect(self):
- f = ESRegionSelect()
- out = '''<select name="regions">
-<option value="AN">Andalusia</option>
-<option value="AR">Aragon</option>
-<option value="O">Principality of Asturias</option>
-<option value="IB">Balearic Islands</option>
-<option value="PV">Basque Country</option>
-<option value="CN">Canary Islands</option>
-<option value="S">Cantabria</option>
-<option value="CM">Castile-La Mancha</option>
-<option value="CL">Castile and Leon</option>
-<option value="CT" selected="selected">Catalonia</option>
-<option value="EX">Extremadura</option>
-<option value="GA">Galicia</option>
-<option value="LO">La Rioja</option>
-<option value="M">Madrid</option>
-<option value="MU">Region of Murcia</option>
-<option value="NA">Foral Community of Navarre</option>
-<option value="VC">Valencian Community</option>
-</select>'''
- self.assertHTMLEqual(f.render('regions', 'CT'), out)
-
- def test_ESProvinceSelect(self):
- f = ESProvinceSelect()
- out = '''<select name="provinces">
-<option value="01">Araba</option>
-<option value="02">Albacete</option>
-<option value="03">Alacant</option>
-<option value="04">Almeria</option>
-<option value="05">Avila</option>
-<option value="06">Badajoz</option>
-<option value="07">Illes Balears</option>
-<option value="08" selected="selected">Barcelona</option>
-<option value="09">Burgos</option>
-<option value="10">Caceres</option>
-<option value="11">Cadiz</option>
-<option value="12">Castello</option>
-<option value="13">Ciudad Real</option>
-<option value="14">Cordoba</option>
-<option value="15">A Coruna</option>
-<option value="16">Cuenca</option>
-<option value="17">Girona</option>
-<option value="18">Granada</option>
-<option value="19">Guadalajara</option>
-<option value="20">Guipuzkoa</option>
-<option value="21">Huelva</option>
-<option value="22">Huesca</option>
-<option value="23">Jaen</option>
-<option value="24">Leon</option>
-<option value="25">Lleida</option>
-<option value="26">La Rioja</option>
-<option value="27">Lugo</option>
-<option value="28">Madrid</option>
-<option value="29">Malaga</option>
-<option value="30">Murcia</option>
-<option value="31">Navarre</option>
-<option value="32">Ourense</option>
-<option value="33">Asturias</option>
-<option value="34">Palencia</option>
-<option value="35">Las Palmas</option>
-<option value="36">Pontevedra</option>
-<option value="37">Salamanca</option>
-<option value="38">Santa Cruz de Tenerife</option>
-<option value="39">Cantabria</option>
-<option value="40">Segovia</option>
-<option value="41">Seville</option>
-<option value="42">Soria</option>
-<option value="43">Tarragona</option>
-<option value="44">Teruel</option>
-<option value="45">Toledo</option>
-<option value="46">Valencia</option>
-<option value="47">Valladolid</option>
-<option value="48">Bizkaia</option>
-<option value="49">Zamora</option>
-<option value="50">Zaragoza</option>
-<option value="51">Ceuta</option>
-<option value="52">Melilla</option>
-</select>'''
- self.assertHTMLEqual(f.render('provinces', '08'), out)
-
- def test_ESPostalCodeField(self):
- error_invalid = ['Enter a valid postal code in the range and format 01XXX - 52XXX.']
- valid = {
- '08028': '08028',
- '28080': '28080',
- }
- invalid = {
- '53001': error_invalid,
- '0801': error_invalid,
- '080001': error_invalid,
- '00999': error_invalid,
- '08 01': error_invalid,
- '08A01': error_invalid,
- }
- self.assertFieldOutput(ESPostalCodeField, valid, invalid)
-
- def test_ESPhoneNumberField(self):
- error_invalid = ['Enter a valid phone number in one of the formats 6XXXXXXXX, 8XXXXXXXX or 9XXXXXXXX.']
- valid = {
- '650010101': '650010101',
- '931234567': '931234567',
- '800123123': '800123123',
- '789789789': '789789789',
- }
- invalid = {
- '555555555': error_invalid,
- '489489489': error_invalid,
- '99123123': error_invalid,
- '9999123123': error_invalid,
- }
- self.assertFieldOutput(ESPhoneNumberField, valid, invalid)
-
- def test_ESIdentityCardNumberField(self):
- error_invalid = ['Please enter a valid NIF, NIE, or CIF.']
- error_checksum_nif = ['Invalid checksum for NIF.']
- error_checksum_nie = ['Invalid checksum for NIE.']
- error_checksum_cif = ['Invalid checksum for CIF.']
- valid = {
- '78699688J': '78699688J',
- '78699688-J': '78699688J',
- '78699688 J': '78699688J',
- '78699688 j': '78699688J',
- 'X0901797J': 'X0901797J',
- 'X-6124387-Q': 'X6124387Q',
- 'X 0012953 G': 'X0012953G',
- 'x-3287690-r': 'X3287690R',
- 't-03287690r': 'T03287690R',
- 'P2907500I': 'P2907500I',
- 'B38790911': 'B38790911',
- 'B31234560': 'B31234560',
- 'B-3879091A': 'B3879091A',
- 'B 38790911': 'B38790911',
- 'P-3900800-H': 'P3900800H',
- 'P 39008008': 'P39008008',
- 'C-28795565': 'C28795565',
- 'C 2879556E': 'C2879556E',
- }
- invalid = {
- '78699688T': error_checksum_nif,
- 'X-03287690': error_invalid,
- 'X-03287690-T': error_checksum_nie,
- 'B 38790917': error_checksum_cif,
- 'C28795567': error_checksum_cif,
- 'I38790911': error_invalid,
- '78699688-2': error_invalid,
- }
- self.assertFieldOutput(ESIdentityCardNumberField, valid, invalid)
-
- def test_ESCCCField(self):
- error_invalid = ['Please enter a valid bank account number in format XXXX-XXXX-XX-XXXXXXXXXX.']
- error_checksum = ['Invalid checksum for bank account number.']
- valid = {
- '20770338793100254321': '20770338793100254321',
- '2077 0338 79 3100254321': '2077 0338 79 3100254321',
- '2077-0338-79-3100254321': '2077-0338-79-3100254321',
- }
- invalid = {
- '2077.0338.79.3100254321': error_invalid,
- '2077-0338-78-3100254321': error_checksum,
- '2077-0338-89-3100254321': error_checksum,
- '2077-03-3879-3100254321': error_invalid,
- }
- self.assertFieldOutput(ESCCCField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/fi/__init__.py b/tests/regressiontests/localflavor/fi/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/fi/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/fi/tests.py b/tests/regressiontests/localflavor/fi/tests.py
deleted file mode 100644
index bfd2e2a010..0000000000
--- a/tests/regressiontests/localflavor/fi/tests.py
+++ /dev/null
@@ -1,383 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.fi.forms import (FIZipCodeField,
- FISocialSecurityNumber, FIMunicipalitySelect)
-
-from django.test import SimpleTestCase
-
-
-class FILocalFlavorTests(SimpleTestCase):
- def test_FIMunicipalitySelect(self):
- f = FIMunicipalitySelect()
- out = '''<select name="municipalities">
-<option value="akaa">Akaa</option>
-<option value="alajarvi">Alaj\xe4rvi</option>
-<option value="alavieska">Alavieska</option>
-<option value="alavus">Alavus</option>
-<option value="artjarvi">Artj\xe4rvi</option>
-<option value="asikkala">Asikkala</option>
-<option value="askola">Askola</option>
-<option value="aura">Aura</option>
-<option value="brando">Br\xe4nd\xf6</option>
-<option value="eckero">Ecker\xf6</option>
-<option value="enonkoski">Enonkoski</option>
-<option value="enontekio">Enonteki\xf6</option>
-<option value="espoo">Espoo</option>
-<option value="eura">Eura</option>
-<option value="eurajoki">Eurajoki</option>
-<option value="evijarvi">Evij\xe4rvi</option>
-<option value="finstrom">Finstr\xf6m</option>
-<option value="forssa">Forssa</option>
-<option value="foglo">F\xf6gl\xf6</option>
-<option value="geta">Geta</option>
-<option value="haapajarvi">Haapaj\xe4rvi</option>
-<option value="haapavesi">Haapavesi</option>
-<option value="hailuoto">Hailuoto</option>
-<option value="halsua">Halsua</option>
-<option value="hamina">Hamina</option>
-<option value="hammarland">Hammarland</option>
-<option value="hankasalmi">Hankasalmi</option>
-<option value="hanko">Hanko</option>
-<option value="harjavalta">Harjavalta</option>
-<option value="hartola">Hartola</option>
-<option value="hattula">Hattula</option>
-<option value="haukipudas">Haukipudas</option>
-<option value="hausjarvi">Hausj\xe4rvi</option>
-<option value="heinola">Heinola</option>
-<option value="heinavesi">Hein\xe4vesi</option>
-<option value="helsinki">Helsinki</option>
-<option value="hirvensalmi">Hirvensalmi</option>
-<option value="hollola">Hollola</option>
-<option value="honkajoki">Honkajoki</option>
-<option value="huittinen">Huittinen</option>
-<option value="humppila">Humppila</option>
-<option value="hyrynsalmi">Hyrynsalmi</option>
-<option value="hyvinkaa">Hyvink\xe4\xe4</option>
-<option value="hameenkoski">H\xe4meenkoski</option>
-<option value="hameenkyro">H\xe4meenkyr\xf6</option>
-<option value="hameenlinna">H\xe4meenlinna</option>
-<option value="ii">Ii</option>
-<option value="iisalmi">Iisalmi</option>
-<option value="iitti">Iitti</option>
-<option value="ikaalinen">Ikaalinen</option>
-<option value="ilmajoki">Ilmajoki</option>
-<option value="ilomantsi">Ilomantsi</option>
-<option value="imatra">Imatra</option>
-<option value="inari">Inari</option>
-<option value="inkoo">Inkoo</option>
-<option value="isojoki">Isojoki</option>
-<option value="isokyro">Isokyr\xf6</option>
-<option value="jalasjarvi">Jalasj\xe4rvi</option>
-<option value="janakkala">Janakkala</option>
-<option value="joensuu">Joensuu</option>
-<option value="jokioinen">Jokioinen</option>
-<option value="jomala">Jomala</option>
-<option value="joroinen">Joroinen</option>
-<option value="joutsa">Joutsa</option>
-<option value="juankoski">Juankoski</option>
-<option value="juuka">Juuka</option>
-<option value="juupajoki">Juupajoki</option>
-<option value="juva">Juva</option>
-<option value="jyvaskyla">Jyv\xe4skyl\xe4</option>
-<option value="jamijarvi">J\xe4mij\xe4rvi</option>
-<option value="jamsa">J\xe4ms\xe4</option>
-<option value="jarvenpaa">J\xe4rvenp\xe4\xe4</option>
-<option value="kaarina">Kaarina</option>
-<option value="kaavi">Kaavi</option>
-<option value="kajaani">Kajaani</option>
-<option value="kalajoki">Kalajoki</option>
-<option value="kangasala">Kangasala</option>
-<option value="kangasniemi">Kangasniemi</option>
-<option value="kankaanpaa">Kankaanp\xe4\xe4</option>
-<option value="kannonkoski">Kannonkoski</option>
-<option value="kannus">Kannus</option>
-<option value="karijoki">Karijoki</option>
-<option value="karjalohja">Karjalohja</option>
-<option value="karkkila">Karkkila</option>
-<option value="karstula">Karstula</option>
-<option value="karttula">Karttula</option>
-<option value="karvia">Karvia</option>
-<option value="kaskinen">Kaskinen</option>
-<option value="kauhajoki">Kauhajoki</option>
-<option value="kauhava">Kauhava</option>
-<option value="kauniainen">Kauniainen</option>
-<option value="kaustinen">Kaustinen</option>
-<option value="keitele">Keitele</option>
-<option value="kemi">Kemi</option>
-<option value="kemijarvi">Kemij\xe4rvi</option>
-<option value="keminmaa">Keminmaa</option>
-<option value="kemionsaari">Kemi\xf6nsaari</option>
-<option value="kempele">Kempele</option>
-<option value="kerava">Kerava</option>
-<option value="kerimaki">Kerim\xe4ki</option>
-<option value="kesalahti">Kes\xe4lahti</option>
-<option value="keuruu">Keuruu</option>
-<option value="kihnio">Kihni\xf6</option>
-<option value="kiikoinen">Kiikoinen</option>
-<option value="kiiminki">Kiiminki</option>
-<option value="kinnula">Kinnula</option>
-<option value="kirkkonummi">Kirkkonummi</option>
-<option value="kitee">Kitee</option>
-<option value="kittila">Kittil\xe4</option>
-<option value="kiuruvesi">Kiuruvesi</option>
-<option value="kivijarvi">Kivij\xe4rvi</option>
-<option value="kokemaki">Kokem\xe4ki</option>
-<option value="kokkola">Kokkola</option>
-<option value="kolari">Kolari</option>
-<option value="konnevesi">Konnevesi</option>
-<option value="kontiolahti">Kontiolahti</option>
-<option value="korsnas">Korsn\xe4s</option>
-<option value="koskitl">Koski Tl</option>
-<option value="kotka">Kotka</option>
-<option value="kouvola">Kouvola</option>
-<option value="kristiinankaupunki">Kristiinankaupunki</option>
-<option value="kruunupyy">Kruunupyy</option>
-<option value="kuhmalahti">Kuhmalahti</option>
-<option value="kuhmo">Kuhmo</option>
-<option value="kuhmoinen">Kuhmoinen</option>
-<option value="kumlinge">Kumlinge</option>
-<option value="kuopio">Kuopio</option>
-<option value="kuortane">Kuortane</option>
-<option value="kurikka">Kurikka</option>
-<option value="kustavi">Kustavi</option>
-<option value="kuusamo">Kuusamo</option>
-<option value="kylmakoski">Kylm\xe4koski</option>
-<option value="kyyjarvi">Kyyj\xe4rvi</option>
-<option value="karkola">K\xe4rk\xf6l\xe4</option>
-<option value="karsamaki">K\xe4rs\xe4m\xe4ki</option>
-<option value="kokar">K\xf6kar</option>
-<option value="koylio">K\xf6yli\xf6</option>
-<option value="lahti">Lahti</option>
-<option value="laihia">Laihia</option>
-<option value="laitila">Laitila</option>
-<option value="lapinjarvi">Lapinj\xe4rvi</option>
-<option value="lapinlahti">Lapinlahti</option>
-<option value="lappajarvi">Lappaj\xe4rvi</option>
-<option value="lappeenranta">Lappeenranta</option>
-<option value="lapua">Lapua</option>
-<option value="laukaa">Laukaa</option>
-<option value="lavia">Lavia</option>
-<option value="lemi">Lemi</option>
-<option value="lemland">Lemland</option>
-<option value="lempaala">Lemp\xe4\xe4l\xe4</option>
-<option value="leppavirta">Lepp\xe4virta</option>
-<option value="lestijarvi">Lestij\xe4rvi</option>
-<option value="lieksa">Lieksa</option>
-<option value="lieto">Lieto</option>
-<option value="liminka">Liminka</option>
-<option value="liperi">Liperi</option>
-<option value="lohja">Lohja</option>
-<option value="loimaa">Loimaa</option>
-<option value="loppi">Loppi</option>
-<option value="loviisa">Loviisa</option>
-<option value="luhanka">Luhanka</option>
-<option value="lumijoki">Lumijoki</option>
-<option value="lumparland">Lumparland</option>
-<option value="luoto">Luoto</option>
-<option value="luumaki">Luum\xe4ki</option>
-<option value="luvia">Luvia</option>
-<option value="lansi-turunmaa">L\xe4nsi-Turunmaa</option>
-<option value="maalahti">Maalahti</option>
-<option value="maaninka">Maaninka</option>
-<option value="maarianhamina">Maarianhamina</option>
-<option value="marttila">Marttila</option>
-<option value="masku">Masku</option>
-<option value="merijarvi">Merij\xe4rvi</option>
-<option value="merikarvia">Merikarvia</option>
-<option value="miehikkala">Miehikk\xe4l\xe4</option>
-<option value="mikkeli">Mikkeli</option>
-<option value="muhos">Muhos</option>
-<option value="multia">Multia</option>
-<option value="muonio">Muonio</option>
-<option value="mustasaari">Mustasaari</option>
-<option value="muurame">Muurame</option>
-<option value="mynamaki">Myn\xe4m\xe4ki</option>
-<option value="myrskyla">Myrskyl\xe4</option>
-<option value="mantsala">M\xe4nts\xe4l\xe4</option>
-<option value="mantta-vilppula">M\xe4ntt\xe4-Vilppula</option>
-<option value="mantyharju">M\xe4ntyharju</option>
-<option value="naantali">Naantali</option>
-<option value="nakkila">Nakkila</option>
-<option value="nastola">Nastola</option>
-<option value="nilsia">Nilsi\xe4</option>
-<option value="nivala">Nivala</option>
-<option value="nokia">Nokia</option>
-<option value="nousiainen">Nousiainen</option>
-<option value="nummi-pusula">Nummi-Pusula</option>
-<option value="nurmes">Nurmes</option>
-<option value="nurmijarvi">Nurmij\xe4rvi</option>
-<option value="narpio">N\xe4rpi\xf6</option>
-<option value="oravainen">Oravainen</option>
-<option value="orimattila">Orimattila</option>
-<option value="oripaa">Orip\xe4\xe4</option>
-<option value="orivesi">Orivesi</option>
-<option value="oulainen">Oulainen</option>
-<option value="oulu">Oulu</option>
-<option value="oulunsalo">Oulunsalo</option>
-<option value="outokumpu">Outokumpu</option>
-<option value="padasjoki">Padasjoki</option>
-<option value="paimio">Paimio</option>
-<option value="paltamo">Paltamo</option>
-<option value="parikkala">Parikkala</option>
-<option value="parkano">Parkano</option>
-<option value="pedersore">Peders\xf6re</option>
-<option value="pelkosenniemi">Pelkosenniemi</option>
-<option value="pello">Pello</option>
-<option value="perho">Perho</option>
-<option value="pertunmaa">Pertunmaa</option>
-<option value="petajavesi">Pet\xe4j\xe4vesi</option>
-<option value="pieksamaki">Pieks\xe4m\xe4ki</option>
-<option value="pielavesi">Pielavesi</option>
-<option value="pietarsaari">Pietarsaari</option>
-<option value="pihtipudas">Pihtipudas</option>
-<option value="pirkkala">Pirkkala</option>
-<option value="polvijarvi">Polvij\xe4rvi</option>
-<option value="pomarkku">Pomarkku</option>
-<option value="pori">Pori</option>
-<option value="pornainen">Pornainen</option>
-<option value="porvoo">Porvoo</option>
-<option value="posio">Posio</option>
-<option value="pudasjarvi">Pudasj\xe4rvi</option>
-<option value="pukkila">Pukkila</option>
-<option value="punkaharju">Punkaharju</option>
-<option value="punkalaidun">Punkalaidun</option>
-<option value="puolanka">Puolanka</option>
-<option value="puumala">Puumala</option>
-<option value="pyhtaa">Pyht\xe4\xe4</option>
-<option value="pyhajoki">Pyh\xe4joki</option>
-<option value="pyhajarvi">Pyh\xe4j\xe4rvi</option>
-<option value="pyhanta">Pyh\xe4nt\xe4</option>
-<option value="pyharanta">Pyh\xe4ranta</option>
-<option value="palkane">P\xe4lk\xe4ne</option>
-<option value="poytya">P\xf6yty\xe4</option>
-<option value="raahe">Raahe</option>
-<option value="raasepori">Raasepori</option>
-<option value="raisio">Raisio</option>
-<option value="rantasalmi">Rantasalmi</option>
-<option value="ranua">Ranua</option>
-<option value="rauma">Rauma</option>
-<option value="rautalampi">Rautalampi</option>
-<option value="rautavaara">Rautavaara</option>
-<option value="rautjarvi">Rautj\xe4rvi</option>
-<option value="reisjarvi">Reisj\xe4rvi</option>
-<option value="riihimaki">Riihim\xe4ki</option>
-<option value="ristiina">Ristiina</option>
-<option value="ristijarvi">Ristij\xe4rvi</option>
-<option value="rovaniemi">Rovaniemi</option>
-<option value="ruokolahti">Ruokolahti</option>
-<option value="ruovesi">Ruovesi</option>
-<option value="rusko">Rusko</option>
-<option value="raakkyla">R\xe4\xe4kkyl\xe4</option>
-<option value="saarijarvi">Saarij\xe4rvi</option>
-<option value="salla">Salla</option>
-<option value="salo">Salo</option>
-<option value="saltvik">Saltvik</option>
-<option value="sastamala">Sastamala</option>
-<option value="sauvo">Sauvo</option>
-<option value="savitaipale">Savitaipale</option>
-<option value="savonlinna">Savonlinna</option>
-<option value="savukoski">Savukoski</option>
-<option value="seinajoki">Sein\xe4joki</option>
-<option value="sievi">Sievi</option>
-<option value="siikainen">Siikainen</option>
-<option value="siikajoki">Siikajoki</option>
-<option value="siikalatva">Siikalatva</option>
-<option value="siilinjarvi">Siilinj\xe4rvi</option>
-<option value="simo">Simo</option>
-<option value="sipoo">Sipoo</option>
-<option value="siuntio">Siuntio</option>
-<option value="sodankyla">Sodankyl\xe4</option>
-<option value="soini">Soini</option>
-<option value="somero">Somero</option>
-<option value="sonkajarvi">Sonkaj\xe4rvi</option>
-<option value="sotkamo">Sotkamo</option>
-<option value="sottunga">Sottunga</option>
-<option value="sulkava">Sulkava</option>
-<option value="sund">Sund</option>
-<option value="suomenniemi">Suomenniemi</option>
-<option value="suomussalmi">Suomussalmi</option>
-<option value="suonenjoki">Suonenjoki</option>
-<option value="sysma">Sysm\xe4</option>
-<option value="sakyla">S\xe4kyl\xe4</option>
-<option value="taipalsaari">Taipalsaari</option>
-<option value="taivalkoski">Taivalkoski</option>
-<option value="taivassalo">Taivassalo</option>
-<option value="tammela">Tammela</option>
-<option value="tampere">Tampere</option>
-<option value="tarvasjoki">Tarvasjoki</option>
-<option value="tervo">Tervo</option>
-<option value="tervola">Tervola</option>
-<option value="teuva">Teuva</option>
-<option value="tohmajarvi">Tohmaj\xe4rvi</option>
-<option value="toholampi">Toholampi</option>
-<option value="toivakka">Toivakka</option>
-<option value="tornio">Tornio</option>
-<option value="turku" selected="selected">Turku</option>
-<option value="tuusniemi">Tuusniemi</option>
-<option value="tuusula">Tuusula</option>
-<option value="tyrnava">Tyrn\xe4v\xe4</option>
-<option value="toysa">T\xf6ys\xe4</option>
-<option value="ulvila">Ulvila</option>
-<option value="urjala">Urjala</option>
-<option value="utajarvi">Utaj\xe4rvi</option>
-<option value="utsjoki">Utsjoki</option>
-<option value="uurainen">Uurainen</option>
-<option value="uusikaarlepyy">Uusikaarlepyy</option>
-<option value="uusikaupunki">Uusikaupunki</option>
-<option value="vaala">Vaala</option>
-<option value="vaasa">Vaasa</option>
-<option value="valkeakoski">Valkeakoski</option>
-<option value="valtimo">Valtimo</option>
-<option value="vantaa">Vantaa</option>
-<option value="varkaus">Varkaus</option>
-<option value="varpaisjarvi">Varpaisj\xe4rvi</option>
-<option value="vehmaa">Vehmaa</option>
-<option value="vesanto">Vesanto</option>
-<option value="vesilahti">Vesilahti</option>
-<option value="veteli">Veteli</option>
-<option value="vierema">Vierem\xe4</option>
-<option value="vihanti">Vihanti</option>
-<option value="vihti">Vihti</option>
-<option value="viitasaari">Viitasaari</option>
-<option value="vimpeli">Vimpeli</option>
-<option value="virolahti">Virolahti</option>
-<option value="virrat">Virrat</option>
-<option value="vardo">V\xe5rd\xf6</option>
-<option value="vahakyro">V\xe4h\xe4kyr\xf6</option>
-<option value="voyri-maksamaa">V\xf6yri-Maksamaa</option>
-<option value="yli-ii">Yli-Ii</option>
-<option value="ylitornio">Ylitornio</option>
-<option value="ylivieska">Ylivieska</option>
-<option value="ylojarvi">Yl\xf6j\xe4rvi</option>
-<option value="ypaja">Yp\xe4j\xe4</option>
-<option value="ahtari">\xc4ht\xe4ri</option>
-<option value="aanekoski">\xc4\xe4nekoski</option>
-</select>'''
- self.assertHTMLEqual(f.render('municipalities', 'turku'), out)
-
- def test_FIZipCodeField(self):
- error_format = ['Enter a zip code in the format XXXXX.']
- valid = {
- '20540': '20540',
- '20101': '20101',
- }
- invalid = {
- '20s40': error_format,
- '205401': error_format
- }
- self.assertFieldOutput(FIZipCodeField, valid, invalid)
-
- def test_FISocialSecurityNumber(self):
- error_invalid = ['Enter a valid Finnish social security number.']
- valid = {
- '010101-0101': '010101-0101',
- '010101+0101': '010101+0101',
- '010101A0101': '010101A0101',
- }
- invalid = {
- '101010-0102': error_invalid,
- '10a010-0101': error_invalid,
- '101010-0\xe401': error_invalid,
- '101010b0101': error_invalid,
- }
- self.assertFieldOutput(FISocialSecurityNumber, valid, invalid)
diff --git a/tests/regressiontests/localflavor/fr/__init__.py b/tests/regressiontests/localflavor/fr/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/fr/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/fr/tests.py b/tests/regressiontests/localflavor/fr/tests.py
deleted file mode 100644
index 8e99ef462b..0000000000
--- a/tests/regressiontests/localflavor/fr/tests.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.fr.forms import (FRZipCodeField,
- FRPhoneNumberField, FRDepartmentSelect)
-
-from django.test import SimpleTestCase
-
-
-class FRLocalFlavorTests(SimpleTestCase):
- def test_FRZipCodeField(self):
- error_format = ['Enter a zip code in the format XXXXX.']
- valid = {
- '75001': '75001',
- '93200': '93200',
- }
- invalid = {
- '2A200': error_format,
- '980001': ['Ensure this value has at most 5 characters (it has 6).'
- ] + error_format,
- }
- self.assertFieldOutput(FRZipCodeField, valid, invalid)
-
- def test_FRPhoneNumberField(self):
- error_format = ['Phone numbers must be in 0X XX XX XX XX format.']
- valid = {
- '01 55 44 58 64': '01 55 44 58 64',
- '0155445864': '01 55 44 58 64',
- '01 5544 5864': '01 55 44 58 64',
- '01 55.44.58.64': '01 55 44 58 64',
- '01.55.44.58.64': '01 55 44 58 64',
- }
- invalid = {
- '01,55,44,58,64': error_format,
- '555 015 544': error_format,
- }
- self.assertFieldOutput(FRPhoneNumberField, valid, invalid)
-
- def test_FRDepartmentSelect(self):
- f = FRDepartmentSelect()
- out = '''<select name="dep">
-<option value="01">01 - Ain</option>
-<option value="02">02 - Aisne</option>
-<option value="03">03 - Allier</option>
-<option value="04">04 - Alpes-de-Haute-Provence</option>
-<option value="05">05 - Hautes-Alpes</option>
-<option value="06">06 - Alpes-Maritimes</option>
-<option value="07">07 - Ardèche</option>
-<option value="08">08 - Ardennes</option>
-<option value="09">09 - Ariège</option>
-<option value="10">10 - Aube</option>
-<option value="11">11 - Aude</option>
-<option value="12">12 - Aveyron</option>
-<option value="13">13 - Bouches-du-Rhône</option>
-<option value="14">14 - Calvados</option>
-<option value="15">15 - Cantal</option>
-<option value="16">16 - Charente</option>
-<option value="17">17 - Charente-Maritime</option>
-<option value="18">18 - Cher</option>
-<option value="19">19 - Corrèze</option>
-<option value="2A">2A - Corse-du-Sud</option>
-<option value="2B">2B - Haute-Corse</option>
-<option value="21">21 - Côte-d&#39;Or</option>
-<option value="22">22 - Côtes-d&#39;Armor</option>
-<option value="23">23 - Creuse</option>
-<option value="24">24 - Dordogne</option>
-<option value="25">25 - Doubs</option>
-<option value="26">26 - Drôme</option>
-<option value="27">27 - Eure</option>
-<option value="28">28 - Eure-et-Loir</option>
-<option value="29">29 - Finistère</option>
-<option value="30">30 - Gard</option>
-<option value="31">31 - Haute-Garonne</option>
-<option value="32">32 - Gers</option>
-<option value="33">33 - Gironde</option>
-<option value="34">34 - Hérault</option>
-<option value="35">35 - Ille-et-Vilaine</option>
-<option value="36">36 - Indre</option>
-<option value="37">37 - Indre-et-Loire</option>
-<option value="38">38 - Isère</option>
-<option value="39">39 - Jura</option>
-<option value="40">40 - Landes</option>
-<option value="41">41 - Loir-et-Cher</option>
-<option value="42">42 - Loire</option>
-<option value="43">43 - Haute-Loire</option>
-<option value="44">44 - Loire-Atlantique</option>
-<option value="45">45 - Loiret</option>
-<option value="46">46 - Lot</option>
-<option value="47">47 - Lot-et-Garonne</option>
-<option value="48">48 - Lozère</option>
-<option value="49">49 - Maine-et-Loire</option>
-<option value="50">50 - Manche</option>
-<option value="51">51 - Marne</option>
-<option value="52">52 - Haute-Marne</option>
-<option value="53">53 - Mayenne</option>
-<option value="54">54 - Meurthe-et-Moselle</option>
-<option value="55">55 - Meuse</option>
-<option value="56">56 - Morbihan</option>
-<option value="57">57 - Moselle</option>
-<option value="58">58 - Nièvre</option>
-<option value="59">59 - Nord</option>
-<option value="60">60 - Oise</option>
-<option value="61">61 - Orne</option>
-<option value="62">62 - Pas-de-Calais</option>
-<option value="63">63 - Puy-de-Dôme</option>
-<option value="64">64 - Pyrénées-Atlantiques</option>
-<option value="65">65 - Hautes-Pyrénées</option>
-<option value="66">66 - Pyrénées-Orientales</option>
-<option value="67">67 - Bas-Rhin</option>
-<option value="68">68 - Haut-Rhin</option>
-<option value="69">69 - Rhône</option>
-<option value="70">70 - Haute-Saône</option>
-<option value="71">71 - Saône-et-Loire</option>
-<option value="72">72 - Sarthe</option>
-<option value="73">73 - Savoie</option>
-<option value="74">74 - Haute-Savoie</option>
-<option value="75" selected="selected">75 - Paris</option>
-<option value="76">76 - Seine-Maritime</option>
-<option value="77">77 - Seine-et-Marne</option>
-<option value="78">78 - Yvelines</option>
-<option value="79">79 - Deux-Sèvres</option>
-<option value="80">80 - Somme</option>
-<option value="81">81 - Tarn</option>
-<option value="82">82 - Tarn-et-Garonne</option>
-<option value="83">83 - Var</option>
-<option value="84">84 - Vaucluse</option>
-<option value="85">85 - Vendée</option>
-<option value="86">86 - Vienne</option>
-<option value="87">87 - Haute-Vienne</option>
-<option value="88">88 - Vosges</option>
-<option value="89">89 - Yonne</option>
-<option value="90">90 - Territoire de Belfort</option>
-<option value="91">91 - Essonne</option>
-<option value="92">92 - Hauts-de-Seine</option>
-<option value="93">93 - Seine-Saint-Denis</option>
-<option value="94">94 - Val-de-Marne</option>
-<option value="95">95 - Val-d&#39;Oise</option>
-<option value="971">971 - Guadeloupe</option>
-<option value="972">972 - Martinique</option>
-<option value="973">973 - Guyane</option>
-<option value="974">974 - La Réunion</option>
-<option value="975">975 - Saint-Pierre-et-Miquelon</option>
-<option value="976">976 - Mayotte</option>
-<option value="977">977 - Saint-Barthélemy</option>
-<option value="978">978 - Saint-Martin</option>
-<option value="984">984 - Terres australes et antarctiques françaises</option>
-<option value="986">986 - Wallis et Futuna</option>
-<option value="987">987 - Polynésie française</option>
-<option value="988">988 - Nouvelle-Calédonie</option>
-<option value="989">989 - Île de Clipperton</option>
-</select>'''
- self.assertHTMLEqual(f.render('dep', '75'), out)
diff --git a/tests/regressiontests/localflavor/gb/__init__.py b/tests/regressiontests/localflavor/gb/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/gb/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/gb/tests.py b/tests/regressiontests/localflavor/gb/tests.py
deleted file mode 100644
index 5a267105d5..0000000000
--- a/tests/regressiontests/localflavor/gb/tests.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.gb.forms import GBPostcodeField
-
-from django.test import SimpleTestCase
-
-
-class GBLocalFlavorTests(SimpleTestCase):
- def test_GBPostcodeField(self):
- error_invalid = ['Enter a valid postcode.']
- valid = {
- 'BT32 4PX': 'BT32 4PX',
- 'GIR 0AA': 'GIR 0AA',
- 'BT324PX': 'BT32 4PX',
- ' so11aa ': 'SO1 1AA',
- ' so1 1aa ': 'SO1 1AA',
- 'G2 3wt': 'G2 3WT',
- 'EC1A 1BB': 'EC1A 1BB',
- 'Ec1a1BB': 'EC1A 1BB',
- }
- invalid = {
- '1NV 4L1D': error_invalid,
- '1NV4L1D': error_invalid,
- ' b0gUS': error_invalid,
- }
- self.assertFieldOutput(GBPostcodeField, valid, invalid)
- valid = {}
- invalid = {
- '1NV 4L1D': ['Enter a bloody postcode!'],
- }
- kwargs = {'error_messages': {'invalid': 'Enter a bloody postcode!'}}
- self.assertFieldOutput(GBPostcodeField, valid, invalid, field_kwargs=kwargs)
diff --git a/tests/regressiontests/localflavor/hk/__init__.py b/tests/regressiontests/localflavor/hk/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/hk/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/hk/forms.py b/tests/regressiontests/localflavor/hk/forms.py
deleted file mode 100644
index a6233d4245..0000000000
--- a/tests/regressiontests/localflavor/hk/forms.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from __future__ import absolute_import
-
-from django.forms import ModelForm
-
-from .models import HKPlace
-
-
-class HKPlaceForm(ModelForm):
-
- class Meta:
- model = HKPlace
diff --git a/tests/regressiontests/localflavor/hk/tests.py b/tests/regressiontests/localflavor/hk/tests.py
deleted file mode 100644
index ed5e623ee2..0000000000
--- a/tests/regressiontests/localflavor/hk/tests.py
+++ /dev/null
@@ -1,35 +0,0 @@
-from __future__ import absolute_import
-
-from django.contrib.localflavor.hk.forms import HKPhoneNumberField
-from django.test import SimpleTestCase
-
-
-class HKLocalFlavorTests(SimpleTestCase):
- """Tests for Hong Kong Local Flavors"""
-
- def test_HKPhoneNumberField(self):
- error_msgs = HKPhoneNumberField.default_error_messages
- valid = {
- '2111-1111': '2111-1111',
- '3111 1111': '3111-1111',
- '51111111': '5111-1111',
- '852-6111-1111': '6111-1111',
- '(+852) 8111-1111': '8111-1111',
- '(+852) 9111-1111': '9111-1111',
- '85291111111': '9111-1111',
- }
- invalid = {
- '9991-1111': [error_msgs['disguise'], ],
- '9921-1111': [error_msgs['disguise'], ],
- '1121-1111': [error_msgs['disguise'], ],
- '99987654': [error_msgs['disguise'], ],
- '99287654': [error_msgs['disguise'], ],
- '11287654': [error_msgs['disguise'], ],
- '1': [error_msgs['invalid'], ],
- '2111--1111': [error_msgs['invalid'], ],
- '11111111': [error_msgs['prefix'], ],
- '00000000': [error_msgs['prefix'], ],
- '44444444': [error_msgs['prefix'], ],
- '77777777': [error_msgs['prefix'], ],
- }
- self.assertFieldOutput(HKPhoneNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/hr/__init__.py b/tests/regressiontests/localflavor/hr/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/hr/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/hr/tests.py b/tests/regressiontests/localflavor/hr/tests.py
deleted file mode 100644
index c1b097c03f..0000000000
--- a/tests/regressiontests/localflavor/hr/tests.py
+++ /dev/null
@@ -1,192 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.hr.forms import (HRCountySelect,
- HRPhoneNumberPrefixSelect, HRLicensePlatePrefixSelect, HRPhoneNumberField,
- HRLicensePlateField, HRPostalCodeField, HROIBField, HRJMBGField,
- HRJMBAGField)
-
-from django.test import SimpleTestCase
-
-class HRLocalFlavorTests(SimpleTestCase):
- def test_HRCountySelect(self):
- f = HRCountySelect()
- out = '''<select name="county">
-<option value="GZG" selected="selected">Grad Zagreb</option>
-<option value="BBŽ">Bjelovarsko-bilogorska županija</option>
-<option value="BPŽ">Brodsko-posavska županija</option>
-<option value="DNŽ">Dubrovačko-neretvanska županija</option>
-<option value="IŽ">Istarska županija</option>
-<option value="KŽ">Karlovačka županija</option>
-<option value="KKŽ">Koprivničko-križevačka županija</option>
-<option value="KZŽ">Krapinsko-zagorska županija</option>
-<option value="LSŽ">Ličko-senjska županija</option>
-<option value="MŽ">Međimurska županija</option>
-<option value="OBŽ">Osječko-baranjska županija</option>
-<option value="PSŽ">Požeško-slavonska županija</option>
-<option value="PGŽ">Primorsko-goranska županija</option>
-<option value="SMŽ">Sisačko-moslavačka županija</option>
-<option value="SDŽ">Splitsko-dalmatinska županija</option>
-<option value="ŠKŽ">Šibensko-kninska županija</option>
-<option value="VŽ">Varaždinska županija</option>
-<option value="VPŽ">Virovitičko-podravska županija</option>
-<option value="VSŽ">Vukovarsko-srijemska županija</option>
-<option value="ZDŽ">Zadarska županija</option>
-<option value="ZGŽ">Zagrebačka županija</option>
-</select>'''
- self.assertHTMLEqual(f.render('county', 'GZG'), out)
-
- def test_HRPhoneNumberPrefixSelect(self):
- f = HRPhoneNumberPrefixSelect()
- out = '''<select name="phone">
-<option value="1" selected="selected">01</option>
-<option value="20">020</option>
-<option value="21">021</option>
-<option value="22">022</option>
-<option value="23">023</option>
-<option value="31">031</option>
-<option value="32">032</option>
-<option value="33">033</option>
-<option value="34">034</option>
-<option value="35">035</option>
-<option value="40">040</option>
-<option value="42">042</option>
-<option value="43">043</option>
-<option value="44">044</option>
-<option value="47">047</option>
-<option value="48">048</option>
-<option value="49">049</option>
-<option value="51">051</option>
-<option value="52">052</option>
-<option value="53">053</option>
-<option value="91">091</option>
-<option value="92">092</option>
-<option value="95">095</option>
-<option value="97">097</option>
-<option value="98">098</option>
-<option value="99">099</option>
-</select>'''
- self.assertHTMLEqual(f.render('phone', '1'), out)
-
- def test_HRLicensePlatePrefixSelect(self):
- f = HRLicensePlatePrefixSelect()
- out = '''<select name="license">
-<option value="BJ" selected="selected">BJ</option>
-<option value="BM">BM</option>
-<option value="ČK">ČK</option>
-<option value="DA">DA</option>
-<option value="DE">DE</option>
-<option value="DJ">DJ</option>
-<option value="DU">DU</option>
-<option value="GS">GS</option>
-<option value="IM">IM</option>
-<option value="KA">KA</option>
-<option value="KC">KC</option>
-<option value="KR">KR</option>
-<option value="KT">KT</option>
-<option value="KŽ">KŽ</option>
-<option value="MA">MA</option>
-<option value="NA">NA</option>
-<option value="NG">NG</option>
-<option value="OG">OG</option>
-<option value="OS">OS</option>
-<option value="PU">PU</option>
-<option value="PŽ">PŽ</option>
-<option value="RI">RI</option>
-<option value="SB">SB</option>
-<option value="SK">SK</option>
-<option value="SL">SL</option>
-<option value="ST">ST</option>
-<option value="ŠI">ŠI</option>
-<option value="VK">VK</option>
-<option value="VT">VT</option>
-<option value="VU">VU</option>
-<option value="VŽ">VŽ</option>
-<option value="ZD">ZD</option>
-<option value="ZG">ZG</option>
-<option value="ŽU">ŽU</option>
-</select>'''
- self.assertHTMLEqual(f.render('license', 'BJ'), out)
-
- def test_HRPhoneNumberField(self):
- error_invalid = ['Enter a valid phone number']
- error_area = ['Enter a valid area or mobile network code']
- error_number = ['The phone nubmer is too long']
- valid = {
- '+38511234567': '+38511234567',
- '0038511234567': '+38511234567',
- '011234567': '+38511234567',
- '+38521123456': '+38521123456',
- '0038521123456': '+38521123456',
- '021123456': '+38521123456',
- }
- invalid = {
- '123456789': error_invalid,
- '0811234567': error_area,
- '0111234567': error_number,
- }
- self.assertFieldOutput(HRPhoneNumberField, valid, invalid)
-
- def test_HRLicensePlateField(self):
- error_invalid = ['Enter a valid vehicle license plate number']
- error_area = ['Enter a valid location code']
- error_number = ['Number part cannot be zero']
- valid = {
- 'ZG 1234-AA': 'ZG 1234-AA',
- 'ZG 123-A': 'ZG 123-A',
- }
- invalid = {
- 'PV12345': error_invalid,
- 'PV1234AA': error_area,
- 'ZG0000CC': error_number,
- }
- self.assertFieldOutput(HRLicensePlateField, valid, invalid)
-
- def test_HRPostalCodeField(self):
- error_invalid = ['Enter a valid 5 digit postal code']
- valid = {
- '10000': '10000',
- '35410': '35410',
- }
- invalid = {
- 'ABCD': error_invalid,
- '99999': error_invalid,
- }
- self.assertFieldOutput(HRPostalCodeField, valid, invalid)
-
- def test_HROIBField(self):
- error_invalid = ['Enter a valid 11 digit OIB']
- valid = {
- '12345678901': '12345678901',
- }
- invalid = {
- '1234567890': ['Ensure this value has at least 11 characters (it has 10).'] + error_invalid,
- 'ABCDEFGHIJK': error_invalid,
- }
- self.assertFieldOutput(HROIBField, valid, invalid)
-
- def test_HRJMBGField(self):
- error_invalid = ['Enter a valid 13 digit JMBG']
- error_date = ['Error in date segment']
- valid = {
- '1211984302155': '1211984302155',
- '2701984307107': '2701984307107',
- }
- invalid = {
- '1211984302156': error_invalid,
- 'ABCDEFG': error_invalid,
- '9999999123456': error_date,
- }
- self.assertFieldOutput(HRJMBGField, valid, invalid)
-
- def test_HRJMBAGField(self):
- error_invalid = ['Enter a valid 19 digit JMBAG starting with 601983']
- error_copy = ['Card issue number cannot be zero']
- valid = {
- '601983 11 0130185856 4': '6019831101301858564',
- }
- invalid = {
- '601983 11 0130185856 5': error_invalid,
- '601983 01 0130185856 4': error_copy,
- }
- self.assertFieldOutput(HRJMBAGField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/id/__init__.py b/tests/regressiontests/localflavor/id/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/id/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/id/tests.py b/tests/regressiontests/localflavor/id/tests.py
deleted file mode 100644
index dd712d02a3..0000000000
--- a/tests/regressiontests/localflavor/id/tests.py
+++ /dev/null
@@ -1,195 +0,0 @@
-from __future__ import unicode_literals
-
-import warnings
-
-from django.contrib.localflavor.id.forms import (IDPhoneNumberField,
- IDPostCodeField, IDNationalIdentityNumberField, IDLicensePlateField,
- IDProvinceSelect, IDLicensePlatePrefixSelect)
-
-from django.test import SimpleTestCase
-
-
-class IDLocalFlavorTests(SimpleTestCase):
- def setUp(self):
- self.save_warnings_state()
- warnings.filterwarnings(
- "ignore",
- category=RuntimeWarning,
- module='django.contrib.localflavor.id.id_choices'
- )
-
- def tearDown(self):
- self.restore_warnings_state()
-
- def test_IDProvinceSelect(self):
- f = IDProvinceSelect()
- out = '''<select name="provinces">
-<option value="ACE">Aceh</option>
-<option value="BLI">Bali</option>
-<option value="BTN">Banten</option>
-<option value="BKL">Bengkulu</option>
-<option value="DIY">Yogyakarta</option>
-<option value="JKT">Jakarta</option>
-<option value="GOR">Gorontalo</option>
-<option value="JMB">Jambi</option>
-<option value="JBR">Jawa Barat</option>
-<option value="JTG">Jawa Tengah</option>
-<option value="JTM">Jawa Timur</option>
-<option value="KBR">Kalimantan Barat</option>
-<option value="KSL">Kalimantan Selatan</option>
-<option value="KTG">Kalimantan Tengah</option>
-<option value="KTM">Kalimantan Timur</option>
-<option value="BBL">Kepulauan Bangka-Belitung</option>
-<option value="KRI">Kepulauan Riau</option>
-<option value="LPG" selected="selected">Lampung</option>
-<option value="MLK">Maluku</option>
-<option value="MUT">Maluku Utara</option>
-<option value="NTB">Nusa Tenggara Barat</option>
-<option value="NTT">Nusa Tenggara Timur</option>
-<option value="PPA">Papua</option>
-<option value="PPB">Papua Barat</option>
-<option value="RIU">Riau</option>
-<option value="SLB">Sulawesi Barat</option>
-<option value="SLS">Sulawesi Selatan</option>
-<option value="SLT">Sulawesi Tengah</option>
-<option value="SLR">Sulawesi Tenggara</option>
-<option value="SLU">Sulawesi Utara</option>
-<option value="SMB">Sumatera Barat</option>
-<option value="SMS">Sumatera Selatan</option>
-<option value="SMU">Sumatera Utara</option>
-</select>'''
- self.assertHTMLEqual(f.render('provinces', 'LPG'), out)
-
- def test_IDLicensePlatePrefixSelect(self):
- f = IDLicensePlatePrefixSelect()
- out = '''<select name="codes">
-<option value="A">Banten</option>
-<option value="AA">Magelang</option>
-<option value="AB">Yogyakarta</option>
-<option value="AD">Surakarta - Solo</option>
-<option value="AE">Madiun</option>
-<option value="AG">Kediri</option>
-<option value="B">Jakarta</option>
-<option value="BA">Sumatera Barat</option>
-<option value="BB">Tapanuli</option>
-<option value="BD">Bengkulu</option>
-<option value="BE" selected="selected">Lampung</option>
-<option value="BG">Sumatera Selatan</option>
-<option value="BH">Jambi</option>
-<option value="BK">Sumatera Utara</option>
-<option value="BL">Nanggroe Aceh Darussalam</option>
-<option value="BM">Riau</option>
-<option value="BN">Kepulauan Bangka Belitung</option>
-<option value="BP">Kepulauan Riau</option>
-<option value="CC">Corps Consulate</option>
-<option value="CD">Corps Diplomatic</option>
-<option value="D">Bandung</option>
-<option value="DA">Kalimantan Selatan</option>
-<option value="DB">Sulawesi Utara Daratan</option>
-<option value="DC">Sulawesi Barat</option>
-<option value="DD">Sulawesi Selatan</option>
-<option value="DE">Maluku</option>
-<option value="DG">Maluku Utara</option>
-<option value="DH">NTT - Timor</option>
-<option value="DK">Bali</option>
-<option value="DL">Sulawesi Utara Kepulauan</option>
-<option value="DM">Gorontalo</option>
-<option value="DN">Sulawesi Tengah</option>
-<option value="DR">NTB - Lombok</option>
-<option value="DS">Papua dan Papua Barat</option>
-<option value="DT">Sulawesi Tenggara</option>
-<option value="E">Cirebon</option>
-<option value="EA">NTB - Sumbawa</option>
-<option value="EB">NTT - Flores</option>
-<option value="ED">NTT - Sumba</option>
-<option value="F">Bogor</option>
-<option value="G">Pekalongan</option>
-<option value="H">Semarang</option>
-<option value="K">Pati</option>
-<option value="KB">Kalimantan Barat</option>
-<option value="KH">Kalimantan Tengah</option>
-<option value="KT">Kalimantan Timur</option>
-<option value="L">Surabaya</option>
-<option value="M">Madura</option>
-<option value="N">Malang</option>
-<option value="P">Jember</option>
-<option value="R">Banyumas</option>
-<option value="RI">Federal Government</option>
-<option value="S">Bojonegoro</option>
-<option value="T">Purwakarta</option>
-<option value="W">Sidoarjo</option>
-<option value="Z">Garut</option>
-</select>'''
- self.assertHTMLEqual(f.render('codes', 'BE'), out)
-
- def test_IDPhoneNumberField(self):
- error_invalid = ['Enter a valid phone number']
- valid = {
- '0812-3456789': '0812-3456789',
- '081234567890': '081234567890',
- '021 345 6789': '021 345 6789',
- '0213456789': '0213456789',
- '+62-21-3456789': '+62-21-3456789',
- '(021) 345 6789': '(021) 345 6789',
- }
- invalid = {
- '0123456789': error_invalid,
- '+62-021-3456789': error_invalid,
- '+62-0812-3456789': error_invalid,
- '0812345678901': error_invalid,
- 'foo': error_invalid,
- }
- self.assertFieldOutput(IDPhoneNumberField, valid, invalid)
-
- def test_IDPostCodeField(self):
- error_invalid = ['Enter a valid post code']
- valid = {
- '12340': '12340',
- '25412': '25412',
- ' 12340 ': '12340',
- }
- invalid = {
- '12 3 4 0': error_invalid,
- '12345': error_invalid,
- '10100': error_invalid,
- '123456': error_invalid,
- 'foo': error_invalid,
- }
- self.assertFieldOutput(IDPostCodeField, valid, invalid)
-
- def test_IDNationalIdentityNumberField(self):
- error_invalid = ['Enter a valid NIK/KTP number']
- valid = {
- ' 12.3456.010178 3456 ': '12.3456.010178.3456',
- '1234560101783456': '12.3456.010178.3456',
- '12.3456.010101.3456': '12.3456.010101.3456',
- }
- invalid = {
- '12.3456.310278.3456': error_invalid,
- '00.0000.010101.0000': error_invalid,
- '1234567890123456': error_invalid,
- 'foo': error_invalid,
- }
- self.assertFieldOutput(IDNationalIdentityNumberField, valid, invalid)
-
- def test_IDLicensePlateField(self):
- error_invalid = ['Enter a valid vehicle license plate number']
- valid = {
- ' b 1234 ab ': 'B 1234 AB',
- 'B 1234 ABC': 'B 1234 ABC',
- 'A 12': 'A 12',
- 'DK 12345 12': 'DK 12345 12',
- 'RI 10': 'RI 10',
- 'CD 12 12': 'CD 12 12',
- }
- invalid = {
- 'CD 10 12': error_invalid,
- 'CD 1234 12': error_invalid,
- 'RI 10 AB': error_invalid,
- 'B 12345 01': error_invalid,
- 'N 1234 12': error_invalid,
- 'A 12 XYZ': error_invalid,
- 'Q 1234 AB': error_invalid,
- 'foo': error_invalid,
- }
- self.assertFieldOutput(IDLicensePlateField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/ie/__init__.py b/tests/regressiontests/localflavor/ie/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/ie/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/ie/tests.py b/tests/regressiontests/localflavor/ie/tests.py
deleted file mode 100644
index 717fa9d1c7..0000000000
--- a/tests/regressiontests/localflavor/ie/tests.py
+++ /dev/null
@@ -1,45 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.ie.forms import IECountySelect
-
-from django.test import SimpleTestCase
-
-
-class IELocalFlavorTests(SimpleTestCase):
- def test_IECountySelect(self):
- f = IECountySelect()
- out = '''<select name="counties">
-<option value="antrim">Antrim</option>
-<option value="armagh">Armagh</option>
-<option value="carlow">Carlow</option>
-<option value="cavan">Cavan</option>
-<option value="clare">Clare</option>
-<option value="cork">Cork</option>
-<option value="derry">Derry</option>
-<option value="donegal">Donegal</option>
-<option value="down">Down</option>
-<option value="dublin" selected="selected">Dublin</option>
-<option value="fermanagh">Fermanagh</option>
-<option value="galway">Galway</option>
-<option value="kerry">Kerry</option>
-<option value="kildare">Kildare</option>
-<option value="kilkenny">Kilkenny</option>
-<option value="laois">Laois</option>
-<option value="leitrim">Leitrim</option>
-<option value="limerick">Limerick</option>
-<option value="longford">Longford</option>
-<option value="louth">Louth</option>
-<option value="mayo">Mayo</option>
-<option value="meath">Meath</option>
-<option value="monaghan">Monaghan</option>
-<option value="offaly">Offaly</option>
-<option value="roscommon">Roscommon</option>
-<option value="sligo">Sligo</option>
-<option value="tipperary">Tipperary</option>
-<option value="tyrone">Tyrone</option>
-<option value="waterford">Waterford</option>
-<option value="westmeath">Westmeath</option>
-<option value="wexford">Wexford</option>
-<option value="wicklow">Wicklow</option>
-</select>'''
- self.assertHTMLEqual(f.render('counties', 'dublin'), out)
diff --git a/tests/regressiontests/localflavor/il/__init__.py b/tests/regressiontests/localflavor/il/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/il/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/il/tests.py b/tests/regressiontests/localflavor/il/tests.py
deleted file mode 100644
index 1b87cf2c19..0000000000
--- a/tests/regressiontests/localflavor/il/tests.py
+++ /dev/null
@@ -1,41 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.il.forms import (ILPostalCodeField,
- ILIDNumberField)
-
-from django.test import SimpleTestCase
-
-
-class ILLocalFlavorTests(SimpleTestCase):
- def test_ILPostalCodeField(self):
- error_format = ['Enter a postal code in the format XXXXX']
- valid = {
- '69973': '69973',
- '699 73': '69973',
- '12345': '12345',
- }
- invalid = {
- '84545x': error_format,
- '123456': error_format,
- '1234': error_format,
- '123 4': error_format,
- }
- self.assertFieldOutput(ILPostalCodeField, valid, invalid)
-
- def test_ILIDNumberField(self):
- error_invalid = ['Enter a valid ID number.']
- valid = {
- '3933742-3': '39337423',
- '39337423': '39337423',
- '039337423': '039337423',
- '03933742-3': '039337423',
- '0091': '0091',
- }
- invalid = {
- '123456789': error_invalid,
- '12345678-9': error_invalid,
- '012346578': error_invalid,
- '012346578-': error_invalid,
- '0001': error_invalid,
- }
- self.assertFieldOutput(ILIDNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/in_/__init__.py b/tests/regressiontests/localflavor/in_/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/in_/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/in_/tests.py b/tests/regressiontests/localflavor/in_/tests.py
deleted file mode 100644
index 57d50f0ebf..0000000000
--- a/tests/regressiontests/localflavor/in_/tests.py
+++ /dev/null
@@ -1,178 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.in_.forms import (INZipCodeField,
- INStateField, INStateSelect, INPhoneNumberField)
-
-from django.test import SimpleTestCase
-
-
-
-class INLocalFlavorTests(SimpleTestCase):
- def test_INPhoneNumberField(self):
- error_format = ['Phone numbers must be in 02X-8X or 03X-7X or 04X-6X format.']
- valid = {
- '0423-2443667': '0423-2443667',
- '0423 2443667': '0423 2443667',
- '04236-244366': '04236-244366',
- '040-24436678': '040-24436678',
- }
- invalid = {
- '04-2443667': error_format,
- '423-2443667': error_format,
- '0423-9442667': error_format,
- '0423-0443667': error_format,
- '0423-244366': error_format,
- '04232442667': error_format,
- '0423DJANGO': error_format,
- }
- self.assertFieldOutput(INPhoneNumberField, valid, invalid)
-
- def test_INPStateSelect(self):
- f = INStateSelect()
- out = '''<select name="state">
-<option value="KA">Karnataka</option>
-<option value="AP" selected="selected">Andhra Pradesh</option>
-<option value="KL">Kerala</option>
-<option value="TN">Tamil Nadu</option>
-<option value="MH">Maharashtra</option>
-<option value="UP">Uttar Pradesh</option>
-<option value="GA">Goa</option>
-<option value="GJ">Gujarat</option>
-<option value="RJ">Rajasthan</option>
-<option value="HP">Himachal Pradesh</option>
-<option value="JK">Jammu and Kashmir</option>
-<option value="AR">Arunachal Pradesh</option>
-<option value="AS">Assam</option>
-<option value="BR">Bihar</option>
-<option value="CG">Chattisgarh</option>
-<option value="HR">Haryana</option>
-<option value="JH">Jharkhand</option>
-<option value="MP">Madhya Pradesh</option>
-<option value="MN">Manipur</option>
-<option value="ML">Meghalaya</option>
-<option value="MZ">Mizoram</option>
-<option value="NL">Nagaland</option>
-<option value="OR">Orissa</option>
-<option value="PB">Punjab</option>
-<option value="SK">Sikkim</option>
-<option value="TR">Tripura</option>
-<option value="UA">Uttarakhand</option>
-<option value="WB">West Bengal</option>
-<option value="AN">Andaman and Nicobar</option>
-<option value="CH">Chandigarh</option>
-<option value="DN">Dadra and Nagar Haveli</option>
-<option value="DD">Daman and Diu</option>
-<option value="DL">Delhi</option>
-<option value="LD">Lakshadweep</option>
-<option value="PY">Pondicherry</option>
-</select>'''
- self.assertHTMLEqual(f.render('state', 'AP'), out)
-
- def test_INZipCodeField(self):
- error_format = ['Enter a zip code in the format XXXXXX or XXX XXX.']
- valid = {
- '360311': '360311',
- '360 311': '360311',
- }
- invalid = {
- '36 0311': error_format,
- '3603111': error_format,
- '360 31': error_format,
- '36031': error_format,
- 'O2B 2R3': error_format
- }
- self.assertFieldOutput(INZipCodeField, valid, invalid)
-
- def test_INStateField(self):
- error_format = ['Enter an Indian state or territory.']
- valid = {
- 'an': 'AN',
- 'AN': 'AN',
- 'andaman and nicobar': 'AN',
- 'andra pradesh': 'AP',
- 'andrapradesh': 'AP',
- 'andhrapradesh': 'AP',
- 'ap': 'AP',
- 'andhra pradesh': 'AP',
- 'ar': 'AR',
- 'arunachal pradesh': 'AR',
- 'assam': 'AS',
- 'as': 'AS',
- 'bihar': 'BR',
- 'br': 'BR',
- 'cg': 'CG',
- 'chattisgarh': 'CG',
- 'ch': 'CH',
- 'chandigarh': 'CH',
- 'daman and diu': 'DD',
- 'dd': 'DD',
- 'dl': 'DL',
- 'delhi': 'DL',
- 'dn': 'DN',
- 'dadra and nagar haveli': 'DN',
- 'ga': 'GA',
- 'goa': 'GA',
- 'gj': 'GJ',
- 'gujarat': 'GJ',
- 'himachal pradesh': 'HP',
- 'hp': 'HP',
- 'hr': 'HR',
- 'haryana': 'HR',
- 'jharkhand': 'JH',
- 'jh': 'JH',
- 'jammu and kashmir': 'JK',
- 'jk': 'JK',
- 'karnataka': 'KA',
- 'karnatka': 'KA',
- 'ka': 'KA',
- 'kerala': 'KL',
- 'kl': 'KL',
- 'ld': 'LD',
- 'lakshadweep': 'LD',
- 'maharastra': 'MH',
- 'mh': 'MH',
- 'maharashtra': 'MH',
- 'meghalaya': 'ML',
- 'ml': 'ML',
- 'mn': 'MN',
- 'manipur': 'MN',
- 'madhya pradesh': 'MP',
- 'mp': 'MP',
- 'mizoram': 'MZ',
- 'mizo': 'MZ',
- 'mz': 'MZ',
- 'nl': 'NL',
- 'nagaland': 'NL',
- 'orissa': 'OR',
- 'odisa': 'OR',
- 'orisa': 'OR',
- 'or': 'OR',
- 'pb': 'PB',
- 'punjab': 'PB',
- 'py': 'PY',
- 'pondicherry': 'PY',
- 'rajasthan': 'RJ',
- 'rajastan': 'RJ',
- 'rj': 'RJ',
- 'sikkim': 'SK',
- 'sk': 'SK',
- 'tamil nadu': 'TN',
- 'tn': 'TN',
- 'tamilnadu': 'TN',
- 'tamilnad': 'TN',
- 'tr': 'TR',
- 'tripura': 'TR',
- 'ua': 'UA',
- 'uttarakhand': 'UA',
- 'up': 'UP',
- 'uttar pradesh': 'UP',
- 'westbengal': 'WB',
- 'bengal': 'WB',
- 'wb': 'WB',
- 'west bengal': 'WB'
- }
- invalid = {
- 'florida': error_format,
- 'FL': error_format,
- }
- self.assertFieldOutput(INStateField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/is_/__init__.py b/tests/regressiontests/localflavor/is_/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/is_/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/is_/tests.py b/tests/regressiontests/localflavor/is_/tests.py
deleted file mode 100644
index 3ed15e937b..0000000000
--- a/tests/regressiontests/localflavor/is_/tests.py
+++ /dev/null
@@ -1,200 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.is_.forms import (ISIdNumberField,
- ISPhoneNumberField, ISPostalCodeSelect)
-
-from django.test import SimpleTestCase
-
-
-class ISLocalFlavorTests(SimpleTestCase):
- def test_ISPostalCodeSelect(self):
- f = ISPostalCodeSelect()
- out = '''<select name="foo">
-<option value="101">101 Reykjav\xedk</option>
-<option value="103">103 Reykjav\xedk</option>
-<option value="104">104 Reykjav\xedk</option>
-<option value="105">105 Reykjav\xedk</option>
-<option value="107">107 Reykjav\xedk</option>
-<option value="108">108 Reykjav\xedk</option>
-<option value="109">109 Reykjav\xedk</option>
-<option value="110">110 Reykjav\xedk</option>
-<option value="111">111 Reykjav\xedk</option>
-<option value="112">112 Reykjav\xedk</option>
-<option value="113">113 Reykjav\xedk</option>
-<option value="116">116 Kjalarnes</option>
-<option value="121">121 Reykjav\xedk</option>
-<option value="123">123 Reykjav\xedk</option>
-<option value="124">124 Reykjav\xedk</option>
-<option value="125">125 Reykjav\xedk</option>
-<option value="127">127 Reykjav\xedk</option>
-<option value="128">128 Reykjav\xedk</option>
-<option value="129">129 Reykjav\xedk</option>
-<option value="130">130 Reykjav\xedk</option>
-<option value="132">132 Reykjav\xedk</option>
-<option value="150">150 Reykjav\xedk</option>
-<option value="155">155 Reykjav\xedk</option>
-<option value="170">170 Seltjarnarnes</option>
-<option value="172">172 Seltjarnarnes</option>
-<option value="190">190 Vogar</option>
-<option value="200">200 K\xf3pavogur</option>
-<option value="201">201 K\xf3pavogur</option>
-<option value="202">202 K\xf3pavogur</option>
-<option value="203">203 K\xf3pavogur</option>
-<option value="210">210 Gar\xf0ab\xe6r</option>
-<option value="212">212 Gar\xf0ab\xe6r</option>
-<option value="220">220 Hafnarfj\xf6r\xf0ur</option>
-<option value="221">221 Hafnarfj\xf6r\xf0ur</option>
-<option value="222">222 Hafnarfj\xf6r\xf0ur</option>
-<option value="225">225 \xc1lftanes</option>
-<option value="230">230 Reykjanesb\xe6r</option>
-<option value="232">232 Reykjanesb\xe6r</option>
-<option value="233">233 Reykjanesb\xe6r</option>
-<option value="235">235 Keflav\xedkurflugv\xf6llur</option>
-<option value="240">240 Grindav\xedk</option>
-<option value="245">245 Sandger\xf0i</option>
-<option value="250">250 Gar\xf0ur</option>
-<option value="260">260 Reykjanesb\xe6r</option>
-<option value="270">270 Mosfellsb\xe6r</option>
-<option value="300">300 Akranes</option>
-<option value="301">301 Akranes</option>
-<option value="302">302 Akranes</option>
-<option value="310">310 Borgarnes</option>
-<option value="311">311 Borgarnes</option>
-<option value="320">320 Reykholt \xed Borgarfir\xf0i</option>
-<option value="340">340 Stykkish\xf3lmur</option>
-<option value="345">345 Flatey \xe1 Brei\xf0afir\xf0i</option>
-<option value="350">350 Grundarfj\xf6r\xf0ur</option>
-<option value="355">355 \xd3lafsv\xedk</option>
-<option value="356">356 Sn\xe6fellsb\xe6r</option>
-<option value="360">360 Hellissandur</option>
-<option value="370">370 B\xfa\xf0ardalur</option>
-<option value="371">371 B\xfa\xf0ardalur</option>
-<option value="380">380 Reykh\xf3lahreppur</option>
-<option value="400">400 \xcdsafj\xf6r\xf0ur</option>
-<option value="401">401 \xcdsafj\xf6r\xf0ur</option>
-<option value="410">410 Hn\xedfsdalur</option>
-<option value="415">415 Bolungarv\xedk</option>
-<option value="420">420 S\xfa\xf0av\xedk</option>
-<option value="425">425 Flateyri</option>
-<option value="430">430 Su\xf0ureyri</option>
-<option value="450">450 Patreksfj\xf6r\xf0ur</option>
-<option value="451">451 Patreksfj\xf6r\xf0ur</option>
-<option value="460">460 T\xe1lknafj\xf6r\xf0ur</option>
-<option value="465">465 B\xedldudalur</option>
-<option value="470">470 \xdeingeyri</option>
-<option value="471">471 \xdeingeyri</option>
-<option value="500">500 Sta\xf0ur</option>
-<option value="510">510 H\xf3lmav\xedk</option>
-<option value="512">512 H\xf3lmav\xedk</option>
-<option value="520">520 Drangsnes</option>
-<option value="522">522 Kj\xf6rvogur</option>
-<option value="523">523 B\xe6r</option>
-<option value="524">524 Nor\xf0urfj\xf6r\xf0ur</option>
-<option value="530">530 Hvammstangi</option>
-<option value="531">531 Hvammstangi</option>
-<option value="540">540 Bl\xf6ndu\xf3s</option>
-<option value="541">541 Bl\xf6ndu\xf3s</option>
-<option value="545">545 Skagastr\xf6nd</option>
-<option value="550">550 Sau\xf0\xe1rkr\xf3kur</option>
-<option value="551">551 Sau\xf0\xe1rkr\xf3kur</option>
-<option value="560">560 Varmahl\xed\xf0</option>
-<option value="565">565 Hofs\xf3s</option>
-<option value="566">566 Hofs\xf3s</option>
-<option value="570">570 Flj\xf3t</option>
-<option value="580">580 Siglufj\xf6r\xf0ur</option>
-<option value="600">600 Akureyri</option>
-<option value="601">601 Akureyri</option>
-<option value="602">602 Akureyri</option>
-<option value="603">603 Akureyri</option>
-<option value="610">610 Greniv\xedk</option>
-<option value="611">611 Gr\xedmsey</option>
-<option value="620">620 Dalv\xedk</option>
-<option value="621">621 Dalv\xedk</option>
-<option value="625">625 \xd3lafsfj\xf6r\xf0ur</option>
-<option value="630">630 Hr\xedsey</option>
-<option value="640">640 H\xfasav\xedk</option>
-<option value="641">641 H\xfasav\xedk</option>
-<option value="645">645 Fossh\xf3ll</option>
-<option value="650">650 Laugar</option>
-<option value="660">660 M\xfdvatn</option>
-<option value="670">670 K\xf3pasker</option>
-<option value="671">671 K\xf3pasker</option>
-<option value="675">675 Raufarh\xf6fn</option>
-<option value="680">680 \xde\xf3rsh\xf6fn</option>
-<option value="681">681 \xde\xf3rsh\xf6fn</option>
-<option value="685">685 Bakkafj\xf6r\xf0ur</option>
-<option value="690">690 Vopnafj\xf6r\xf0ur</option>
-<option value="700">700 Egilssta\xf0ir</option>
-<option value="701">701 Egilssta\xf0ir</option>
-<option value="710">710 Sey\xf0isfj\xf6r\xf0ur</option>
-<option value="715">715 Mj\xf3ifj\xf6r\xf0ur</option>
-<option value="720">720 Borgarfj\xf6r\xf0ur eystri</option>
-<option value="730">730 Rey\xf0arfj\xf6r\xf0ur</option>
-<option value="735">735 Eskifj\xf6r\xf0ur</option>
-<option value="740">740 Neskaupsta\xf0ur</option>
-<option value="750">750 F\xe1skr\xfa\xf0sfj\xf6r\xf0ur</option>
-<option value="755">755 St\xf6\xf0varfj\xf6r\xf0ur</option>
-<option value="760">760 Brei\xf0dalsv\xedk</option>
-<option value="765">765 Dj\xfapivogur</option>
-<option value="780">780 H\xf6fn \xed Hornafir\xf0i</option>
-<option value="781">781 H\xf6fn \xed Hornafir\xf0i</option>
-<option value="785">785 \xd6r\xe6fi</option>
-<option value="800">800 Selfoss</option>
-<option value="801">801 Selfoss</option>
-<option value="802">802 Selfoss</option>
-<option value="810">810 Hverager\xf0i</option>
-<option value="815">815 \xdeorl\xe1ksh\xf6fn</option>
-<option value="820">820 Eyrarbakki</option>
-<option value="825">825 Stokkseyri</option>
-<option value="840">840 Laugarvatn</option>
-<option value="845">845 Fl\xfa\xf0ir</option>
-<option value="850">850 Hella</option>
-<option value="851">851 Hella</option>
-<option value="860">860 Hvolsv\xf6llur</option>
-<option value="861">861 Hvolsv\xf6llur</option>
-<option value="870">870 V\xedk</option>
-<option value="871">871 V\xedk</option>
-<option value="880">880 Kirkjub\xe6jarklaustur</option>
-<option value="900">900 Vestmannaeyjar</option>
-<option value="902">902 Vestmannaeyjar</option>
-</select>'''
- self.assertHTMLEqual(f.render('foo', 'bar'), out)
-
- def test_ISIdNumberField(self):
- error_atleast = ['Ensure this value has at least 10 characters (it has 9).']
- error_invalid = ['Enter a valid Icelandic identification number. The format is XXXXXX-XXXX.']
- error_atmost = ['Ensure this value has at most 11 characters (it has 12).']
- error_notvalid = ['The Icelandic identification number is not valid.']
- valid = {
- '2308803449': '230880-3449',
- '230880-3449': '230880-3449',
- '230880 3449': '230880-3449',
- '2308803440': '230880-3440',
- }
- invalid = {
- '230880343': error_atleast + error_invalid,
- '230880343234': error_atmost + error_invalid,
- 'abcdefghijk': error_invalid,
- '2308803439': error_notvalid,
-
- }
- self.assertFieldOutput(ISIdNumberField, valid, invalid)
-
- def test_ISPhoneNumberField(self):
- error_invalid = ['Enter a valid value.']
- error_atleast = ['Ensure this value has at least 7 characters (it has 6).']
- error_atmost = ['Ensure this value has at most 8 characters (it has 9).']
- valid = {
- '1234567': '1234567',
- '123 4567': '1234567',
- '123-4567': '1234567',
- }
- invalid = {
- '123-456': error_invalid,
- '123456': error_atleast + error_invalid,
- '123456555': error_atmost + error_invalid,
- 'abcdefg': error_invalid,
- ' 1234567 ': error_atmost + error_invalid,
- ' 12367 ': error_invalid
- }
- self.assertFieldOutput(ISPhoneNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/it/__init__.py b/tests/regressiontests/localflavor/it/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/it/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/it/tests.py b/tests/regressiontests/localflavor/it/tests.py
deleted file mode 100644
index 680444400f..0000000000
--- a/tests/regressiontests/localflavor/it/tests.py
+++ /dev/null
@@ -1,71 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.it.forms import (ITZipCodeField, ITRegionSelect,
- ITSocialSecurityNumberField, ITVatNumberField)
-
-from django.test import SimpleTestCase
-
-
-class ITLocalFlavorTests(SimpleTestCase):
- def test_ITRegionSelect(self):
- f = ITRegionSelect()
- out = '''<select name="regions">
-<option value="ABR">Abruzzo</option>
-<option value="BAS">Basilicata</option>
-<option value="CAL">Calabria</option>
-<option value="CAM">Campania</option>
-<option value="EMR">Emilia-Romagna</option>
-<option value="FVG">Friuli-Venezia Giulia</option>
-<option value="LAZ">Lazio</option>
-<option value="LIG">Liguria</option>
-<option value="LOM">Lombardia</option>
-<option value="MAR">Marche</option>
-<option value="MOL">Molise</option>
-<option value="PMN" selected="selected">Piemonte</option>
-<option value="PUG">Puglia</option>
-<option value="SAR">Sardegna</option>
-<option value="SIC">Sicilia</option>
-<option value="TOS">Toscana</option>
-<option value="TAA">Trentino-Alto Adige</option>
-<option value="UMB">Umbria</option>
-<option value="VAO">Valle d\u2019Aosta</option>
-<option value="VEN">Veneto</option>
-</select>'''
- self.assertHTMLEqual(f.render('regions', 'PMN'), out)
-
- def test_ITZipCodeField(self):
- error_invalid = ['Enter a valid zip code.']
- valid = {
- '00100': '00100',
- }
- invalid = {
- ' 00100': error_invalid,
- }
- self.assertFieldOutput(ITZipCodeField, valid, invalid)
-
- def test_ITSocialSecurityNumberField(self):
- error_invalid = ['Enter a valid Social Security number.']
- valid = {
- 'LVSGDU99T71H501L': 'LVSGDU99T71H501L',
- 'LBRRME11A01L736W': 'LBRRME11A01L736W',
- 'lbrrme11a01l736w': 'LBRRME11A01L736W',
- 'LBR RME 11A01 L736W': 'LBRRME11A01L736W',
- }
- invalid = {
- 'LBRRME11A01L736A': error_invalid,
- '%BRRME11A01L736W': error_invalid,
- }
- self.assertFieldOutput(ITSocialSecurityNumberField, valid, invalid)
-
- def test_ITVatNumberField(self):
- error_invalid = ['Enter a valid VAT number.']
- valid = {
- '07973780013': '07973780013',
- '7973780013': '07973780013',
- 7973780013: '07973780013',
- }
- invalid = {
- '07973780014': error_invalid,
- 'A7973780013': error_invalid,
- }
- self.assertFieldOutput(ITVatNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/jp/__init__.py b/tests/regressiontests/localflavor/jp/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/jp/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/jp/tests.py b/tests/regressiontests/localflavor/jp/tests.py
deleted file mode 100644
index d31c679bcb..0000000000
--- a/tests/regressiontests/localflavor/jp/tests.py
+++ /dev/null
@@ -1,75 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.jp.forms import (JPPostalCodeField,
- JPPrefectureSelect)
-
-from django.test import SimpleTestCase
-
-
-class JPLocalFlavorTests(SimpleTestCase):
- def test_JPPrefectureSelect(self):
- f = JPPrefectureSelect()
- out = '''<select name="prefecture">
-<option value="hokkaido">Hokkaido</option>
-<option value="aomori">Aomori</option>
-<option value="iwate">Iwate</option>
-<option value="miyagi">Miyagi</option>
-<option value="akita">Akita</option>
-<option value="yamagata">Yamagata</option>
-<option value="fukushima">Fukushima</option>
-<option value="ibaraki">Ibaraki</option>
-<option value="tochigi">Tochigi</option>
-<option value="gunma">Gunma</option>
-<option value="saitama">Saitama</option>
-<option value="chiba">Chiba</option>
-<option value="tokyo">Tokyo</option>
-<option value="kanagawa" selected="selected">Kanagawa</option>
-<option value="yamanashi">Yamanashi</option>
-<option value="nagano">Nagano</option>
-<option value="niigata">Niigata</option>
-<option value="toyama">Toyama</option>
-<option value="ishikawa">Ishikawa</option>
-<option value="fukui">Fukui</option>
-<option value="gifu">Gifu</option>
-<option value="shizuoka">Shizuoka</option>
-<option value="aichi">Aichi</option>
-<option value="mie">Mie</option>
-<option value="shiga">Shiga</option>
-<option value="kyoto">Kyoto</option>
-<option value="osaka">Osaka</option>
-<option value="hyogo">Hyogo</option>
-<option value="nara">Nara</option>
-<option value="wakayama">Wakayama</option>
-<option value="tottori">Tottori</option>
-<option value="shimane">Shimane</option>
-<option value="okayama">Okayama</option>
-<option value="hiroshima">Hiroshima</option>
-<option value="yamaguchi">Yamaguchi</option>
-<option value="tokushima">Tokushima</option>
-<option value="kagawa">Kagawa</option>
-<option value="ehime">Ehime</option>
-<option value="kochi">Kochi</option>
-<option value="fukuoka">Fukuoka</option>
-<option value="saga">Saga</option>
-<option value="nagasaki">Nagasaki</option>
-<option value="kumamoto">Kumamoto</option>
-<option value="oita">Oita</option>
-<option value="miyazaki">Miyazaki</option>
-<option value="kagoshima">Kagoshima</option>
-<option value="okinawa">Okinawa</option>
-</select>'''
- self.assertHTMLEqual(f.render('prefecture', 'kanagawa'), out)
-
- def test_JPPostalCodeField(self):
- error_format = ['Enter a postal code in the format XXXXXXX or XXX-XXXX.']
- valid = {
- '251-0032': '2510032',
- '2510032': '2510032',
- }
- invalid = {
- '2510-032': error_format,
- '251a0032': error_format,
- 'a51-0032': error_format,
- '25100321': error_format,
- }
- self.assertFieldOutput(JPPostalCodeField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/kw/__init__.py b/tests/regressiontests/localflavor/kw/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/kw/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/kw/tests.py b/tests/regressiontests/localflavor/kw/tests.py
deleted file mode 100644
index 0cf645b918..0000000000
--- a/tests/regressiontests/localflavor/kw/tests.py
+++ /dev/null
@@ -1,17 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.kw.forms import KWCivilIDNumberField
-
-from django.test import SimpleTestCase
-
-
-class KWLocalFlavorTests(SimpleTestCase):
- def test_KWCivilIDNumberField(self):
- error_invalid = ['Enter a valid Kuwaiti Civil ID number']
- valid = {
- '282040701483': '282040701483',
- }
- invalid = {
- '289332013455': error_invalid,
- }
- self.assertFieldOutput(KWCivilIDNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/mk/__init__.py b/tests/regressiontests/localflavor/mk/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/mk/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/mk/forms.py b/tests/regressiontests/localflavor/mk/forms.py
deleted file mode 100644
index d41bee77de..0000000000
--- a/tests/regressiontests/localflavor/mk/forms.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from __future__ import absolute_import
-
-from django.forms import ModelForm
-
-from .models import MKPerson
-
-
-class MKPersonForm(ModelForm):
-
- class Meta:
- model = MKPerson
diff --git a/tests/regressiontests/localflavor/mk/models.py b/tests/regressiontests/localflavor/mk/models.py
deleted file mode 100644
index 29a8f587de..0000000000
--- a/tests/regressiontests/localflavor/mk/models.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from django.contrib.localflavor.mk.models import (
- MKIdentityCardNumberField, MKMunicipalityField, UMCNField)
-from django.db import models
-
-
-class MKPerson(models.Model):
- first_name = models.CharField(max_length = 20)
- last_name = models.CharField(max_length = 20)
- umcn = UMCNField()
- id_number = MKIdentityCardNumberField()
- municipality = MKMunicipalityField(blank = True)
- municipality_req = MKMunicipalityField(blank = False)
-
- class Meta:
- app_label = 'localflavor'
diff --git a/tests/regressiontests/localflavor/mk/tests.py b/tests/regressiontests/localflavor/mk/tests.py
deleted file mode 100644
index 4e075c5881..0000000000
--- a/tests/regressiontests/localflavor/mk/tests.py
+++ /dev/null
@@ -1,308 +0,0 @@
-# -*- encoding: utf-8 -*-
-from __future__ import absolute_import, unicode_literals
-
-from django.contrib.localflavor.mk.forms import (
- MKIdentityCardNumberField, MKMunicipalitySelect, UMCNField)
-from django.test import SimpleTestCase
-
-from .forms import MKPersonForm
-
-
-class MKLocalFlavorTests(SimpleTestCase):
-
- def setUp(self):
- self.form = MKPersonForm({
- 'first_name':'Someone',
- 'last_name':'Something',
- 'umcn': '2402983450006',
- 'municipality':'OD',
- 'municipality_req':'VE',
- 'id_number':'A1234567',
- })
-
- def test_get_display_methods(self):
- """
- Test that the get_*_display() methods are added to the model instances.
- """
- person = self.form.save()
- self.assertEqual(person.get_municipality_display(), 'Ohrid')
- self.assertEqual(person.get_municipality_req_display(), 'Veles')
-
- def test_municipality_required(self):
- """
- Test that required MKMunicipalityFields throw appropriate errors.
- """
-
- form = MKPersonForm({
- 'first_name':'Someone',
- 'last_name':'Something',
- 'umcn': '2402983450006',
- 'municipality':'OD',
- 'id_number':'A1234567',
- })
- self.assertFalse(form.is_valid())
- self.assertEqual(
- form.errors['municipality_req'], ['This field is required.'])
-
- def test_umcn_invalid(self):
- """
- Test that UMCNFields throw appropriate errors for invalid UMCNs.
- """
- form = MKPersonForm({
- 'first_name':'Someone',
- 'last_name':'Something',
- 'umcn': '2402983450007',
- 'municipality':'OD',
- 'municipality_req':'VE',
- 'id_number':'A1234567',
- })
- self.assertFalse(form.is_valid())
- self.assertEqual(form.errors['umcn'], ['The UMCN is not valid.'])
-
- form = MKPersonForm({
- 'first_name':'Someone',
- 'last_name':'Something',
- 'umcn': '3002983450007',
- 'municipality':'OD',
- 'municipality_req':'VE',
- 'id_number':'A1234567',
- })
- self.assertEqual(form.errors['umcn'],
- ['The first 7 digits of the UMCN must represent a valid past date.'])
-
- def test_idnumber_invalid(self):
- """
- Test that MKIdentityCardNumberFields throw
- appropriate errors for invalid values
- """
-
- form = MKPersonForm({
- 'first_name':'Someone',
- 'last_name':'Something',
- 'umcn': '2402983450007',
- 'municipality':'OD',
- 'municipality_req':'VE',
- 'id_number':'A123456a',
- })
- self.assertFalse(form.is_valid())
- self.assertEqual(form.errors['id_number'],
- ['Identity card numbers must contain either 4 to 7 '
- 'digits or an uppercase letter and 7 digits.'])
-
- def test_field_blank_option(self):
- """
- Test that the empty option is there.
- """
- municipality_select_html = """\
-<select name="municipality" id="id_municipality">
-<option value="">---------</option>
-<option value="AD">Aerodrom</option>
-<option value="AR">Aračinovo</option>
-<option value="BR">Berovo</option>
-<option value="TL">Bitola</option>
-<option value="BG">Bogdanci</option>
-<option value="VJ">Bogovinje</option>
-<option value="BS">Bosilovo</option>
-<option value="BN">Brvenica</option>
-<option value="BU">Butel</option>
-<option value="VA">Valandovo</option>
-<option value="VL">Vasilevo</option>
-<option value="VV">Vevčani</option>
-<option value="VE">Veles</option>
-<option value="NI">Vinica</option>
-<option value="VC">Vraneštica</option>
-<option value="VH">Vrapčište</option>
-<option value="GB">Gazi Baba</option>
-<option value="GV">Gevgelija</option>
-<option value="GT">Gostivar</option>
-<option value="GR">Gradsko</option>
-<option value="DB">Debar</option>
-<option value="DA">Debarca</option>
-<option value="DL">Delčevo</option>
-<option value="DK">Demir Kapija</option>
-<option value="DM">Demir Hisar</option>
-<option value="DE">Dolneni</option>
-<option value="DR">Drugovo</option>
-<option value="GP">Gjorče Petrov</option>
-<option value="ZE">Želino</option>
-<option value="ZA">Zajas</option>
-<option value="ZK">Zelenikovo</option>
-<option value="ZR">Zrnovci</option>
-<option value="IL">Ilinden</option>
-<option value="JG">Jegunovce</option>
-<option value="AV">Kavadarci</option>
-<option value="KB">Karbinci</option>
-<option value="KX">Karpoš</option>
-<option value="VD">Kisela Voda</option>
-<option value="KH">Kičevo</option>
-<option value="KN">Konče</option>
-<option value="OC">Koćani</option>
-<option value="KY">Kratovo</option>
-<option value="KZ">Kriva Palanka</option>
-<option value="KG">Krivogaštani</option>
-<option value="KS">Kruševo</option>
-<option value="UM">Kumanovo</option>
-<option value="LI">Lipkovo</option>
-<option value="LO">Lozovo</option>
-<option value="MR">Mavrovo i Rostuša</option>
-<option value="MK">Makedonska Kamenica</option>
-<option value="MD">Makedonski Brod</option>
-<option value="MG">Mogila</option>
-<option value="NG">Negotino</option>
-<option value="NV">Novaci</option>
-<option value="NS">Novo Selo</option>
-<option value="OS">Oslomej</option>
-<option value="OD" selected="selected">Ohrid</option>
-<option value="PE">Petrovec</option>
-<option value="PH">Pehčevo</option>
-<option value="PN">Plasnica</option>
-<option value="PP">Prilep</option>
-<option value="PT">Probištip</option>
-<option value="RV">Radoviš</option>
-<option value="RN">Rankovce</option>
-<option value="RE">Resen</option>
-<option value="RO">Rosoman</option>
-<option value="AJ">Saraj</option>
-<option value="SL">Sveti Nikole</option>
-<option value="SS">Sopište</option>
-<option value="SD">Star Dojran</option>
-<option value="NA">Staro Nagoričane</option>
-<option value="UG">Struga</option>
-<option value="RU">Strumica</option>
-<option value="SU">Studeničani</option>
-<option value="TR">Tearce</option>
-<option value="ET">Tetovo</option>
-<option value="CE">Centar</option>
-<option value="CZ">Centar-Župa</option>
-<option value="CI">Čair</option>
-<option value="CA">Čaška</option>
-<option value="CH">Češinovo-Obleševo</option>
-<option value="CS">Čučer-Sandevo</option>
-<option value="ST">Štip</option>
-<option value="SO">Šuto Orizari</option>
-</select>"""
- self.assertHTMLEqual(str(self.form['municipality']), municipality_select_html)
-
- def test_MKIdentityCardNumberField(self):
- error_invalid = ['Identity card numbers must contain either 4 to 7 '
- 'digits or an uppercase letter and 7 digits.']
- valid = {
- 'L0018077':'L0018077',
- 'A0078315' : 'A0078315',
- }
- invalid = {
- '123': error_invalid,
- 'abcdf': error_invalid,
- '234390a': error_invalid,
- }
- self.assertFieldOutput(MKIdentityCardNumberField, valid, invalid)
-
- def test_MKMunicipalitySelect(self):
- f = MKMunicipalitySelect()
- out='''<select name="municipality">
-<option value="AD">Aerodrom</option>
-<option value="AR">Ara\u010dinovo</option>
-<option value="BR">Berovo</option>
-<option value="TL">Bitola</option>
-<option value="BG">Bogdanci</option>
-<option value="VJ">Bogovinje</option>
-<option value="BS">Bosilovo</option>
-<option value="BN">Brvenica</option>
-<option value="BU">Butel</option>
-<option value="VA">Valandovo</option>
-<option value="VL">Vasilevo</option>
-<option value="VV">Vev\u010dani</option>
-<option value="VE">Veles</option>
-<option value="NI">Vinica</option>
-<option value="VC">Vrane\u0161tica</option>
-<option value="VH">Vrap\u010di\u0161te</option>
-<option value="GB">Gazi Baba</option>
-<option value="GV">Gevgelija</option>
-<option value="GT">Gostivar</option>
-<option value="GR">Gradsko</option>
-<option value="DB">Debar</option>
-<option value="DA">Debarca</option>
-<option value="DL" selected="selected">Del\u010devo</option>
-<option value="DK">Demir Kapija</option>
-<option value="DM">Demir Hisar</option>
-<option value="DE">Dolneni</option>
-<option value="DR">Drugovo</option>
-<option value="GP">Gjor\u010de Petrov</option>
-<option value="ZE">\u017delino</option>
-<option value="ZA">Zajas</option>
-<option value="ZK">Zelenikovo</option>
-<option value="ZR">Zrnovci</option>
-<option value="IL">Ilinden</option>
-<option value="JG">Jegunovce</option>
-<option value="AV">Kavadarci</option>
-<option value="KB">Karbinci</option>
-<option value="KX">Karpo\u0161</option>
-<option value="VD">Kisela Voda</option>
-<option value="KH">Ki\u010devo</option>
-<option value="KN">Kon\u010de</option>
-<option value="OC">Ko\u0107ani</option>
-<option value="KY">Kratovo</option>
-<option value="KZ">Kriva Palanka</option>
-<option value="KG">Krivoga\u0161tani</option>
-<option value="KS">Kru\u0161evo</option>
-<option value="UM">Kumanovo</option>
-<option value="LI">Lipkovo</option>
-<option value="LO">Lozovo</option>
-<option value="MR">Mavrovo i Rostu\u0161a</option>
-<option value="MK">Makedonska Kamenica</option>
-<option value="MD">Makedonski Brod</option>
-<option value="MG">Mogila</option>
-<option value="NG">Negotino</option>
-<option value="NV">Novaci</option>
-<option value="NS">Novo Selo</option>
-<option value="OS">Oslomej</option>
-<option value="OD">Ohrid</option>
-<option value="PE">Petrovec</option>
-<option value="PH">Peh\u010devo</option>
-<option value="PN">Plasnica</option>
-<option value="PP">Prilep</option>
-<option value="PT">Probi\u0161tip</option>
-<option value="RV">Radovi\u0161</option>
-<option value="RN">Rankovce</option>
-<option value="RE">Resen</option>
-<option value="RO">Rosoman</option>
-<option value="AJ">Saraj</option>
-<option value="SL">Sveti Nikole</option>
-<option value="SS">Sopi\u0161te</option>
-<option value="SD">Star Dojran</option>
-<option value="NA">Staro Nagori\u010dane</option>
-<option value="UG">Struga</option>
-<option value="RU">Strumica</option>
-<option value="SU">Studeni\u010dani</option>
-<option value="TR">Tearce</option>
-<option value="ET">Tetovo</option>
-<option value="CE">Centar</option>
-<option value="CZ">Centar-\u017dupa</option>
-<option value="CI">\u010cair</option>
-<option value="CA">\u010ca\u0161ka</option>
-<option value="CH">\u010ce\u0161inovo-Oble\u0161evo</option>
-<option value="CS">\u010cu\u010der-Sandevo</option>
-<option value="ST">\u0160tip</option>
-<option value="SO">\u0160uto Orizari</option>
-</select>'''
- self.assertHTMLEqual(f.render('municipality', 'DL' ), out)
-
- def test_UMCNField(self):
- error_invalid = ['This field should contain exactly 13 digits.']
- error_checksum = ['The UMCN is not valid.']
- error_date = ['The first 7 digits of the UMCN '
- 'must represent a valid past date.']
- valid = {
- '2402983450006': '2402983450006',
- '2803984430038': '2803984430038',
- '1909982045004': '1909982045004',
- }
- invalid = {
- '240298345': error_invalid,
- 'abcdefghj': error_invalid,
- '2402082450006': error_date,
- '3002982450006': error_date,
- '2402983450007': error_checksum,
- '2402982450006': error_checksum,
- }
- self.assertFieldOutput(UMCNField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/mx/__init__.py b/tests/regressiontests/localflavor/mx/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/mx/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/mx/forms.py b/tests/regressiontests/localflavor/mx/forms.py
deleted file mode 100644
index dac05319c8..0000000000
--- a/tests/regressiontests/localflavor/mx/forms.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from __future__ import absolute_import
-
-from django.forms import ModelForm
-
-from .models import MXPersonProfile
-
-
-class MXPersonProfileForm(ModelForm):
-
- class Meta:
- model = MXPersonProfile
diff --git a/tests/regressiontests/localflavor/mx/models.py b/tests/regressiontests/localflavor/mx/models.py
deleted file mode 100644
index 4905836d3d..0000000000
--- a/tests/regressiontests/localflavor/mx/models.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from django.contrib.localflavor.mx.models import (
- MXStateField, MXRFCField, MXCURPField, MXZipCodeField)
-from django.db import models
-
-
-class MXPersonProfile(models.Model):
- state = MXStateField()
- rfc = MXRFCField()
- curp = MXCURPField()
- zip_code = MXZipCodeField()
-
- class Meta:
- app_label = 'localflavor'
diff --git a/tests/regressiontests/localflavor/mx/mx.py b/tests/regressiontests/localflavor/mx/mx.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/mx/mx.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/mx/tests.py b/tests/regressiontests/localflavor/mx/tests.py
deleted file mode 100644
index 5eeceec276..0000000000
--- a/tests/regressiontests/localflavor/mx/tests.py
+++ /dev/null
@@ -1,198 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import absolute_import, unicode_literals
-
-from django.contrib.localflavor.mx.forms import (MXZipCodeField, MXRFCField,
- MXStateSelect, MXCURPField)
-from django.test import SimpleTestCase
-
-from .forms import MXPersonProfileForm
-
-
-class MXLocalFlavorTests(SimpleTestCase):
-
- def setUp(self):
- self.form = MXPersonProfileForm({
- 'state': 'MIC',
- 'rfc': 'toma880125kv3',
- 'curp': 'toma880125hmnrrn02',
- 'zip_code': '58120',
- })
-
- def test_get_display_methods(self):
- """Test that the get_*_display() methods are added to the model instances."""
- place = self.form.save()
- self.assertEqual(place.get_state_display(), 'Michoacán')
-
- def test_errors(self):
- """Test that required MXFields throw appropriate errors."""
- form = MXPersonProfileForm({
- 'state': 'Invalid state',
- 'rfc': 'invalid rfc',
- 'curp': 'invalid curp',
- 'zip_code': 'xxx',
- })
- self.assertFalse(form.is_valid())
- self.assertEqual(form.errors['state'], ['Select a valid choice. Invalid state is not one of the available choices.'])
- self.assertEqual(form.errors['rfc'], ['Enter a valid RFC.'])
- self.assertEqual(form.errors['curp'], ['Ensure this value has at least 18 characters (it has 12).', 'Enter a valid CURP.'])
- self.assertEqual(form.errors['zip_code'], ['Enter a valid zip code in the format XXXXX.'])
-
- def test_field_blank_option(self):
- """Test that the empty option is there."""
- state_select_html = """\
-<select name="state" id="id_state">
-<option value="">---------</option>
-<option value="AGU">Aguascalientes</option>
-<option value="BCN">Baja California</option>
-<option value="BCS">Baja California Sur</option>
-<option value="CAM">Campeche</option>
-<option value="CHH">Chihuahua</option>
-<option value="CHP">Chiapas</option>
-<option value="COA">Coahuila</option>
-<option value="COL">Colima</option>
-<option value="DIF">Distrito Federal</option>
-<option value="DUR">Durango</option>
-<option value="GRO">Guerrero</option>
-<option value="GUA">Guanajuato</option>
-<option value="HID">Hidalgo</option>
-<option value="JAL">Jalisco</option>
-<option value="MEX">Estado de México</option>
-<option value="MIC" selected="selected">Michoacán</option>
-<option value="MOR">Morelos</option>
-<option value="NAY">Nayarit</option>
-<option value="NLE">Nuevo León</option>
-<option value="OAX">Oaxaca</option>
-<option value="PUE">Puebla</option>
-<option value="QUE">Querétaro</option>
-<option value="ROO">Quintana Roo</option>
-<option value="SIN">Sinaloa</option>
-<option value="SLP">San Luis Potosí</option>
-<option value="SON">Sonora</option>
-<option value="TAB">Tabasco</option>
-<option value="TAM">Tamaulipas</option>
-<option value="TLA">Tlaxcala</option>
-<option value="VER">Veracruz</option>
-<option value="YUC">Yucatán</option>
-<option value="ZAC">Zacatecas</option>
-</select>"""
- self.assertHTMLEqual(str(self.form['state']), state_select_html)
-
- def test_MXStateSelect(self):
- f = MXStateSelect()
- out = '''<select name="state">
-<option value="AGU">Aguascalientes</option>
-<option value="BCN">Baja California</option>
-<option value="BCS">Baja California Sur</option>
-<option value="CAM">Campeche</option>
-<option value="CHH">Chihuahua</option>
-<option value="CHP">Chiapas</option>
-<option value="COA">Coahuila</option>
-<option value="COL">Colima</option>
-<option value="DIF">Distrito Federal</option>
-<option value="DUR">Durango</option>
-<option value="GRO">Guerrero</option>
-<option value="GUA">Guanajuato</option>
-<option value="HID">Hidalgo</option>
-<option value="JAL">Jalisco</option>
-<option value="MEX">Estado de México</option>
-<option value="MIC" selected="selected">Michoacán</option>
-<option value="MOR">Morelos</option>
-<option value="NAY">Nayarit</option>
-<option value="NLE">Nuevo León</option>
-<option value="OAX">Oaxaca</option>
-<option value="PUE">Puebla</option>
-<option value="QUE">Querétaro</option>
-<option value="ROO">Quintana Roo</option>
-<option value="SIN">Sinaloa</option>
-<option value="SLP">San Luis Potosí</option>
-<option value="SON">Sonora</option>
-<option value="TAB">Tabasco</option>
-<option value="TAM">Tamaulipas</option>
-<option value="TLA">Tlaxcala</option>
-<option value="VER">Veracruz</option>
-<option value="YUC">Yucatán</option>
-<option value="ZAC">Zacatecas</option>
-</select>'''
- self.assertHTMLEqual(f.render('state', 'MIC'), out)
-
- def test_MXZipCodeField(self):
- error_format = ['Enter a valid zip code in the format XXXXX.']
- valid = {
- '58120': '58120',
- '58502': '58502',
- '59310': '59310',
- '99999': '99999',
- }
- invalid = {
- '17000': error_format,
- '18000': error_format,
- '19000': error_format,
- '00000': error_format,
- }
- self.assertFieldOutput(MXZipCodeField, valid, invalid)
-
- def test_MXRFCField(self):
- error_format = ['Enter a valid RFC.']
- error_checksum = ['Invalid checksum for RFC.']
- valid = {
- 'MoFN641205eX5': 'MOFN641205EX5',
- 'ICa060120873': 'ICA060120873',
- 'eUcG751104rT0': 'EUCG751104RT0',
- 'GME08100195A': 'GME08100195A',
- 'AA&060524KX5': 'AA&060524KX5',
- 'CAÑ0708045P7': 'CAÑ0708045P7',
- 'aaa000101aa9': 'AAA000101AA9',
- }
- invalid = {
- 'MED0000000XA': error_format,
- '0000000000XA': error_format,
- 'AAA000000AA6': error_format,
- # Dates
- 'XXX880002XXX': error_format,
- 'XXX880200XXX': error_format,
- 'XXX880132XXX': error_format,
- 'XXX880230XXX': error_format,
- 'XXX880431XXX': error_format,
- # Incorrect checksum
- 'MOGR650524E73': error_checksum,
- 'HVA7810058F1': error_checksum,
- 'MoFN641205eX2': error_checksum,
- 'ICa060120871': error_checksum,
- 'eUcG751104rT7': error_checksum,
- 'GME081001955': error_checksum,
- 'AA&060524KX9': error_checksum,
- 'CAÑ0708045P2': error_checksum,
- }
- self.assertFieldOutput(MXRFCField, valid, invalid)
-
- def test_MXCURPField(self):
- error_format = ['Enter a valid CURP.']
- error_checksum = ['Invalid checksum for CURP.']
- valid = {
- 'AaMG890608HDFLJL00': 'AAMG890608HDFLJL00',
- 'BAAd890419HMNRRV07': 'BAAD890419HMNRRV07',
- 'VIAA900930MMNClL08': 'VIAA900930MMNCLL08',
- 'HEGR891009HMNRRD09': 'HEGR891009HMNRRD09',
- 'MARR890512HMNRMN09': 'MARR890512HMNRMN09',
- 'MESJ890928HMNZNS00': 'MESJ890928HMNZNS00',
- 'BAAA890317HDFRLL03': 'BAAA890317HDFRLL03',
- 'TOMA880125HMNRRNO2': 'TOMA880125HMNRRNO2',
- 'OOMG890727HMNRSR06': 'OOMG890727HMNRSR06',
- 'AAAA000101HDFCCC09': 'AAAA000101HDFCCC09',
- }
- invalid = {
- 'AAAA000000HDFCCC09': error_format,
- 'AAAA000000HDFAAA03': error_format,
- 'AAAA000000HXXCCC08': error_format,
- 'AAAA000000XMNCCC02': error_format,
- 'HEGR891009HMNRRD0A': error_format,
- 'MARR890512HMNRMN0A': error_format,
- 'AaMG890608HDFLJL01': error_checksum,
- 'BAAd890419HMNRRV08': error_checksum,
- 'VIAA900930MMNClL09': error_checksum,
- 'MESJ890928HMNZNS01': error_checksum,
- 'BAAA890317HDFRLL04': error_checksum,
- 'TOMA880125HMNRRNO3': error_checksum,
- 'OOMG890727HMNRSR07': error_checksum,
- }
- self.assertFieldOutput(MXCURPField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/nl/__init__.py b/tests/regressiontests/localflavor/nl/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/nl/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/nl/tests.py b/tests/regressiontests/localflavor/nl/tests.py
deleted file mode 100644
index ef8bd3cf35..0000000000
--- a/tests/regressiontests/localflavor/nl/tests.py
+++ /dev/null
@@ -1,64 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.nl.forms import (NLPhoneNumberField,
- NLZipCodeField, NLSoFiNumberField, NLProvinceSelect)
-
-from django.test import SimpleTestCase
-
-
-class NLLocalFlavorTests(SimpleTestCase):
- def test_NLProvinceSelect(self):
- f = NLProvinceSelect()
- out = '''<select name="provinces">
-<option value="DR">Drenthe</option>
-<option value="FL">Flevoland</option>
-<option value="FR">Friesland</option>
-<option value="GL">Gelderland</option>
-<option value="GR">Groningen</option>
-<option value="LB">Limburg</option>
-<option value="NB">Noord-Brabant</option>
-<option value="NH">Noord-Holland</option>
-<option value="OV" selected="selected">Overijssel</option>
-<option value="UT">Utrecht</option>
-<option value="ZE">Zeeland</option>
-<option value="ZH">Zuid-Holland</option>
-</select>'''
- self.assertHTMLEqual(f.render('provinces', 'OV'), out)
-
- def test_NLPhoneNumberField(self):
- error_invalid = ['Enter a valid phone number']
- valid = {
- '012-3456789': '012-3456789',
- '0123456789': '0123456789',
- '+31-12-3456789': '+31-12-3456789',
- '(0123) 456789': '(0123) 456789',
- }
- invalid = {
- 'foo': error_invalid,
- }
- self.assertFieldOutput(NLPhoneNumberField, valid, invalid)
-
- def test_NLZipCodeField(self):
- error_invalid = ['Enter a valid postal code']
- valid = {
- '1234ab': '1234 AB',
- '1234 ab': '1234 AB',
- '1234 AB': '1234 AB',
- }
- invalid = {
- '0123AB': error_invalid,
- 'foo': error_invalid,
- }
- self.assertFieldOutput(NLZipCodeField, valid, invalid)
-
- def test_NLSoFiNumberField(self):
- error_invalid = ['Enter a valid SoFi number']
- valid = {
- '123456782': '123456782',
- }
- invalid = {
- '000000000': error_invalid,
- '123456789': error_invalid,
- 'foo': error_invalid,
- }
- self.assertFieldOutput(NLSoFiNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/pl/__init__.py b/tests/regressiontests/localflavor/pl/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/pl/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/pl/tests.py b/tests/regressiontests/localflavor/pl/tests.py
deleted file mode 100644
index 82c5d615c1..0000000000
--- a/tests/regressiontests/localflavor/pl/tests.py
+++ /dev/null
@@ -1,480 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.pl.forms import (PLProvinceSelect,
- PLCountySelect, PLPostalCodeField, PLNIPField, PLPESELField, PLNationalIDCardNumberField, PLREGONField)
-
-from django.test import SimpleTestCase
-
-
-class PLLocalFlavorTests(SimpleTestCase):
- def test_PLProvinceSelect(self):
- f = PLProvinceSelect()
- out = '''<select name="voivodeships">
-<option value="lower_silesia">Lower Silesia</option>
-<option value="kuyavia-pomerania">Kuyavia-Pomerania</option>
-<option value="lublin">Lublin</option>
-<option value="lubusz">Lubusz</option>
-<option value="lodz">Lodz</option>
-<option value="lesser_poland">Lesser Poland</option>
-<option value="masovia">Masovia</option>
-<option value="opole">Opole</option>
-<option value="subcarpatia">Subcarpatia</option>
-<option value="podlasie">Podlasie</option>
-<option value="pomerania" selected="selected">Pomerania</option>
-<option value="silesia">Silesia</option>
-<option value="swietokrzyskie">Swietokrzyskie</option>
-<option value="warmia-masuria">Warmia-Masuria</option>
-<option value="greater_poland">Greater Poland</option>
-<option value="west_pomerania">West Pomerania</option>
-</select>'''
- self.assertHTMLEqual(f.render('voivodeships', 'pomerania'), out)
-
- def test_PLCountrySelect(self):
- f = PLCountySelect()
- out = '''<select name="administrativeunit">
-<option value="wroclaw">Wroc\u0142aw</option>
-<option value="jeleniagora">Jelenia G\xf3ra</option>
-<option value="legnica">Legnica</option>
-<option value="boleslawiecki">boles\u0142awiecki</option>
-<option value="dzierzoniowski">dzier\u017coniowski</option>
-<option value="glogowski">g\u0142ogowski</option>
-<option value="gorowski">g\xf3rowski</option>
-<option value="jaworski">jaworski</option>
-<option value="jeleniogorski">jeleniog\xf3rski</option>
-<option value="kamiennogorski">kamiennog\xf3rski</option>
-<option value="klodzki">k\u0142odzki</option>
-<option value="legnicki">legnicki</option>
-<option value="lubanski">luba\u0144ski</option>
-<option value="lubinski">lubi\u0144ski</option>
-<option value="lwowecki">lw\xf3wecki</option>
-<option value="milicki">milicki</option>
-<option value="olesnicki">ole\u015bnicki</option>
-<option value="olawski">o\u0142awski</option>
-<option value="polkowicki">polkowicki</option>
-<option value="strzelinski">strzeli\u0144ski</option>
-<option value="sredzki">\u015bredzki</option>
-<option value="swidnicki">\u015bwidnicki</option>
-<option value="trzebnicki">trzebnicki</option>
-<option value="walbrzyski">wa\u0142brzyski</option>
-<option value="wolowski">wo\u0142owski</option>
-<option value="wroclawski">wroc\u0142awski</option>
-<option value="zabkowicki">z\u0105bkowicki</option>
-<option value="zgorzelecki">zgorzelecki</option>
-<option value="zlotoryjski">z\u0142otoryjski</option>
-<option value="bydgoszcz">Bydgoszcz</option>
-<option value="torun">Toru\u0144</option>
-<option value="wloclawek">W\u0142oc\u0142awek</option>
-<option value="grudziadz">Grudzi\u0105dz</option>
-<option value="aleksandrowski">aleksandrowski</option>
-<option value="brodnicki">brodnicki</option>
-<option value="bydgoski">bydgoski</option>
-<option value="chelminski">che\u0142mi\u0144ski</option>
-<option value="golubsko-dobrzynski">golubsko-dobrzy\u0144ski</option>
-<option value="grudziadzki">grudzi\u0105dzki</option>
-<option value="inowroclawski">inowroc\u0142awski</option>
-<option value="lipnowski">lipnowski</option>
-<option value="mogilenski">mogile\u0144ski</option>
-<option value="nakielski">nakielski</option>
-<option value="radziejowski">radziejowski</option>
-<option value="rypinski">rypi\u0144ski</option>
-<option value="sepolenski">s\u0119pole\u0144ski</option>
-<option value="swiecki">\u015bwiecki</option>
-<option value="torunski">toru\u0144ski</option>
-<option value="tucholski">tucholski</option>
-<option value="wabrzeski">w\u0105brzeski</option>
-<option value="wloclawski">wroc\u0142awski</option>
-<option value="zninski">\u017ani\u0144ski</option>
-<option value="lublin">Lublin</option>
-<option value="biala-podlaska">Bia\u0142a Podlaska</option>
-<option value="chelm">Che\u0142m</option>
-<option value="zamosc">Zamo\u015b\u0107</option>
-<option value="bialski">bialski</option>
-<option value="bilgorajski">bi\u0142gorajski</option>
-<option value="chelmski">che\u0142mski</option>
-<option value="hrubieszowski">hrubieszowski</option>
-<option value="janowski">janowski</option>
-<option value="krasnostawski">krasnostawski</option>
-<option value="krasnicki">kra\u015bnicki</option>
-<option value="lubartowski">lubartowski</option>
-<option value="lubelski">lubelski</option>
-<option value="leczynski">\u0142\u0119czy\u0144ski</option>
-<option value="lukowski">\u0142ukowski</option>
-<option value="opolski">opolski</option>
-<option value="parczewski">parczewski</option>
-<option value="pulawski">pu\u0142awski</option>
-<option value="radzynski">radzy\u0144ski</option>
-<option value="rycki">rycki</option>
-<option value="swidnicki">\u015bwidnicki</option>
-<option value="tomaszowski">tomaszowski</option>
-<option value="wlodawski">w\u0142odawski</option>
-<option value="zamojski">zamojski</option>
-<option value="gorzow-wielkopolski">Gorz\xf3w Wielkopolski</option>
-<option value="zielona-gora">Zielona G\xf3ra</option>
-<option value="gorzowski">gorzowski</option>
-<option value="krosnienski">kro\u015bnie\u0144ski</option>
-<option value="miedzyrzecki">mi\u0119dzyrzecki</option>
-<option value="nowosolski">nowosolski</option>
-<option value="slubicki">s\u0142ubicki</option>
-<option value="strzelecko-drezdenecki">strzelecko-drezdenecki</option>
-<option value="sulecinski">sule\u0144ci\u0144ski</option>
-<option value="swiebodzinski">\u015bwiebodzi\u0144ski</option>
-<option value="wschowski">wschowski</option>
-<option value="zielonogorski">zielonog\xf3rski</option>
-<option value="zaganski">\u017caga\u0144ski</option>
-<option value="zarski">\u017carski</option>
-<option value="lodz">\u0141\xf3d\u017a</option>
-<option value="piotrkow-trybunalski">Piotrk\xf3w Trybunalski</option>
-<option value="skierniewice">Skierniewice</option>
-<option value="belchatowski">be\u0142chatowski</option>
-<option value="brzezinski">brzezi\u0144ski</option>
-<option value="kutnowski">kutnowski</option>
-<option value="laski">\u0142aski</option>
-<option value="leczycki">\u0142\u0119czycki</option>
-<option value="lowicki">\u0142owicki</option>
-<option value="lodzki wschodni">\u0142\xf3dzki wschodni</option>
-<option value="opoczynski">opoczy\u0144ski</option>
-<option value="pabianicki">pabianicki</option>
-<option value="pajeczanski">paj\u0119cza\u0144ski</option>
-<option value="piotrkowski">piotrkowski</option>
-<option value="poddebicki">podd\u0119bicki</option>
-<option value="radomszczanski">radomszcza\u0144ski</option>
-<option value="rawski">rawski</option>
-<option value="sieradzki">sieradzki</option>
-<option value="skierniewicki">skierniewicki</option>
-<option value="tomaszowski">tomaszowski</option>
-<option value="wielunski">wielu\u0144ski</option>
-<option value="wieruszowski">wieruszowski</option>
-<option value="zdunskowolski">zdu\u0144skowolski</option>
-<option value="zgierski">zgierski</option>
-<option value="krakow">Krak\xf3w</option>
-<option value="tarnow">Tarn\xf3w</option>
-<option value="nowy-sacz">Nowy S\u0105cz</option>
-<option value="bochenski">boche\u0144ski</option>
-<option value="brzeski">brzeski</option>
-<option value="chrzanowski">chrzanowski</option>
-<option value="dabrowski">d\u0105browski</option>
-<option value="gorlicki">gorlicki</option>
-<option value="krakowski">krakowski</option>
-<option value="limanowski">limanowski</option>
-<option value="miechowski">miechowski</option>
-<option value="myslenicki">my\u015blenicki</option>
-<option value="nowosadecki">nowos\u0105decki</option>
-<option value="nowotarski">nowotarski</option>
-<option value="olkuski">olkuski</option>
-<option value="oswiecimski">o\u015bwi\u0119cimski</option>
-<option value="proszowicki">proszowicki</option>
-<option value="suski">suski</option>
-<option value="tarnowski">tarnowski</option>
-<option value="tatrzanski">tatrza\u0144ski</option>
-<option value="wadowicki">wadowicki</option>
-<option value="wielicki">wielicki</option>
-<option value="warszawa">Warszawa</option>
-<option value="ostroleka">Ostro\u0142\u0119ka</option>
-<option value="plock">P\u0142ock</option>
-<option value="radom">Radom</option>
-<option value="siedlce">Siedlce</option>
-<option value="bialobrzeski">bia\u0142obrzeski</option>
-<option value="ciechanowski">ciechanowski</option>
-<option value="garwolinski">garwoli\u0144ski</option>
-<option value="gostyninski">gostyni\u0144ski</option>
-<option value="grodziski">grodziski</option>
-<option value="grojecki">gr\xf3jecki</option>
-<option value="kozienicki">kozenicki</option>
-<option value="legionowski">legionowski</option>
-<option value="lipski">lipski</option>
-<option value="losicki">\u0142osicki</option>
-<option value="makowski">makowski</option>
-<option value="minski">mi\u0144ski</option>
-<option value="mlawski">m\u0142awski</option>
-<option value="nowodworski">nowodworski</option>
-<option value="ostrolecki">ostro\u0142\u0119cki</option>
-<option value="ostrowski">ostrowski</option>
-<option value="otwocki">otwocki</option>
-<option value="piaseczynski">piaseczy\u0144ski</option>
-<option value="plocki">p\u0142ocki</option>
-<option value="plonski">p\u0142o\u0144ski</option>
-<option value="pruszkowski">pruszkowski</option>
-<option value="przasnyski">przasnyski</option>
-<option value="przysuski">przysuski</option>
-<option value="pultuski">pu\u0142tuski</option>
-<option value="radomski">radomski</option>
-<option value="siedlecki">siedlecki</option>
-<option value="sierpecki">sierpecki</option>
-<option value="sochaczewski">sochaczewski</option>
-<option value="sokolowski">soko\u0142owski</option>
-<option value="szydlowiecki">szyd\u0142owiecki</option>
-<option value="warszawski-zachodni">warszawski zachodni</option>
-<option value="wegrowski">w\u0119growski</option>
-<option value="wolominski">wo\u0142omi\u0144ski</option>
-<option value="wyszkowski">wyszkowski</option>
-<option value="zwolenski">zwole\u0144ski</option>
-<option value="zurominski">\u017curomi\u0144ski</option>
-<option value="zyrardowski">\u017cyrardowski</option>
-<option value="opole">Opole</option>
-<option value="brzeski">brzeski</option>
-<option value="glubczycki">g\u0142ubczyski</option>
-<option value="kedzierzynsko-kozielski">k\u0119dzierzy\u0144ski-kozielski</option>
-<option value="kluczborski">kluczborski</option>
-<option value="krapkowicki">krapkowicki</option>
-<option value="namyslowski">namys\u0142owski</option>
-<option value="nyski">nyski</option>
-<option value="oleski">oleski</option>
-<option value="opolski">opolski</option>
-<option value="prudnicki">prudnicki</option>
-<option value="strzelecki">strzelecki</option>
-<option value="rzeszow">Rzesz\xf3w</option>
-<option value="krosno">Krosno</option>
-<option value="przemysl">Przemy\u015bl</option>
-<option value="tarnobrzeg">Tarnobrzeg</option>
-<option value="bieszczadzki">bieszczadzki</option>
-<option value="brzozowski">brzozowski</option>
-<option value="debicki">d\u0119bicki</option>
-<option value="jaroslawski">jaros\u0142awski</option>
-<option value="jasielski">jasielski</option>
-<option value="kolbuszowski">kolbuszowski</option>
-<option value="krosnienski">kro\u015bnie\u0144ski</option>
-<option value="leski">leski</option>
-<option value="lezajski">le\u017cajski</option>
-<option value="lubaczowski">lubaczowski</option>
-<option value="lancucki">\u0142a\u0144cucki</option>
-<option value="mielecki">mielecki</option>
-<option value="nizanski">ni\u017ca\u0144ski</option>
-<option value="przemyski">przemyski</option>
-<option value="przeworski">przeworski</option>
-<option value="ropczycko-sedziszowski">ropczycko-s\u0119dziszowski</option>
-<option value="rzeszowski">rzeszowski</option>
-<option value="sanocki">sanocki</option>
-<option value="stalowowolski">stalowowolski</option>
-<option value="strzyzowski">strzy\u017cowski</option>
-<option value="tarnobrzeski">tarnobrzeski</option>
-<option value="bialystok">Bia\u0142ystok</option>
-<option value="lomza">\u0141om\u017ca</option>
-<option value="suwalki">Suwa\u0142ki</option>
-<option value="augustowski">augustowski</option>
-<option value="bialostocki">bia\u0142ostocki</option>
-<option value="bielski">bielski</option>
-<option value="grajewski">grajewski</option>
-<option value="hajnowski">hajnowski</option>
-<option value="kolnenski">kolne\u0144ski</option>
-<option value="\u0142omzynski">\u0142om\u017cy\u0144ski</option>
-<option value="moniecki">moniecki</option>
-<option value="sejnenski">sejne\u0144ski</option>
-<option value="siemiatycki">siematycki</option>
-<option value="sokolski">sok\xf3lski</option>
-<option value="suwalski">suwalski</option>
-<option value="wysokomazowiecki">wysokomazowiecki</option>
-<option value="zambrowski">zambrowski</option>
-<option value="gdansk">Gda\u0144sk</option>
-<option value="gdynia">Gdynia</option>
-<option value="slupsk">S\u0142upsk</option>
-<option value="sopot">Sopot</option>
-<option value="bytowski">bytowski</option>
-<option value="chojnicki">chojnicki</option>
-<option value="czluchowski">cz\u0142uchowski</option>
-<option value="kartuski">kartuski</option>
-<option value="koscierski">ko\u015bcierski</option>
-<option value="kwidzynski">kwidzy\u0144ski</option>
-<option value="leborski">l\u0119borski</option>
-<option value="malborski">malborski</option>
-<option value="nowodworski">nowodworski</option>
-<option value="gdanski">gda\u0144ski</option>
-<option value="pucki">pucki</option>
-<option value="slupski">s\u0142upski</option>
-<option value="starogardzki">starogardzki</option>
-<option value="sztumski">sztumski</option>
-<option value="tczewski">tczewski</option>
-<option value="wejherowski">wejcherowski</option>
-<option value="katowice" selected="selected">Katowice</option>
-<option value="bielsko-biala">Bielsko-Bia\u0142a</option>
-<option value="bytom">Bytom</option>
-<option value="chorzow">Chorz\xf3w</option>
-<option value="czestochowa">Cz\u0119stochowa</option>
-<option value="dabrowa-gornicza">D\u0105browa G\xf3rnicza</option>
-<option value="gliwice">Gliwice</option>
-<option value="jastrzebie-zdroj">Jastrz\u0119bie Zdr\xf3j</option>
-<option value="jaworzno">Jaworzno</option>
-<option value="myslowice">Mys\u0142owice</option>
-<option value="piekary-slaskie">Piekary \u015al\u0105skie</option>
-<option value="ruda-slaska">Ruda \u015al\u0105ska</option>
-<option value="rybnik">Rybnik</option>
-<option value="siemianowice-slaskie">Siemianowice \u015al\u0105skie</option>
-<option value="sosnowiec">Sosnowiec</option>
-<option value="swietochlowice">\u015awi\u0119toch\u0142owice</option>
-<option value="tychy">Tychy</option>
-<option value="zabrze">Zabrze</option>
-<option value="zory">\u017bory</option>
-<option value="bedzinski">b\u0119dzi\u0144ski</option>
-<option value="bielski">bielski</option>
-<option value="bierunsko-ledzinski">bieru\u0144sko-l\u0119dzi\u0144ski</option>
-<option value="cieszynski">cieszy\u0144ski</option>
-<option value="czestochowski">cz\u0119stochowski</option>
-<option value="gliwicki">gliwicki</option>
-<option value="klobucki">k\u0142obucki</option>
-<option value="lubliniecki">lubliniecki</option>
-<option value="mikolowski">miko\u0142owski</option>
-<option value="myszkowski">myszkowski</option>
-<option value="pszczynski">pszczy\u0144ski</option>
-<option value="raciborski">raciborski</option>
-<option value="rybnicki">rybnicki</option>
-<option value="tarnogorski">tarnog\xf3rski</option>
-<option value="wodzislawski">wodzis\u0142awski</option>
-<option value="zawiercianski">zawiercia\u0144ski</option>
-<option value="zywiecki">\u017cywiecki</option>
-<option value="kielce">Kielce</option>
-<option value="buski">buski</option>
-<option value="jedrzejowski">j\u0119drzejowski</option>
-<option value="kazimierski">kazimierski</option>
-<option value="kielecki">kielecki</option>
-<option value="konecki">konecki</option>
-<option value="opatowski">opatowski</option>
-<option value="ostrowiecki">ostrowiecki</option>
-<option value="pinczowski">pi\u0144czowski</option>
-<option value="sandomierski">sandomierski</option>
-<option value="skarzyski">skar\u017cyski</option>
-<option value="starachowicki">starachowicki</option>
-<option value="staszowski">staszowski</option>
-<option value="wloszczowski">w\u0142oszczowski</option>
-<option value="olsztyn">Olsztyn</option>
-<option value="elblag">Elbl\u0105g</option>
-<option value="bartoszycki">bartoszycki</option>
-<option value="braniewski">braniewski</option>
-<option value="dzialdowski">dzia\u0142dowski</option>
-<option value="elblaski">elbl\u0105ski</option>
-<option value="elcki">e\u0142cki</option>
-<option value="gizycki">gi\u017cycki</option>
-<option value="goldapski">go\u0142dapski</option>
-<option value="ilawski">i\u0142awski</option>
-<option value="ketrzynski">k\u0119trzy\u0144ski</option>
-<option value="lidzbarski">lidzbarski</option>
-<option value="mragowski">mr\u0105gowski</option>
-<option value="nidzicki">nidzicki</option>
-<option value="nowomiejski">nowomiejski</option>
-<option value="olecki">olecki</option>
-<option value="olsztynski">olszty\u0144ski</option>
-<option value="ostrodzki">ostr\xf3dzki</option>
-<option value="piski">piski</option>
-<option value="szczycienski">szczycie\u0144ski</option>
-<option value="wegorzewski">w\u0119gorzewski</option>
-<option value="poznan">Pozna\u0144</option>
-<option value="kalisz">Kalisz</option>
-<option value="konin">Konin</option>
-<option value="leszno">Leszno</option>
-<option value="chodzieski">chodziejski</option>
-<option value="czarnkowsko-trzcianecki">czarnkowsko-trzcianecki</option>
-<option value="gnieznienski">gnie\u017anie\u0144ski</option>
-<option value="gostynski">gosty\u0144ski</option>
-<option value="grodziski">grodziski</option>
-<option value="jarocinski">jaroci\u0144ski</option>
-<option value="kaliski">kaliski</option>
-<option value="kepinski">k\u0119pi\u0144ski</option>
-<option value="kolski">kolski</option>
-<option value="koninski">koni\u0144ski</option>
-<option value="koscianski">ko\u015bcia\u0144ski</option>
-<option value="krotoszynski">krotoszy\u0144ski</option>
-<option value="leszczynski">leszczy\u0144ski</option>
-<option value="miedzychodzki">mi\u0119dzychodzki</option>
-<option value="nowotomyski">nowotomyski</option>
-<option value="obornicki">obornicki</option>
-<option value="ostrowski">ostrowski</option>
-<option value="ostrzeszowski">ostrzeszowski</option>
-<option value="pilski">pilski</option>
-<option value="pleszewski">pleszewski</option>
-<option value="poznanski">pozna\u0144ski</option>
-<option value="rawicki">rawicki</option>
-<option value="slupecki">s\u0142upecki</option>
-<option value="szamotulski">szamotulski</option>
-<option value="sredzki">\u015bredzki</option>
-<option value="sremski">\u015bremski</option>
-<option value="turecki">turecki</option>
-<option value="wagrowiecki">w\u0105growiecki</option>
-<option value="wolsztynski">wolszty\u0144ski</option>
-<option value="wrzesinski">wrzesi\u0144ski</option>
-<option value="zlotowski">z\u0142otowski</option>
-<option value="bialogardzki">bia\u0142ogardzki</option>
-<option value="choszczenski">choszcze\u0144ski</option>
-<option value="drawski">drawski</option>
-<option value="goleniowski">goleniowski</option>
-<option value="gryficki">gryficki</option>
-<option value="gryfinski">gryfi\u0144ski</option>
-<option value="kamienski">kamie\u0144ski</option>
-<option value="kolobrzeski">ko\u0142obrzeski</option>
-<option value="koszalinski">koszali\u0144ski</option>
-<option value="lobeski">\u0142obeski</option>
-<option value="mysliborski">my\u015bliborski</option>
-<option value="policki">policki</option>
-<option value="pyrzycki">pyrzycki</option>
-<option value="slawienski">s\u0142awie\u0144ski</option>
-<option value="stargardzki">stargardzki</option>
-<option value="szczecinecki">szczecinecki</option>
-<option value="swidwinski">\u015bwidwi\u0144ski</option>
-<option value="walecki">wa\u0142ecki</option>
-</select>'''
- self.assertHTMLEqual(f.render('administrativeunit', 'katowice'), out)
-
- def test_PLPostalCodeField(self):
- error_format = ['Enter a postal code in the format XX-XXX.']
- valid = {
- '41-403': '41-403',
- }
- invalid = {
- '43--434': error_format,
- }
- self.assertFieldOutput(PLPostalCodeField, valid, invalid)
-
- def test_PLNIPField(self):
- error_format = ['Enter a tax number field (NIP) in the format XXX-XXX-XX-XX, XXX-XX-XX-XXX or XXXXXXXXXX.']
- error_checksum = ['Wrong checksum for the Tax Number (NIP).']
- valid = {
- '646-241-41-24': '6462414124',
- '646-24-14-124': '6462414124',
- '6462414124': '6462414124',
- }
- invalid = {
- '43-343-234-323': error_format,
- '64-62-414-124': error_format,
- '646-241-41-23': error_checksum,
- }
- self.assertFieldOutput(PLNIPField, valid, invalid)
-
- def test_PLPESELField(self):
- error_checksum = ['Wrong checksum for the National Identification Number.']
- error_format = ['National Identification Number consists of 11 digits.']
- valid = {
- '80071610614': '80071610614',
- }
- invalid = {
- '80071610610': error_checksum,
- '80': error_format,
- '800716106AA': error_format,
- }
- self.assertFieldOutput(PLPESELField, valid, invalid)
-
- def test_PLNationalIDCardNumberField(self):
- error_checksum = ['Wrong checksum for the National ID Card Number.']
- error_format = ['National ID Card Number consists of 3 letters and 6 digits.']
- valid = {
- 'ABC123458': 'ABC123458',
- 'abc123458': 'ABC123458',
- }
- invalid = {
- 'ABC123457': error_checksum,
- 'abc123457': error_checksum,
- 'a12Aaaaaa': error_format,
- 'AA1234443': error_format,
- }
- self.assertFieldOutput(PLNationalIDCardNumberField, valid, invalid)
-
- def test_PLREGONField(self):
- error_checksum = ['Wrong checksum for the National Business Register Number (REGON).']
- error_format = ['National Business Register Number (REGON) consists of 9 or 14 digits.']
- valid = {
- '12345678512347': '12345678512347',
- '590096454': '590096454',
- }
- invalid = {
- '123456784': error_checksum,
- '12345678412342': error_checksum,
- '590096453': error_checksum,
- '590096': error_format,
- }
- self.assertFieldOutput(PLREGONField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/pt/__init__.py b/tests/regressiontests/localflavor/pt/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/pt/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/pt/tests.py b/tests/regressiontests/localflavor/pt/tests.py
deleted file mode 100644
index 051e78084b..0000000000
--- a/tests/regressiontests/localflavor/pt/tests.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.pt.forms import PTZipCodeField, PTPhoneNumberField
-
-from django.test import SimpleTestCase
-
-
-class PTLocalFlavorTests(SimpleTestCase):
- def test_PTZipCodeField(self):
- error_format = ['Enter a zip code in the format XXXX-XXX.']
- valid = {
- '3030-034': '3030-034',
- '1003456': '1003-456',
- }
- invalid = {
- '2A200': error_format,
- '980001': error_format,
- }
- self.assertFieldOutput(PTZipCodeField, valid, invalid)
-
- def test_PTPhoneNumberField(self):
- error_format = ['Phone numbers must have 9 digits, or start by + or 00.']
- valid = {
- '917845189': '917845189',
- '91 784 5189': '917845189',
- '+351 91 111': '+35191111',
- '00351873': '00351873',
- }
- invalid = {
- '91 784 51 8': error_format,
- '091 456 987 1': error_format,
- }
- self.assertFieldOutput(PTPhoneNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/py/__init__.py b/tests/regressiontests/localflavor/py/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/py/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/py/tests.py b/tests/regressiontests/localflavor/py/tests.py
deleted file mode 100644
index fb7836dc9a..0000000000
--- a/tests/regressiontests/localflavor/py/tests.py
+++ /dev/null
@@ -1,55 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.py.forms import (PyDepartmentSelect,
- PyNumberedDepartmentSelect)
-
-from django.test import SimpleTestCase
-
-class PYLocalFlavorTests(SimpleTestCase):
- def test_PyDepartmentSelect(self):
- py = PyDepartmentSelect()
- out = '''<select name="department">
-<option value="AG">Alto Paraguay</option>
-<option value="AA">Alto Paran\xe1</option>
-<option value="AM">Amambay</option>
-<option value="AS">Asunci\xf3n</option>
-<option value="BQ">Boquer\xf3n</option>
-<option value="CG">Caaguaz\xfa</option>
-<option value="CZ">Caazap\xe1</option>
-<option value="CY">Canindey\xfa</option>
-<option value="CE">Central</option>
-<option value="CN">Concepci\xf3n</option>
-<option value="CR">Cordillera</option>
-<option value="GU">Guair\xe1</option>
-<option value="IT">Itap\xfaa</option>
-<option value="MI">Misiones</option>
-<option value="NE">\xd1eembuc\xfa</option>
-<option value="PG">Paraguar\xed</option>
-<option value="PH">Pdte. Hayes</option>
-<option value="SP">San Pedro</option>
-</select>'''
- self.assertHTMLEqual(py.render('department', 'M'), out)
-
- def test_PyNumberedDepartmentSelect(self):
- py = PyNumberedDepartmentSelect()
- out = '''<select name="department">
-<option value="CN">I Concepci\xf3n</option>
-<option value="SP">II San Pedro</option>
-<option value="CR">III Cordillera</option>
-<option value="GU">IV Guair\xe1</option>
-<option value="CG">V Caaguaz\xfa</option>
-<option value="CZ">VI Caazap\xe1</option>
-<option value="IT">VII Itap\xfaa</option>
-<option value="MI">VIII Misiones</option>
-<option value="PG">IX Paraguar\xed</option>
-<option value="AA">X Alto Paran\xe1</option>
-<option value="CE">XI Central</option>
-<option value="NE">XII \xd1eembuc\xfa</option>
-<option value="AM" selected="selected">XIII Amambay</option>
-<option value="CY">XIV Canindey\xfa</option>
-<option value="PH">XV Pdte. Hayes</option>
-<option value="AG">XVI Alto Paraguay</option>
-<option value="BQ">XVII Boquer\xf3n</option>
-<option value="AS">XVIII Asunci\xf3n</option>
-</select>'''
- self.assertHTMLEqual(py.render('department', 'AM'), out)
diff --git a/tests/regressiontests/localflavor/ro/__init__.py b/tests/regressiontests/localflavor/ro/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/ro/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/ro/tests.py b/tests/regressiontests/localflavor/ro/tests.py
deleted file mode 100644
index 2e63bdc619..0000000000
--- a/tests/regressiontests/localflavor/ro/tests.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.ro.forms import (ROCIFField, ROCNPField,
- ROCountyField, ROCountySelect, ROIBANField, ROPhoneNumberField,
- ROPostalCodeField)
-
-from django.test import SimpleTestCase
-
-
-class ROLocalFlavorTests(SimpleTestCase):
- def test_ROCountySelect(self):
- f = ROCountySelect()
- out = '''<select name="county">
-<option value="AB">Alba</option>
-<option value="AR">Arad</option>
-<option value="AG">Arge\u015f</option>
-<option value="BC">Bac\u0103u</option>
-<option value="BH">Bihor</option>
-<option value="BN">Bistri\u0163a-N\u0103s\u0103ud</option>
-<option value="BT">Boto\u015fani</option>
-<option value="BV">Bra\u015fov</option>
-<option value="BR">Br\u0103ila</option>
-<option value="B">Bucure\u015fti</option>
-<option value="BZ">Buz\u0103u</option>
-<option value="CS">Cara\u015f-Severin</option>
-<option value="CL">C\u0103l\u0103ra\u015fi</option>
-<option value="CJ" selected="selected">Cluj</option>
-<option value="CT">Constan\u0163a</option>
-<option value="CV">Covasna</option>
-<option value="DB">D\xe2mbovi\u0163a</option>
-<option value="DJ">Dolj</option>
-<option value="GL">Gala\u0163i</option>
-<option value="GR">Giurgiu</option>
-<option value="GJ">Gorj</option>
-<option value="HR">Harghita</option>
-<option value="HD">Hunedoara</option>
-<option value="IL">Ialomi\u0163a</option>
-<option value="IS">Ia\u015fi</option>
-<option value="IF">Ilfov</option>
-<option value="MM">Maramure\u015f</option>
-<option value="MH">Mehedin\u0163i</option>
-<option value="MS">Mure\u015f</option>
-<option value="NT">Neam\u0163</option>
-<option value="OT">Olt</option>
-<option value="PH">Prahova</option>
-<option value="SM">Satu Mare</option>
-<option value="SJ">S\u0103laj</option>
-<option value="SB">Sibiu</option>
-<option value="SV">Suceava</option>
-<option value="TR">Teleorman</option>
-<option value="TM">Timi\u015f</option>
-<option value="TL">Tulcea</option>
-<option value="VS">Vaslui</option>
-<option value="VL">V\xe2lcea</option>
-<option value="VN">Vrancea</option>
-</select>'''
- self.assertHTMLEqual(f.render('county', 'CJ'), out)
-
- def test_ROCIFField(self):
- error_invalid = ['Enter a valid CIF.']
- error_atmost = ['Ensure this value has at most 10 characters (it has 11).']
- error_atleast = ['Ensure this value has at least 2 characters (it has 1).']
- valid = {
- '21694681': '21694681',
- 'RO21694681': '21694681',
- }
- invalid = {
- '21694680': error_invalid,
- '21694680000': error_atmost,
- '0': error_atleast + error_invalid,
- }
- self.assertFieldOutput(ROCIFField, valid, invalid)
-
- def test_ROCNPField(self):
- error_invalid = ['Enter a valid CNP.']
- error_atleast = ['Ensure this value has at least 13 characters (it has 10).']
- error_atmost = ['Ensure this value has at most 13 characters (it has 14).']
- valid = {
- '1981211204489': '1981211204489',
- }
- invalid = {
- '1981211204487': error_invalid,
- '1981232204489': error_invalid,
- '9981211204489': error_invalid,
- '9981211209': error_atleast + error_invalid,
- '19812112044891': error_atmost,
- }
- self.assertFieldOutput(ROCNPField, valid, invalid)
-
- def test_ROCountyField(self):
- error_format = ['Enter a Romanian county code or name.']
- valid = {
- 'CJ': 'CJ',
- 'cj': 'CJ',
- 'Argeş': 'AG',
- 'argeş': 'AG',
- }
- invalid = {
- 'Arges': error_format,
- }
- self.assertFieldOutput(ROCountyField, valid, invalid)
-
- def test_ROIBANField(self):
- error_invalid = ['Enter a valid IBAN in ROXX-XXXX-XXXX-XXXX-XXXX-XXXX format']
- error_atleast = ['Ensure this value has at least 24 characters (it has 23).']
- valid = {
- 'RO56RZBR0000060003291177': 'RO56RZBR0000060003291177',
- 'RO56-RZBR-0000-0600-0329-1177': 'RO56RZBR0000060003291177',
- }
- invalid = {
- 'RO56RZBR0000060003291176': error_invalid,
- 'AT61 1904 3002 3457 3201': error_invalid,
- 'RO56RZBR000006000329117': error_atleast + error_invalid,
- }
- self.assertFieldOutput(ROIBANField, valid, invalid)
-
- def test_ROPhoneNumberField(self):
- error_format = ['Phone numbers must be in XXXX-XXXXXX format.']
- error_atleast = ['Ensure this value has at least 10 characters (it has 9).']
- error_invalid = ['Phone numbers must be in XXXX-XXXXXX format.']
- valid = {
- '0264485936': '0264485936',
- '(0264)-485936': '0264485936',
- }
- invalid = {
- '02644859368': error_format,
- '026448593': error_atleast + error_invalid,
- }
- self.assertFieldOutput(ROPhoneNumberField, valid, invalid)
-
- def test_ROPostalCodeField(self):
- error_atleast = ['Ensure this value has at least 6 characters (it has 5).']
- error_atmost = ['Ensure this value has at most 6 characters (it has 7).']
- error_invalid = ['Enter a valid postal code in the format XXXXXX']
-
- valid = {
- '400473': '400473',
- }
- invalid = {
- '40047': error_atleast + error_invalid,
- '4004731': error_atmost + error_invalid,
- }
- self.assertFieldOutput(ROPostalCodeField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/ru/__init__.py b/tests/regressiontests/localflavor/ru/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/ru/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/ru/tests.py b/tests/regressiontests/localflavor/ru/tests.py
deleted file mode 100644
index 758c5ae7d8..0000000000
--- a/tests/regressiontests/localflavor/ru/tests.py
+++ /dev/null
@@ -1,150 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.ru.forms import *
-
-from django.test import SimpleTestCase
-
-
-class RULocalFlavorTests(SimpleTestCase):
-
- def test_RUPassportNumberField(self):
- error = ['Enter a passport number in the format XXXX XXXXXX.']
- valid = {
- '1981 211204': '1981 211204',
- '0305 967876': '0305 967876',
- }
- invalid = {
- '1981 2112044': error,
- '1981 23220': error,
- '9981211201': error,
- }
- self.assertFieldOutput(RUPassportNumberField, valid, invalid)
-
- def test_RUAlienPassportNumberField(self):
- error = ['Enter a passport number in the format XX XXXXXXX.']
- valid = {
- '19 8111204': '19 8111204',
- '03 0567876': '03 0567876',
- }
- invalid = {
- '198 1112044': error,
- '19 81123220': error,
- '99 812112': error,
- }
- self.assertFieldOutput(RUAlienPassportNumberField, valid, invalid)
-
- def test_RUPostalCodeField(self):
- error = ['Enter a postal code in the format XXXXXX.']
- valid = {
- '987654': '987654',
- '123456': '123456'
- }
- invalid = {
- '123 34': error,
- '1234567': error,
- '12345': error
- }
- self.assertFieldOutput(RUPostalCodeField, valid, invalid)
-
- def test_RUCountySelect(self):
- f = RUCountySelect()
- out = '''<select name="county">
-<option value="Central Federal County">Central Federal County</option>
-<option value="South Federal County">South Federal County</option>
-<option value="North-West Federal County">North-West Federal County</option>
-<option value="Far-East Federal County">Far-East Federal County</option>
-<option value="Siberian Federal County">Siberian Federal County</option>
-<option value="Ural Federal County">Ural Federal County</option>
-<option value="Privolzhsky Federal County">Privolzhsky Federal County</option>
-<option value="North-Caucasian Federal County">North-Caucasian Federal County</option>
-</select>'''
- self.assertHTMLEqual(f.render('county', None), out)
-
- def test_RURegionSelect(self):
- f = RURegionSelect()
- out = '''<select name="region">
-<option value="77">Moskva</option>
-<option value="78">Saint-Peterburg</option>
-<option value="50">Moskovskaya oblast&#39;</option>
-<option value="01">Adygeya, Respublika</option>
-<option value="02">Bashkortostan, Respublika</option>
-<option value="03">Buryatia, Respublika</option>
-<option value="04">Altay, Respublika</option>
-<option value="05">Dagestan, Respublika</option>
-<option value="06">Ingushskaya Respublika</option>
-<option value="07">Kabardino-Balkarskaya Respublika</option>
-<option value="08">Kalmykia, Respublika</option>
-<option value="09">Karachaevo-Cherkesskaya Respublika</option>
-<option value="10">Karelia, Respublika</option>
-<option value="11">Komi, Respublika</option>
-<option value="12">Mariy Ehl, Respublika</option>
-<option value="13">Mordovia, Respublika</option>
-<option value="14">Sakha, Respublika (Yakutiya)</option>
-<option value="15">Severnaya Osetia, Respublika (Alania)</option>
-<option value="16">Tatarstan, Respublika</option>
-<option value="17">Tyva, Respublika (Tuva)</option>
-<option value="18">Udmurtskaya Respublika</option>
-<option value="19">Khakassiya, Respublika</option>
-<option value="95">Chechenskaya Respublika</option>
-<option value="21">Chuvashskaya Respublika</option>
-<option value="22">Altayskiy Kray</option>
-<option value="80">Zabaykalskiy Kray</option>
-<option value="82">Kamchatskiy Kray</option>
-<option value="23">Krasnodarskiy Kray</option>
-<option value="24">Krasnoyarskiy Kray</option>
-<option value="81">Permskiy Kray</option>
-<option value="25">Primorskiy Kray</option>
-<option value="26">Stavropol&#39;siyy Kray</option>
-<option value="27">Khabarovskiy Kray</option>
-<option value="28">Amurskaya oblast&#39;</option>
-<option value="29">Arkhangel&#39;skaya oblast&#39;</option>
-<option value="30">Astrakhanskaya oblast&#39;</option>
-<option value="31">Belgorodskaya oblast&#39;</option>
-<option value="32">Bryanskaya oblast&#39;</option>
-<option value="33">Vladimirskaya oblast&#39;</option>
-<option value="34">Volgogradskaya oblast&#39;</option>
-<option value="35">Vologodskaya oblast&#39;</option>
-<option value="36">Voronezhskaya oblast&#39;</option>
-<option value="37">Ivanovskaya oblast&#39;</option>
-<option value="38">Irkutskaya oblast&#39;</option>
-<option value="39">Kaliningradskaya oblast&#39;</option>
-<option value="40">Kaluzhskaya oblast&#39;</option>
-<option value="42">Kemerovskaya oblast&#39;</option>
-<option value="43">Kirovskaya oblast&#39;</option>
-<option value="44">Kostromskaya oblast&#39;</option>
-<option value="45">Kurganskaya oblast&#39;</option>
-<option value="46">Kurskaya oblast&#39;</option>
-<option value="47">Leningradskaya oblast&#39;</option>
-<option value="48">Lipeckaya oblast&#39;</option>
-<option value="49">Magadanskaya oblast&#39;</option>
-<option value="51">Murmanskaya oblast&#39;</option>
-<option value="52">Nizhegorodskaja oblast&#39;</option>
-<option value="53">Novgorodskaya oblast&#39;</option>
-<option value="54">Novosibirskaya oblast&#39;</option>
-<option value="55">Omskaya oblast&#39;</option>
-<option value="56">Orenburgskaya oblast&#39;</option>
-<option value="57">Orlovskaya oblast&#39;</option>
-<option value="58">Penzenskaya oblast&#39;</option>
-<option value="60">Pskovskaya oblast&#39;</option>
-<option value="61">Rostovskaya oblast&#39;</option>
-<option value="62">Rjazanskaya oblast&#39;</option>
-<option value="63">Samarskaya oblast&#39;</option>
-<option value="64">Saratovskaya oblast&#39;</option>
-<option value="65">Sakhalinskaya oblast&#39;</option>
-<option value="66">Sverdlovskaya oblast&#39;</option>
-<option value="67" selected="selected">Smolenskaya oblast&#39;</option>
-<option value="68">Tambovskaya oblast&#39;</option>
-<option value="69">Tverskaya oblast&#39;</option>
-<option value="70">Tomskaya oblast&#39;</option>
-<option value="71">Tul&#39;skaya oblast&#39;</option>
-<option value="72">Tyumenskaya oblast&#39;</option>
-<option value="73">Ul&#39;ianovskaya oblast&#39;</option>
-<option value="74">Chelyabinskaya oblast&#39;</option>
-<option value="76">Yaroslavskaya oblast&#39;</option>
-<option value="79">Evreyskaya avtonomnaja oblast&#39;</option>
-<option value="83">Neneckiy autonomnyy okrug</option>
-<option value="86">Khanty-Mansiyskiy avtonomnyy okrug - Yugra</option>
-<option value="87">Chukotskiy avtonomnyy okrug</option>
-<option value="89">Yamalo-Neneckiy avtonomnyy okrug</option>
-</select>'''
- self.assertHTMLEqual(f.render('region', '67'), out)
diff --git a/tests/regressiontests/localflavor/se/__init__.py b/tests/regressiontests/localflavor/se/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/se/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/se/tests.py b/tests/regressiontests/localflavor/se/tests.py
deleted file mode 100644
index f61c61e9d4..0000000000
--- a/tests/regressiontests/localflavor/se/tests.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.se.forms import (SECountySelect,
- SEOrganisationNumberField, SEPersonalIdentityNumberField,
- SEPostalCodeField)
-import datetime
-
-from django.test import SimpleTestCase
-
-
-class SELocalFlavorTests(SimpleTestCase):
-
- def setUp(self):
- # Mocking datetime.date to make sure
- # localflavor.se.utils.validate_id_birthday works
- class MockDate(datetime.date):
- def today(cls):
- return datetime.date(2008, 5, 14)
- today = classmethod(today)
- self._olddate = datetime.date
- datetime.date = MockDate
-
- def tearDown(self):
- datetime.date = self._olddate
-
- def test_SECountySelect(self):
- f = SECountySelect()
- out = '''<select name="swedish_county">
-<option value="AB">Stockholm</option>
-<option value="AC">V\xe4sterbotten</option>
-<option value="BD">Norrbotten</option>
-<option value="C">Uppsala</option>
-<option value="D">S\xf6dermanland</option>
-<option value="E" selected="selected">\xd6sterg\xf6tland</option>
-<option value="F">J\xf6nk\xf6ping</option>
-<option value="G">Kronoberg</option>
-<option value="H">Kalmar</option>
-<option value="I">Gotland</option>
-<option value="K">Blekinge</option>
-<option value="M">Sk\xe5ne</option>
-<option value="N">Halland</option>
-<option value="O">V\xe4stra G\xf6taland</option>
-<option value="S">V\xe4rmland</option>
-<option value="T">\xd6rebro</option>
-<option value="U">V\xe4stmanland</option>
-<option value="W">Dalarna</option>
-<option value="X">G\xe4vleborg</option>
-<option value="Y">V\xe4sternorrland</option>
-<option value="Z">J\xe4mtland</option>
-</select>'''
- self.assertHTMLEqual(f.render('swedish_county', 'E'), out)
-
- def test_SEOrganizationNumberField(self):
- error_invalid = ['Enter a valid Swedish organisation number.']
- valid = {
- '870512-1989': '198705121989',
- '19870512-1989': '198705121989',
- '870512-2128': '198705122128',
- '081015-6315': '190810156315',
- '081015+6315': '180810156315',
- '0810156315': '190810156315',
- # Test some different organisation numbers
- # IKEA Linköping
- '556074-7569': '5560747569',
- # Volvo Personvagnar
- '556074-3089': '5560743089',
- # LJS (organisation)
- '822001-5476': '8220015476',
- # LJS (organisation)
- '8220015476': '8220015476',
- # Katedralskolan Linköping (school)
- '2120000449': '2120000449',
- # Faux organisation number, which tests that the checksum can be 0
- '232518-5060': '2325185060',
- }
- invalid = {
- # Ordinary personal identity numbers for sole proprietors
- # The same rules as for SEPersonalIdentityField applies here
- '081015 6315': error_invalid,
- '950231-4496': error_invalid,
- '6914104499': error_invalid,
- '950d314496': error_invalid,
- 'invalid!!!': error_invalid,
- '870514-1111': error_invalid,
- # Co-ordination number checking
- # Co-ordination numbers are not valid organisation numbers
- '870574-1315': error_invalid,
- '870573-1311': error_invalid,
- # Volvo Personvagnar, bad format
- '556074+3089': error_invalid,
- # Invalid checksum
- '2120000441': error_invalid,
- # Valid checksum but invalid organisation type
- '1120000441': error_invalid,
- }
- self.assertFieldOutput(SEOrganisationNumberField, valid, invalid)
-
- def test_SEPersonalIdentityNumberField(self):
- error_invalid = ['Enter a valid Swedish personal identity number.']
- error_coord = ['Co-ordination numbers are not allowed.']
- valid = {
- '870512-1989': '198705121989',
- '870512-2128': '198705122128',
- '19870512-1989': '198705121989',
- '198705121989': '198705121989',
- '081015-6315': '190810156315',
- '0810156315': '190810156315',
- # This is a "special-case" in the checksum calculation,
- # where the sum is divisible by 10 (the checksum digit == 0)
- '8705141060': '198705141060',
- # + means that the person is older than 100 years
- '081015+6315': '180810156315',
- # Co-ordination number checking
- '870574-1315': '198705741315',
- '870574+1315': '188705741315',
- '198705741315': '198705741315',
- }
- invalid = {
- '081015 6315': error_invalid,
- '950d314496': error_invalid,
- 'invalid!!!': error_invalid,
- # Invalid dates
- # February 31st does not exist
- '950231-4496': error_invalid,
- # Month 14 does not exist
- '6914104499': error_invalid,
- # There are no Swedish personal id numbers where year < 1800
- '17430309-7135': error_invalid,
- # Invalid checksum
- '870514-1111': error_invalid,
- # Co-ordination number with bad checksum
- '870573-1311': error_invalid,
- }
- self.assertFieldOutput(SEPersonalIdentityNumberField, valid, invalid)
-
- valid = {}
- invalid = {
- # Check valid co-ordination numbers that should not be accepted
- # because of coordination_number=False
- '870574-1315': error_coord,
- '870574+1315': error_coord,
- '8705741315': error_coord,
- # Invalid co-ordination numbers should be treated as invalid, and not
- # as co-ordination numbers
- '870573-1311': error_invalid,
- }
- kwargs = {'coordination_number': False,}
- self.assertFieldOutput(SEPersonalIdentityNumberField, valid, invalid,
- field_kwargs=kwargs)
-
- def test_SEPostalCodeField(self):
- error_format = ['Enter a Swedish postal code in the format XXXXX.']
- valid = {
- '589 37': '58937',
- '58937': '58937',
- }
- invalid = {
- 'abcasfassadf': error_format,
- # Only one space is allowed for separation
- '589 37': error_format,
- # The postal code must not start with 0
- '01234': error_format,
-
- }
- self.assertFieldOutput(SEPostalCodeField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/si/__init__.py b/tests/regressiontests/localflavor/si/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/si/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/si/tests.py b/tests/regressiontests/localflavor/si/tests.py
deleted file mode 100644
index 123683bff4..0000000000
--- a/tests/regressiontests/localflavor/si/tests.py
+++ /dev/null
@@ -1,557 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from datetime import date
-
-from django.contrib.localflavor.si.forms import (SIEMSOField, SITaxNumberField,
- SIPhoneNumberField, SIPostalCodeField, SIPostalCodeSelect)
-from django.test import SimpleTestCase
-
-
-class SILocalFlavorTests(SimpleTestCase):
- def test_SITaxNumberField(self):
- error_invalid = ['Enter a valid tax number in form SIXXXXXXXX']
- valid = {
- '15012557': '15012557',
- 'SI15012557': '15012557',
- '22111310': '22111310',
- }
- invalid = {
- '22241310': error_invalid,
- '15012558': error_invalid,
- '1501': error_invalid,
- '1501123123123': error_invalid,
- 'abcdabcd': error_invalid,
- '01234579': error_invalid,
- }
- self.assertFieldOutput(SITaxNumberField, valid, invalid)
-
- def test_SIEMSOField(self):
- error_invalid = ['This field should contain exactly 13 digits.']
- error_invalid_date = ['The first 7 digits of the EMSO must represent a valid past date.']
- error_invalid_chksum = ['The EMSO is not valid.']
- valid = {
- '0205951500462': '0205951500462',
- '2309002500068': '2309002500068',
- '1010985500400': '1010985500400',
- }
- invalid = {
- '0205951500463': error_invalid_chksum,
- '020': error_invalid,
- '020020595150046020595150046': error_invalid,
- 'aaaabbbbccccd': error_invalid,
- '1010985500800': error_invalid_chksum,
- '2020095500070': error_invalid_date,
- '5050095500078': error_invalid_date,
- '1010889500408': error_invalid_date,
- }
- self.assertFieldOutput(SIEMSOField, valid, invalid)
-
- def test_SIEMSOField_info_dict(self):
- valid = {
- '0205951500462': {'nationality': 50, 'gender': 'male', 'birthdate': date(1951, 5, 2)},
- '2309002504063': {'nationality': 50, 'gender': 'male', 'birthdate': date(2002, 9, 23)},
- '1010985505402': {'nationality': 50, 'gender': 'female', 'birthdate': date(1985, 10, 10)},
- }
- for input, info in valid.items():
- f = SIEMSOField()
- f.clean(input)
- self.assertEqual(f.info, info)
-
- def test_SIPhoneNumberField(self):
- error_invalid = ['Enter phone number in form +386XXXXXXXX or 0XXXXXXXX.']
- valid = {
- '+38640999999': '40999999',
- '+3861999999': '1999999',
- '0038640999999': '40999999',
- '040999999': '40999999',
- '01999999': '1999999',
- '059099999': '59099999',
- '059 09 99 99': '59099999',
- '0590/999-99': '59099999',
- }
- invalid = {
- '03861999999': error_invalid,
- '3861999999': error_invalid,
- }
- self.assertFieldOutput(SIPhoneNumberField, valid, invalid)
-
- def test_SIPostalCodeField(self):
- valid = {
- '4000': '4000',
- '1000': '1000'
- }
- invalid = {
- '1113': ['Select a valid choice. 1113 is not one of the available choices.'],
- '111': ['Select a valid choice. 111 is not one of the available choices.'],
- }
- self.assertFieldOutput(SIPostalCodeField, valid, invalid)
-
- def test_SIPostalCodeSelect(self):
- f = SIPostalCodeSelect()
- out = '''<select name="Kranj">
-<option value="8341">Adle\u0161i\u010di</option>
-<option value="5270">Ajdov\u0161\u010dina</option>
-<option value="6280">Ankaran - Ancarano</option>
-<option value="9253">Apa\u010de</option>
-<option value="8253">Arti\u010de</option>
-<option value="4275">Begunje na Gorenjskem</option>
-<option value="1382">Begunje pri Cerknici</option>
-<option value="9231">Beltinci</option>
-<option value="2234">Benedikt</option>
-<option value="2345">Bistrica ob Dravi</option>
-<option value="3256">Bistrica ob Sotli</option>
-<option value="8259">Bizeljsko</option>
-<option value="1223">Blagovica</option>
-<option value="8283">Blanca</option>
-<option value="4260">Bled</option>
-<option value="4273">Blejska Dobrava</option>
-<option value="9265">Bodonci</option>
-<option value="9222">Bogojina</option>
-<option value="4263">Bohinjska Bela</option>
-<option value="4264">Bohinjska Bistrica</option>
-<option value="4265">Bohinjsko jezero</option>
-<option value="1353">Borovnica</option>
-<option value="5230">Bovec</option>
-<option value="8294">Bo\u0161tanj</option>
-<option value="5295">Branik</option>
-<option value="3314">Braslov\u010de</option>
-<option value="5223">Breginj</option>
-<option value="8280">Brestanica</option>
-<option value="2354">Bresternica</option>
-<option value="4243">Brezje</option>
-<option value="1351">Brezovica pri Ljubljani</option>
-<option value="8250">Bre\u017eice</option>
-<option value="4210">Brnik - aerodrom</option>
-<option value="8321">Brusnice</option>
-<option value="3255">Bu\u010de</option>
-<option value="8276">Bu\u010dka</option>
-<option value="9261">Cankova</option>
-<option value="3000">Celje</option>
-<option value="4207">Cerklje na Gorenjskem</option>
-<option value="8263">Cerklje ob Krki</option>
-<option value="1380">Cerknica</option>
-<option value="5282">Cerkno</option>
-<option value="2236">Cerkvenjak</option>
-<option value="2215">Cer\u0161ak</option>
-<option value="2326">Cirkovce</option>
-<option value="2282">Cirkulane</option>
-<option value="5273">Col</option>
-<option value="6271">Dekani</option>
-<option value="5210">Deskle</option>
-<option value="2253">Destrnik</option>
-<option value="6215">Diva\u010da</option>
-<option value="1233">Dob</option>
-<option value="3224">Dobje pri Planini</option>
-<option value="8257">Dobova</option>
-<option value="1423">Dobovec</option>
-<option value="5263">Dobravlje</option>
-<option value="3204">Dobrna</option>
-<option value="8211">Dobrni\u010d</option>
-<option value="1356">Dobrova</option>
-<option value="9223">Dobrovnik - Dobronak</option>
-<option value="5212">Dobrovo v Brdih</option>
-<option value="1431">Dol pri Hrastniku</option>
-<option value="1262">Dol pri Ljubljani</option>
-<option value="1273">Dole pri Litiji</option>
-<option value="1331">Dolenja vas</option>
-<option value="8350">Dolenjske Toplice</option>
-<option value="1230">Dom\u017eale</option>
-<option value="2252">Dornava</option>
-<option value="5294">Dornberk</option>
-<option value="1319">Draga</option>
-<option value="8343">Dragatu\u0161</option>
-<option value="3222">Dramlje</option>
-<option value="2370">Dravograd</option>
-<option value="4203">Duplje</option>
-<option value="6221">Dutovlje</option>
-<option value="8361">Dvor</option>
-<option value="2343">Fala</option>
-<option value="9208">Fokovci</option>
-<option value="2313">Fram</option>
-<option value="3213">Frankolovo</option>
-<option value="1274">Gabrovka</option>
-<option value="8254">Globoko</option>
-<option value="5275">Godovi\u010d</option>
-<option value="4204">Golnik</option>
-<option value="3303">Gomilsko</option>
-<option value="4224">Gorenja vas</option>
-<option value="3263">Gorica pri Slivnici</option>
-<option value="2272">Gori\u0161nica</option>
-<option value="9250">Gornja Radgona</option>
-<option value="3342">Gornji Grad</option>
-<option value="4282">Gozd Martuljek</option>
-<option value="9264">Grad</option>
-<option value="8332">Gradac</option>
-<option value="1384">Grahovo</option>
-<option value="5242">Grahovo ob Ba\u010di</option>
-<option value="6272">Gra\u010di\u0161\u010de</option>
-<option value="5251">Grgar</option>
-<option value="3302">Gri\u017ee</option>
-<option value="3231">Grobelno</option>
-<option value="1290">Grosuplje</option>
-<option value="2288">Hajdina</option>
-<option value="8362">Hinje</option>
-<option value="9205">Hodo\u0161 - Hodos</option>
-<option value="1354">Horjul</option>
-<option value="1372">Hotedr\u0161ica</option>
-<option value="2311">Ho\u010de</option>
-<option value="1430">Hrastnik</option>
-<option value="6225">Hru\u0161evje</option>
-<option value="4276">Hru\u0161ica</option>
-<option value="5280">Idrija</option>
-<option value="1292">Ig</option>
-<option value="6250">Ilirska Bistrica</option>
-<option value="6251">Ilirska Bistrica - Trnovo</option>
-<option value="2259">Ivanjkovci</option>
-<option value="1295">Ivan\u010dna Gorica</option>
-<option value="1411">Izlake</option>
-<option value="6310">Izola - Isola</option>
-<option value="2222">Jakobski Dol</option>
-<option value="2221">Jarenina</option>
-<option value="6254">Jel\u0161ane</option>
-<option value="4270">Jesenice</option>
-<option value="8261">Jesenice na Dolenjskem</option>
-<option value="3273">Jurklo\u0161ter</option>
-<option value="2223">Jurovski Dol</option>
-<option value="2256">Jur\u0161inci</option>
-<option value="5214">Kal nad Kanalom</option>
-<option value="3233">Kalobje</option>
-<option value="4246">Kamna Gorica</option>
-<option value="2351">Kamnica</option>
-<option value="1241">Kamnik</option>
-<option value="5213">Kanal</option>
-<option value="8258">Kapele</option>
-<option value="2362">Kapla</option>
-<option value="2325">Kidri\u010devo</option>
-<option value="1412">Kisovec</option>
-<option value="6253">Kne\u017eak</option>
-<option value="5222">Kobarid</option>
-<option value="9227">Kobilje</option>
-<option value="2276">Kog</option>
-<option value="5211">Kojsko</option>
-<option value="6223">Komen</option>
-<option value="1218">Komenda</option>
-<option value="6000">Koper</option>
-<option value="8282">Koprivnica</option>
-<option value="5296">Kostanjevica na Krasu</option>
-<option value="8311">Kostanjevica na Krki</option>
-<option value="1336">Kostel</option>
-<option value="2394">Kotlje</option>
-<option value="6240">Kozina</option>
-<option value="3260">Kozje</option>
-<option value="1330">Ko\u010devje</option>
-<option value="1338">Ko\u010devska Reka</option>
-<option value="6256">Ko\u0161ana</option>
-<option value="4000" selected="selected">Kranj</option>
-<option value="4280">Kranjska Gora</option>
-<option value="1281">Kresnice</option>
-<option value="4294">Kri\u017ee</option>
-<option value="9206">Kri\u017eevci</option>
-<option value="9242">Kri\u017eevci pri Ljutomeru</option>
-<option value="1301">Krka</option>
-<option value="8296">Krmelj</option>
-<option value="4245">Kropa</option>
-<option value="8262">Kr\u0161ka vas</option>
-<option value="8270">Kr\u0161ko</option>
-<option value="9263">Kuzma</option>
-<option value="2318">Laporje</option>
-<option value="1219">Laze v Tuhinju</option>
-<option value="3270">La\u0161ko</option>
-<option value="2230">Lenart v Slovenskih goricah</option>
-<option value="9220">Lendava - Lendva</option>
-<option value="4248">Lesce</option>
-<option value="3261">Lesi\u010dno</option>
-<option value="8273">Leskovec pri Kr\u0161kem</option>
-<option value="2372">Libeli\u010de</option>
-<option value="2341">Limbu\u0161</option>
-<option value="1270">Litija</option>
-<option value="3202">Ljube\u010dna</option>
-<option value="1000">Ljubljana</option>
-<option value="3333">Ljubno ob Savinji</option>
-<option value="9240">Ljutomer</option>
-<option value="5231">Log pod Mangartom</option>
-<option value="1358">Log pri Brezovici</option>
-<option value="1370">Logatec</option>
-<option value="1434">Loka pri Zidanem Mostu</option>
-<option value="3223">Loka pri \u017dusmu</option>
-<option value="6219">Lokev</option>
-<option value="2324">Lovrenc na Dravskem polju</option>
-<option value="2344">Lovrenc na Pohorju</option>
-<option value="3215">Lo\u010de</option>
-<option value="1318">Lo\u0161ki Potok</option>
-<option value="1225">Lukovica</option>
-<option value="3334">Lu\u010de</option>
-<option value="2322">Maj\u0161perk</option>
-<option value="2321">Makole</option>
-<option value="9243">Mala Nedelja</option>
-<option value="2229">Male\u010dnik</option>
-<option value="6273">Marezige</option>
-<option value="2000">Maribor</option>
-<option value="2206">Marjeta na Dravskem polju</option>
-<option value="2281">Markovci</option>
-<option value="9221">Martjanci</option>
-<option value="6242">Materija</option>
-<option value="4211">Mav\u010di\u010de</option>
-<option value="9202">Ma\u010dkovci</option>
-<option value="1215">Medvode</option>
-<option value="1234">Menge\u0161</option>
-<option value="8330">Metlika</option>
-<option value="2392">Me\u017eica</option>
-<option value="2204">Miklav\u017e na Dravskem polju</option>
-<option value="2275">Miklav\u017e pri Ormo\u017eu</option>
-<option value="5291">Miren</option>
-<option value="8233">Mirna</option>
-<option value="8216">Mirna Pe\u010d</option>
-<option value="2382">Mislinja</option>
-<option value="4281">Mojstrana</option>
-<option value="8230">Mokronog</option>
-<option value="9226">Moravske Toplice</option>
-<option value="1251">Morav\u010de</option>
-<option value="5216">Most na So\u010di</option>
-<option value="1221">Motnik</option>
-<option value="3330">Mozirje</option>
-<option value="9000">Murska Sobota</option>
-<option value="2366">Muta</option>
-<option value="4202">Naklo</option>
-<option value="3331">Nazarje</option>
-<option value="1357">Notranje Gorice</option>
-<option value="3203">Nova Cerkev</option>
-<option value="5000">Nova Gorica</option>
-<option value="1385">Nova vas</option>
-<option value="8000">Novo mesto</option>
-<option value="6243">Obrov</option>
-<option value="9233">Odranci</option>
-<option value="2317">Oplotnica</option>
-<option value="2312">Orehova vas</option>
-<option value="2270">Ormo\u017e</option>
-<option value="1316">Ortnek</option>
-<option value="1337">Osilnica</option>
-<option value="8222">Oto\u010dec</option>
-<option value="2361">O\u017ebalt</option>
-<option value="2231">Pernica</option>
-<option value="2211">Pesnica pri Mariboru</option>
-<option value="9203">Petrovci</option>
-<option value="3301">Petrov\u010de</option>
-<option value="6330">Piran - Pirano</option>
-<option value="6257">Pivka</option>
-<option value="8255">Pi\u0161ece</option>
-<option value="6232">Planina</option>
-<option value="3225">Planina pri Sevnici</option>
-<option value="6276">Pobegi</option>
-<option value="8312">Podbo\u010dje</option>
-<option value="5243">Podbrdo</option>
-<option value="2273">Podgorci</option>
-<option value="6216">Podgorje</option>
-<option value="2381">Podgorje pri Slovenj Gradcu</option>
-<option value="6244">Podgrad</option>
-<option value="1414">Podkum</option>
-<option value="2286">Podlehnik</option>
-<option value="5272">Podnanos</option>
-<option value="4244">Podnart</option>
-<option value="3241">Podplat</option>
-<option value="3257">Podsreda</option>
-<option value="2363">Podvelka</option>
-<option value="3254">Pod\u010detrtek</option>
-<option value="2208">Pohorje</option>
-<option value="2257">Polen\u0161ak</option>
-<option value="1355">Polhov Gradec</option>
-<option value="4223">Poljane nad \u0160kofjo Loko</option>
-<option value="2319">Polj\u010dane</option>
-<option value="3313">Polzela</option>
-<option value="1272">Pol\u0161nik</option>
-<option value="3232">Ponikva</option>
-<option value="6320">Portoro\u017e - Portorose</option>
-<option value="6230">Postojna</option>
-<option value="2331">Pragersko</option>
-<option value="3312">Prebold</option>
-<option value="4205">Preddvor</option>
-<option value="6255">Prem</option>
-<option value="1352">Preserje</option>
-<option value="6258">Prestranek</option>
-<option value="2391">Prevalje</option>
-<option value="3262">Prevorje</option>
-<option value="1276">Primskovo</option>
-<option value="3253">Pristava pri Mestinju</option>
-<option value="9207">Prosenjakovci - Partosfalva</option>
-<option value="5297">Prva\u010dina</option>
-<option value="2250">Ptuj</option>
-<option value="2323">Ptujska Gora</option>
-<option value="9201">Puconci</option>
-<option value="9252">Radenci</option>
-<option value="1433">Rade\u010de</option>
-<option value="2360">Radlje ob Dravi</option>
-<option value="1235">Radomlje</option>
-<option value="4240">Radovljica</option>
-<option value="8274">Raka</option>
-<option value="1381">Rakek</option>
-<option value="4283">Rate\u010de - Planica</option>
-<option value="2390">Ravne na Koro\u0161kem</option>
-<option value="2327">Ra\u010de</option>
-<option value="5292">Ren\u010de</option>
-<option value="3332">Re\u010dica ob Savinji</option>
-<option value="1310">Ribnica</option>
-<option value="2364">Ribnica na Pohorju</option>
-<option value="3272">Rimske Toplice</option>
-<option value="1314">Rob</option>
-<option value="3252">Rogatec</option>
-<option value="3250">Roga\u0161ka Slatina</option>
-<option value="9262">Roga\u0161ovci</option>
-<option value="1373">Rovte</option>
-<option value="5215">Ro\u010dinj</option>
-<option value="2342">Ru\u0161e</option>
-<option value="1282">Sava</option>
-<option value="4227">Selca</option>
-<option value="2352">Selnica ob Dravi</option>
-<option value="8333">Semi\u010d</option>
-<option value="8281">Senovo</option>
-<option value="6224">Seno\u017ee\u010de</option>
-<option value="8290">Sevnica</option>
-<option value="6333">Se\u010dovlje - Sicciole</option>
-<option value="6210">Se\u017eana</option>
-<option value="2214">Sladki vrh</option>
-<option value="5283">Slap ob Idrijci</option>
-<option value="2380">Slovenj Gradec</option>
-<option value="2310">Slovenska Bistrica</option>
-<option value="3210">Slovenske Konjice</option>
-<option value="1216">Smlednik</option>
-<option value="1317">Sodra\u017eica</option>
-<option value="5250">Solkan</option>
-<option value="3335">Sol\u010dava</option>
-<option value="4229">Sorica</option>
-<option value="4225">Sovodenj</option>
-<option value="5232">So\u010da</option>
-<option value="5281">Spodnja Idrija</option>
-<option value="2241">Spodnji Duplek</option>
-<option value="9245">Spodnji Ivanjci</option>
-<option value="2277">Sredi\u0161\u010de ob Dravi</option>
-<option value="4267">Srednja vas v Bohinju</option>
-<option value="8256">Sromlje</option>
-<option value="5224">Srpenica</option>
-<option value="1242">Stahovica</option>
-<option value="1332">Stara Cerkev</option>
-<option value="8342">Stari trg ob Kolpi</option>
-<option value="1386">Stari trg pri Lo\u017eu</option>
-<option value="2205">Star\u0161e</option>
-<option value="2289">Stoperce</option>
-<option value="8322">Stopi\u010de</option>
-<option value="3206">Stranice</option>
-<option value="8351">Stra\u017ea</option>
-<option value="1313">Struge</option>
-<option value="8293">Studenec</option>
-<option value="8331">Suhor</option>
-<option value="2353">Sv. Duh na Ostrem Vrhu</option>
-<option value="2233">Sveta Ana v Slovenskih goricah</option>
-<option value="2235">Sveta Trojica v Slovenskih goricah</option>
-<option value="9244">Sveti Jurij ob \u0160\u010davnici</option>
-<option value="2258">Sveti Toma\u017e</option>
-<option value="3264">Sveti \u0160tefan</option>
-<option value="3304">Tabor</option>
-<option value="3221">Teharje</option>
-<option value="9251">Ti\u0161ina</option>
-<option value="5220">Tolmin</option>
-<option value="3326">Topol\u0161ica</option>
-<option value="2371">Trbonje</option>
-<option value="1420">Trbovlje</option>
-<option value="8231">Trebelno</option>
-<option value="8210">Trebnje</option>
-<option value="5252">Trnovo pri Gorici</option>
-<option value="2254">Trnovska vas</option>
-<option value="1222">Trojane</option>
-<option value="1236">Trzin</option>
-<option value="4290">Tr\u017ei\u010d</option>
-<option value="8295">Tr\u017ei\u0161\u010de</option>
-<option value="1311">Turjak</option>
-<option value="9224">Turni\u0161\u010de</option>
-<option value="8323">Ur\u0161na sela</option>
-<option value="1252">Va\u010de</option>
-<option value="3320">Velenje - dostava</option>
-<option value="3322">Velenje - po\u0161tni predali</option>
-<option value="8212">Velika Loka</option>
-<option value="2274">Velika Nedelja</option>
-<option value="9225">Velika Polana</option>
-<option value="1315">Velike La\u0161\u010de</option>
-<option value="8213">Veliki Gaber</option>
-<option value="9241">Ver\u017eej</option>
-<option value="1312">Videm - Dobrepolje</option>
-<option value="2284">Videm pri Ptuju</option>
-<option value="8344">Vinica pri \u010crnomlju</option>
-<option value="5271">Vipava</option>
-<option value="4212">Visoko</option>
-<option value="3205">Vitanje</option>
-<option value="2255">Vitomarci</option>
-<option value="1294">Vi\u0161nja Gora</option>
-<option value="1217">Vodice</option>
-<option value="3212">Vojnik</option>
-<option value="2232">Voli\u010dina</option>
-<option value="5293">Vol\u010dja Draga</option>
-<option value="3305">Vransko</option>
-<option value="6217">Vremski Britof</option>
-<option value="1360">Vrhnika</option>
-<option value="2365">Vuhred</option>
-<option value="2367">Vuzenica</option>
-<option value="8292">Zabukovje</option>
-<option value="1410">Zagorje ob Savi</option>
-<option value="1303">Zagradec</option>
-<option value="2283">Zavr\u010d</option>
-<option value="8272">Zdole</option>
-<option value="4201">Zgornja Besnica</option>
-<option value="2242">Zgornja Korena</option>
-<option value="2201">Zgornja Kungota</option>
-<option value="2316">Zgornja Lo\u017enica</option>
-<option value="2314">Zgornja Polskava</option>
-<option value="2213">Zgornja Velka</option>
-<option value="4247">Zgornje Gorje</option>
-<option value="4206">Zgornje Jezersko</option>
-<option value="2285">Zgornji Leskovec</option>
-<option value="1432">Zidani Most</option>
-<option value="3214">Zre\u010de</option>
-<option value="8251">\u010cate\u017e ob Savi</option>
-<option value="1413">\u010cem\u0161enik</option>
-<option value="5253">\u010cepovan</option>
-<option value="9232">\u010cren\u0161ovci</option>
-<option value="2393">\u010crna na Koro\u0161kem</option>
-<option value="6275">\u010crni Kal</option>
-<option value="5274">\u010crni Vrh nad Idrijo</option>
-<option value="5262">\u010crni\u010de</option>
-<option value="8340">\u010crnomelj</option>
-<option value="9204">\u0160alovci</option>
-<option value="5261">\u0160empas</option>
-<option value="5290">\u0160empeter pri Gorici</option>
-<option value="3311">\u0160empeter v Savinjski dolini</option>
-<option value="2212">\u0160entilj v Slovenskih goricah</option>
-<option value="8297">\u0160entjan\u017e</option>
-<option value="2373">\u0160entjan\u017e pri Dravogradu</option>
-<option value="8310">\u0160entjernej</option>
-<option value="3230">\u0160entjur</option>
-<option value="3271">\u0160entrupert</option>
-<option value="8232">\u0160entrupert</option>
-<option value="1296">\u0160entvid pri Sti\u010dni</option>
-<option value="4208">\u0160en\u010dur</option>
-<option value="8275">\u0160kocjan</option>
-<option value="6281">\u0160kofije</option>
-<option value="4220">\u0160kofja Loka</option>
-<option value="3211">\u0160kofja vas</option>
-<option value="1291">\u0160kofljica</option>
-<option value="6274">\u0160marje</option>
-<option value="1293">\u0160marje - Sap</option>
-<option value="3240">\u0160marje pri Jel\u0161ah</option>
-<option value="8220">\u0160marje\u0161ke Toplice</option>
-<option value="2315">\u0160martno na Pohorju</option>
-<option value="3341">\u0160martno ob Dreti</option>
-<option value="3327">\u0160martno ob Paki</option>
-<option value="1275">\u0160martno pri Litiji</option>
-<option value="2383">\u0160martno pri Slovenj Gradcu</option>
-<option value="3201">\u0160martno v Ro\u017eni dolini</option>
-<option value="3325">\u0160o\u0161tanj</option>
-<option value="6222">\u0160tanjel</option>
-<option value="3220">\u0160tore</option>
-<option value="4209">\u017dabnica</option>
-<option value="3310">\u017dalec</option>
-<option value="4228">\u017delezniki</option>
-<option value="2287">\u017detale</option>
-<option value="4226">\u017diri</option>
-<option value="4274">\u017dirovnica</option>
-<option value="8360">\u017du\u017eemberk</option>
-</select>'''
- self.assertHTMLEqual(f.render('Kranj', '4000'), out)
diff --git a/tests/regressiontests/localflavor/sk/__init__.py b/tests/regressiontests/localflavor/sk/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/sk/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/sk/tests.py b/tests/regressiontests/localflavor/sk/tests.py
deleted file mode 100644
index b51fee2681..0000000000
--- a/tests/regressiontests/localflavor/sk/tests.py
+++ /dev/null
@@ -1,118 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.sk.forms import (SKRegionSelect,
- SKPostalCodeField, SKDistrictSelect)
-
-from django.test import SimpleTestCase
-
-
-class SKLocalFlavorTests(SimpleTestCase):
- def test_SKRegionSelect(self):
- f = SKRegionSelect()
- out = '''<select name="regions">
-<option value="BB">Banska Bystrica region</option>
-<option value="BA">Bratislava region</option>
-<option value="KE">Kosice region</option>
-<option value="NR">Nitra region</option>
-<option value="PO">Presov region</option>
-<option value="TN">Trencin region</option>
-<option value="TT" selected="selected">Trnava region</option>
-<option value="ZA">Zilina region</option>
-</select>'''
- self.assertHTMLEqual(f.render('regions', 'TT'), out)
-
- def test_SKDistrictSelect(self):
- f = SKDistrictSelect()
- out = '''<select name="Districts">
-<option value="BB">Banska Bystrica</option>
-<option value="BS">Banska Stiavnica</option>
-<option value="BJ">Bardejov</option>
-<option value="BN">Banovce nad Bebravou</option>
-<option value="BR">Brezno</option>
-<option value="BA1">Bratislava I</option>
-<option value="BA2">Bratislava II</option>
-<option value="BA3">Bratislava III</option>
-<option value="BA4">Bratislava IV</option>
-<option value="BA5">Bratislava V</option>
-<option value="BY">Bytca</option>
-<option value="CA">Cadca</option>
-<option value="DT">Detva</option>
-<option value="DK">Dolny Kubin</option>
-<option value="DS">Dunajska Streda</option>
-<option value="GA">Galanta</option>
-<option value="GL">Gelnica</option>
-<option value="HC">Hlohovec</option>
-<option value="HE">Humenne</option>
-<option value="IL">Ilava</option>
-<option value="KK">Kezmarok</option>
-<option value="KN">Komarno</option>
-<option value="KE1">Kosice I</option>
-<option value="KE2">Kosice II</option>
-<option value="KE3">Kosice III</option>
-<option value="KE4">Kosice IV</option>
-<option value="KEO">Kosice - okolie</option>
-<option value="KA">Krupina</option>
-<option value="KM">Kysucke Nove Mesto</option>
-<option value="LV">Levice</option>
-<option value="LE">Levoca</option>
-<option value="LM">Liptovsky Mikulas</option>
-<option value="LC">Lucenec</option>
-<option value="MA">Malacky</option>
-<option value="MT">Martin</option>
-<option value="ML">Medzilaborce</option>
-<option value="MI">Michalovce</option>
-<option value="MY">Myjava</option>
-<option value="NO">Namestovo</option>
-<option value="NR">Nitra</option>
-<option value="NM">Nove Mesto nad Vahom</option>
-<option value="NZ">Nove Zamky</option>
-<option value="PE">Partizanske</option>
-<option value="PK">Pezinok</option>
-<option value="PN">Piestany</option>
-<option value="PT">Poltar</option>
-<option value="PP">Poprad</option>
-<option value="PB">Povazska Bystrica</option>
-<option value="PO">Presov</option>
-<option value="PD">Prievidza</option>
-<option value="PU">Puchov</option>
-<option value="RA">Revuca</option>
-<option value="RS">Rimavska Sobota</option>
-<option value="RV">Roznava</option>
-<option value="RK" selected="selected">Ruzomberok</option>
-<option value="SB">Sabinov</option>
-<option value="SC">Senec</option>
-<option value="SE">Senica</option>
-<option value="SI">Skalica</option>
-<option value="SV">Snina</option>
-<option value="SO">Sobrance</option>
-<option value="SN">Spisska Nova Ves</option>
-<option value="SL">Stara Lubovna</option>
-<option value="SP">Stropkov</option>
-<option value="SK">Svidnik</option>
-<option value="SA">Sala</option>
-<option value="TO">Topolcany</option>
-<option value="TV">Trebisov</option>
-<option value="TN">Trencin</option>
-<option value="TT">Trnava</option>
-<option value="TR">Turcianske Teplice</option>
-<option value="TS">Tvrdosin</option>
-<option value="VK">Velky Krtis</option>
-<option value="VT">Vranov nad Toplou</option>
-<option value="ZM">Zlate Moravce</option>
-<option value="ZV">Zvolen</option>
-<option value="ZC">Zarnovica</option>
-<option value="ZH">Ziar nad Hronom</option>
-<option value="ZA">Zilina</option>
-</select>'''
- self.assertHTMLEqual(f.render('Districts', 'RK'), out)
-
- def test_SKPostalCodeField(self):
- error_format = ['Enter a postal code in the format XXXXX or XXX XX.']
- valid = {
- '91909': '91909',
- '917 01': '91701',
- }
- invalid = {
- '84545x': error_format,
- }
- self.assertFieldOutput(SKPostalCodeField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/tests.py b/tests/regressiontests/localflavor/tests.py
index 856e518bed..52b771c405 100644
--- a/tests/regressiontests/localflavor/tests.py
+++ b/tests/regressiontests/localflavor/tests.py
@@ -1,45 +1,3 @@
from __future__ import absolute_import
-from .ar.tests import ARLocalFlavorTests
-from .at.tests import ATLocalFlavorTests
-from .au.tests import AULocalflavorTests
-from .be.tests import BELocalFlavorTests
-from .br.tests import BRLocalFlavorTests
-from .ca.tests import CALocalFlavorTests
-from .ch.tests import CHLocalFlavorTests
-from .cl.tests import CLLocalFlavorTests
-from .cn.tests import CNLocalFlavorTests
-from .co.tests import COLocalFlavorTests
-from .cz.tests import CZLocalFlavorTests
-from .de.tests import DELocalFlavorTests
-from .ec.tests import ECLocalFlavorTests
-from .es.tests import ESLocalFlavorTests
-from .fi.tests import FILocalFlavorTests
-from .fr.tests import FRLocalFlavorTests
-from .gb.tests import GBLocalFlavorTests
from .generic.tests import GenericLocalFlavorTests
-from .hk.tests import HKLocalFlavorTests
-from .hr.tests import HRLocalFlavorTests
-from .id.tests import IDLocalFlavorTests
-from .ie.tests import IELocalFlavorTests
-from .il.tests import ILLocalFlavorTests
-from .in_.tests import INLocalFlavorTests
-from .is_.tests import ISLocalFlavorTests
-from .it.tests import ITLocalFlavorTests
-from .jp.tests import JPLocalFlavorTests
-from .kw.tests import KWLocalFlavorTests
-from .mk.tests import MKLocalFlavorTests
-from .mx.tests import MXLocalFlavorTests
-from .nl.tests import NLLocalFlavorTests
-from .pl.tests import PLLocalFlavorTests
-from .pt.tests import PTLocalFlavorTests
-from .py.tests import PYLocalFlavorTests
-from .ro.tests import ROLocalFlavorTests
-from .ru.tests import RULocalFlavorTests
-from .se.tests import SELocalFlavorTests
-from .si.tests import SILocalFlavorTests
-from .sk.tests import SKLocalFlavorTests
-from .tr.tests import TRLocalFlavorTests
-from .us.tests import USLocalFlavorTests
-from .uy.tests import UYLocalFlavorTests
-from .za.tests import ZALocalFlavorTests
diff --git a/tests/regressiontests/localflavor/tr/__init__.py b/tests/regressiontests/localflavor/tr/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/tr/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/tr/tests.py b/tests/regressiontests/localflavor/tr/tests.py
deleted file mode 100644
index 476efc12ba..0000000000
--- a/tests/regressiontests/localflavor/tr/tests.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Tests for the contrib/localflavor/ TR form fields.
-
-from django.contrib.localflavor.tr import forms as trforms
-from django.core.exceptions import ValidationError
-from django.utils import six
-from django.utils.unittest import TestCase
-
-
-class TRLocalFlavorTests(TestCase):
- def test_TRPostalCodeField(self):
- f = trforms.TRPostalCodeField()
- self.assertEqual(f.clean("06531"), "06531")
- self.assertEqual(f.clean("12345"), "12345")
- six.assertRaisesRegex(self, ValidationError,
- "Enter a postal code in the format XXXXX.",
- f.clean, "a1234")
- six.assertRaisesRegex(self, ValidationError,
- "Enter a postal code in the format XXXXX.",
- f.clean, "1234")
- six.assertRaisesRegex(self, ValidationError,
- "Enter a postal code in the format XXXXX.",
- f.clean, "82123")
- six.assertRaisesRegex(self, ValidationError,
- "Enter a postal code in the format XXXXX.",
- f.clean, "00123")
- six.assertRaisesRegex(self, ValidationError,
- "Enter a postal code in the format XXXXX.",
- f.clean, "123456")
- six.assertRaisesRegex(self, ValidationError,
- "Enter a postal code in the format XXXXX.",
- f.clean, "12 34")
- self.assertRaises(ValidationError, f.clean, None)
-
- def test_TRPhoneNumberField(self):
- f = trforms.TRPhoneNumberField()
- self.assertEqual(f.clean("312 455 56 78"), "3124555678")
- self.assertEqual(f.clean("312 4555678"), "3124555678")
- self.assertEqual(f.clean("3124555678"), "3124555678")
- self.assertEqual(f.clean("0312 455 5678"), "3124555678")
- self.assertEqual(f.clean("0 312 455 5678"), "3124555678")
- self.assertEqual(f.clean("0 (312) 455 5678"), "3124555678")
- self.assertEqual(f.clean("+90 312 455 4567"), "3124554567")
- self.assertEqual(f.clean("+90 312 455 45 67"), "3124554567")
- self.assertEqual(f.clean("+90 (312) 4554567"), "3124554567")
- six.assertRaisesRegex(self, ValidationError,
- 'Phone numbers must be in 0XXX XXX XXXX format.',
- f.clean, "1234 233 1234")
- six.assertRaisesRegex(self, ValidationError,
- 'Phone numbers must be in 0XXX XXX XXXX format.',
- f.clean, "0312 233 12345")
- six.assertRaisesRegex(self, ValidationError,
- 'Phone numbers must be in 0XXX XXX XXXX format.',
- f.clean, "0312 233 123")
- six.assertRaisesRegex(self, ValidationError,
- 'Phone numbers must be in 0XXX XXX XXXX format.',
- f.clean, "0312 233 xxxx")
-
- def test_TRIdentificationNumberField(self):
- f = trforms.TRIdentificationNumberField()
- self.assertEqual(f.clean("10000000146"), "10000000146")
- six.assertRaisesRegex(self, ValidationError,
- 'Enter a valid Turkish Identification number.',
- f.clean, "10000000136")
- six.assertRaisesRegex(self, ValidationError,
- 'Enter a valid Turkish Identification number.',
- f.clean, "10000000147")
- six.assertRaisesRegex(self, ValidationError,
- 'Turkish Identification number must be 11 digits.',
- f.clean, "123456789")
- six.assertRaisesRegex(self, ValidationError,
- 'Enter a valid Turkish Identification number.',
- f.clean, "1000000014x")
- six.assertRaisesRegex(self, ValidationError,
- 'Enter a valid Turkish Identification number.',
- f.clean, "x0000000146")
diff --git a/tests/regressiontests/localflavor/us/__init__.py b/tests/regressiontests/localflavor/us/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/us/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/us/forms.py b/tests/regressiontests/localflavor/us/forms.py
deleted file mode 100644
index fe925c3c7b..0000000000
--- a/tests/regressiontests/localflavor/us/forms.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from __future__ import absolute_import
-
-from django.forms import ModelForm
-
-from .models import USPlace
-
-
-class USPlaceForm(ModelForm):
-
- class Meta:
- model = USPlace
diff --git a/tests/regressiontests/localflavor/us/models.py b/tests/regressiontests/localflavor/us/models.py
deleted file mode 100644
index ff48ed16bb..0000000000
--- a/tests/regressiontests/localflavor/us/models.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from django.contrib.localflavor.us.models import USStateField, USPostalCodeField
-from django.db import models
-
-# When creating models you need to remember to add a app_label as
-# 'localflavor', so your model can be found
-
-class USPlace(models.Model):
- state = USStateField(blank=True)
- state_req = USStateField()
- state_default = USStateField(default="CA", blank=True)
- postal_code = USPostalCodeField(blank=True)
- name = models.CharField(max_length=20)
-
- class Meta:
- app_label = 'localflavor'
diff --git a/tests/regressiontests/localflavor/us/tests.py b/tests/regressiontests/localflavor/us/tests.py
deleted file mode 100644
index 45967cb9dc..0000000000
--- a/tests/regressiontests/localflavor/us/tests.py
+++ /dev/null
@@ -1,286 +0,0 @@
-from __future__ import absolute_import, unicode_literals
-
-from django.contrib.localflavor.us.forms import (USZipCodeField,
- USPhoneNumberField, USStateField, USStateSelect,
- USSocialSecurityNumberField)
-from django.test import SimpleTestCase
-
-from .forms import USPlaceForm
-
-
-class USLocalFlavorTests(SimpleTestCase):
-
- def setUp(self):
- self.form = USPlaceForm({'state':'GA', 'state_req':'NC', 'postal_code': 'GA', 'name':'impossible'})
-
- def test_get_display_methods(self):
- """Test that the get_*_display() methods are added to the model instances."""
- place = self.form.save()
- self.assertEqual(place.get_state_display(), 'Georgia')
- self.assertEqual(place.get_state_req_display(), 'North Carolina')
-
- def test_required(self):
- """Test that required USStateFields throw appropriate errors."""
- form = USPlaceForm({'state':'GA', 'name':'Place in GA'})
- self.assertFalse(form.is_valid())
- self.assertEqual(form.errors['state_req'], ['This field is required.'])
-
- def test_field_blank_option(self):
- """Test that the empty option is there."""
- state_select_html = """\
-<select name="state" id="id_state">
-<option value="">---------</option>
-<option value="AL">Alabama</option>
-<option value="AK">Alaska</option>
-<option value="AS">American Samoa</option>
-<option value="AZ">Arizona</option>
-<option value="AR">Arkansas</option>
-<option value="AA">Armed Forces Americas</option>
-<option value="AE">Armed Forces Europe</option>
-<option value="AP">Armed Forces Pacific</option>
-<option value="CA">California</option>
-<option value="CO">Colorado</option>
-<option value="CT">Connecticut</option>
-<option value="DE">Delaware</option>
-<option value="DC">District of Columbia</option>
-<option value="FL">Florida</option>
-<option value="GA" selected="selected">Georgia</option>
-<option value="GU">Guam</option>
-<option value="HI">Hawaii</option>
-<option value="ID">Idaho</option>
-<option value="IL">Illinois</option>
-<option value="IN">Indiana</option>
-<option value="IA">Iowa</option>
-<option value="KS">Kansas</option>
-<option value="KY">Kentucky</option>
-<option value="LA">Louisiana</option>
-<option value="ME">Maine</option>
-<option value="MD">Maryland</option>
-<option value="MA">Massachusetts</option>
-<option value="MI">Michigan</option>
-<option value="MN">Minnesota</option>
-<option value="MS">Mississippi</option>
-<option value="MO">Missouri</option>
-<option value="MT">Montana</option>
-<option value="NE">Nebraska</option>
-<option value="NV">Nevada</option>
-<option value="NH">New Hampshire</option>
-<option value="NJ">New Jersey</option>
-<option value="NM">New Mexico</option>
-<option value="NY">New York</option>
-<option value="NC">North Carolina</option>
-<option value="ND">North Dakota</option>
-<option value="MP">Northern Mariana Islands</option>
-<option value="OH">Ohio</option>
-<option value="OK">Oklahoma</option>
-<option value="OR">Oregon</option>
-<option value="PA">Pennsylvania</option>
-<option value="PR">Puerto Rico</option>
-<option value="RI">Rhode Island</option>
-<option value="SC">South Carolina</option>
-<option value="SD">South Dakota</option>
-<option value="TN">Tennessee</option>
-<option value="TX">Texas</option>
-<option value="UT">Utah</option>
-<option value="VT">Vermont</option>
-<option value="VI">Virgin Islands</option>
-<option value="VA">Virginia</option>
-<option value="WA">Washington</option>
-<option value="WV">West Virginia</option>
-<option value="WI">Wisconsin</option>
-<option value="WY">Wyoming</option>
-</select>"""
- self.assertHTMLEqual(str(self.form['state']), state_select_html)
-
- def test_full_postal_code_list(self):
- """Test that the full USPS code field is really the full list."""
- usps_select_html = """\
-<select name="postal_code" id="id_postal_code">
-<option value="">---------</option>
-<option value="AL">Alabama</option>
-<option value="AK">Alaska</option>
-<option value="AS">American Samoa</option>
-<option value="AZ">Arizona</option>
-<option value="AR">Arkansas</option>
-<option value="AA">Armed Forces Americas</option>
-<option value="AE">Armed Forces Europe</option>
-<option value="AP">Armed Forces Pacific</option>
-<option value="CA">California</option>
-<option value="CO">Colorado</option>
-<option value="CT">Connecticut</option>
-<option value="DE">Delaware</option>
-<option value="DC">District of Columbia</option>
-<option value="FM">Federated States of Micronesia</option>
-<option value="FL">Florida</option>
-<option value="GA" selected="selected">Georgia</option>
-<option value="GU">Guam</option>
-<option value="HI">Hawaii</option>
-<option value="ID">Idaho</option>
-<option value="IL">Illinois</option>
-<option value="IN">Indiana</option>
-<option value="IA">Iowa</option>
-<option value="KS">Kansas</option>
-<option value="KY">Kentucky</option>
-<option value="LA">Louisiana</option>
-<option value="ME">Maine</option>
-<option value="MH">Marshall Islands</option>
-<option value="MD">Maryland</option>
-<option value="MA">Massachusetts</option>
-<option value="MI">Michigan</option>
-<option value="MN">Minnesota</option>
-<option value="MS">Mississippi</option>
-<option value="MO">Missouri</option>
-<option value="MT">Montana</option>
-<option value="NE">Nebraska</option>
-<option value="NV">Nevada</option>
-<option value="NH">New Hampshire</option>
-<option value="NJ">New Jersey</option>
-<option value="NM">New Mexico</option>
-<option value="NY">New York</option>
-<option value="NC">North Carolina</option>
-<option value="ND">North Dakota</option>
-<option value="MP">Northern Mariana Islands</option>
-<option value="OH">Ohio</option>
-<option value="OK">Oklahoma</option>
-<option value="OR">Oregon</option>
-<option value="PW">Palau</option>
-<option value="PA">Pennsylvania</option>
-<option value="PR">Puerto Rico</option>
-<option value="RI">Rhode Island</option>
-<option value="SC">South Carolina</option>
-<option value="SD">South Dakota</option>
-<option value="TN">Tennessee</option>
-<option value="TX">Texas</option>
-<option value="UT">Utah</option>
-<option value="VT">Vermont</option>
-<option value="VI">Virgin Islands</option>
-<option value="VA">Virginia</option>
-<option value="WA">Washington</option>
-<option value="WV">West Virginia</option>
-<option value="WI">Wisconsin</option>
-<option value="WY">Wyoming</option>
-</select>"""
- self.assertHTMLEqual(str(self.form['postal_code']), usps_select_html)
-
- def test_USStateSelect(self):
- f = USStateSelect()
- out = '''<select name="state">
-<option value="AL">Alabama</option>
-<option value="AK">Alaska</option>
-<option value="AS">American Samoa</option>
-<option value="AZ">Arizona</option>
-<option value="AR">Arkansas</option>
-<option value="AA">Armed Forces Americas</option>
-<option value="AE">Armed Forces Europe</option>
-<option value="AP">Armed Forces Pacific</option>
-<option value="CA">California</option>
-<option value="CO">Colorado</option>
-<option value="CT">Connecticut</option>
-<option value="DE">Delaware</option>
-<option value="DC">District of Columbia</option>
-<option value="FL">Florida</option>
-<option value="GA">Georgia</option>
-<option value="GU">Guam</option>
-<option value="HI">Hawaii</option>
-<option value="ID">Idaho</option>
-<option value="IL" selected="selected">Illinois</option>
-<option value="IN">Indiana</option>
-<option value="IA">Iowa</option>
-<option value="KS">Kansas</option>
-<option value="KY">Kentucky</option>
-<option value="LA">Louisiana</option>
-<option value="ME">Maine</option>
-<option value="MD">Maryland</option>
-<option value="MA">Massachusetts</option>
-<option value="MI">Michigan</option>
-<option value="MN">Minnesota</option>
-<option value="MS">Mississippi</option>
-<option value="MO">Missouri</option>
-<option value="MT">Montana</option>
-<option value="NE">Nebraska</option>
-<option value="NV">Nevada</option>
-<option value="NH">New Hampshire</option>
-<option value="NJ">New Jersey</option>
-<option value="NM">New Mexico</option>
-<option value="NY">New York</option>
-<option value="NC">North Carolina</option>
-<option value="ND">North Dakota</option>
-<option value="MP">Northern Mariana Islands</option>
-<option value="OH">Ohio</option>
-<option value="OK">Oklahoma</option>
-<option value="OR">Oregon</option>
-<option value="PA">Pennsylvania</option>
-<option value="PR">Puerto Rico</option>
-<option value="RI">Rhode Island</option>
-<option value="SC">South Carolina</option>
-<option value="SD">South Dakota</option>
-<option value="TN">Tennessee</option>
-<option value="TX">Texas</option>
-<option value="UT">Utah</option>
-<option value="VT">Vermont</option>
-<option value="VI">Virgin Islands</option>
-<option value="VA">Virginia</option>
-<option value="WA">Washington</option>
-<option value="WV">West Virginia</option>
-<option value="WI">Wisconsin</option>
-<option value="WY">Wyoming</option>
-</select>'''
- self.assertHTMLEqual(f.render('state', 'IL'), out)
-
- def test_USZipCodeField(self):
- error_format = ['Enter a zip code in the format XXXXX or XXXXX-XXXX.']
- valid = {
- '60606': '60606',
- 60606: '60606',
- '04000': '04000',
- '60606-1234': '60606-1234',
- }
- invalid = {
- '4000': error_format,
- '6060-1234': error_format,
- '60606-': error_format,
- }
- self.assertFieldOutput(USZipCodeField, valid, invalid)
-
- def test_USPhoneNumberField(self):
- error_format = ['Phone numbers must be in XXX-XXX-XXXX format.']
- valid = {
- '312-555-1212': '312-555-1212',
- '3125551212': '312-555-1212',
- '312 555-1212': '312-555-1212',
- '(312) 555-1212': '312-555-1212',
- '312 555 1212': '312-555-1212',
- '312.555.1212': '312-555-1212',
- '312.555-1212': '312-555-1212',
- ' (312) 555.1212 ': '312-555-1212',
- }
- invalid = {
- '555-1212': error_format,
- '312-55-1212': error_format,
- }
- self.assertFieldOutput(USPhoneNumberField, valid, invalid)
-
- def test_USStateField(self):
- error_invalid = ['Enter a U.S. state or territory.']
- valid = {
- 'il': 'IL',
- 'IL': 'IL',
- 'illinois': 'IL',
- ' illinois ': 'IL',
- }
- invalid = {
- 60606: error_invalid,
- }
- self.assertFieldOutput(USStateField, valid, invalid)
-
- def test_USSocialSecurityNumberField(self):
- error_invalid = ['Enter a valid U.S. Social Security number in XXX-XX-XXXX format.']
-
- valid = {
- '987-65-4330': '987-65-4330',
- '987654330': '987-65-4330',
- }
- invalid = {
- '078-05-1120': error_invalid,
- }
- self.assertFieldOutput(USSocialSecurityNumberField, valid, invalid)
diff --git a/tests/regressiontests/localflavor/uy/__init__.py b/tests/regressiontests/localflavor/uy/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/uy/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/uy/tests.py b/tests/regressiontests/localflavor/uy/tests.py
deleted file mode 100644
index 5bbbbe4122..0000000000
--- a/tests/regressiontests/localflavor/uy/tests.py
+++ /dev/null
@@ -1,53 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.uy.forms import UYDepartamentSelect, UYCIField
-from django.contrib.localflavor.uy.util import get_validation_digit
-
-from django.test import SimpleTestCase
-
-
-class UYLocalFlavorTests(SimpleTestCase):
- def test_UYDepartmentSelect(self):
- f = UYDepartamentSelect()
- out = '''<select name="departamentos">
-<option value="G">Artigas</option>
-<option value="A">Canelones</option>
-<option value="E">Cerro Largo</option>
-<option value="L">Colonia</option>
-<option value="Q">Durazno</option>
-<option value="N">Flores</option>
-<option value="O">Florida</option>
-<option value="P">Lavalleja</option>
-<option value="B">Maldonado</option>
-<option value="S" selected="selected">Montevideo</option>
-<option value="I">Paysand\xfa</option>
-<option value="J">R\xedo Negro</option>
-<option value="F">Rivera</option>
-<option value="C">Rocha</option>
-<option value="H">Salto</option>
-<option value="M">San Jos\xe9</option>
-<option value="K">Soriano</option>
-<option value="R">Tacuaremb\xf3</option>
-<option value="D">Treinta y Tres</option>
-</select>'''
- self.assertHTMLEqual(f.render('departamentos', 'S'), out)
-
- def test_UYCIField(self):
- error_format = ['Enter a valid CI number in X.XXX.XXX-X,XXXXXXX-X or XXXXXXXX format.']
- error_invalid = ['Enter a valid CI number.']
- valid = {
- '4098053': '4098053',
- '409805-3': '409805-3',
- '409.805-3': '409.805-3',
- '10054112': '10054112',
- '1005411-2': '1005411-2',
- '1.005.411-2': '1.005.411-2',
- }
- invalid = {
- 'foo': ['Enter a valid CI number in X.XXX.XXX-X,XXXXXXX-X or XXXXXXXX format.'],
- '409805-2': ['Enter a valid CI number.'],
- '1.005.411-5': ['Enter a valid CI number.'],
- }
- self.assertFieldOutput(UYCIField, valid, invalid)
- self.assertEqual(get_validation_digit(409805), 3)
- self.assertEqual(get_validation_digit(1005411), 2)
diff --git a/tests/regressiontests/localflavor/za/__init__.py b/tests/regressiontests/localflavor/za/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/tests/regressiontests/localflavor/za/__init__.py
+++ /dev/null
diff --git a/tests/regressiontests/localflavor/za/tests.py b/tests/regressiontests/localflavor/za/tests.py
deleted file mode 100644
index 81e8d65eec..0000000000
--- a/tests/regressiontests/localflavor/za/tests.py
+++ /dev/null
@@ -1,31 +0,0 @@
-from __future__ import unicode_literals
-
-from django.contrib.localflavor.za.forms import ZAIDField, ZAPostCodeField
-
-from django.test import SimpleTestCase
-
-
-class ZALocalFlavorTests(SimpleTestCase):
- def test_ZAIDField(self):
- error_invalid = ['Enter a valid South African ID number']
- valid = {
- '0002290001003': '0002290001003',
- '000229 0001 003': '0002290001003',
- }
- invalid = {
- '0102290001001': error_invalid,
- '811208': error_invalid,
- '0002290001004': error_invalid,
- }
- self.assertFieldOutput(ZAIDField, valid, invalid)
-
- def test_ZAPostCodeField(self):
- error_invalid = ['Enter a valid South African postal code']
- valid = {
- '0000': '0000',
- }
- invalid = {
- 'abcd': error_invalid,
- ' 7530': error_invalid,
- }
- self.assertFieldOutput(ZAPostCodeField, valid, invalid)
diff --git a/tests/regressiontests/logging_tests/logconfig.py b/tests/regressiontests/logging_tests/logconfig.py
new file mode 100644
index 0000000000..fc5ea1a0bd
--- /dev/null
+++ b/tests/regressiontests/logging_tests/logconfig.py
@@ -0,0 +1,8 @@
+import logging
+
+from django.conf import settings
+
+class MyHandler(logging.Handler):
+ def __init__(self):
+ logging.Handler.__init__(self)
+ self.config = settings.LOGGING
diff --git a/tests/regressiontests/logging_tests/tests.py b/tests/regressiontests/logging_tests/tests.py
index 4ae3c1b1a9..e40800efde 100644
--- a/tests/regressiontests/logging_tests/tests.py
+++ b/tests/regressiontests/logging_tests/tests.py
@@ -1,13 +1,17 @@
from __future__ import unicode_literals
import copy
+import logging
import warnings
from django.conf import compat_patch_logging_config
from django.core import mail
from django.test import TestCase, RequestFactory
from django.test.utils import override_settings
-from django.utils.log import CallbackFilter, RequireDebugFalse, getLogger
+from django.utils.log import CallbackFilter, RequireDebugFalse
+from django.utils.six import StringIO
+
+from ..admin_scripts.tests import AdminScriptTestCase
# logging config prior to using filter with mail_admins
@@ -106,6 +110,28 @@ class PatchLoggingConfigTest(TestCase):
self.assertEqual(config, new_config)
+class DefaultLoggingTest(TestCase):
+ def setUp(self):
+ self.logger = logging.getLogger('django')
+ self.old_stream = self.logger.handlers[0].stream
+
+ def tearDown(self):
+ self.logger.handlers[0].stream = self.old_stream
+
+ def test_django_logger(self):
+ """
+ The 'django' base logger only output anything when DEBUG=True.
+ """
+ output = StringIO()
+ self.logger.handlers[0].stream = output
+ self.logger.error("Hey, this is an error.")
+ self.assertEqual(output.getvalue(), '')
+
+ with self.settings(DEBUG=True):
+ self.logger.error("Hey, this is an error.")
+ self.assertEqual(output.getvalue(), 'Hey, this is an error.\n')
+
+
class CallbackFilterTest(TestCase):
def test_sense(self):
f_false = CallbackFilter(lambda r: False)
@@ -128,6 +154,7 @@ class CallbackFilterTest(TestCase):
class AdminEmailHandlerTest(TestCase):
+ logger = logging.getLogger('django.request')
def get_admin_email_handler(self, logger):
# Inspired from regressiontests/views/views.py: send_log()
@@ -153,14 +180,13 @@ class AdminEmailHandlerTest(TestCase):
token1 = 'ping'
token2 = 'pong'
- logger = getLogger('django.request')
- admin_email_handler = self.get_admin_email_handler(logger)
+ admin_email_handler = self.get_admin_email_handler(self.logger)
# Backup then override original filters
orig_filters = admin_email_handler.filters
try:
admin_email_handler.filters = []
- logger.error(message, token1, token2)
+ self.logger.error(message, token1, token2)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].to, ['admin@example.com'])
@@ -184,15 +210,14 @@ class AdminEmailHandlerTest(TestCase):
token1 = 'ping'
token2 = 'pong'
- logger = getLogger('django.request')
- admin_email_handler = self.get_admin_email_handler(logger)
+ admin_email_handler = self.get_admin_email_handler(self.logger)
# Backup then override original filters
orig_filters = admin_email_handler.filters
try:
admin_email_handler.filters = []
rf = RequestFactory()
request = rf.get('/')
- logger.error(message, token1, token2,
+ self.logger.error(message, token1, token2,
extra={
'status_code': 403,
'request': request,
@@ -222,8 +247,7 @@ class AdminEmailHandlerTest(TestCase):
self.assertEqual(len(mail.outbox), 0)
- logger = getLogger('django.request')
- logger.error(message)
+ self.logger.error(message)
self.assertEqual(len(mail.outbox), 1)
self.assertFalse('\n' in mail.outbox[0].subject)
@@ -247,8 +271,34 @@ class AdminEmailHandlerTest(TestCase):
self.assertEqual(len(mail.outbox), 0)
- logger = getLogger('django.request')
- logger.error(message)
+ self.logger.error(message)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, expected_subject)
+
+
+class SettingsConfigTest(AdminScriptTestCase):
+ """
+ Test that accessing settings in a custom logging handler does not trigger
+ a circular import error.
+ """
+ def setUp(self):
+ log_config = """{
+ 'version': 1,
+ 'handlers': {
+ 'custom_handler': {
+ 'level': 'INFO',
+ 'class': 'logging_tests.logconfig.MyHandler',
+ }
+ }
+}"""
+ self.write_settings('settings.py', sdict={'LOGGING': log_config})
+
+ def tearDown(self):
+ self.remove_settings('settings.py')
+
+ def test_circular_dependency(self):
+ # validate is just an example command to trigger settings configuration
+ out, err = self.run_manage(['validate'])
+ self.assertNoOutput(err)
+ self.assertOutput(out, "0 errors found")
diff --git a/tests/regressiontests/mail/tests.py b/tests/regressiontests/mail/tests.py
index 3e9ae84650..33898cc1d5 100644
--- a/tests/regressiontests/mail/tests.py
+++ b/tests/regressiontests/mail/tests.py
@@ -498,6 +498,11 @@ class LocmemBackendTests(BaseEmailBackendTests, TestCase):
connection2.send_messages([email])
self.assertEqual(len(mail.outbox), 2)
+ def test_validate_multiline_headers(self):
+ # Ticket #18861 - Validate emails when using the locmem backend
+ with self.assertRaises(BadHeaderError):
+ send_mail('Subject\nMultiline', 'Content', 'from@example.com', ['to@example.com'])
+
class FileBackendTests(BaseEmailBackendTests, TestCase):
email_backend = 'django.core.mail.backends.filebased.EmailBackend'
diff --git a/tests/regressiontests/managers_regress/models.py b/tests/regressiontests/managers_regress/models.py
index 892505f24a..d72970d86e 100644
--- a/tests/regressiontests/managers_regress/models.py
+++ b/tests/regressiontests/managers_regress/models.py
@@ -10,14 +10,17 @@ class OnlyFred(models.Manager):
def get_query_set(self):
return super(OnlyFred, self).get_query_set().filter(name='fred')
+
class OnlyBarney(models.Manager):
def get_query_set(self):
return super(OnlyBarney, self).get_query_set().filter(name='barney')
+
class Value42(models.Manager):
def get_query_set(self):
return super(Value42, self).get_query_set().filter(value=42)
+
class AbstractBase1(models.Model):
name = models.CharField(max_length=50)
@@ -29,6 +32,7 @@ class AbstractBase1(models.Model):
manager2 = OnlyBarney()
objects = models.Manager()
+
class AbstractBase2(models.Model):
value = models.IntegerField()
@@ -38,6 +42,7 @@ class AbstractBase2(models.Model):
# Custom manager
restricted = Value42()
+
# No custom manager on this class to make sure the default case doesn't break.
class AbstractBase3(models.Model):
comment = models.CharField(max_length=50)
@@ -45,6 +50,7 @@ class AbstractBase3(models.Model):
class Meta:
abstract = True
+
@python_2_unicode_compatible
class Parent(models.Model):
name = models.CharField(max_length=50)
@@ -54,6 +60,7 @@ class Parent(models.Model):
def __str__(self):
return self.name
+
# Managers from base classes are inherited and, if no manager is specified
# *and* the parent has a manager specified, the first one (in the MRO) will
# become the default.
@@ -64,6 +71,7 @@ class Child1(AbstractBase1):
def __str__(self):
return self.data
+
@python_2_unicode_compatible
class Child2(AbstractBase1, AbstractBase2):
data = models.CharField(max_length=25)
@@ -71,6 +79,7 @@ class Child2(AbstractBase1, AbstractBase2):
def __str__(self):
return self.data
+
@python_2_unicode_compatible
class Child3(AbstractBase1, AbstractBase3):
data = models.CharField(max_length=25)
@@ -78,6 +87,7 @@ class Child3(AbstractBase1, AbstractBase3):
def __str__(self):
return self.data
+
@python_2_unicode_compatible
class Child4(AbstractBase1):
data = models.CharField(max_length=25)
@@ -89,6 +99,7 @@ class Child4(AbstractBase1):
def __str__(self):
return self.data
+
@python_2_unicode_compatible
class Child5(AbstractBase3):
name = models.CharField(max_length=25)
@@ -99,10 +110,12 @@ class Child5(AbstractBase3):
def __str__(self):
return self.name
+
# Will inherit managers from AbstractBase1, but not Child4.
class Child6(Child4):
value = models.IntegerField()
+
# Will not inherit default manager from parent.
class Child7(Parent):
pass
diff --git a/tests/regressiontests/managers_regress/tests.py b/tests/regressiontests/managers_regress/tests.py
index dd6cb66857..f3721a4c01 100644
--- a/tests/regressiontests/managers_regress/tests.py
+++ b/tests/regressiontests/managers_regress/tests.py
@@ -1,26 +1,42 @@
from __future__ import absolute_import
+import copy
+from django.conf import settings
+from django.db import models
+from django.db.models.loading import cache
from django.test import TestCase
+from django.test.utils import override_settings
-from .models import Child1, Child2, Child3, Child4, Child5, Child6, Child7
+from .models import (
+ Child1,
+ Child2,
+ Child3,
+ Child4,
+ Child5,
+ Child6,
+ Child7,
+ AbstractBase1,
+ AbstractBase2,
+ AbstractBase3,
+)
class ManagersRegressionTests(TestCase):
def test_managers(self):
- a1 = Child1.objects.create(name='fred', data='a1')
- a2 = Child1.objects.create(name='barney', data='a2')
- b1 = Child2.objects.create(name='fred', data='b1', value=1)
- b2 = Child2.objects.create(name='barney', data='b2', value=42)
- c1 = Child3.objects.create(name='fred', data='c1', comment='yes')
- c2 = Child3.objects.create(name='barney', data='c2', comment='no')
- d1 = Child4.objects.create(name='fred', data='d1')
- d2 = Child4.objects.create(name='barney', data='d2')
- e1 = Child5.objects.create(name='fred', comment='yes')
- e2 = Child5.objects.create(name='barney', comment='no')
- f1 = Child6.objects.create(name='fred', data='f1', value=42)
- f2 = Child6.objects.create(name='barney', data='f2', value=42)
- g1 = Child7.objects.create(name='fred')
- g2 = Child7.objects.create(name='barney')
+ Child1.objects.create(name='fred', data='a1')
+ Child1.objects.create(name='barney', data='a2')
+ Child2.objects.create(name='fred', data='b1', value=1)
+ Child2.objects.create(name='barney', data='b2', value=42)
+ Child3.objects.create(name='fred', data='c1', comment='yes')
+ Child3.objects.create(name='barney', data='c2', comment='no')
+ Child4.objects.create(name='fred', data='d1')
+ Child4.objects.create(name='barney', data='d2')
+ Child5.objects.create(name='fred', comment='yes')
+ Child5.objects.create(name='barney', comment='no')
+ Child6.objects.create(name='fred', data='f1', value=42)
+ Child6.objects.create(name='barney', data='f2', value=42)
+ Child7.objects.create(name='fred')
+ Child7.objects.create(name='barney')
self.assertQuerysetEqual(Child1.manager1.all(), ["<Child1: a1>"])
self.assertQuerysetEqual(Child1.manager2.all(), ["<Child1: a2>"])
@@ -54,3 +70,125 @@ class ManagersRegressionTests(TestCase):
"<Child7: fred>"
]
)
+
+ def test_abstract_manager(self):
+ # Accessing the manager on an abstract model should
+ # raise an attribute error with an appropriate message.
+ try:
+ AbstractBase3.objects.all()
+ self.fail('Should raise an AttributeError')
+ except AttributeError as e:
+ # This error message isn't ideal, but if the model is abstract and
+ # a lot of the class instantiation logic isn't invoked; if the
+ # manager is implied, then we don't get a hook to install the
+ # error-raising manager.
+ self.assertEqual(str(e), "type object 'AbstractBase3' has no attribute 'objects'")
+
+ def test_custom_abstract_manager(self):
+ # Accessing the manager on an abstract model with an custom
+ # manager should raise an attribute error with an appropriate
+ # message.
+ try:
+ AbstractBase2.restricted.all()
+ self.fail('Should raise an AttributeError')
+ except AttributeError as e:
+ self.assertEqual(str(e), "Manager isn't available; AbstractBase2 is abstract")
+
+ def test_explicit_abstract_manager(self):
+ # Accessing the manager on an abstract model with an explicit
+ # manager should raise an attribute error with an appropriate
+ # message.
+ try:
+ AbstractBase1.objects.all()
+ self.fail('Should raise an AttributeError')
+ except AttributeError as e:
+ self.assertEqual(str(e), "Manager isn't available; AbstractBase1 is abstract")
+
+ def test_swappable_manager(self):
+ try:
+ # This test adds dummy models to the app cache. These
+ # need to be removed in order to prevent bad interactions
+ # with the flush operation in other tests.
+ old_app_models = copy.deepcopy(cache.app_models)
+ old_app_store = copy.deepcopy(cache.app_store)
+
+ settings.TEST_SWAPPABLE_MODEL = 'managers_regress.Parent'
+
+ class SwappableModel(models.Model):
+ class Meta:
+ swappable = 'TEST_SWAPPABLE_MODEL'
+
+ # Accessing the manager on a swappable model should
+ # raise an attribute error with a helpful message
+ try:
+ SwappableModel.objects.all()
+ self.fail('Should raise an AttributeError')
+ except AttributeError as e:
+ self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'")
+
+ finally:
+ del settings.TEST_SWAPPABLE_MODEL
+ cache.app_models = old_app_models
+ cache.app_store = old_app_store
+
+ def test_custom_swappable_manager(self):
+ try:
+ # This test adds dummy models to the app cache. These
+ # need to be removed in order to prevent bad interactions
+ # with the flush operation in other tests.
+ old_app_models = copy.deepcopy(cache.app_models)
+ old_app_store = copy.deepcopy(cache.app_store)
+
+ settings.TEST_SWAPPABLE_MODEL = 'managers_regress.Parent'
+
+ class SwappableModel(models.Model):
+
+ stuff = models.Manager()
+
+ class Meta:
+ swappable = 'TEST_SWAPPABLE_MODEL'
+
+ # Accessing the manager on a swappable model with an
+ # explicit manager should raise an attribute error with a
+ # helpful message
+ try:
+ SwappableModel.stuff.all()
+ self.fail('Should raise an AttributeError')
+ except AttributeError as e:
+ self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'")
+
+ finally:
+ del settings.TEST_SWAPPABLE_MODEL
+ cache.app_models = old_app_models
+ cache.app_store = old_app_store
+
+ def test_explicit_swappable_manager(self):
+ try:
+ # This test adds dummy models to the app cache. These
+ # need to be removed in order to prevent bad interactions
+ # with the flush operation in other tests.
+ old_app_models = copy.deepcopy(cache.app_models)
+ old_app_store = copy.deepcopy(cache.app_store)
+
+ settings.TEST_SWAPPABLE_MODEL = 'managers_regress.Parent'
+
+ class SwappableModel(models.Model):
+
+ objects = models.Manager()
+
+ class Meta:
+ swappable = 'TEST_SWAPPABLE_MODEL'
+
+ # Accessing the manager on a swappable model with an
+ # explicit manager should raise an attribute error with a
+ # helpful message
+ try:
+ SwappableModel.objects.all()
+ self.fail('Should raise an AttributeError')
+ except AttributeError as e:
+ self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'")
+
+ finally:
+ del settings.TEST_SWAPPABLE_MODEL
+ cache.app_models = old_app_models
+ cache.app_store = old_app_store
diff --git a/tests/regressiontests/middleware/tests.py b/tests/regressiontests/middleware/tests.py
index eb66f2bbf3..de901f4a80 100644
--- a/tests/regressiontests/middleware/tests.py
+++ b/tests/regressiontests/middleware/tests.py
@@ -8,7 +8,7 @@ from io import BytesIO
from django.conf import settings
from django.core import mail
from django.http import HttpRequest
-from django.http import HttpResponse
+from django.http import HttpResponse, StreamingHttpResponse
from django.middleware.clickjacking import XFrameOptionsMiddleware
from django.middleware.common import CommonMiddleware
from django.middleware.http import ConditionalGetMiddleware
@@ -322,6 +322,12 @@ class ConditionalGetMiddlewareTest(TestCase):
self.assertTrue('Content-Length' in self.resp)
self.assertEqual(int(self.resp['Content-Length']), content_length)
+ def test_content_length_header_not_added(self):
+ resp = StreamingHttpResponse('content')
+ self.assertFalse('Content-Length' in resp)
+ resp = ConditionalGetMiddleware().process_response(self.req, resp)
+ self.assertFalse('Content-Length' in resp)
+
def test_content_length_header_not_changed(self):
bad_content_length = len(self.resp.content) + 10
self.resp['Content-Length'] = bad_content_length
@@ -351,6 +357,29 @@ class ConditionalGetMiddlewareTest(TestCase):
self.resp = ConditionalGetMiddleware().process_response(self.req, self.resp)
self.assertEqual(self.resp.status_code, 200)
+ @override_settings(USE_ETAGS=True)
+ def test_etag(self):
+ req = HttpRequest()
+ res = HttpResponse('content')
+ self.assertTrue(
+ CommonMiddleware().process_response(req, res).has_header('ETag'))
+
+ @override_settings(USE_ETAGS=True)
+ def test_etag_streaming_response(self):
+ req = HttpRequest()
+ res = StreamingHttpResponse(['content'])
+ res['ETag'] = 'tomatoes'
+ self.assertEqual(
+ CommonMiddleware().process_response(req, res).get('ETag'),
+ 'tomatoes')
+
+ @override_settings(USE_ETAGS=True)
+ def test_no_etag_streaming_response(self):
+ req = HttpRequest()
+ res = StreamingHttpResponse(['content'])
+ self.assertFalse(
+ CommonMiddleware().process_response(req, res).has_header('ETag'))
+
# Tests for the Last-Modified header
def test_if_modified_since_and_no_last_modified(self):
@@ -511,6 +540,7 @@ class GZipMiddlewareTest(TestCase):
short_string = b"This string is too short to be worth compressing."
compressible_string = b'a' * 500
uncompressible_string = b''.join(six.int2byte(random.randint(0, 255)) for _ in xrange(500))
+ sequence = [b'a' * 500, b'b' * 200, b'a' * 300]
def setUp(self):
self.req = HttpRequest()
@@ -525,6 +555,8 @@ class GZipMiddlewareTest(TestCase):
self.resp.status_code = 200
self.resp.content = self.compressible_string
self.resp['Content-Type'] = 'text/html; charset=UTF-8'
+ self.stream_resp = StreamingHttpResponse(self.sequence)
+ self.stream_resp['Content-Type'] = 'text/html; charset=UTF-8'
@staticmethod
def decompress(gzipped_string):
@@ -539,6 +571,15 @@ class GZipMiddlewareTest(TestCase):
self.assertEqual(r.get('Content-Encoding'), 'gzip')
self.assertEqual(r.get('Content-Length'), str(len(r.content)))
+ def test_compress_streaming_response(self):
+ """
+ Tests that compression is performed on responses with streaming content.
+ """
+ r = GZipMiddleware().process_response(self.req, self.stream_resp)
+ self.assertEqual(self.decompress(b''.join(r)), b''.join(self.sequence))
+ self.assertEqual(r.get('Content-Encoding'), 'gzip')
+ self.assertFalse(r.has_header('Content-Length'))
+
def test_compress_non_200_response(self):
"""
Tests that compression is performed on responses with a status other than 200.
diff --git a/tests/regressiontests/model_fields/models.py b/tests/regressiontests/model_fields/models.py
index d9c123fb39..1d20f44fae 100644
--- a/tests/regressiontests/model_fields/models.py
+++ b/tests/regressiontests/model_fields/models.py
@@ -66,6 +66,11 @@ class BooleanModel(models.Model):
bfield = models.BooleanField()
string = models.CharField(max_length=10, default='abc')
+class FksToBooleans(models.Model):
+ """Model wih FKs to models with {Null,}BooleanField's, #15040"""
+ bf = models.ForeignKey(BooleanModel)
+ nbf = models.ForeignKey(NullBooleanModel)
+
class RenamedField(models.Model):
modelname = models.IntegerField(name="fieldname", choices=((1,'One'),))
diff --git a/tests/regressiontests/model_fields/tests.py b/tests/regressiontests/model_fields/tests.py
index 526aca4f98..a49894e36c 100644
--- a/tests/regressiontests/model_fields/tests.py
+++ b/tests/regressiontests/model_fields/tests.py
@@ -12,7 +12,8 @@ from django.utils import six
from django.utils import unittest
from .models import (Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post,
- NullBooleanModel, BooleanModel, Document, RenamedField, VerboseNameField)
+ NullBooleanModel, BooleanModel, Document, RenamedField, VerboseNameField,
+ FksToBooleans)
from .imagefield import (ImageFieldTests, ImageFieldTwoDimensionsTests,
TwoImageFieldTests, ImageFieldNoDimensionsTests,
@@ -218,6 +219,43 @@ class BooleanFieldTests(unittest.TestCase):
select={'string_col': 'string'})[0]
self.assertFalse(isinstance(b5.pk, bool))
+ def test_select_related(self):
+ """
+ Test type of boolean fields when retrieved via select_related() (MySQL,
+ #15040)
+ """
+ bmt = BooleanModel.objects.create(bfield=True)
+ bmf = BooleanModel.objects.create(bfield=False)
+ nbmt = NullBooleanModel.objects.create(nbfield=True)
+ nbmf = NullBooleanModel.objects.create(nbfield=False)
+
+ m1 = FksToBooleans.objects.create(bf=bmt, nbf=nbmt)
+ m2 = FksToBooleans.objects.create(bf=bmf, nbf=nbmf)
+
+ # Test select_related('fk_field_name')
+ ma = FksToBooleans.objects.select_related('bf').get(pk=m1.id)
+ # verify types -- should't be 0/1
+ self.assertIsInstance(ma.bf.bfield, bool)
+ self.assertIsInstance(ma.nbf.nbfield, bool)
+ # verify values
+ self.assertEqual(ma.bf.bfield, True)
+ self.assertEqual(ma.nbf.nbfield, True)
+
+ # Test select_related()
+ mb = FksToBooleans.objects.select_related().get(pk=m1.id)
+ mc = FksToBooleans.objects.select_related().get(pk=m2.id)
+ # verify types -- shouldn't be 0/1
+ self.assertIsInstance(mb.bf.bfield, bool)
+ self.assertIsInstance(mb.nbf.nbfield, bool)
+ self.assertIsInstance(mc.bf.bfield, bool)
+ self.assertIsInstance(mc.nbf.nbfield, bool)
+ # verify values
+ self.assertEqual(mb.bf.bfield, True)
+ self.assertEqual(mb.nbf.nbfield, True)
+ self.assertEqual(mc.bf.bfield, False)
+ self.assertEqual(mc.nbf.nbfield, False)
+
+
class ChoicesTests(test.TestCase):
def test_choices_and_field_display(self):
"""
diff --git a/tests/regressiontests/multiple_database/tests.py b/tests/regressiontests/multiple_database/tests.py
index 782fe2bfc6..79fe6beebd 100644
--- a/tests/regressiontests/multiple_database/tests.py
+++ b/tests/regressiontests/multiple_database/tests.py
@@ -4,13 +4,13 @@ import datetime
import pickle
from operator import attrgetter
-from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.core import management
from django.db import connections, router, DEFAULT_DB_ALIAS
from django.db.models import signals
from django.test import TestCase
+from django.test.utils import override_settings
from django.utils.six import StringIO
from .models import Book, Person, Pet, Review, UserProfile
@@ -652,7 +652,8 @@ class QueryTestCase(TestCase):
new_bob_profile = UserProfile(flavor="spring surprise")
- charlie = User(username='charlie',email='charlie@example.com')
+ # assigning a profile requires a explicit pk as the object isn't saved
+ charlie = User(pk=51, username='charlie', email='charlie@example.com')
charlie.set_unusable_password()
# initially, no db assigned
@@ -1619,20 +1620,11 @@ class AuthTestCase(TestCase):
command_output = new_io.getvalue().strip()
self.assertTrue('"email": "alice@example.com",' in command_output)
-_missing = object()
-class UserProfileTestCase(TestCase):
- def setUp(self):
- self.old_auth_profile_module = getattr(settings, 'AUTH_PROFILE_MODULE', _missing)
- settings.AUTH_PROFILE_MODULE = 'multiple_database.UserProfile'
- def tearDown(self):
- if self.old_auth_profile_module is _missing:
- del settings.AUTH_PROFILE_MODULE
- else:
- settings.AUTH_PROFILE_MODULE = self.old_auth_profile_module
+@override_settings(AUTH_PROFILE_MODULE='multiple_database.UserProfile')
+class UserProfileTestCase(TestCase):
def test_user_profiles(self):
-
alice = User.objects.create_user('alice', 'alice@example.com')
bob = User.objects.db_manager('other').create_user('bob', 'bob@example.com')
diff --git a/tests/regressiontests/one_to_one_regress/tests.py b/tests/regressiontests/one_to_one_regress/tests.py
index eced88598b..615536ba38 100644
--- a/tests/regressiontests/one_to_one_regress/tests.py
+++ b/tests/regressiontests/one_to_one_regress/tests.py
@@ -202,3 +202,43 @@ class OneToOneRegressionTests(TestCase):
with self.assertNumQueries(0):
with self.assertRaises(UndergroundBar.DoesNotExist):
self.p1.undergroundbar
+
+ def test_get_reverse_on_unsaved_object(self):
+ """
+ Regression for #18153 and #19089.
+
+ Accessing the reverse relation on an unsaved object
+ always raises an exception.
+ """
+ p = Place()
+
+ # When there's no instance of the origin of the one-to-one
+ with self.assertNumQueries(0):
+ with self.assertRaises(UndergroundBar.DoesNotExist):
+ p.undergroundbar
+
+ UndergroundBar.objects.create()
+
+ # When there's one instance of the origin
+ # (p.undergroundbar used to return that instance)
+ with self.assertNumQueries(0):
+ with self.assertRaises(UndergroundBar.DoesNotExist):
+ p.undergroundbar
+
+ UndergroundBar.objects.create()
+
+ # When there are several instances of the origin
+ with self.assertNumQueries(0):
+ with self.assertRaises(UndergroundBar.DoesNotExist):
+ p.undergroundbar
+
+ def test_set_reverse_on_unsaved_object(self):
+ """
+ Writing to the reverse relation on an unsaved object
+ is impossible too.
+ """
+ p = Place()
+ b = UndergroundBar.objects.create()
+ with self.assertNumQueries(0):
+ with self.assertRaises(ValueError):
+ p.undergroundbar = b
diff --git a/tests/regressiontests/queries/tests.py b/tests/regressiontests/queries/tests.py
index 71ac107486..c2a4ad1caf 100644
--- a/tests/regressiontests/queries/tests.py
+++ b/tests/regressiontests/queries/tests.py
@@ -1698,6 +1698,13 @@ class EmptyQuerySetTests(TestCase):
[]
)
+ def test_ticket_19151(self):
+ # #19151 -- Calling .values() or .values_list() on an EmptyQuerySet
+ # should return EmptyQuerySet and not cause an error.
+ q = EmptyQuerySet()
+ self.assertQuerysetEqual(q.values(), [])
+ self.assertQuerysetEqual(q.values_list(), [])
+
class ValuesQuerysetTests(BaseQuerysetTest):
def test_flat_values_lits(self):
diff --git a/tests/regressiontests/requests/tests.py b/tests/regressiontests/requests/tests.py
index f9e1112b2e..6522620d5f 100644
--- a/tests/regressiontests/requests/tests.py
+++ b/tests/regressiontests/requests/tests.py
@@ -5,10 +5,11 @@ import warnings
from datetime import datetime, timedelta
from io import BytesIO
-from django.conf import settings
+from django.core.exceptions import SuspiciousOperation
from django.core.handlers.wsgi import WSGIRequest, LimitedStream
from django.http import HttpRequest, HttpResponse, parse_cookie, build_request_repr, UnreadablePostError
-from django.test.utils import str_prefix
+from django.test.client import FakePayload
+from django.test.utils import override_settings, str_prefix
from django.utils import unittest
from django.utils.http import cookie_date
from django.utils.timezone import utc
@@ -56,7 +57,7 @@ class RequestsTests(unittest.TestCase):
str_prefix("<WSGIRequest\npath:/otherpath/,\nGET:{%(_)s'a': %(_)s'b'},\nPOST:{%(_)s'c': %(_)s'd'},\nCOOKIES:{%(_)s'e': %(_)s'f'},\nMETA:{%(_)s'g': %(_)s'h'}>"))
def test_parse_cookie(self):
- self.assertEqual(parse_cookie('invalid:key=true'), {})
+ self.assertEqual(parse_cookie('invalid@key=true'), {})
def test_httprequest_location(self):
request = HttpRequest()
@@ -68,93 +69,146 @@ class RequestsTests(unittest.TestCase):
self.assertEqual(request.build_absolute_uri(location="/path/with:colons"),
'http://www.example.com/path/with:colons')
+ @override_settings(USE_X_FORWARDED_HOST=False)
def test_http_get_host(self):
- old_USE_X_FORWARDED_HOST = settings.USE_X_FORWARDED_HOST
- try:
- settings.USE_X_FORWARDED_HOST = False
+ # Check if X_FORWARDED_HOST is provided.
+ request = HttpRequest()
+ request.META = {
+ 'HTTP_X_FORWARDED_HOST': 'forward.com',
+ 'HTTP_HOST': 'example.com',
+ 'SERVER_NAME': 'internal.com',
+ 'SERVER_PORT': 80,
+ }
+ # X_FORWARDED_HOST is ignored.
+ self.assertEqual(request.get_host(), 'example.com')
- # Check if X_FORWARDED_HOST is provided.
- request = HttpRequest()
- request.META = {
- 'HTTP_X_FORWARDED_HOST': 'forward.com',
- 'HTTP_HOST': 'example.com',
- 'SERVER_NAME': 'internal.com',
- 'SERVER_PORT': 80,
- }
- # X_FORWARDED_HOST is ignored.
- self.assertEqual(request.get_host(), 'example.com')
+ # Check if X_FORWARDED_HOST isn't provided.
+ request = HttpRequest()
+ request.META = {
+ 'HTTP_HOST': 'example.com',
+ 'SERVER_NAME': 'internal.com',
+ 'SERVER_PORT': 80,
+ }
+ self.assertEqual(request.get_host(), 'example.com')
- # Check if X_FORWARDED_HOST isn't provided.
- request = HttpRequest()
- request.META = {
- 'HTTP_HOST': 'example.com',
- 'SERVER_NAME': 'internal.com',
- 'SERVER_PORT': 80,
- }
- self.assertEqual(request.get_host(), 'example.com')
+ # Check if HTTP_HOST isn't provided.
+ request = HttpRequest()
+ request.META = {
+ 'SERVER_NAME': 'internal.com',
+ 'SERVER_PORT': 80,
+ }
+ self.assertEqual(request.get_host(), 'internal.com')
- # Check if HTTP_HOST isn't provided.
- request = HttpRequest()
- request.META = {
- 'SERVER_NAME': 'internal.com',
- 'SERVER_PORT': 80,
- }
- self.assertEqual(request.get_host(), 'internal.com')
+ # Check if HTTP_HOST isn't provided, and we're on a nonstandard port
+ request = HttpRequest()
+ request.META = {
+ 'SERVER_NAME': 'internal.com',
+ 'SERVER_PORT': 8042,
+ }
+ self.assertEqual(request.get_host(), 'internal.com:8042')
+
+ # Poisoned host headers are rejected as suspicious
+ legit_hosts = [
+ 'example.com',
+ 'example.com:80',
+ '12.34.56.78',
+ '12.34.56.78:443',
+ '[2001:19f0:feee::dead:beef:cafe]',
+ '[2001:19f0:feee::dead:beef:cafe]:8080',
+ ]
- # Check if HTTP_HOST isn't provided, and we're on a nonstandard port
+ poisoned_hosts = [
+ 'example.com@evil.tld',
+ 'example.com:dr.frankenstein@evil.tld',
+ 'example.com:someone@somestie.com:80',
+ 'example.com:80/badpath'
+ ]
+
+ for host in legit_hosts:
request = HttpRequest()
request.META = {
- 'SERVER_NAME': 'internal.com',
- 'SERVER_PORT': 8042,
+ 'HTTP_HOST': host,
}
- self.assertEqual(request.get_host(), 'internal.com:8042')
+ request.get_host()
- finally:
- settings.USE_X_FORWARDED_HOST = old_USE_X_FORWARDED_HOST
+ for host in poisoned_hosts:
+ with self.assertRaises(SuspiciousOperation):
+ request = HttpRequest()
+ request.META = {
+ 'HTTP_HOST': host,
+ }
+ request.get_host()
+ @override_settings(USE_X_FORWARDED_HOST=True)
def test_http_get_host_with_x_forwarded_host(self):
- old_USE_X_FORWARDED_HOST = settings.USE_X_FORWARDED_HOST
- try:
- settings.USE_X_FORWARDED_HOST = True
+ # Check if X_FORWARDED_HOST is provided.
+ request = HttpRequest()
+ request.META = {
+ 'HTTP_X_FORWARDED_HOST': 'forward.com',
+ 'HTTP_HOST': 'example.com',
+ 'SERVER_NAME': 'internal.com',
+ 'SERVER_PORT': 80,
+ }
+ # X_FORWARDED_HOST is obeyed.
+ self.assertEqual(request.get_host(), 'forward.com')
- # Check if X_FORWARDED_HOST is provided.
- request = HttpRequest()
- request.META = {
- 'HTTP_X_FORWARDED_HOST': 'forward.com',
- 'HTTP_HOST': 'example.com',
- 'SERVER_NAME': 'internal.com',
- 'SERVER_PORT': 80,
- }
- # X_FORWARDED_HOST is obeyed.
- self.assertEqual(request.get_host(), 'forward.com')
+ # Check if X_FORWARDED_HOST isn't provided.
+ request = HttpRequest()
+ request.META = {
+ 'HTTP_HOST': 'example.com',
+ 'SERVER_NAME': 'internal.com',
+ 'SERVER_PORT': 80,
+ }
+ self.assertEqual(request.get_host(), 'example.com')
- # Check if X_FORWARDED_HOST isn't provided.
- request = HttpRequest()
- request.META = {
- 'HTTP_HOST': 'example.com',
- 'SERVER_NAME': 'internal.com',
- 'SERVER_PORT': 80,
- }
- self.assertEqual(request.get_host(), 'example.com')
+ # Check if HTTP_HOST isn't provided.
+ request = HttpRequest()
+ request.META = {
+ 'SERVER_NAME': 'internal.com',
+ 'SERVER_PORT': 80,
+ }
+ self.assertEqual(request.get_host(), 'internal.com')
- # Check if HTTP_HOST isn't provided.
- request = HttpRequest()
- request.META = {
- 'SERVER_NAME': 'internal.com',
- 'SERVER_PORT': 80,
- }
- self.assertEqual(request.get_host(), 'internal.com')
+ # Check if HTTP_HOST isn't provided, and we're on a nonstandard port
+ request = HttpRequest()
+ request.META = {
+ 'SERVER_NAME': 'internal.com',
+ 'SERVER_PORT': 8042,
+ }
+ self.assertEqual(request.get_host(), 'internal.com:8042')
+
+ # Poisoned host headers are rejected as suspicious
+ legit_hosts = [
+ 'example.com',
+ 'example.com:80',
+ '12.34.56.78',
+ '12.34.56.78:443',
+ '[2001:19f0:feee::dead:beef:cafe]',
+ '[2001:19f0:feee::dead:beef:cafe]:8080',
+ ]
- # Check if HTTP_HOST isn't provided, and we're on a nonstandard port
+ poisoned_hosts = [
+ 'example.com@evil.tld',
+ 'example.com:dr.frankenstein@evil.tld',
+ 'example.com:dr.frankenstein@evil.tld:80',
+ 'example.com:80/badpath'
+ ]
+
+ for host in legit_hosts:
request = HttpRequest()
request.META = {
- 'SERVER_NAME': 'internal.com',
- 'SERVER_PORT': 8042,
+ 'HTTP_HOST': host,
}
- self.assertEqual(request.get_host(), 'internal.com:8042')
+ request.get_host()
+
+ for host in poisoned_hosts:
+ with self.assertRaises(SuspiciousOperation):
+ request = HttpRequest()
+ request.META = {
+ 'HTTP_HOST': host,
+ }
+ request.get_host()
- finally:
- settings.USE_X_FORWARDED_HOST = old_USE_X_FORWARDED_HOST
def test_near_expiration(self):
"Cookie will expire when an near expiration time is provided"
@@ -263,10 +317,11 @@ class RequestsTests(unittest.TestCase):
self.assertEqual(stream.read(), b'')
def test_stream(self):
- payload = b'name=value'
+ payload = FakePayload('name=value')
request = WSGIRequest({'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CONTENT_LENGTH': len(payload),
- 'wsgi.input': BytesIO(payload)})
+ 'wsgi.input': payload})
self.assertEqual(request.read(), b'name=value')
def test_read_after_value(self):
@@ -274,10 +329,11 @@ class RequestsTests(unittest.TestCase):
Reading from request is allowed after accessing request contents as
POST or body.
"""
- payload = b'name=value'
+ payload = FakePayload('name=value')
request = WSGIRequest({'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CONTENT_LENGTH': len(payload),
- 'wsgi.input': BytesIO(payload)})
+ 'wsgi.input': payload})
self.assertEqual(request.POST, {'name': ['value']})
self.assertEqual(request.body, b'name=value')
self.assertEqual(request.read(), b'name=value')
@@ -287,10 +343,11 @@ class RequestsTests(unittest.TestCase):
Construction of POST or body is not allowed after reading
from request.
"""
- payload = b'name=value'
+ payload = FakePayload('name=value')
request = WSGIRequest({'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CONTENT_LENGTH': len(payload),
- 'wsgi.input': BytesIO(payload)})
+ 'wsgi.input': payload})
self.assertEqual(request.read(2), b'na')
self.assertRaises(Exception, lambda: request.body)
self.assertEqual(request.POST, {})
@@ -302,17 +359,17 @@ class RequestsTests(unittest.TestCase):
# Because multipart is used for large amounts fo data i.e. file uploads,
# we don't want the data held in memory twice, and we don't want to
# silence the error by setting body = '' either.
- payload = "\r\n".join([
+ payload = FakePayload("\r\n".join([
'--boundary',
'Content-Disposition: form-data; name="name"',
'',
'value',
'--boundary--'
- '']).encode('utf-8')
+ '']))
request = WSGIRequest({'REQUEST_METHOD': 'POST',
'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
'CONTENT_LENGTH': len(payload),
- 'wsgi.input': BytesIO(payload)})
+ 'wsgi.input': payload})
self.assertEqual(request.POST, {'name': ['value']})
self.assertRaises(Exception, lambda: request.body)
@@ -324,34 +381,54 @@ class RequestsTests(unittest.TestCase):
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13
# Every request.POST with Content-Length >= 0 is a valid request,
# this test ensures that we handle Content-Length == 0.
- payload = "\r\n".join([
+ payload = FakePayload("\r\n".join([
'--boundary',
'Content-Disposition: form-data; name="name"',
'',
'value',
'--boundary--'
- '']).encode('utf-8')
+ '']))
request = WSGIRequest({'REQUEST_METHOD': 'POST',
'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
'CONTENT_LENGTH': 0,
- 'wsgi.input': BytesIO(payload)})
+ 'wsgi.input': payload})
+ self.assertEqual(request.POST, {})
+
+ def test_POST_binary_only(self):
+ payload = b'\r\n\x01\x00\x00\x00ab\x00\x00\xcd\xcc,@'
+ environ = {'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'application/octet-stream',
+ 'CONTENT_LENGTH': len(payload),
+ 'wsgi.input': BytesIO(payload)}
+ request = WSGIRequest(environ)
self.assertEqual(request.POST, {})
+ self.assertEqual(request.FILES, {})
+ self.assertEqual(request.body, payload)
+
+ # Same test without specifying content-type
+ environ.update({'CONTENT_TYPE': '', 'wsgi.input': BytesIO(payload)})
+ request = WSGIRequest(environ)
+ self.assertEqual(request.POST, {})
+ self.assertEqual(request.FILES, {})
+ self.assertEqual(request.body, payload)
def test_read_by_lines(self):
- payload = b'name=value'
+ payload = FakePayload('name=value')
request = WSGIRequest({'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CONTENT_LENGTH': len(payload),
- 'wsgi.input': BytesIO(payload)})
+ 'wsgi.input': payload})
self.assertEqual(list(request), [b'name=value'])
def test_POST_after_body_read(self):
"""
POST should be populated even if body is read first
"""
- payload = b'name=value'
+ payload = FakePayload('name=value')
request = WSGIRequest({'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CONTENT_LENGTH': len(payload),
- 'wsgi.input': BytesIO(payload)})
+ 'wsgi.input': payload})
raw_data = request.body
self.assertEqual(request.POST, {'name': ['value']})
@@ -360,10 +437,11 @@ class RequestsTests(unittest.TestCase):
POST should be populated even if body is read first, and then
the stream is read second.
"""
- payload = b'name=value'
+ payload = FakePayload('name=value')
request = WSGIRequest({'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CONTENT_LENGTH': len(payload),
- 'wsgi.input': BytesIO(payload)})
+ 'wsgi.input': payload})
raw_data = request.body
self.assertEqual(request.read(1), b'n')
self.assertEqual(request.POST, {'name': ['value']})
@@ -373,17 +451,17 @@ class RequestsTests(unittest.TestCase):
POST should be populated even if body is read first, and then
the stream is read second. Using multipart/form-data instead of urlencoded.
"""
- payload = "\r\n".join([
+ payload = FakePayload("\r\n".join([
'--boundary',
'Content-Disposition: form-data; name="name"',
'',
'value',
'--boundary--'
- '']).encode('utf-8')
+ '']))
request = WSGIRequest({'REQUEST_METHOD': 'POST',
'CONTENT_TYPE': 'multipart/form-data; boundary=boundary',
'CONTENT_LENGTH': len(payload),
- 'wsgi.input': BytesIO(payload)})
+ 'wsgi.input': payload})
raw_data = request.body
# Consume enough data to mess up the parsing:
self.assertEqual(request.read(13), b'--boundary\r\nC')
@@ -393,11 +471,11 @@ class RequestsTests(unittest.TestCase):
"""
HttpRequest.raw_post_body should be the same as HttpRequest.body
"""
- payload = b'Hello There!'
+ payload = FakePayload('Hello There!')
request = WSGIRequest({
'REQUEST_METHOD': 'POST',
'CONTENT_LENGTH': len(payload),
- 'wsgi.input': BytesIO(payload)
+ 'wsgi.input': payload,
})
with warnings.catch_warnings(record=True):
@@ -414,6 +492,7 @@ class RequestsTests(unittest.TestCase):
payload = b'name=value'
request = WSGIRequest({'REQUEST_METHOD': 'POST',
+ 'CONTENT_TYPE': 'application/x-www-form-urlencoded',
'CONTENT_LENGTH': len(payload),
'wsgi.input': ExplodingBytesIO(payload)})
diff --git a/tests/regressiontests/servers/tests.py b/tests/regressiontests/servers/tests.py
index c90c785a6e..f54e34ce28 100644
--- a/tests/regressiontests/servers/tests.py
+++ b/tests/regressiontests/servers/tests.py
@@ -1,6 +1,9 @@
+# -*- encoding: utf-8 -*-
"""
Tests for django.core.servers.
"""
+from __future__ import unicode_literals
+
import os
try:
from urllib.request import urlopen, HTTPError
@@ -11,6 +14,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.test import LiveServerTestCase
from django.core.servers.basehttp import WSGIServerException
from django.test.utils import override_settings
+from django.utils.http import urlencode
from .models import Person
@@ -134,6 +138,10 @@ class LiveServerViews(LiveServerBase):
f = self.urlopen('/media/example_media_file.txt')
self.assertEqual(f.read().rstrip(b'\r\n'), b'example media file')
+ def test_environ(self):
+ f = self.urlopen('/environ_view/?%s' % urlencode({'q': 'тест'}))
+ self.assertIn(b"QUERY_STRING: 'q=%D1%82%D0%B5%D1%81%D1%82'", f.read())
+
class LiveServerDatabase(LiveServerBase):
diff --git a/tests/regressiontests/servers/urls.py b/tests/regressiontests/servers/urls.py
index c8ca1ac7a4..a857c45f95 100644
--- a/tests/regressiontests/servers/urls.py
+++ b/tests/regressiontests/servers/urls.py
@@ -9,4 +9,5 @@ urlpatterns = patterns('',
url(r'^example_view/$', views.example_view),
url(r'^model_view/$', views.model_view),
url(r'^create_model_instance/$', views.create_model_instance),
-) \ No newline at end of file
+ url(r'^environ_view/$', views.environ_view),
+)
diff --git a/tests/regressiontests/servers/views.py b/tests/regressiontests/servers/views.py
index 94a4f2d9ef..00baf4b5ac 100644
--- a/tests/regressiontests/servers/views.py
+++ b/tests/regressiontests/servers/views.py
@@ -14,4 +14,8 @@ def model_view(request):
def create_model_instance(request):
person = Person(name='emily')
person.save()
- return HttpResponse('') \ No newline at end of file
+ return HttpResponse('')
+
+
+def environ_view(request):
+ return HttpResponse("\n".join(["%s: %r" % (k, v) for k, v in request.environ.items()]))
diff --git a/tests/regressiontests/syndication/feeds.py b/tests/regressiontests/syndication/feeds.py
index 748420c9d2..04a67f4bdb 100644
--- a/tests/regressiontests/syndication/feeds.py
+++ b/tests/regressiontests/syndication/feeds.py
@@ -46,6 +46,14 @@ class TestRss091Feed(TestRss2Feed):
feed_type = feedgenerator.RssUserland091Feed
+class TestNoPubdateFeed(views.Feed):
+ title = 'Test feed'
+ link = '/feed/'
+
+ def items(self):
+ return Entry.objects.all()
+
+
class TestAtomFeed(TestRss2Feed):
feed_type = feedgenerator.Atom1Feed
subtitle = TestRss2Feed.description
diff --git a/tests/regressiontests/syndication/tests.py b/tests/regressiontests/syndication/tests.py
index 1790d8cae6..10413b4ddd 100644
--- a/tests/regressiontests/syndication/tests.py
+++ b/tests/regressiontests/syndication/tests.py
@@ -226,6 +226,14 @@ class SyndicationFeedTest(FeedTestCase):
updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText
self.assertEqual(updated[-6:], '+00:42')
+ def test_feed_last_modified_time(self):
+ response = self.client.get('/syndication/naive-dates/')
+ self.assertEqual(response['Last-Modified'], 'Thu, 03 Jan 2008 19:30:00 GMT')
+
+ # No last-modified when feed has no item_pubdate
+ response = self.client.get('/syndication/no_pubdate/')
+ self.assertFalse(response.has_header('Last-Modified'))
+
def test_feed_url(self):
"""
Test that the feed_url can be overridden.
diff --git a/tests/regressiontests/syndication/urls.py b/tests/regressiontests/syndication/urls.py
index 2199e29f06..57f9d81a73 100644
--- a/tests/regressiontests/syndication/urls.py
+++ b/tests/regressiontests/syndication/urls.py
@@ -9,6 +9,7 @@ urlpatterns = patterns('django.contrib.syndication.views',
(r'^syndication/complex/(?P<foo>.*)/$', feeds.ComplexFeed()),
(r'^syndication/rss2/$', feeds.TestRss2Feed()),
(r'^syndication/rss091/$', feeds.TestRss091Feed()),
+ (r'^syndication/no_pubdate/$', feeds.TestNoPubdateFeed()),
(r'^syndication/atom/$', feeds.TestAtomFeed()),
(r'^syndication/custom/$', feeds.TestCustomFeed()),
(r'^syndication/naive-dates/$', feeds.NaiveDatesFeed()),
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
index 41f40e7467..c95b5bfa3c 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -155,16 +155,8 @@ class UTF8Class:
def __str__(self):
return 'ŠĐĆŽćžšđ'
+@override_settings(MEDIA_URL="/media/", STATIC_URL="/static/")
class Templates(unittest.TestCase):
- def setUp(self):
- self.old_static_url = settings.STATIC_URL
- self.old_media_url = settings.MEDIA_URL
- settings.STATIC_URL = "/static/"
- settings.MEDIA_URL = "/media/"
-
- def tearDown(self):
- settings.STATIC_URL = self.old_static_url
- settings.MEDIA_URL = self.old_media_url
def test_loaders_security(self):
ad_loader = app_directories.Loader()
@@ -229,11 +221,11 @@ class Templates(unittest.TestCase):
loader.template_source_loaders = (filesystem.Loader(),)
# We rely on the fact that runtests.py sets up TEMPLATE_DIRS to
- # point to a directory containing a 404.html file. Also that
+ # point to a directory containing a login.html file. Also that
# the file system and app directories loaders both inherit the
# load_template method from the BaseLoader class, so we only need
# to test one of them.
- load_name = '404.html'
+ load_name = 'login.html'
template = loader.get_template(load_name)
template_name = template.nodelist[0].source[0].name
self.assertTrue(template_name.endswith(load_name),
diff --git a/tests/regressiontests/test_client_regress/tests.py b/tests/regressiontests/test_client_regress/tests.py
index d80293b358..f424321663 100644
--- a/tests/regressiontests/test_client_regress/tests.py
+++ b/tests/regressiontests/test_client_regress/tests.py
@@ -16,6 +16,7 @@ from django.test import Client, TestCase
from django.test.client import encode_file, RequestFactory
from django.test.utils import ContextList, override_settings, str_prefix
from django.template.response import SimpleTemplateResponse
+from django.utils.translation import ugettext_lazy
from django.http import HttpResponse
@@ -129,6 +130,14 @@ class AssertContainsTests(TestCase):
self.assertNotContains(r, 'はたけ')
self.assertNotContains(r, b'\xe3\x81\xaf\xe3\x81\x9f\xe3\x81\x91'.decode('utf-8'))
+ def test_nontext_contains(self):
+ r = self.client.get('/test_client_regress/no_template_view/')
+ self.assertContains(r, ugettext_lazy('once'))
+
+ def test_nontext_not_contains(self):
+ r = self.client.get('/test_client_regress/no_template_view/')
+ self.assertNotContains(r, ugettext_lazy('never'))
+
def test_assert_contains_renders_template_response(self):
""" Test that we can pass in an unrendered SimpleTemplateReponse
without throwing an error.
@@ -490,11 +499,11 @@ class AssertFormErrorTests(TestCase):
try:
self.assertFormError(response, 'form', 'email', 'Some error.')
except AssertionError as e:
- self.assertIn(str_prefix("The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [%(_)s'Enter a valid e-mail address.'])"), str(e))
+ self.assertIn(str_prefix("The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [%(_)s'Enter a valid email address.'])"), str(e))
try:
self.assertFormError(response, 'form', 'email', 'Some error.', msg_prefix='abc')
except AssertionError as e:
- self.assertIn(str_prefix("abc: The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [%(_)s'Enter a valid e-mail address.'])"), str(e))
+ self.assertIn(str_prefix("abc: The field 'email' on form 'form' in context 0 does not contain the error 'Some error.' (actual errors: [%(_)s'Enter a valid email address.'])"), str(e))
def test_unknown_nonfield_error(self):
"""
@@ -619,15 +628,6 @@ class TemplateExceptionTests(TestCase):
if hasattr(template_loader, 'reset'):
template_loader.reset()
- @override_settings(TEMPLATE_DIRS=(),)
- def test_no_404_template(self):
- "Missing templates are correctly reported by test client"
- try:
- response = self.client.get("/no_such_view/")
- self.fail("Should get error about missing template")
- except TemplateDoesNotExist:
- pass
-
@override_settings(
TEMPLATE_DIRS=(os.path.join(os.path.dirname(__file__), 'bad_templates'),)
)
diff --git a/tests/regressiontests/test_utils/tests.py b/tests/regressiontests/test_utils/tests.py
index 468af77f44..95913b5aab 100644
--- a/tests/regressiontests/test_utils/tests.py
+++ b/tests/regressiontests/test_utils/tests.py
@@ -450,6 +450,46 @@ class HTMLEqualTests(TestCase):
self.assertContains(response, '<p class="help">Some help text for the title (with unicode ŠĐĆŽćžšđ)</p>', html=True)
+class XMLEqualTests(TestCase):
+ def test_simple_equal(self):
+ xml1 = "<elem attr1='a' attr2='b' />"
+ xml2 = "<elem attr1='a' attr2='b' />"
+ self.assertXMLEqual(xml1, xml2)
+
+ def test_simple_equal_unordered(self):
+ xml1 = "<elem attr1='a' attr2='b' />"
+ xml2 = "<elem attr2='b' attr1='a' />"
+ self.assertXMLEqual(xml1, xml2)
+
+ def test_simple_equal_raise(self):
+ xml1 = "<elem attr1='a' />"
+ xml2 = "<elem attr2='b' attr1='a' />"
+ with self.assertRaises(AssertionError):
+ self.assertXMLEqual(xml1, xml2)
+
+ def test_simple_not_equal(self):
+ xml1 = "<elem attr1='a' attr2='c' />"
+ xml2 = "<elem attr1='a' attr2='b' />"
+ self.assertXMLNotEqual(xml1, xml2)
+
+ def test_simple_not_equal_raise(self):
+ xml1 = "<elem attr1='a' attr2='b' />"
+ xml2 = "<elem attr2='b' attr1='a' />"
+ with self.assertRaises(AssertionError):
+ self.assertXMLNotEqual(xml1, xml2)
+
+ def test_parsing_errors(self):
+ xml_unvalid = "<elem attr1='a attr2='b' />"
+ xml2 = "<elem attr2='b' attr1='a' />"
+ with self.assertRaises(AssertionError):
+ self.assertXMLNotEqual(xml_unvalid, xml2)
+
+ def test_comment_root(self):
+ xml1 = "<?xml version='1.0'?><!-- comment1 --><elem attr1='a' attr2='b' />"
+ xml2 = "<?xml version='1.0'?><!-- comment2 --><elem attr2='b' attr1='a' />"
+ self.assertXMLEqual(xml1, xml2)
+
+
class SkippingExtraTests(TestCase):
fixtures = ['should_not_be_loaded.json']
@@ -476,7 +516,7 @@ class AssertRaisesMsgTest(SimpleTestCase):
class AssertFieldOutputTests(SimpleTestCase):
def test_assert_field_output(self):
- error_invalid = ['Enter a valid e-mail address.']
+ error_invalid = ['Enter a valid email address.']
self.assertFieldOutput(EmailField, {'a@a.com': 'a@a.com'}, {'aaa': error_invalid})
self.assertRaises(AssertionError, self.assertFieldOutput, EmailField, {'a@a.com': 'a@a.com'}, {'aaa': error_invalid + ['Another error']})
self.assertRaises(AssertionError, self.assertFieldOutput, EmailField, {'a@a.com': 'Wrong output'}, {'aaa': error_invalid})
diff --git a/tests/regressiontests/urlpatterns_reverse/namespace_urls.py b/tests/regressiontests/urlpatterns_reverse/namespace_urls.py
index fa892a4346..ab2e77af24 100644
--- a/tests/regressiontests/urlpatterns_reverse/namespace_urls.py
+++ b/tests/regressiontests/urlpatterns_reverse/namespace_urls.py
@@ -28,6 +28,7 @@ otherobj2 = URLObject('nodefault', 'other-ns2')
urlpatterns = patterns('regressiontests.urlpatterns_reverse.views',
url(r'^normal/$', 'empty_view', name='normal-view'),
url(r'^normal/(?P<arg1>\d+)/(?P<arg2>\d+)/$', 'empty_view', name='normal-view'),
+ url(r'^resolver_match/$', 'pass_resolver_match_view', name='test-resolver-match'),
url(r'^\+\\\$\*/$', 'empty_view', name='special-view'),
diff --git a/tests/regressiontests/urlpatterns_reverse/tests.py b/tests/regressiontests/urlpatterns_reverse/tests.py
index 0ea5ffe380..234897d267 100644
--- a/tests/regressiontests/urlpatterns_reverse/tests.py
+++ b/tests/regressiontests/urlpatterns_reverse/tests.py
@@ -512,6 +512,11 @@ class ResolverMatchTests(TestCase):
self.assertEqual(match[1], args)
self.assertEqual(match[2], kwargs)
+ def test_resolver_match_on_request(self):
+ response = self.client.get('/resolver_match/')
+ resolver_match = response.resolver_match
+ self.assertEqual(resolver_match.url_name, 'test-resolver-match')
+
class ErroneousViewTests(TestCase):
urls = 'regressiontests.urlpatterns_reverse.erroneous_urls'
diff --git a/tests/regressiontests/urlpatterns_reverse/views.py b/tests/regressiontests/urlpatterns_reverse/views.py
index f631acf3ec..88d169a118 100644
--- a/tests/regressiontests/urlpatterns_reverse/views.py
+++ b/tests/regressiontests/urlpatterns_reverse/views.py
@@ -19,6 +19,11 @@ def defaults_view(request, arg1, arg2):
def erroneous_view(request):
import non_existent
+def pass_resolver_match_view(request, *args, **kwargs):
+ response = HttpResponse('')
+ response.resolver_match = request.resolver_match
+ return response
+
uncallable = "Can I be a view? Pleeeease?"
class ViewClass(object):
diff --git a/tests/regressiontests/utils/datastructures.py b/tests/regressiontests/utils/datastructures.py
index dbc65d37a8..f65fc5c770 100644
--- a/tests/regressiontests/utils/datastructures.py
+++ b/tests/regressiontests/utils/datastructures.py
@@ -128,6 +128,12 @@ class SortedDictTests(SimpleTestCase):
self.assertEqual(self.d1, {})
self.assertEqual(self.d1.keyOrder, [])
+ def test_reversed(self):
+ self.assertEqual(list(self.d1), [7, 1, 9])
+ self.assertEqual(list(self.d2), [1, 9, 0, 7])
+ self.assertEqual(list(reversed(self.d1)), [9, 1, 7])
+ self.assertEqual(list(reversed(self.d2)), [7, 0, 9, 1])
+
def test_insert(self):
d = SortedDict()
with warnings.catch_warnings(record=True) as w:
@@ -206,19 +212,18 @@ class MultiValueDictTests(SimpleTestCase):
self.assertEqual(d['name'], 'Simon')
self.assertEqual(d.get('name'), 'Simon')
self.assertEqual(d.getlist('name'), ['Adrian', 'Simon'])
- self.assertEqual(list(six.iteritems(d)),
- [('position', 'Developer'), ('name', 'Simon')])
+ self.assertEqual(sorted(list(six.iteritems(d))),
+ [('name', 'Simon'), ('position', 'Developer')])
- self.assertEqual(list(six.iterlists(d)),
- [('position', ['Developer']),
- ('name', ['Adrian', 'Simon'])])
+ self.assertEqual(sorted(list(six.iterlists(d))),
+ [('name', ['Adrian', 'Simon']),
+ ('position', ['Developer'])])
# MultiValueDictKeyError: "Key 'lastname' not found in
# <MultiValueDict: {'position': ['Developer'],
# 'name': ['Adrian', 'Simon']}>"
- self.assertRaisesMessage(MultiValueDictKeyError,
- '"Key \'lastname\' not found in <MultiValueDict: {\'position\':'\
- ' [\'Developer\'], \'name\': [\'Adrian\', \'Simon\']}>"',
+ six.assertRaisesRegex(self, MultiValueDictKeyError,
+ r'"Key \'lastname\' not found in <MultiValueDict',
d.__getitem__, 'lastname')
self.assertEqual(d.get('lastname'), None)
@@ -229,8 +234,8 @@ class MultiValueDictTests(SimpleTestCase):
d.setlist('lastname', ['Holovaty', 'Willison'])
self.assertEqual(d.getlist('lastname'), ['Holovaty', 'Willison'])
- self.assertEqual(list(six.itervalues(d)),
- ['Developer', 'Simon', 'Willison'])
+ self.assertEqual(sorted(list(six.itervalues(d))),
+ ['Developer', 'Simon', 'Willison'])
def test_appendlist(self):
d = MultiValueDict()
diff --git a/tests/regressiontests/utils/dateformat.py b/tests/regressiontests/utils/dateformat.py
index 0f18bb2a4d..0f4fd67f6f 100644
--- a/tests/regressiontests/utils/dateformat.py
+++ b/tests/regressiontests/utils/dateformat.py
@@ -72,6 +72,11 @@ class DateFormatTests(unittest.TestCase):
self.assertEqual(dateformat.format(my_birthday, 'a'), 'p.m.')
+ def test_microsecond(self):
+ # Regression test for #18951
+ dt = datetime(2009, 5, 16, microsecond=123)
+ self.assertEqual(dateformat.format(dt, 'u'), '000123')
+
def test_date_formats(self):
my_birthday = datetime(1979, 7, 8, 22, 00)
timestamp = datetime(2008, 5, 19, 11, 45, 23, 123456)
diff --git a/tests/regressiontests/utils/html.py b/tests/regressiontests/utils/html.py
index 98df80a5e2..6a93dff85e 100644
--- a/tests/regressiontests/utils/html.py
+++ b/tests/regressiontests/utils/html.py
@@ -154,4 +154,4 @@ class TestUtilsHtml(unittest.TestCase):
("<a>x</a> <p><b>y</b></p>", "a b", "x <p>y</p>"),
)
for value, tags, output in items:
- self.assertEquals(f(value, tags), output)
+ self.assertEqual(f(value, tags), output)
diff --git a/tests/regressiontests/utils/http.py b/tests/regressiontests/utils/http.py
index f22e05496d..6d3bc025af 100644
--- a/tests/regressiontests/utils/http.py
+++ b/tests/regressiontests/utils/http.py
@@ -1,3 +1,4 @@
+from datetime import datetime
import sys
from django.http import HttpResponse, utils
@@ -7,6 +8,7 @@ from django.utils import http
from django.utils import six
from django.utils import unittest
+
class TestUtilsHttp(unittest.TestCase):
def test_same_origin_true(self):
@@ -132,3 +134,30 @@ class TestUtilsHttp(unittest.TestCase):
for n, b36 in [(0, '0'), (1, '1'), (42, '16'), (818469960, 'django')]:
self.assertEqual(http.int_to_base36(n), b36)
self.assertEqual(http.base36_to_int(b36), n)
+
+
+class ETagProcessingTests(unittest.TestCase):
+ def testParsing(self):
+ etags = http.parse_etags(r'"", "etag", "e\"t\"ag", "e\\tag", W/"weak"')
+ self.assertEqual(etags, ['', 'etag', 'e"t"ag', r'e\tag', 'weak'])
+
+ def testQuoting(self):
+ quoted_etag = http.quote_etag(r'e\t"ag')
+ self.assertEqual(quoted_etag, r'"e\\t\"ag"')
+
+
+class HttpDateProcessingTests(unittest.TestCase):
+ def testParsingRfc1123(self):
+ parsed = http.parse_http_date('Sun, 06 Nov 1994 08:49:37 GMT')
+ self.assertEqual(datetime.utcfromtimestamp(parsed),
+ datetime(1994, 11, 6, 8, 49, 37))
+
+ def testParsingRfc850(self):
+ parsed = http.parse_http_date('Sunday, 06-Nov-94 08:49:37 GMT')
+ self.assertEqual(datetime.utcfromtimestamp(parsed),
+ datetime(1994, 11, 6, 8, 49, 37))
+
+ def testParsingAsctime(self):
+ parsed = http.parse_http_date('Sun Nov 6 08:49:37 1994')
+ self.assertEqual(datetime.utcfromtimestamp(parsed),
+ datetime(1994, 11, 6, 8, 49, 37))
diff --git a/tests/regressiontests/utils/numberformat.py b/tests/regressiontests/utils/numberformat.py
new file mode 100644
index 0000000000..f9d9031e48
--- /dev/null
+++ b/tests/regressiontests/utils/numberformat.py
@@ -0,0 +1,47 @@
+from unittest import TestCase
+from django.utils.numberformat import format as nformat
+from sys import float_info
+
+
+class TestNumberFormat(TestCase):
+
+ def test_format_number(self):
+ self.assertEqual(nformat(1234, '.'), '1234')
+ self.assertEqual(nformat(1234.2, '.'), '1234.2')
+ self.assertEqual(nformat(1234, '.', decimal_pos=2), '1234.00')
+ self.assertEqual(nformat(1234, '.', grouping=2, thousand_sep=','),
+ '1234')
+ self.assertEqual(nformat(1234, '.', grouping=2, thousand_sep=',',
+ force_grouping=True), '12,34')
+ self.assertEqual(nformat(-1234.33, '.', decimal_pos=1), '-1234.3')
+
+ def test_format_string(self):
+ self.assertEqual(nformat('1234', '.'), '1234')
+ self.assertEqual(nformat('1234.2', '.'), '1234.2')
+ self.assertEqual(nformat('1234', '.', decimal_pos=2), '1234.00')
+ self.assertEqual(nformat('1234', '.', grouping=2, thousand_sep=','),
+ '1234')
+ self.assertEqual(nformat('1234', '.', grouping=2, thousand_sep=',',
+ force_grouping=True), '12,34')
+ self.assertEqual(nformat('-1234.33', '.', decimal_pos=1), '-1234.3')
+
+ def test_large_number(self):
+ most_max = ('{0}179769313486231570814527423731704356798070567525844996'
+ '598917476803157260780028538760589558632766878171540458953'
+ '514382464234321326889464182768467546703537516986049910576'
+ '551282076245490090389328944075868508455133942304583236903'
+ '222948165808559332123348274797826204144723168738177180919'
+ '29988125040402618412485836{1}')
+ most_max2 = ('{0}35953862697246314162905484746340871359614113505168999'
+ '31978349536063145215600570775211791172655337563430809179'
+ '07028764928468642653778928365536935093407075033972099821'
+ '15310256415249098018077865788815173701691026788460916647'
+ '38064458963316171186642466965495956524082894463374763543'
+ '61838599762500808052368249716736')
+ int_max = int(float_info.max)
+ self.assertEqual(nformat(int_max, '.'), most_max.format('', '8'))
+ self.assertEqual(nformat(int_max + 1, '.'), most_max.format('', '9'))
+ self.assertEqual(nformat(int_max * 2, '.'), most_max2.format(''))
+ self.assertEqual(nformat(0 - int_max, '.'), most_max.format('-', '8'))
+ self.assertEqual(nformat(-1 - int_max, '.'), most_max.format('-', '9'))
+ self.assertEqual(nformat(-2 * int_max, '.'), most_max2.format('-'))
diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py
index 061c669eb7..11dd7c320e 100644
--- a/tests/regressiontests/utils/tests.py
+++ b/tests/regressiontests/utils/tests.py
@@ -17,10 +17,11 @@ from .encoding import TestEncodingUtils
from .feedgenerator import FeedgeneratorTest
from .functional import FunctionalTestCase
from .html import TestUtilsHtml
-from .http import TestUtilsHttp
+from .http import TestUtilsHttp, ETagProcessingTests, HttpDateProcessingTests
from .ipv6 import TestUtilsIPv6
from .jslex import JsToCForGettextTest, JsTokensTest
from .module_loading import CustomLoader, DefaultLoader, EggLoader
+from .numberformat import TestNumberFormat
from .os_utils import SafeJoinTests
from .regex_helper import NormalizeTests
from .simplelazyobject import TestUtilsSimpleLazyObject
diff --git a/tests/regressiontests/views/tests/__init__.py b/tests/regressiontests/views/tests/__init__.py
index 63db5da2a3..12d0c59014 100644
--- a/tests/regressiontests/views/tests/__init__.py
+++ b/tests/regressiontests/views/tests/__init__.py
@@ -7,4 +7,4 @@ from .defaults import DefaultsTests
from .i18n import JsI18NTests, I18NTests, JsI18NTestsMultiPackage
from .shortcuts import ShortcutTests
from .specials import URLHandling
-from .static import StaticHelperTest, StaticTests
+from .static import StaticHelperTest, StaticUtilsTests, StaticTests
diff --git a/tests/regressiontests/views/tests/debug.py b/tests/regressiontests/views/tests/debug.py
index 8592b07efe..e616d184b8 100644
--- a/tests/regressiontests/views/tests/debug.py
+++ b/tests/regressiontests/views/tests/debug.py
@@ -1,3 +1,6 @@
+# -*- coding: utf-8 -*-
+# This coding header is significant for tests, as the debug view is parsing
+# files to search for such a header to decode the source file content
from __future__ import absolute_import, unicode_literals
import inspect
diff --git a/tests/regressiontests/views/tests/defaults.py b/tests/regressiontests/views/tests/defaults.py
index 2dd40b4a1a..3ca7f79136 100644
--- a/tests/regressiontests/views/tests/defaults.py
+++ b/tests/regressiontests/views/tests/defaults.py
@@ -1,7 +1,8 @@
-from __future__ import absolute_import
+from __future__ import absolute_import, unicode_literals
-from django.test import TestCase
from django.contrib.contenttypes.models import ContentType
+from django.test import TestCase
+from django.test.utils import setup_test_template_loader, restore_template_loaders
from ..models import Author, Article, UrlArticle
@@ -71,6 +72,23 @@ class DefaultsTests(TestCase):
response = self.client.get('/views/server_error/')
self.assertEqual(response.status_code, 500)
+ def test_custom_templates(self):
+ """
+ Test that 404.html and 500.html templates are picked by their respective
+ handler.
+ """
+ setup_test_template_loader(
+ {'404.html': 'This is a test template for a 404 error.',
+ '500.html': 'This is a test template for a 500 error.'}
+ )
+ try:
+ for code, url in ((404, '/views/non_existing_url/'), (500, '/views/server_error/')):
+ response = self.client.get(url)
+ self.assertContains(response, "test template for a %d error" % code,
+ status_code=code)
+ finally:
+ restore_template_loaders()
+
def test_get_absolute_url_attributes(self):
"A model can set attributes on the get_absolute_url method"
self.assertTrue(getattr(UrlArticle.get_absolute_url, 'purge', False),
diff --git a/tests/regressiontests/views/tests/static.py b/tests/regressiontests/views/tests/static.py
index 9d87ade137..8b8ef8ba9b 100644
--- a/tests/regressiontests/views/tests/static.py
+++ b/tests/regressiontests/views/tests/static.py
@@ -2,54 +2,59 @@ from __future__ import absolute_import
import mimetypes
from os import path
+import unittest
-from django.conf import settings
from django.conf.urls.static import static
-from django.test import TestCase
from django.http import HttpResponseNotModified
+from django.test import TestCase
+from django.test.utils import override_settings
+from django.utils.http import http_date
+from django.views.static import was_modified_since
from .. import urls
from ..urls import media_dir
+@override_settings(DEBUG=True)
class StaticTests(TestCase):
"""Tests django views in django/views/static.py"""
- def setUp(self):
- self.prefix = 'site_media'
- self.old_debug = settings.DEBUG
- settings.DEBUG = True
-
- def tearDown(self):
- settings.DEBUG = self.old_debug
+ prefix = 'site_media'
def test_serve(self):
"The static view can serve static media"
media_files = ['file.txt', 'file.txt.gz']
for filename in media_files:
response = self.client.get('/views/%s/%s' % (self.prefix, filename))
+ response_content = b''.join(response)
+ response.close()
file_path = path.join(media_dir, filename)
with open(file_path, 'rb') as fp:
- self.assertEqual(fp.read(), response.content)
- self.assertEqual(len(response.content), int(response['Content-Length']))
+ self.assertEqual(fp.read(), response_content)
+ self.assertEqual(len(response_content), int(response['Content-Length']))
self.assertEqual(mimetypes.guess_type(file_path)[1], response.get('Content-Encoding', None))
def test_unknown_mime_type(self):
response = self.client.get('/views/%s/file.unknown' % self.prefix)
+ response.close()
self.assertEqual('application/octet-stream', response['Content-Type'])
def test_copes_with_empty_path_component(self):
file_name = 'file.txt'
response = self.client.get('/views/%s//%s' % (self.prefix, file_name))
+ response_content = b''.join(response)
+ response.close()
with open(path.join(media_dir, file_name), 'rb') as fp:
- self.assertEqual(fp.read(), response.content)
+ self.assertEqual(fp.read(), response_content)
def test_is_modified_since(self):
file_name = 'file.txt'
response = self.client.get('/views/%s/%s' % (self.prefix, file_name),
HTTP_IF_MODIFIED_SINCE='Thu, 1 Jan 1970 00:00:00 GMT')
+ response_content = b''.join(response)
+ response.close()
with open(path.join(media_dir, file_name), 'rb') as fp:
- self.assertEqual(fp.read(), response.content)
+ self.assertEqual(fp.read(), response_content)
def test_not_modified_since(self):
file_name = 'file.txt'
@@ -71,9 +76,11 @@ class StaticTests(TestCase):
invalid_date = 'Mon, 28 May 999999999999 28:25:26 GMT'
response = self.client.get('/views/%s/%s' % (self.prefix, file_name),
HTTP_IF_MODIFIED_SINCE=invalid_date)
+ response_content = b''.join(response)
+ response.close()
with open(path.join(media_dir, file_name), 'rb') as fp:
- self.assertEqual(fp.read(), response.content)
- self.assertEqual(len(response.content),
+ self.assertEqual(fp.read(), response_content)
+ self.assertEqual(len(response_content),
int(response['Content-Length']))
def test_invalid_if_modified_since2(self):
@@ -86,9 +93,11 @@ class StaticTests(TestCase):
invalid_date = ': 1291108438, Wed, 20 Oct 2010 14:05:00 GMT'
response = self.client.get('/views/%s/%s' % (self.prefix, file_name),
HTTP_IF_MODIFIED_SINCE=invalid_date)
+ response_content = b''.join(response)
+ response.close()
with open(path.join(media_dir, file_name), 'rb') as fp:
- self.assertEqual(fp.read(), response.content)
- self.assertEqual(len(response.content),
+ self.assertEqual(fp.read(), response_content)
+ self.assertEqual(len(response_content),
int(response['Content-Length']))
@@ -98,10 +107,20 @@ class StaticHelperTest(StaticTests):
"""
def setUp(self):
super(StaticHelperTest, self).setUp()
- self.prefix = 'media'
self._old_views_urlpatterns = urls.urlpatterns[:]
urls.urlpatterns += static('/media/', document_root=media_dir)
def tearDown(self):
super(StaticHelperTest, self).tearDown()
urls.urlpatterns = self._old_views_urlpatterns
+
+
+class StaticUtilsTests(unittest.TestCase):
+ def test_was_modified_since_fp(self):
+ """
+ Test that a floating point mtime does not disturb was_modified_since.
+ (#18675)
+ """
+ mtime = 1343416141.107817
+ header = http_date(mtime)
+ self.assertFalse(was_modified_since(header, mtime))
diff --git a/tests/templates/404.html b/tests/templates/404.html
deleted file mode 100644
index da627e2222..0000000000
--- a/tests/templates/404.html
+++ /dev/null
@@ -1 +0,0 @@
-Django Internal Tests: 404 Error \ No newline at end of file
diff --git a/tests/templates/500.html b/tests/templates/500.html
deleted file mode 100644
index ff028cbeb0..0000000000
--- a/tests/templates/500.html
+++ /dev/null
@@ -1 +0,0 @@
-Django Internal Tests: 500 Error \ No newline at end of file