Ticket #11603: assertformseterror.diff

File assertformseterror.diff, 20.8 KB (added by martin_speleo, 13 years ago)

Fixed failing unittests, changed form parameter to form_index

  • AUTHORS

     
    215215    pradeep.gowda@gmail.com
    216216    Collin Grady <collin@collingrady.com>
    217217    Gabriel Grant <g@briel.ca>
     218    Martin Green
    218219    Simon Greenhill <dev@simon.net.nz>
    219220    Owen Griffiths
    220221    Espen Grindhaug <http://grindhaug.org/>
  • docs/topics/testing.txt

     
    15691569
    15701570    ``errors`` is an error string, or a list of error strings, that are
    15711571    expected as a result of form validation.
     1572 
     1573.. method:: TestCase.assertFormsetError(response, formset, form_index, field, errors, msg_prefix='')
    15721574
     1575    .. versionadded:: 1.4
     1576   
     1577    Asserts that the formset raises the provided list of errors when rendered.
     1578
     1579    ``formset`` is the name the ``Formset`` instance was given in the template
     1580    context.
     1581
     1582    ``form_index`` is the number of the form within the ``Formset``.  If ``form_index``
     1583    has a value of ``None``, non-form errors (errors you can access via
     1584    ``formset.non_form_errors()``) will be checked.
     1585
     1586    ``field`` is the name of the field on the form to check. If ``field``
     1587    has a value of ``None``, non-field errors (errors you can access via
     1588    ``form.non_field_errors()``) will be checked.
     1589
     1590    ``errors`` is an error string, or a list of error strings, that are
     1591    expected as a result of form validation.
     1592
    15731593.. method:: TestCase.assertTemplateUsed(response, template_name, msg_prefix='')
    15741594
    15751595    Asserts that the template with the given name was used in rendering the
  • docs/releases/1.4.txt

     
    266266  about :ref:`the 403 (HTTP Forbidden) view<http_forbidden_view>` for more
    267267  information.
    268268
     269* Added an `assertFormsetError` into the unittest framework
     270
    269271.. _backwards-incompatible-changes-1.4:
    270272
    271273Backwards incompatible changes in 1.4
  • django/test/testcases.py

     
    568568            self.fail(msg_prefix + "The form '%s' was not used to render the"
    569569                      " response" % form)
    570570
     571    def assertFormsetError(self, response, formset, form_index, field, errors,
     572                           msg_prefix=''):
     573        """
     574        Asserts that a formset used to render the response has a specific error.
     575
     576        For field errors specify the form_index and the field.
     577        For non-field errors specify the form_index and the field as None.
     578        For non-form errors specify form_index as None and the field as None.
     579        """
     580
     581        # Add punctuation to msg_prefix
     582        if msg_prefix:
     583            msg_prefix += ": "
     584
     585        # Put context(s) into a list to simplify processing.
     586        contexts = to_list(response.context)
     587        if not contexts:
     588            self.fail(msg_prefix + 'Response did not use any contexts to '
     589                      'render the response')
     590
     591        # Put error(s) into a list to simplify processing.
     592        errors = to_list(errors)
     593
     594        # Search all contexts for the error.
     595        found_formset = False
     596        for i,context in enumerate(contexts):
     597            if formset not in context:
     598                continue
     599            found_formset = True
     600            for err in errors:
     601                if field is not None:
     602                    if field in context[formset].forms[form_index].errors:
     603                        field_errors = \
     604                                     context[formset].forms[form_index].errors[field]
     605                        self.assertTrue(err in field_errors,
     606                                msg_prefix + "The field '%s' on formset '%s', "
     607                                "form %d in context %d does not contain the "
     608                                "error '%s' (actual errors: %s)" %
     609                                        (field, formset, form_index, i, err,
     610                                        repr(field_errors)))
     611                    elif field in context[formset].forms[form_index].fields:
     612                        self.fail(msg_prefix + "The field '%s' "
     613                                  "on formset '%s', form %d in "
     614                                  "context %d contains no errors" %
     615                                        (field, formset, form_index,i))
     616                    else:
     617                        self.fail(msg_prefix + "The formset '%s', form %d in "
     618                                 "context %d does not contain the field '%s'" %
     619                                        (formset, form_index, i, field))
     620                elif form_index is not None:
     621                    non_field_errors = \
     622                                context[formset].forms[form_index].non_field_errors()
     623                    self.assertFalse(len(non_field_errors) == 0,
     624                                msg_prefix + "The formset '%s', form %d in "
     625                                "context %d does not contain any non-field "
     626                                "errors." % (formset, form_index, i))
     627                    self.assertTrue(err in non_field_errors,
     628                                    msg_prefix + "The formset '%s', form %d "
     629                                    "in context %d does not contain the "
     630                                    "non-field error '%s' "
     631                                    "(actual errors: %s)" %
     632                                        (formset, form_index, i, err,
     633                                         repr(non_field_errors)))
     634                else:
     635                    non_form_errors = context[formset].non_form_errors()
     636                    self.assertFalse(len(non_form_errors) == 0,
     637                                     msg_prefix + "The formset '%s' in "
     638                                     "context %d does not contain any "
     639                                     "non-form errors." % (formset, i))
     640                    self.assertTrue(err in non_form_errors,
     641                                    msg_prefix + "The formset '%s' in context "
     642                                    "%d does not contain the "
     643                                    "non-form error '%s' (actual errors: %s)" %
     644                                      (formset, i, err, repr(non_form_errors)))
     645        if not found_formset:
     646            self.fail(msg_prefix + "The formset '%s' was not used to render "
     647                      "the response" % formset)
     648
     649
    571650    def assertTemplateUsed(self, response, template_name, msg_prefix=''):
    572651        """
    573652        Asserts that the template with the provided name was used in rendering
  • tests/modeltests/test_client/views.py

     
    44from django.template import Context, Template
    55from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound
    66from django.contrib.auth.decorators import login_required, permission_required
    7 from django.forms.forms import Form
     7from django.forms.forms import Form, ValidationError
     8from django.forms.formsets import formset_factory, BaseFormSet
    89from django.forms import fields
    910from django.shortcuts import render_to_response
    1011from django.utils.decorators import method_decorator
     
    9192    value = fields.IntegerField()
    9293    single = fields.ChoiceField(choices=TestChoices)
    9394    multi = fields.MultipleChoiceField(choices=TestChoices)
     95    def clean(self):
     96        cleaned_data = self.cleaned_data
     97        if cleaned_data.get("text") == "Raise non-field error":
     98            raise ValidationError(u"Non-field error.")
     99        # Always return the full collection of cleaned data.
     100        return cleaned_data
    94101
    95102def form_view(request):
    96103    "A view that tests a simple form"
     
    127134        }
    128135    )
    129136
     137class BaseTestFormSet(BaseFormSet):
     138    def clean(self):
     139        """Checks that no two E-mail addresses are the same."""
     140        if any(self.errors):
     141               # Don't bother validating the formset unless each form is valid
     142               # (form.cleaned_data will not exist)
     143               return
     144        emails = []
     145        for i in range(0, self.total_form_count()):
     146            form = self.forms[i]
     147
     148            email = form.cleaned_data['email']
     149            if email in emails:
     150                raise ValidationError, \
     151                      "Forms in a set must have distinct E-mail addresses."
     152            emails.append(email)
     153
     154TestFormSet = formset_factory(TestForm, BaseTestFormSet)
     155
     156def formset_view(request):
     157    "A view that tests a simple formset"
     158    if request.method == 'POST':
     159        formset = TestFormSet(request.POST)
     160        if formset.is_valid():
     161            t = Template('Valid POST data.', name='Valid POST Template')
     162            c = Context()
     163        else:
     164            t = Template('Invalid POST data. {{ my_formset.errors }}',
     165                         name='Invalid POST Template')
     166            c = Context({'my_formset': formset})
     167    else:
     168        formset = TestForm(request.GET)
     169        t = Template('Viewing base formset. {{ my_formset }}.',
     170                     name='Formset GET Template')
     171        c = Context({'my_formset': formset})
     172    return HttpResponse(t.render(c))
     173
    130174def login_protected_view(request):
    131175    "A simple view that is login protected."
    132176    t = Template('This is a login protected test. Username is {{ user.username }}.', name='Login Template')
  • tests/modeltests/test_client/urls.py

     
    1717    (r'^bad_view/$', views.bad_view),
    1818    (r'^form_view/$', views.form_view),
    1919    (r'^form_view_with_template/$', views.form_view_with_template),
     20    (r'^formset_view/$', views.formset_view),
    2021    (r'^login_protected_view/$', views.login_protected_view),
    2122    (r'^login_protected_method_view/$', views.login_protected_method_view),
    2223    (r'^login_protected_view_custom_redirect/$', views.login_protected_view_changed_redirect),
  • tests/regressiontests/test_client_regress/models.py

     
    22"""
    33Regression tests for the Test Client, especially the customized assertions.
    44"""
     5from __future__ import with_statement
    56import os
    67import warnings
    78
     
    478479        except AssertionError, e:
    479480            self.assertIn("abc: The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )", str(e))
    480481
     482class AssertFormsetErrorTests(TestCase):
     483    msg_prefixes = [("", {}), ("abc: ", {"msg_prefix": "abc"})]
     484    def setUp(self):
     485        """Makes response object for testing field and non-field errors"""
     486        #For testing field and non-field errors
     487        self.response_form_errors = self.getResponse(
     488           {'form-TOTAL_FORMS': u'2',
     489            'form-INITIAL_FORMS': u'2',
     490            'form-0-text': 'Raise non-field error',
     491            'form-0-email': 'not an email address',
     492            'form-0-value': 37,
     493            'form-0-single': 'b',
     494            'form-0-multi': ('b','c','e'),
     495            'form-1-text': 'Hello World',
     496            'form-1-email': 'email@domain.com',
     497            'form-1-value': 37,
     498            'form-1-single': 'b',
     499            'form-1-multi': ('b','c','e'),
     500        })
     501        #For testing non-form errors
     502        self.response_nonform_errors = self.getResponse(
     503           {'form-TOTAL_FORMS': u'2',
     504            'form-INITIAL_FORMS': u'2',
     505            'form-0-text': 'Hello World',
     506            'form-0-email': 'email@domain.com',
     507            'form-0-value': 37,
     508            'form-0-single': 'b',
     509            'form-0-multi': ('b','c','e'),
     510            'form-1-text': 'Hello World',
     511            'form-1-email': 'email@domain.com',
     512            'form-1-value': 37,
     513            'form-1-single': 'b',
     514            'form-1-multi': ('b','c','e'),
     515        })
     516
     517    def getResponse(self, post_data):
     518        response = self.client.post('/test_client/formset_view/',
     519                                    post_data)
     520        self.assertEqual(response.status_code, 200)
     521        self.assertTemplateUsed(response, "Invalid POST Template")
     522        return response
     523
     524    def test_unknown_formset(self):
     525        "An assertion is raised if the formset name is unknown"
     526        for prefix, kwargs in self.msg_prefixes:
     527            with self.assertRaises(AssertionError) as cm:
     528                self.assertFormsetError(self.response_form_errors,
     529                                        'wrong_formset',
     530                                        0,
     531                                        'Some_field',
     532                                        'Some error.',
     533                                        **kwargs)           
     534            self.assertIn(prefix + "The formset 'wrong_formset' was not "
     535                                   "used to render the response",
     536                          str(cm.exception))
     537
     538    def test_unknown_field(self):
     539        "An assertion is raised if the field name is unknown"
     540        for prefix, kwargs in self.msg_prefixes:
     541            with self.assertRaises(AssertionError) as cm:
     542                self.assertFormsetError(self.response_form_errors,
     543                                        'my_formset',
     544                                        0,
     545                                        'Some_field',
     546                                        'Some error.',
     547                                        **kwargs)
     548            self.assertIn(prefix + "The formset 'my_formset', "
     549                                   "form 0 in context 0 "
     550                                   "does not contain the field 'Some_field'",
     551                          str(cm.exception))
     552
     553    def test_noerror_field(self):
     554        "An assertion is raised if the field doesn't have any errors"
     555        for prefix, kwargs in self.msg_prefixes:
     556            with self.assertRaises(AssertionError) as cm:
     557                self.assertFormsetError(self.response_form_errors,
     558                                        'my_formset',
     559                                        1,
     560                                        'value',
     561                                        'Some error.',
     562                                        **kwargs)
     563            self.assertIn(prefix + "The field 'value' "
     564                                   "on formset 'my_formset', form 1 "
     565                                   "in context 0 contains no errors",
     566                          str(cm.exception))
     567
     568    def test_unknown_error(self):
     569        "An assertion is raised if the field doesn't contain the specified error"
     570        for prefix, kwargs in self.msg_prefixes:
     571            with self.assertRaises(AssertionError) as cm:
     572                self.assertFormsetError(self.response_form_errors,
     573                                        'my_formset',
     574                                        0,
     575                                        'email',
     576                                        'Some error.',
     577                                        **kwargs)
     578            self.assertIn(prefix + "The field 'email' "
     579                                   "on formset 'my_formset', form 0 "
     580                                   "in context 0 does not contain the error "
     581                                   "'Some error.' (actual errors: "
     582                                   "[u'Enter a valid e-mail address.'])",
     583                          str(cm.exception))
     584
     585    def test_field_error(self):
     586        "No assertion is raised if the field contains the provided error"
     587        for prefix, kwargs in self.msg_prefixes:
     588            self.assertFormsetError(self.response_form_errors,
     589                                'my_formset',
     590                                0,
     591                                'email',
     592                                'Enter a valid e-mail address.',
     593                                **kwargs)
     594
     595    def test_no_nonfield_error(self):
     596        "An assertion is raised if the formsets non-field errors doesn't contain any errors."
     597        for prefix, kwargs in self.msg_prefixes:
     598            with self.assertRaises(AssertionError) as cm:
     599                self.assertFormsetError(self.response_form_errors,
     600                                        'my_formset',
     601                                        1,
     602                                        None,
     603                                        'Some error.',
     604                                        **kwargs)
     605            self.assertIn(prefix + "The formset 'my_formset', form 1 in "
     606                                   "context 0 does not contain any "
     607                                   "non-field errors.",
     608                          str(cm.exception))
     609
     610    def test_unknown_nonfield_error(self):
     611        "An assertion is raised if the formsets non-field errors doesn't contain the provided error."
     612        for prefix, kwargs in self.msg_prefixes:
     613            with self.assertRaises(AssertionError) as cm:
     614                self.assertFormsetError(self.response_form_errors,
     615                                        'my_formset',
     616                                        0,
     617                                        None,
     618                                        'Some error.',
     619                                        **kwargs)
     620            self.assertIn(prefix + "The formset 'my_formset', form 0 in "
     621                                   "context 0 does not contain the non-field error "
     622                                   "'Some error.' (actual errors: "
     623                                   "[u'Non-field error.'])",
     624                          str(cm.exception))
     625
     626    def test_nonfield_error(self):
     627        "No assertion is raised if the formsets non-field errors contains the provided error."
     628        for prefix, kwargs in self.msg_prefixes:
     629            self.assertFormsetError(self.response_form_errors,
     630                                'my_formset',
     631                                0,
     632                                None,
     633                                'Non-field error.',
     634                                **kwargs)
     635
     636    def test_no_nonform_error(self):
     637        "An assertion is raised if the formsets non-form errors doesn't contain any errors."
     638        for prefix, kwargs in self.msg_prefixes:
     639            with self.assertRaises(AssertionError) as cm:
     640                self.assertFormsetError(self.response_form_errors,
     641                                        'my_formset',
     642                                        None,
     643                                        None,
     644                                        'Some error.',
     645                                        **kwargs)
     646            self.assertIn(prefix + "The formset 'my_formset' in context 0 "
     647                                   "does not contain any non-form errors.",
     648                          str(cm.exception))
     649
     650    def test_unknown_nonform_error(self):
     651        "An assertion is raised if the formsets non-form errors doesn't contain the provided error."
     652        for prefix, kwargs in self.msg_prefixes:
     653            with self.assertRaises(AssertionError) as cm:
     654                self.assertFormsetError(self.response_nonform_errors,
     655                                        'my_formset',
     656                                        None,
     657                                        None,
     658                                        'Some error.',
     659                                        **kwargs)
     660            self.assertIn(prefix + "The formset 'my_formset' in context 0 "
     661                                   "does not contain the non-form error "
     662                                   "'Some error.' (actual errors: [u'Forms "
     663                                   "in a set must have distinct E-mail "
     664                                   "addresses.'])",
     665                          str(cm.exception))
     666
     667    def test_nonform_error(self):
     668        "No assertion is raised if the formsets non-form errors contains the provided error."
     669        for prefix, kwargs in self.msg_prefixes:
     670            self.assertFormsetError(self.response_nonform_errors,
     671                                    'my_formset',
     672                                    None,
     673                                    None,
     674                                    'Forms in a set must have distinct E-mail '
     675                                    'addresses.',
     676                                    **kwargs)
     677
    481678class LoginTests(TestCase):
    482679    fixtures = ['testdata']
    483680
Back to Top