Code

Ticket #11603: assertformseterror.diff.patch

File assertformseterror.diff.patch, 20.4 KB (added by martin_speleo, 2 years ago)

Maintance update of patch, and removal of entry in release notes for 1.4

  • AUTHORS

     
    219219    pradeep.gowda@gmail.com 
    220220    Collin Grady <collin@collingrady.com> 
    221221    Gabriel Grant <g@briel.ca> 
     222    Martin Green 
    222223    Simon Greenhill <dev@simon.net.nz> 
    223224    Owen Griffiths 
    224225    Espen Grindhaug <http://grindhaug.org/> 
  • django/test/testcases.py

     
    717717            self.fail(msg_prefix + "The form '%s' was not used to render the" 
    718718                      " response" % form) 
    719719 
     720    def assertFormsetError(self, response, formset, form_index, field, errors, 
     721                           msg_prefix=''): 
     722        """ 
     723        Asserts that a formset used to render the response has a specific error. 
     724 
     725        For field errors specify the form_index and the field. 
     726        For non-field errors specify the form_index and the field as None. 
     727        For non-form errors specify form_index as None and the field as None. 
     728        """ 
     729 
     730        # Add punctuation to msg_prefix 
     731        if msg_prefix: 
     732            msg_prefix += ": " 
     733 
     734        # Put context(s) into a list to simplify processing. 
     735        contexts = to_list(response.context) 
     736        if not contexts: 
     737            self.fail(msg_prefix + 'Response did not use any contexts to ' 
     738                      'render the response') 
     739 
     740        # Put error(s) into a list to simplify processing. 
     741        errors = to_list(errors) 
     742 
     743        # Search all contexts for the error. 
     744        found_formset = False 
     745        for i,context in enumerate(contexts): 
     746            if formset not in context: 
     747                continue 
     748            found_formset = True 
     749            for err in errors: 
     750                if field is not None: 
     751                    if field in context[formset].forms[form_index].errors: 
     752                        field_errors = \ 
     753                                     context[formset].forms[form_index].errors[field] 
     754                        self.assertTrue(err in field_errors, 
     755                                msg_prefix + "The field '%s' on formset '%s', " 
     756                                "form %d in context %d does not contain the " 
     757                                "error '%s' (actual errors: %s)" % 
     758                                        (field, formset, form_index, i, err, 
     759                                        repr(field_errors))) 
     760                    elif field in context[formset].forms[form_index].fields: 
     761                        self.fail(msg_prefix + "The field '%s' " 
     762                                  "on formset '%s', form %d in " 
     763                                  "context %d contains no errors" % 
     764                                        (field, formset, form_index,i)) 
     765                    else: 
     766                        self.fail(msg_prefix + "The formset '%s', form %d in " 
     767                                 "context %d does not contain the field '%s'" % 
     768                                        (formset, form_index, i, field)) 
     769                elif form_index is not None: 
     770                    non_field_errors = \ 
     771                                context[formset].forms[form_index].non_field_errors() 
     772                    self.assertFalse(len(non_field_errors) == 0, 
     773                                msg_prefix + "The formset '%s', form %d in " 
     774                                "context %d does not contain any non-field " 
     775                                "errors." % (formset, form_index, i)) 
     776                    self.assertTrue(err in non_field_errors, 
     777                                    msg_prefix + "The formset '%s', form %d " 
     778                                    "in context %d does not contain the " 
     779                                    "non-field error '%s' " 
     780                                    "(actual errors: %s)" % 
     781                                        (formset, form_index, i, err, 
     782                                         repr(non_field_errors))) 
     783                else: 
     784                    non_form_errors = context[formset].non_form_errors() 
     785                    self.assertFalse(len(non_form_errors) == 0, 
     786                                     msg_prefix + "The formset '%s' in " 
     787                                     "context %d does not contain any " 
     788                                     "non-form errors." % (formset, i)) 
     789                    self.assertTrue(err in non_form_errors, 
     790                                    msg_prefix + "The formset '%s' in context " 
     791                                    "%d does not contain the " 
     792                                    "non-form error '%s' (actual errors: %s)" % 
     793                                      (formset, i, err, repr(non_form_errors))) 
     794        if not found_formset: 
     795            self.fail(msg_prefix + "The formset '%s' was not used to render " 
     796                      "the response" % formset) 
     797 
    720798    def assertTemplateUsed(self, response=None, template_name=None, msg_prefix=''): 
    721799        """ 
    722800        Asserts that the template with the provided name was used in rendering 
  • docs/topics/testing.txt

     
    15831583 
    15841584    ``errors`` is an error string, or a list of error strings, that are 
    15851585    expected as a result of form validation. 
     1586  
     1587.. method:: TestCase.assertFormsetError(response, formset, form_index, field, errors, msg_prefix='') 
    15861588 
     1589    .. versionadded:: 1.4 
     1590     
     1591    Asserts that the formset raises the provided list of errors when rendered. 
     1592 
     1593    ``formset`` is the name the ``Formset`` instance was given in the template 
     1594    context. 
     1595 
     1596    ``form_index`` is the number of the form within the ``Formset``.  If ``form_index`` 
     1597    has a value of ``None``, non-form errors (errors you can access via 
     1598    ``formset.non_form_errors()``) will be checked. 
     1599 
     1600    ``field`` is the name of the field on the form to check. If ``field`` 
     1601    has a value of ``None``, non-field errors (errors you can access via 
     1602    ``form.non_field_errors()``) will be checked. 
     1603 
     1604    ``errors`` is an error string, or a list of error strings, that are 
     1605    expected as a result of form validation. 
     1606 
    15871607.. method:: TestCase.assertTemplateUsed(response, template_name, msg_prefix='') 
    15881608 
    15891609    Asserts that the template with the given name was used in rendering the 
  • tests/modeltests/test_client/urls.py

     
    2121    (r'^bad_view/$', views.bad_view), 
    2222    (r'^form_view/$', views.form_view), 
    2323    (r'^form_view_with_template/$', views.form_view_with_template), 
     24    (r'^formset_view/$', views.formset_view), 
    2425    (r'^login_protected_view/$', views.login_protected_view), 
    2526    (r'^login_protected_method_view/$', views.login_protected_method_view), 
    2627    (r'^login_protected_view_custom_redirect/$', views.login_protected_view_changed_redirect), 
  • tests/modeltests/test_client/views.py

     
    33from django.contrib.auth.decorators import login_required, permission_required 
    44from django.core import mail 
    55from django.forms import fields 
    6 from django.forms.forms import Form 
     6from django.forms.forms import Form, ValidationError 
     7from django.forms.formsets import formset_factory, BaseFormSet 
    78from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound 
    89from django.shortcuts import render_to_response 
    910from django.template import Context, Template 
     
    9293    value = fields.IntegerField() 
    9394    single = fields.ChoiceField(choices=TestChoices) 
    9495    multi = fields.MultipleChoiceField(choices=TestChoices) 
     96    def clean(self): 
     97        cleaned_data = self.cleaned_data 
     98        if cleaned_data.get("text") == "Raise non-field error": 
     99            raise ValidationError(u"Non-field error.") 
     100        # Always return the full collection of cleaned data. 
     101        return cleaned_data 
    95102 
    96103def form_view(request): 
    97104    "A view that tests a simple form" 
     
    128135        } 
    129136    ) 
    130137 
     138class BaseTestFormSet(BaseFormSet): 
     139    def clean(self): 
     140        """Checks that no two E-mail addresses are the same.""" 
     141        if any(self.errors): 
     142               # Don't bother validating the formset unless each form is valid 
     143               # (form.cleaned_data will not exist) 
     144               return 
     145        emails = [] 
     146        for i in range(0, self.total_form_count()): 
     147            form = self.forms[i] 
     148 
     149            email = form.cleaned_data['email'] 
     150            if email in emails: 
     151                raise ValidationError, \ 
     152                      "Forms in a set must have distinct E-mail addresses." 
     153            emails.append(email) 
     154 
     155TestFormSet = formset_factory(TestForm, BaseTestFormSet) 
     156 
     157def formset_view(request): 
     158    "A view that tests a simple formset" 
     159    if request.method == 'POST': 
     160        formset = TestFormSet(request.POST) 
     161        if formset.is_valid(): 
     162            t = Template('Valid POST data.', name='Valid POST Template') 
     163            c = Context() 
     164        else: 
     165            t = Template('Invalid POST data. {{ my_formset.errors }}',  
     166                         name='Invalid POST Template') 
     167            c = Context({'my_formset': formset}) 
     168    else: 
     169        formset = TestForm(request.GET) 
     170        t = Template('Viewing base formset. {{ my_formset }}.',  
     171                     name='Formset GET Template') 
     172        c = Context({'my_formset': formset}) 
     173    return HttpResponse(t.render(c)) 
     174 
    131175def login_protected_view(request): 
    132176    "A simple view that is login protected." 
    133177    t = Template('This is a login protected test. Username is {{ user.username }}.', name='Login Template') 
  • 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 
     
    523524        except AssertionError, e: 
    524525            self.assertIn("abc: The form 'form' in context 0 does not contain the non-field error 'Some error.' (actual errors: )", str(e)) 
    525526 
     527class AssertFormsetErrorTests(TestCase): 
     528    msg_prefixes = [("", {}), ("abc: ", {"msg_prefix": "abc"})] 
     529    def setUp(self): 
     530        """Makes response object for testing field and non-field errors""" 
     531        #For testing field and non-field errors 
     532        self.response_form_errors = self.getResponse( 
     533           {'form-TOTAL_FORMS': u'2', 
     534            'form-INITIAL_FORMS': u'2', 
     535            'form-0-text': 'Raise non-field error', 
     536            'form-0-email': 'not an email address', 
     537            'form-0-value': 37, 
     538            'form-0-single': 'b', 
     539            'form-0-multi': ('b','c','e'), 
     540            'form-1-text': 'Hello World', 
     541            'form-1-email': 'email@domain.com', 
     542            'form-1-value': 37, 
     543            'form-1-single': 'b', 
     544            'form-1-multi': ('b','c','e'), 
     545        }) 
     546        #For testing non-form errors 
     547        self.response_nonform_errors = self.getResponse( 
     548           {'form-TOTAL_FORMS': u'2', 
     549            'form-INITIAL_FORMS': u'2', 
     550            'form-0-text': 'Hello World', 
     551            'form-0-email': 'email@domain.com', 
     552            'form-0-value': 37, 
     553            'form-0-single': 'b', 
     554            'form-0-multi': ('b','c','e'), 
     555            'form-1-text': 'Hello World', 
     556            'form-1-email': 'email@domain.com', 
     557            'form-1-value': 37, 
     558            'form-1-single': 'b', 
     559            'form-1-multi': ('b','c','e'), 
     560        }) 
     561 
     562    def getResponse(self, post_data): 
     563        response = self.client.post('/test_client/formset_view/', 
     564                                    post_data) 
     565        self.assertEqual(response.status_code, 200) 
     566        self.assertTemplateUsed(response, "Invalid POST Template") 
     567        return response 
     568 
     569    def test_unknown_formset(self): 
     570        "An assertion is raised if the formset name is unknown" 
     571        for prefix, kwargs in self.msg_prefixes: 
     572            with self.assertRaises(AssertionError) as cm: 
     573                self.assertFormsetError(self.response_form_errors, 
     574                                        'wrong_formset', 
     575                                        0, 
     576                                        'Some_field', 
     577                                        'Some error.', 
     578                                        **kwargs)             
     579            self.assertIn(prefix + "The formset 'wrong_formset' was not " 
     580                                   "used to render the response",  
     581                          str(cm.exception)) 
     582 
     583    def test_unknown_field(self): 
     584        "An assertion is raised if the field name is unknown" 
     585        for prefix, kwargs in self.msg_prefixes: 
     586            with self.assertRaises(AssertionError) as cm: 
     587                self.assertFormsetError(self.response_form_errors, 
     588                                        'my_formset', 
     589                                        0, 
     590                                        'Some_field', 
     591                                        'Some error.', 
     592                                        **kwargs) 
     593            self.assertIn(prefix + "The formset 'my_formset', " 
     594                                   "form 0 in context 0 " 
     595                                   "does not contain the field 'Some_field'", 
     596                          str(cm.exception)) 
     597 
     598    def test_noerror_field(self): 
     599        "An assertion is raised if the field doesn't have any errors" 
     600        for prefix, kwargs in self.msg_prefixes: 
     601            with self.assertRaises(AssertionError) as cm: 
     602                self.assertFormsetError(self.response_form_errors, 
     603                                        'my_formset', 
     604                                        1, 
     605                                        'value', 
     606                                        'Some error.', 
     607                                        **kwargs) 
     608            self.assertIn(prefix + "The field 'value' " 
     609                                   "on formset 'my_formset', form 1 " 
     610                                   "in context 0 contains no errors", 
     611                          str(cm.exception)) 
     612 
     613    def test_unknown_error(self): 
     614        "An assertion is raised if the field doesn't contain the specified error" 
     615        for prefix, kwargs in self.msg_prefixes: 
     616            with self.assertRaises(AssertionError) as cm: 
     617                self.assertFormsetError(self.response_form_errors, 
     618                                        'my_formset', 
     619                                        0, 
     620                                        'email', 
     621                                        'Some error.', 
     622                                        **kwargs) 
     623            self.assertIn(prefix + "The field 'email' " 
     624                                   "on formset 'my_formset', form 0 " 
     625                                   "in context 0 does not contain the error " 
     626                                   "'Some error.' (actual errors: " 
     627                                   "[u'Enter a valid e-mail address.'])", 
     628                          str(cm.exception)) 
     629 
     630    def test_field_error(self): 
     631        "No assertion is raised if the field contains the provided error" 
     632        for prefix, kwargs in self.msg_prefixes: 
     633            self.assertFormsetError(self.response_form_errors, 
     634                                'my_formset', 
     635                                0, 
     636                                'email', 
     637                                'Enter a valid e-mail address.', 
     638                                **kwargs) 
     639 
     640    def test_no_nonfield_error(self): 
     641        "An assertion is raised if the formsets non-field errors doesn't contain any errors." 
     642        for prefix, kwargs in self.msg_prefixes: 
     643            with self.assertRaises(AssertionError) as cm: 
     644                self.assertFormsetError(self.response_form_errors, 
     645                                        'my_formset', 
     646                                        1, 
     647                                        None, 
     648                                        'Some error.', 
     649                                        **kwargs) 
     650            self.assertIn(prefix + "The formset 'my_formset', form 1 in " 
     651                                   "context 0 does not contain any " 
     652                                   "non-field errors.", 
     653                          str(cm.exception)) 
     654 
     655    def test_unknown_nonfield_error(self): 
     656        "An assertion is raised if the formsets non-field errors doesn't contain the provided error." 
     657        for prefix, kwargs in self.msg_prefixes: 
     658            with self.assertRaises(AssertionError) as cm: 
     659                self.assertFormsetError(self.response_form_errors, 
     660                                        'my_formset', 
     661                                        0, 
     662                                        None, 
     663                                        'Some error.', 
     664                                        **kwargs) 
     665            self.assertIn(prefix + "The formset 'my_formset', form 0 in " 
     666                                   "context 0 does not contain the non-field error " 
     667                                   "'Some error.' (actual errors: " 
     668                                   "[u'Non-field error.'])", 
     669                          str(cm.exception)) 
     670 
     671    def test_nonfield_error(self): 
     672        "No assertion is raised if the formsets non-field errors contains the provided error." 
     673        for prefix, kwargs in self.msg_prefixes: 
     674            self.assertFormsetError(self.response_form_errors, 
     675                                'my_formset', 
     676                                0, 
     677                                None, 
     678                                'Non-field error.', 
     679                                **kwargs) 
     680 
     681    def test_no_nonform_error(self): 
     682        "An assertion is raised if the formsets non-form errors doesn't contain any errors." 
     683        for prefix, kwargs in self.msg_prefixes: 
     684            with self.assertRaises(AssertionError) as cm: 
     685                self.assertFormsetError(self.response_form_errors, 
     686                                        'my_formset', 
     687                                        None, 
     688                                        None, 
     689                                        'Some error.', 
     690                                        **kwargs) 
     691            self.assertIn(prefix + "The formset 'my_formset' in context 0 " 
     692                                   "does not contain any non-form errors.", 
     693                          str(cm.exception)) 
     694 
     695    def test_unknown_nonform_error(self): 
     696        "An assertion is raised if the formsets non-form errors doesn't contain the provided error." 
     697        for prefix, kwargs in self.msg_prefixes: 
     698            with self.assertRaises(AssertionError) as cm: 
     699                self.assertFormsetError(self.response_nonform_errors, 
     700                                        'my_formset', 
     701                                        None, 
     702                                        None, 
     703                                        'Some error.', 
     704                                        **kwargs) 
     705            self.assertIn(prefix + "The formset 'my_formset' in context 0 " 
     706                                   "does not contain the non-form error " 
     707                                   "'Some error.' (actual errors: [u'Forms " 
     708                                   "in a set must have distinct E-mail " 
     709                                   "addresses.'])", 
     710                          str(cm.exception)) 
     711 
     712    def test_nonform_error(self): 
     713        "No assertion is raised if the formsets non-form errors contains the provided error." 
     714        for prefix, kwargs in self.msg_prefixes: 
     715            self.assertFormsetError(self.response_nonform_errors, 
     716                                    'my_formset', 
     717                                    None, 
     718                                    None, 
     719                                    'Forms in a set must have distinct E-mail ' 
     720                                    'addresses.', 
     721                                    **kwargs) 
     722 
    526723class LoginTests(TestCase): 
    527724    fixtures = ['testdata'] 
    528725