1
from __future__ import absolute_import, unicode_literals
3
from django import forms
4
from django.core.exceptions import NON_FIELD_ERRORS
5
from django.test import TestCase
7
from . import ValidationTestCase
8
from .models import (Author, Article, ModelToValidate,
9
GenericIPAddressTestModel, GenericIPAddrUnpackUniqueTest)
12
class BaseModelValidationTests(ValidationTestCase):
14
def test_missing_required_field_raises_error(self):
15
mtv = ModelToValidate(f_with_custom_validator=42)
16
self.assertFailsValidation(mtv.full_clean, ['name', 'number'])
18
def test_with_correct_value_model_validates(self):
19
mtv = ModelToValidate(number=10, name='Some Name')
20
self.assertEqual(None, mtv.full_clean())
22
def test_custom_validate_method(self):
23
mtv = ModelToValidate(number=11)
24
self.assertFailsValidation(mtv.full_clean, [NON_FIELD_ERRORS, 'name'])
26
def test_wrong_FK_value_raises_error(self):
27
mtv=ModelToValidate(number=10, name='Some Name', parent_id=3)
28
self.assertFailsValidation(mtv.full_clean, ['parent'])
30
def test_correct_FK_value_validates(self):
31
parent = ModelToValidate.objects.create(number=10, name='Some Name')
32
mtv = ModelToValidate(number=10, name='Some Name', parent_id=parent.pk)
33
self.assertEqual(None, mtv.full_clean())
35
def test_limited_FK_raises_error(self):
36
# The limit_choices_to on the parent field says that a parent object's
37
# number attribute must be 10, so this should fail validation.
38
parent = ModelToValidate.objects.create(number=11, name='Other Name')
39
mtv = ModelToValidate(number=10, name='Some Name', parent_id=parent.pk)
40
self.assertFailsValidation(mtv.full_clean, ['parent'])
42
def test_wrong_email_value_raises_error(self):
43
mtv = ModelToValidate(number=10, name='Some Name', email='not-an-email')
44
self.assertFailsValidation(mtv.full_clean, ['email'])
46
def test_correct_email_value_passes(self):
47
mtv = ModelToValidate(number=10, name='Some Name', email='valid@email.com')
48
self.assertEqual(None, mtv.full_clean())
50
def test_wrong_url_value_raises_error(self):
51
mtv = ModelToValidate(number=10, name='Some Name', url='not a url')
52
self.assertFieldFailsValidationWithMessage(mtv.full_clean, 'url', ['Enter a valid URL.'])
54
def test_text_greater_that_charfields_max_length_raises_erros(self):
55
mtv = ModelToValidate(number=10, name='Some Name'*100)
56
self.assertFailsValidation(mtv.full_clean, ['name'])
58
def test_malformed_slug_raises_error(self):
59
mtv = ModelToValidate(number=10, name='Some Name', slug='##invalid##')
60
self.assertFailsValidation(mtv.full_clean, ['slug'])
63
class ArticleForm(forms.ModelForm):
68
class ModelFormsTests(TestCase):
70
self.author = Author.objects.create(name='Joseph Kocherhans')
72
def test_partial_validation(self):
73
# Make sure the "commit=False and set field values later" idiom still
74
# works with model validation.
76
'title': 'The state of model validation',
77
'pub_date': '2010-1-10 14:49:00'
79
form = ArticleForm(data)
80
self.assertEqual(list(form.errors), [])
81
article = form.save(commit=False)
82
article.author = self.author
85
def test_validation_with_empty_blank_field(self):
86
# Since a value for pub_date wasn't provided and the field is
87
# blank=True, model-validation should pass.
88
# Also, Article.clean() should be run, so pub_date will be filled after
89
# validation, so the form should save cleanly even though pub_date is
90
# not allowed to be null.
92
'title': 'The state of model validation',
94
article = Article(author_id=self.author.id)
95
form = ArticleForm(data, instance=article)
96
self.assertEqual(list(form.errors), [])
97
self.assertNotEqual(form.instance.pub_date, None)
100
def test_validation_with_invalid_blank_field(self):
101
# Even though pub_date is set to blank=True, an invalid value was
102
# provided, so it should fail validation.
104
'title': 'The state of model validation',
107
article = Article(author_id=self.author.id)
108
form = ArticleForm(data, instance=article)
109
self.assertEqual(list(form.errors), ['pub_date'])
112
class GenericIPAddressFieldTests(ValidationTestCase):
114
def test_correct_generic_ip_passes(self):
115
giptm = GenericIPAddressTestModel(generic_ip="1.2.3.4")
116
self.assertIsNone(giptm.full_clean())
117
giptm = GenericIPAddressTestModel(generic_ip="2001::2")
118
self.assertIsNone(giptm.full_clean())
120
def test_invalid_generic_ip_raises_error(self):
121
giptm = GenericIPAddressTestModel(generic_ip="294.4.2.1")
122
self.assertFailsValidation(giptm.full_clean, ['generic_ip',])
123
giptm = GenericIPAddressTestModel(generic_ip="1:2")
124
self.assertFailsValidation(giptm.full_clean, ['generic_ip',])
126
def test_correct_v4_ip_passes(self):
127
giptm = GenericIPAddressTestModel(v4_ip="1.2.3.4")
128
self.assertIsNone(giptm.full_clean())
130
def test_invalid_v4_ip_raises_error(self):
131
giptm = GenericIPAddressTestModel(v4_ip="294.4.2.1")
132
self.assertFailsValidation(giptm.full_clean, ['v4_ip',])
133
giptm = GenericIPAddressTestModel(v4_ip="2001::2")
134
self.assertFailsValidation(giptm.full_clean, ['v4_ip',])
136
def test_correct_v6_ip_passes(self):
137
giptm = GenericIPAddressTestModel(v6_ip="2001::2")
138
self.assertIsNone(giptm.full_clean())
140
def test_invalid_v6_ip_raises_error(self):
141
giptm = GenericIPAddressTestModel(v6_ip="1.2.3.4")
142
self.assertFailsValidation(giptm.full_clean, ['v6_ip',])
143
giptm = GenericIPAddressTestModel(v6_ip="1:2")
144
self.assertFailsValidation(giptm.full_clean, ['v6_ip',])
146
def test_v6_uniqueness_detection(self):
147
# These two addresses are the same with different syntax
148
giptm = GenericIPAddressTestModel(generic_ip="2001::1:0:0:0:0:2")
150
giptm = GenericIPAddressTestModel(generic_ip="2001:0:1:2")
151
self.assertFailsValidation(giptm.full_clean, ['generic_ip',])
153
def test_v4_unpack_uniqueness_detection(self):
154
# These two are different, because we are not doing IPv4 unpacking
155
giptm = GenericIPAddressTestModel(generic_ip="::ffff:10.10.10.10")
157
giptm = GenericIPAddressTestModel(generic_ip="10.10.10.10")
158
self.assertIsNone(giptm.full_clean())
160
# These two are the same, because we are doing IPv4 unpacking
161
giptm = GenericIPAddrUnpackUniqueTest(generic_v4unpack_ip="::ffff:18.52.18.52")
163
giptm = GenericIPAddrUnpackUniqueTest(generic_v4unpack_ip="18.52.18.52")
164
self.assertFailsValidation(giptm.full_clean, ['generic_v4unpack_ip',])
166
def test_empty_generic_ip_passes(self):
167
giptm = GenericIPAddressTestModel(generic_ip="")
168
self.assertIsNone(giptm.full_clean())
169
giptm = GenericIPAddressTestModel(generic_ip=None)
170
self.assertIsNone(giptm.full_clean())