summaryrefslogtreecommitdiff
path: root/tests/modeltests/validation
diff options
context:
space:
mode:
authorJoseph Kocherhans <joseph@jkocherhans.com>2010-01-05 03:56:19 +0000
committerJoseph Kocherhans <joseph@jkocherhans.com>2010-01-05 03:56:19 +0000
commit471596fc1afcb9c6258d317c619eaf5fd394e797 (patch)
tree193767161be3cc23dc2e6be5e4f16d8fd21a2925 /tests/modeltests/validation
parent4e89105d64bb9e04c409139a41e9c7aac263df4c (diff)
Merged soc2009/model-validation to trunk. Thanks, Honza!
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12098 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/modeltests/validation')
-rw-r--r--tests/modeltests/validation/__init__.py21
-rw-r--r--tests/modeltests/validation/models.py53
-rw-r--r--tests/modeltests/validation/test_custom_messages.py13
-rw-r--r--tests/modeltests/validation/test_unique.py58
-rw-r--r--tests/modeltests/validation/tests.py58
-rw-r--r--tests/modeltests/validation/validators.py18
6 files changed, 221 insertions, 0 deletions
diff --git a/tests/modeltests/validation/__init__.py b/tests/modeltests/validation/__init__.py
new file mode 100644
index 0000000000..d0a7d19d49
--- /dev/null
+++ b/tests/modeltests/validation/__init__.py
@@ -0,0 +1,21 @@
+import unittest
+
+from django.core.exceptions import ValidationError
+
+class ValidationTestCase(unittest.TestCase):
+ def assertFailsValidation(self, clean, failed_fields):
+ self.assertRaises(ValidationError, clean)
+ try:
+ clean()
+ except ValidationError, e:
+ self.assertEquals(sorted(failed_fields), sorted(e.message_dict.keys()))
+
+ def assertFieldFailsValidationWithMessage(self, clean, field_name, message):
+ self.assertRaises(ValidationError, clean)
+ try:
+ clean()
+ except ValidationError, e:
+ self.assertTrue(field_name in e.message_dict)
+ self.assertEquals(message, e.message_dict[field_name])
+
+
diff --git a/tests/modeltests/validation/models.py b/tests/modeltests/validation/models.py
new file mode 100644
index 0000000000..f1b0c5188c
--- /dev/null
+++ b/tests/modeltests/validation/models.py
@@ -0,0 +1,53 @@
+from datetime import datetime
+from django.core.exceptions import ValidationError
+from django.db import models
+from django.test import TestCase
+
+
+def validate_answer_to_universe(value):
+ if value != 42:
+ raise ValidationError('This is not the answer to life, universe and everything!', code='not42')
+
+class ModelToValidate(models.Model):
+ name = models.CharField(max_length=100)
+ created = models.DateTimeField(default=datetime.now)
+ number = models.IntegerField()
+ parent = models.ForeignKey('self', blank=True, null=True)
+ email = models.EmailField(blank=True)
+ url = models.URLField(blank=True)
+ f_with_custom_validator = models.IntegerField(blank=True, null=True, validators=[validate_answer_to_universe])
+
+ def validate(self):
+ super(ModelToValidate, self).validate()
+ if self.number == 11:
+ raise ValidationError('Invalid number supplied!')
+
+class UniqueFieldsModel(models.Model):
+ unique_charfield = models.CharField(max_length=100, unique=True)
+ unique_integerfield = models.IntegerField(unique=True)
+ non_unique_field = models.IntegerField()
+
+class CustomPKModel(models.Model):
+ my_pk_field = models.CharField(max_length=100, primary_key=True)
+
+class UniqueTogetherModel(models.Model):
+ cfield = models.CharField(max_length=100)
+ ifield = models.IntegerField()
+ efield = models.EmailField()
+
+ class Meta:
+ unique_together = (('ifield', 'cfield',),('ifield', 'efield'), )
+
+class UniqueForDateModel(models.Model):
+ start_date = models.DateField()
+ end_date = models.DateTimeField()
+ count = models.IntegerField(unique_for_date="start_date", unique_for_year="end_date")
+ order = models.IntegerField(unique_for_month="end_date")
+ name = models.CharField(max_length=100)
+
+class CustomMessagesModel(models.Model):
+ other = models.IntegerField(blank=True, null=True)
+ number = models.IntegerField(
+ error_messages={'null': 'NULL', 'not42': 'AAARGH', 'not_equal': '%s != me'},
+ validators=[validate_answer_to_universe]
+ )
diff --git a/tests/modeltests/validation/test_custom_messages.py b/tests/modeltests/validation/test_custom_messages.py
new file mode 100644
index 0000000000..9a958a0a3f
--- /dev/null
+++ b/tests/modeltests/validation/test_custom_messages.py
@@ -0,0 +1,13 @@
+from modeltests.validation import ValidationTestCase
+from models import CustomMessagesModel
+
+
+class CustomMessagesTest(ValidationTestCase):
+ def test_custom_simple_validator_message(self):
+ cmm = CustomMessagesModel(number=12)
+ self.assertFieldFailsValidationWithMessage(cmm.full_validate, 'number', ['AAARGH'])
+
+ def test_custom_null_message(self):
+ cmm = CustomMessagesModel()
+ self.assertFieldFailsValidationWithMessage(cmm.full_validate, 'number', ['NULL'])
+
diff --git a/tests/modeltests/validation/test_unique.py b/tests/modeltests/validation/test_unique.py
new file mode 100644
index 0000000000..cbb56aa8f5
--- /dev/null
+++ b/tests/modeltests/validation/test_unique.py
@@ -0,0 +1,58 @@
+import unittest
+from django.conf import settings
+from django.db import connection
+from models import CustomPKModel, UniqueTogetherModel, UniqueFieldsModel, UniqueForDateModel, ModelToValidate
+
+
+class GetUniqueCheckTests(unittest.TestCase):
+ def test_unique_fields_get_collected(self):
+ m = UniqueFieldsModel()
+ self.assertEqual(
+ ([('id',), ('unique_charfield',), ('unique_integerfield',)], []),
+ m._get_unique_checks()
+ )
+
+ def test_unique_together_gets_picked_up(self):
+ m = UniqueTogetherModel()
+ self.assertEqual(
+ ([('ifield', 'cfield',),('ifield', 'efield'), ('id',), ], []),
+ m._get_unique_checks()
+ )
+
+ def test_primary_key_is_considered_unique(self):
+ m = CustomPKModel()
+ self.assertEqual(([('my_pk_field',)], []), m._get_unique_checks())
+
+ def test_unique_for_date_gets_picked_up(self):
+ m = UniqueForDateModel()
+ self.assertEqual((
+ [('id',)],
+ [('date', 'count', 'start_date'), ('year', 'count', 'end_date'), ('month', 'order', 'end_date')]
+ ), m._get_unique_checks()
+ )
+
+class PerformUniqueChecksTest(unittest.TestCase):
+ def setUp(self):
+ # Set debug to True to gain access to connection.queries.
+ self._old_debug, settings.DEBUG = settings.DEBUG, True
+ super(PerformUniqueChecksTest, self).setUp()
+
+ def tearDown(self):
+ # Restore old debug value.
+ settings.DEBUG = self._old_debug
+ super(PerformUniqueChecksTest, self).tearDown()
+
+ def test_primary_key_unique_check_performed_when_adding(self):
+ """Regression test for #12132"""
+ l = len(connection.queries)
+ mtv = ModelToValidate(number=10, name='Some Name')
+ setattr(mtv, '_adding', True)
+ mtv.full_validate()
+ self.assertEqual(l+1, len(connection.queries))
+
+ def test_primary_key_unique_check_not_performed_when_not_adding(self):
+ """Regression test for #12132"""
+ l = len(connection.queries)
+ mtv = ModelToValidate(number=10, name='Some Name')
+ mtv.full_validate()
+ self.assertEqual(l, len(connection.queries))
diff --git a/tests/modeltests/validation/tests.py b/tests/modeltests/validation/tests.py
new file mode 100644
index 0000000000..c00070b2ab
--- /dev/null
+++ b/tests/modeltests/validation/tests.py
@@ -0,0 +1,58 @@
+from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
+from django.db import models
+
+from modeltests.validation import ValidationTestCase
+from models import *
+
+from validators import TestModelsWithValidators
+from test_unique import GetUniqueCheckTests, PerformUniqueChecksTest
+from test_custom_messages import CustomMessagesTest
+
+
+class BaseModelValidationTests(ValidationTestCase):
+
+ def test_missing_required_field_raises_error(self):
+ mtv = ModelToValidate(f_with_custom_validator=42)
+ self.assertFailsValidation(mtv.full_validate, ['name', 'number'])
+
+ def test_with_correct_value_model_validates(self):
+ mtv = ModelToValidate(number=10, name='Some Name')
+ self.assertEqual(None, mtv.full_validate())
+
+ def test_custom_validate_method_is_called(self):
+ mtv = ModelToValidate(number=11)
+ self.assertFailsValidation(mtv.full_validate, [NON_FIELD_ERRORS, 'name'])
+
+ def test_wrong_FK_value_raises_error(self):
+ mtv=ModelToValidate(number=10, name='Some Name', parent_id=3)
+ self.assertFailsValidation(mtv.full_validate, ['parent'])
+
+ def test_correct_FK_value_validates(self):
+ parent = ModelToValidate.objects.create(number=10, name='Some Name')
+ mtv=ModelToValidate(number=10, name='Some Name', parent_id=parent.pk)
+ self.assertEqual(None, mtv.full_validate())
+
+ def test_wrong_email_value_raises_error(self):
+ mtv = ModelToValidate(number=10, name='Some Name', email='not-an-email')
+ self.assertFailsValidation(mtv.full_validate, ['email'])
+
+ def test_correct_email_value_passes(self):
+ mtv = ModelToValidate(number=10, name='Some Name', email='valid@email.com')
+ self.assertEqual(None, mtv.full_validate())
+
+ def test_wrong_url_value_raises_error(self):
+ mtv = ModelToValidate(number=10, name='Some Name', url='not a url')
+ self.assertFieldFailsValidationWithMessage(mtv.full_validate, 'url', [u'Enter a valid value.'])
+
+ def test_correct_url_but_nonexisting_gives_404(self):
+ mtv = ModelToValidate(number=10, name='Some Name', url='http://google.com/we-love-microsoft.html')
+ self.assertFieldFailsValidationWithMessage(mtv.full_validate, 'url', [u'This URL appears to be a broken link.'])
+
+ def test_correct_url_value_passes(self):
+ mtv = ModelToValidate(number=10, name='Some Name', url='http://www.djangoproject.com/')
+ self.assertEqual(None, mtv.full_validate()) # This will fail if there's no Internet connection
+
+ def test_text_greater_that_charfields_max_length_eaises_erros(self):
+ mtv = ModelToValidate(number=10, name='Some Name'*100)
+ self.assertFailsValidation(mtv.full_validate, ['name',])
+
diff --git a/tests/modeltests/validation/validators.py b/tests/modeltests/validation/validators.py
new file mode 100644
index 0000000000..dc4cd4eba1
--- /dev/null
+++ b/tests/modeltests/validation/validators.py
@@ -0,0 +1,18 @@
+from unittest import TestCase
+from modeltests.validation import ValidationTestCase
+from models import *
+
+
+class TestModelsWithValidators(ValidationTestCase):
+ def test_custom_validator_passes_for_correct_value(self):
+ mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=42)
+ self.assertEqual(None, mtv.full_validate())
+
+ def test_custom_validator_raises_error_for_incorrect_value(self):
+ mtv = ModelToValidate(number=10, name='Some Name', f_with_custom_validator=12)
+ self.assertFailsValidation(mtv.full_validate, ['f_with_custom_validator'])
+ self.assertFieldFailsValidationWithMessage(
+ mtv.full_validate,
+ 'f_with_custom_validator',
+ [u'This is not the answer to life, universe and everything!']
+ )