Fixed #11603 - Added django.test.SimpleTestCase.assertFormsetError

Thank-you Martin Green for the patch.
This commit is contained in:
Tim Graham 2013-02-08 18:45:26 -05:00
parent 1e29428db2
commit d194714c0a
7 changed files with 340 additions and 1 deletions

View file

@ -21,6 +21,7 @@ urlpatterns = patterns('',
(r'^bad_view/$', views.bad_view),
(r'^form_view/$', views.form_view),
(r'^form_view_with_template/$', views.form_view_with_template),
(r'^formset_view/$', views.formset_view),
(r'^login_protected_view/$', views.login_protected_view),
(r'^login_protected_method_view/$', views.login_protected_method_view),
(r'^login_protected_view_custom_redirect/$', views.login_protected_view_changed_redirect),

View file

@ -7,7 +7,8 @@ from xml.dom.minidom import parseString
from django.contrib.auth.decorators import login_required, permission_required
from django.core import mail
from django.forms import fields
from django.forms.forms import Form
from django.forms.forms import Form, ValidationError
from django.forms.formsets import formset_factory, BaseFormSet
from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound
from django.shortcuts import render_to_response
from django.template import Context, Template
@ -95,6 +96,12 @@ class TestForm(Form):
single = fields.ChoiceField(choices=TestChoices)
multi = fields.MultipleChoiceField(choices=TestChoices)
def clean(self):
cleaned_data = self.cleaned_data
if cleaned_data.get("text") == "Raise non-field error":
raise ValidationError("Non-field error.")
return cleaned_data
def form_view(request):
"A view that tests a simple form"
if request.method == 'POST':
@ -130,6 +137,43 @@ def form_view_with_template(request):
}
)
class BaseTestFormSet(BaseFormSet):
def clean(self):
"""Checks that no two email addresses are the same."""
if any(self.errors):
# Don't bother validating the formset unless each form is valid
return
emails = []
for i in range(0, self.total_form_count()):
form = self.forms[i]
email = form.cleaned_data['email']
if email in emails:
raise ValidationError(
"Forms in a set must have distinct email addresses."
)
emails.append(email)
TestFormSet = formset_factory(TestForm, BaseTestFormSet)
def formset_view(request):
"A view that tests a simple formset"
if request.method == 'POST':
formset = TestFormSet(request.POST)
if formset.is_valid():
t = Template('Valid POST data.', name='Valid POST Template')
c = Context()
else:
t = Template('Invalid POST data. {{ my_formset.errors }}',
name='Invalid POST Template')
c = Context({'my_formset': formset})
else:
formset = TestForm(request.GET)
t = Template('Viewing base formset. {{ my_formset }}.',
name='Formset GET Template')
c = Context({'my_formset': formset})
return HttpResponse(t.render(c))
def login_protected_view(request):
"A simple view that is login protected."
t = Template('This is a login protected test. Username is {{ user.username }}.', name='Login Template')

View file

@ -543,6 +543,197 @@ class AssertFormErrorTests(TestCase):
except AssertionError as e:
self.assertIn("abc: The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )", str(e))
class AssertFormsetErrorTests(TestCase):
msg_prefixes = [("", {}), ("abc: ", {"msg_prefix": "abc"})]
def setUp(self):
"""Makes response object for testing field and non-field errors"""
# For testing field and non-field errors
self.response_form_errors = self.getResponse({
'form-TOTAL_FORMS': '2',
'form-INITIAL_FORMS': '2',
'form-0-text': 'Raise non-field error',
'form-0-email': 'not an email address',
'form-0-value': 37,
'form-0-single': 'b',
'form-0-multi': ('b','c','e'),
'form-1-text': 'Hello World',
'form-1-email': 'email@domain.com',
'form-1-value': 37,
'form-1-single': 'b',
'form-1-multi': ('b','c','e'),
})
# For testing non-form errors
self.response_nonform_errors = self.getResponse({
'form-TOTAL_FORMS': '2',
'form-INITIAL_FORMS': '2',
'form-0-text': 'Hello World',
'form-0-email': 'email@domain.com',
'form-0-value': 37,
'form-0-single': 'b',
'form-0-multi': ('b','c','e'),
'form-1-text': 'Hello World',
'form-1-email': 'email@domain.com',
'form-1-value': 37,
'form-1-single': 'b',
'form-1-multi': ('b','c','e'),
})
def getResponse(self, post_data):
response = self.client.post('/test_client/formset_view/', post_data)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "Invalid POST Template")
return response
def test_unknown_formset(self):
"An assertion is raised if the formset name is unknown"
for prefix, kwargs in self.msg_prefixes:
with self.assertRaises(AssertionError) as cm:
self.assertFormsetError(self.response_form_errors,
'wrong_formset',
0,
'Some_field',
'Some error.',
**kwargs)
self.assertIn(prefix + "The formset 'wrong_formset' was not "
"used to render the response",
str(cm.exception))
def test_unknown_field(self):
"An assertion is raised if the field name is unknown"
for prefix, kwargs in self.msg_prefixes:
with self.assertRaises(AssertionError) as cm:
self.assertFormsetError(self.response_form_errors,
'my_formset',
0,
'Some_field',
'Some error.',
**kwargs)
self.assertIn(prefix + "The formset 'my_formset', "
"form 0 in context 0 "
"does not contain the field 'Some_field'",
str(cm.exception))
def test_no_error_field(self):
"An assertion is raised if the field doesn't have any errors"
for prefix, kwargs in self.msg_prefixes:
with self.assertRaises(AssertionError) as cm:
self.assertFormsetError(self.response_form_errors,
'my_formset',
1,
'value',
'Some error.',
**kwargs)
self.assertIn(prefix + "The field 'value' "
"on formset 'my_formset', form 1 "
"in context 0 contains no errors",
str(cm.exception))
def test_unknown_error(self):
"An assertion is raised if the field doesn't contain the specified error"
for prefix, kwargs in self.msg_prefixes:
with self.assertRaises(AssertionError) as cm:
self.assertFormsetError(self.response_form_errors,
'my_formset',
0,
'email',
'Some error.',
**kwargs)
self.assertIn(str_prefix(prefix + "The field 'email' "
"on formset 'my_formset', form 0 in context 0 does not "
"contain the error 'Some error.' (actual errors: "
"[%(_)s'Enter a valid email address.'])"),
str(cm.exception))
def test_field_error(self):
"No assertion is raised if the field contains the provided error"
for prefix, kwargs in self.msg_prefixes:
self.assertFormsetError(self.response_form_errors,
'my_formset',
0,
'email',
['Enter a valid email address.'],
**kwargs)
def test_no_nonfield_error(self):
"An assertion is raised if the formsets non-field errors doesn't contain any errors."
for prefix, kwargs in self.msg_prefixes:
with self.assertRaises(AssertionError) as cm:
self.assertFormsetError(self.response_form_errors,
'my_formset',
1,
None,
'Some error.',
**kwargs)
self.assertIn(prefix + "The formset 'my_formset', form 1 in "
"context 0 does not contain any "
"non-field errors.",
str(cm.exception))
def test_unknown_nonfield_error(self):
"An assertion is raised if the formsets non-field errors doesn't contain the provided error."
for prefix, kwargs in self.msg_prefixes:
with self.assertRaises(AssertionError) as cm:
self.assertFormsetError(self.response_form_errors,
'my_formset',
0,
None,
'Some error.',
**kwargs)
self.assertIn(str_prefix(prefix +
"The formset 'my_formset', form 0 in context 0 does not "
"contain the non-field error 'Some error.' (actual errors: "
"[%(_)s'Non-field error.'])"), str(cm.exception))
def test_nonfield_error(self):
"No assertion is raised if the formsets non-field errors contains the provided error."
for prefix, kwargs in self.msg_prefixes:
self.assertFormsetError(self.response_form_errors,
'my_formset',
0,
None,
'Non-field error.',
**kwargs)
def test_no_nonform_error(self):
"An assertion is raised if the formsets non-form errors doesn't contain any errors."
for prefix, kwargs in self.msg_prefixes:
with self.assertRaises(AssertionError) as cm:
self.assertFormsetError(self.response_form_errors,
'my_formset',
None,
None,
'Some error.',
**kwargs)
self.assertIn(prefix + "The formset 'my_formset' in context 0 "
"does not contain any non-form errors.",
str(cm.exception))
def test_unknown_nonform_error(self):
"An assertion is raised if the formsets non-form errors doesn't contain the provided error."
for prefix, kwargs in self.msg_prefixes:
with self.assertRaises(AssertionError) as cm:
self.assertFormsetError(self.response_nonform_errors,
'my_formset',
None,
None,
'Some error.',
**kwargs)
self.assertIn(str_prefix(prefix +
"The formset 'my_formset' in context 0 does not contain the "
"non-form error 'Some error.' (actual errors: [%(_)s'Forms "
"in a set must have distinct email addresses.'])"), str(cm.exception))
def test_nonform_error(self):
"No assertion is raised if the formsets non-form errors contains the provided error."
for prefix, kwargs in self.msg_prefixes:
self.assertFormsetError(self.response_nonform_errors,
'my_formset',
None,
None,
'Forms in a set must have distinct email '
'addresses.',
**kwargs)
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class LoginTests(TestCase):
fixtures = ['testdata']