From ec6121693f112ae33b653b4364e812722d2eb567 Mon Sep 17 00:00:00 2001 From: Jon Dufresne Date: Mon, 28 Mar 2016 11:02:04 -0700 Subject: Fixed #22383 -- Added support for HTML5 required attribute on required form fields. --- tests/forms_tests/field_tests/test_charfield.py | 2 +- tests/forms_tests/field_tests/test_choicefield.py | 2 +- tests/forms_tests/field_tests/test_decimalfield.py | 11 +- .../forms_tests/field_tests/test_durationfield.py | 2 +- tests/forms_tests/field_tests/test_emailfield.py | 7 +- tests/forms_tests/field_tests/test_floatfield.py | 14 +- tests/forms_tests/field_tests/test_integerfield.py | 10 +- .../field_tests/test_multivaluefield.py | 16 +- tests/forms_tests/field_tests/test_urlfield.py | 4 +- tests/forms_tests/tests/test_forms.py | 909 ++++++++++++--------- tests/forms_tests/tests/test_regressions.py | 22 +- tests/forms_tests/tests/tests.py | 26 +- 12 files changed, 585 insertions(+), 440 deletions(-) (limited to 'tests/forms_tests') diff --git a/tests/forms_tests/field_tests/test_charfield.py b/tests/forms_tests/field_tests/test_charfield.py index 0927370af3..906b91bc75 100644 --- a/tests/forms_tests/field_tests/test_charfield.py +++ b/tests/forms_tests/field_tests/test_charfield.py @@ -119,4 +119,4 @@ class CharFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_charfield_disabled(self): f = CharField(disabled=True) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') diff --git a/tests/forms_tests/field_tests/test_choicefield.py b/tests/forms_tests/field_tests/test_choicefield.py index 013766d50b..69b4d9e342 100644 --- a/tests/forms_tests/field_tests/test_choicefield.py +++ b/tests/forms_tests/field_tests/test_choicefield.py @@ -81,6 +81,6 @@ class ChoiceFieldTest(FormFieldAssertionsMixin, SimpleTestCase): f = ChoiceField(choices=[('J', 'John'), ('P', 'Paul')], disabled=True) self.assertWidgetRendersTo( f, - '' '' ) diff --git a/tests/forms_tests/field_tests/test_decimalfield.py b/tests/forms_tests/field_tests/test_decimalfield.py index 3b23ced714..02600bcb5b 100644 --- a/tests/forms_tests/field_tests/test_decimalfield.py +++ b/tests/forms_tests/field_tests/test_decimalfield.py @@ -14,7 +14,7 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_decimalfield_1(self): f = DecimalField(max_digits=4, decimal_places=2) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean('') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): @@ -80,7 +80,10 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase): max_value=decimal.Decimal('1.5'), min_value=decimal.Decimal('0.5') ) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo( + f, + '', + ) with self.assertRaisesMessage(ValidationError, "'Ensure this value is less than or equal to 1.5.'"): f.clean('1.6') with self.assertRaisesMessage(ValidationError, "'Ensure this value is greater than or equal to 0.5.'"): @@ -136,7 +139,7 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase): f = DecimalField(max_digits=20) self.assertEqual(f.widget_attrs(NumberInput()), {'step': 'any'}) f = DecimalField(max_digits=6, widget=NumberInput(attrs={'step': '0.01'})) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') def test_decimalfield_localized(self): """ @@ -144,7 +147,7 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase): number input specific attributes. """ f = DecimalField(localize=True) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') def test_decimalfield_changed(self): f = DecimalField(max_digits=2, decimal_places=2) diff --git a/tests/forms_tests/field_tests/test_durationfield.py b/tests/forms_tests/field_tests/test_durationfield.py index 800d5d6ae3..28fd245a79 100644 --- a/tests/forms_tests/field_tests/test_durationfield.py +++ b/tests/forms_tests/field_tests/test_durationfield.py @@ -24,7 +24,7 @@ class DurationFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_durationfield_render(self): self.assertWidgetRendersTo( DurationField(initial=datetime.timedelta(hours=1)), - '', + '', ) def test_durationfield_integer_value(self): diff --git a/tests/forms_tests/field_tests/test_emailfield.py b/tests/forms_tests/field_tests/test_emailfield.py index d9fe64d3bb..4d37a7dc00 100644 --- a/tests/forms_tests/field_tests/test_emailfield.py +++ b/tests/forms_tests/field_tests/test_emailfield.py @@ -11,7 +11,7 @@ class EmailFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_emailfield_1(self): f = EmailField() - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean('') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): @@ -42,7 +42,10 @@ class EmailFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_emailfield_min_max_length(self): f = EmailField(min_length=10, max_length=15) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo( + f, + '', + ) with self.assertRaisesMessage(ValidationError, "'Ensure this value has at least 10 characters (it has 9).'"): f.clean('a@foo.com') self.assertEqual('alf@foo.com', f.clean('alf@foo.com')) diff --git a/tests/forms_tests/field_tests/test_floatfield.py b/tests/forms_tests/field_tests/test_floatfield.py index 5ae799d24b..d4ef4f496b 100644 --- a/tests/forms_tests/field_tests/test_floatfield.py +++ b/tests/forms_tests/field_tests/test_floatfield.py @@ -11,7 +11,7 @@ class FloatFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_floatfield_1(self): f = FloatField() - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean('') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): @@ -48,7 +48,10 @@ class FloatFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_floatfield_3(self): f = FloatField(max_value=1.5, min_value=0.5) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo( + f, + '', + ) with self.assertRaisesMessage(ValidationError, "'Ensure this value is less than or equal to 1.5.'"): f.clean('1.6') with self.assertRaisesMessage(ValidationError, "'Ensure this value is greater than or equal to 0.5.'"): @@ -60,7 +63,10 @@ class FloatFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_floatfield_widget_attrs(self): f = FloatField(widget=NumberInput(attrs={'step': 0.01, 'max': 1.0, 'min': 0.0})) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo( + f, + '', + ) def test_floatfield_localized(self): """ @@ -68,7 +74,7 @@ class FloatFieldTest(FormFieldAssertionsMixin, SimpleTestCase): number input specific attributes. """ f = FloatField(localize=True) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') def test_floatfield_changed(self): f = FloatField() diff --git a/tests/forms_tests/field_tests/test_integerfield.py b/tests/forms_tests/field_tests/test_integerfield.py index 15bbca1ee8..d5c14857ed 100644 --- a/tests/forms_tests/field_tests/test_integerfield.py +++ b/tests/forms_tests/field_tests/test_integerfield.py @@ -11,7 +11,7 @@ class IntegerFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_integerfield_1(self): f = IntegerField() - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean('') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): @@ -53,7 +53,7 @@ class IntegerFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_integerfield_3(self): f = IntegerField(max_value=10) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean(None) self.assertEqual(1, f.clean(1)) @@ -68,7 +68,7 @@ class IntegerFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_integerfield_4(self): f = IntegerField(min_value=10) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean(None) with self.assertRaisesMessage(ValidationError, "'Ensure this value is greater than or equal to 10.'"): @@ -82,7 +82,7 @@ class IntegerFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_integerfield_5(self): f = IntegerField(min_value=10, max_value=20) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean(None) with self.assertRaisesMessage(ValidationError, "'Ensure this value is greater than or equal to 10.'"): @@ -103,7 +103,7 @@ class IntegerFieldTest(FormFieldAssertionsMixin, SimpleTestCase): number input specific attributes. """ f1 = IntegerField(localize=True) - self.assertWidgetRendersTo(f1, '') + self.assertWidgetRendersTo(f1, '') def test_integerfield_float(self): f = IntegerField() diff --git a/tests/forms_tests/field_tests/test_multivaluefield.py b/tests/forms_tests/field_tests/test_multivaluefield.py index 79a3425155..7703371d59 100644 --- a/tests/forms_tests/field_tests/test_multivaluefield.py +++ b/tests/forms_tests/field_tests/test_multivaluefield.py @@ -112,15 +112,15 @@ class MultiValueFieldTest(SimpleTestCase): form.as_table(), """ - - + - - + + """, ) @@ -135,15 +135,15 @@ class MultiValueFieldTest(SimpleTestCase): form.as_table(), """ - - + - - + + """, ) diff --git a/tests/forms_tests/field_tests/test_urlfield.py b/tests/forms_tests/field_tests/test_urlfield.py index 0ad1bb65f9..24da712717 100644 --- a/tests/forms_tests/field_tests/test_urlfield.py +++ b/tests/forms_tests/field_tests/test_urlfield.py @@ -11,7 +11,7 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_urlfield_1(self): f = URLField() - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): f.clean('') with self.assertRaisesMessage(ValidationError, "'This field is required.'"): @@ -91,7 +91,7 @@ class URLFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_urlfield_5(self): f = URLField(min_length=15, max_length=20) - self.assertWidgetRendersTo(f, '') + self.assertWidgetRendersTo(f, '') with self.assertRaisesMessage(ValidationError, "'Ensure this value has at least 15 characters (it has 12).'"): f.clean('http://f.com') self.assertEqual('http://example.com', f.clean('http://example.com')) diff --git a/tests/forms_tests/tests/test_forms.py b/tests/forms_tests/tests/test_forms.py index a5d8fbebdb..4309fb3d86 100644 --- a/tests/forms_tests/tests/test_forms.py +++ b/tests/forms_tests/tests/test_forms.py @@ -60,15 +60,15 @@ class FormsTestCase(SimpleTestCase): self.assertEqual(p.cleaned_data["birthday"], datetime.date(1940, 10, 9)) self.assertHTMLEqual( str(p['first_name']), - '' + '' ) self.assertHTMLEqual( str(p['last_name']), - '' + '' ) self.assertHTMLEqual( str(p['birthday']), - '' + '' ) msg = "Key 'nonexistentfield' not found in 'Person'. Choices are: birthday, first_name, last_name." @@ -82,9 +82,9 @@ class FormsTestCase(SimpleTestCase): self.assertHTMLEqual( '\n'.join(form_output), - """ - -""" + """ + +""" ) form_output = [] @@ -100,11 +100,11 @@ class FormsTestCase(SimpleTestCase): self.assertHTMLEqual( str(p), """ - + - + -""" +""" ) def test_empty_dict(self): @@ -120,49 +120,49 @@ class FormsTestCase(SimpleTestCase): str(p), """ - + - + -""" +""" ) self.assertHTMLEqual( p.as_table(), """ - + - + -""" +""" ) self.assertHTMLEqual( p.as_ul(), """
  • -
  • +
  • -
  • +
  • -
  • """ +""" ) self.assertHTMLEqual( p.as_p(), """

    -

    +

    -

    +

    -

    """ +

    """ ) def test_unbound_form(self): @@ -181,38 +181,38 @@ class FormsTestCase(SimpleTestCase): self.assertHTMLEqual( str(p), """ - + - + -""" +""" ) self.assertHTMLEqual( p.as_table(), """ - + - + -""" +""" ) self.assertHTMLEqual( p.as_ul(), """
  • -
  • +
  • -
  • +
  • -
  • """ +""" ) self.assertHTMLEqual( p.as_p(), """

    -

    +

    -

    +

    -

    """ +

    """ ) def test_unicode_values(self): @@ -225,33 +225,33 @@ class FormsTestCase(SimpleTestCase): self.assertHTMLEqual( p.as_table(), '' - '\n' + '\n' '' '\n' + 'id="id_last_name" required />\n' '' - '' + '' ) self.assertHTMLEqual( p.as_ul(), '
  • ' - '
  • \n' + '\n' '
  • ' '
  • \n' + 'value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" required />\n' '
  • ' - '
  • ' + '' ) self.assertHTMLEqual( p.as_p(), '

    ' - '

    \n' + '

    \n' '

    ' '

    \n' + 'value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" id="id_last_name" required />

    \n' '

    ' - '

    ' + '

    ' ) p = Person({'last_name': 'Lennon'}) @@ -271,9 +271,12 @@ class FormsTestCase(SimpleTestCase): self.assertEqual(p['first_name'].errors.as_text(), '* This field is required.') p = Person() - self.assertHTMLEqual(str(p['first_name']), '') - self.assertHTMLEqual(str(p['last_name']), '') - self.assertHTMLEqual(str(p['birthday']), '') + self.assertHTMLEqual( + str(p['first_name']), + '', + ) + self.assertHTMLEqual(str(p['last_name']), '') + self.assertHTMLEqual(str(p['birthday']), '') def test_cleaned_data_only_fields(self): # cleaned_data will always *only* contain a key for fields defined in the @@ -333,29 +336,29 @@ class FormsTestCase(SimpleTestCase): self.assertHTMLEqual( p.as_table(), """ - + - + -""" +""" ) self.assertHTMLEqual( p.as_ul(), """
  • -
  • +
  • -
  • +
  • -
  • """ +""" ) self.assertHTMLEqual( p.as_p(), """

    -

    +

    -

    +

    -

    """ +

    """ ) def test_auto_id_true(self): @@ -365,11 +368,11 @@ class FormsTestCase(SimpleTestCase): self.assertHTMLEqual( p.as_ul(), """
  • -
  • +
  • -
  • +
  • -
  • """ +""" ) def test_auto_id_false(self): @@ -378,9 +381,9 @@ class FormsTestCase(SimpleTestCase): p = Person(auto_id=False) self.assertHTMLEqual( p.as_ul(), - """
  • First name:
  • -
  • Last name:
  • -
  • Birthday:
  • """ + """
  • First name:
  • +
  • Last name:
  • +
  • Birthday:
  • """ ) def test_id_on_field(self): @@ -390,9 +393,9 @@ class FormsTestCase(SimpleTestCase): self.assertHTMLEqual( p.as_ul(), """
  • -
  • -
  • Last name:
  • -
  • Birthday:
  • """ + +
  • Last name:
  • +
  • Birthday:
  • """ ) def test_auto_id_on_form_and_field(self): @@ -402,11 +405,11 @@ class FormsTestCase(SimpleTestCase): self.assertHTMLEqual( p.as_ul(), """
  • -
  • +
  • -
  • +
  • -
  • """ +""" ) def test_various_boolean_values(self): @@ -415,26 +418,33 @@ class FormsTestCase(SimpleTestCase): get_spam = BooleanField() f = SignupForm(auto_id=False) - self.assertHTMLEqual(str(f['email']), '') - self.assertHTMLEqual(str(f['get_spam']), '') + self.assertHTMLEqual(str(f['email']), '') + self.assertHTMLEqual(str(f['get_spam']), '') f = SignupForm({'email': 'test@example.com', 'get_spam': True}, auto_id=False) - self.assertHTMLEqual(str(f['email']), '') - self.assertHTMLEqual(str(f['get_spam']), '') + self.assertHTMLEqual(str(f['email']), '') + self.assertHTMLEqual( + str(f['get_spam']), + '', + ) # 'True' or 'true' should be rendered without a value attribute f = SignupForm({'email': 'test@example.com', 'get_spam': 'True'}, auto_id=False) - self.assertHTMLEqual(str(f['get_spam']), '') + self.assertHTMLEqual( + str(f['get_spam']), + '', + ) f = SignupForm({'email': 'test@example.com', 'get_spam': 'true'}, auto_id=False) - self.assertHTMLEqual(str(f['get_spam']), '') + self.assertHTMLEqual( + str(f['get_spam']), '') # A value of 'False' or 'false' should be rendered unchecked f = SignupForm({'email': 'test@example.com', 'get_spam': 'False'}, auto_id=False) - self.assertHTMLEqual(str(f['get_spam']), '') + self.assertHTMLEqual(str(f['get_spam']), '') f = SignupForm({'email': 'test@example.com', 'get_spam': 'false'}, auto_id=False) - self.assertHTMLEqual(str(f['get_spam']), '') + self.assertHTMLEqual(str(f['get_spam']), '') # A value of '0' should be interpreted as a True value (#16820) f = SignupForm({'email': 'test@example.com', 'get_spam': '0'}) @@ -448,13 +458,16 @@ class FormsTestCase(SimpleTestCase): message = CharField(widget=Textarea) f = ContactForm(auto_id=False) - self.assertHTMLEqual(str(f['subject']), '') - self.assertHTMLEqual(str(f['message']), '') + self.assertHTMLEqual(str(f['subject']), '') + self.assertHTMLEqual(str(f['message']), '') # as_textarea(), as_text() and as_hidden() are shortcuts for changing the output # widget type: - self.assertHTMLEqual(f['subject'].as_textarea(), '') - self.assertHTMLEqual(f['message'].as_text(), '') + self.assertHTMLEqual( + f['subject'].as_textarea(), + '', + ) + self.assertHTMLEqual(f['message'].as_text(), '') self.assertHTMLEqual(f['message'].as_hidden(), '') # The 'widget' parameter to a Field can also be an instance: @@ -463,17 +476,20 @@ class FormsTestCase(SimpleTestCase): message = CharField(widget=Textarea(attrs={'rows': 80, 'cols': 20})) f = ContactForm(auto_id=False) - self.assertHTMLEqual(str(f['message']), '') + self.assertHTMLEqual(str(f['message']), '') # Instance-level attrs are *not* carried over to as_textarea(), as_text() and # as_hidden(): - self.assertHTMLEqual(f['message'].as_text(), '') + self.assertHTMLEqual(f['message'].as_text(), '') f = ContactForm({'subject': 'Hello', 'message': 'I love you.'}, auto_id=False) self.assertHTMLEqual( f['subject'].as_textarea(), - '' + '' + ) + self.assertHTMLEqual( + f['message'].as_text(), + '', ) - self.assertHTMLEqual(f['message'].as_text(), '') self.assertHTMLEqual(f['message'].as_hidden(), '') def test_forms_with_choices(self): @@ -483,12 +499,12 @@ class FormsTestCase(SimpleTestCase): language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')]) f = FrameworkForm(auto_id=False) - self.assertHTMLEqual(str(f['language']), """ """) f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False) - self.assertHTMLEqual(str(f['language']), """ """) @@ -500,7 +516,7 @@ class FormsTestCase(SimpleTestCase): language = ChoiceField(choices=[('', '------'), ('P', 'Python'), ('J', 'Java')]) f = FrameworkForm(auto_id=False) - self.assertHTMLEqual(str(f['language']), """ @@ -512,12 +528,12 @@ class FormsTestCase(SimpleTestCase): language = ChoiceField(choices=[('P', 'Python'), ('J', 'Java')], widget=Select(attrs={'class': 'foo'})) f = FrameworkForm(auto_id=False) - self.assertHTMLEqual(str(f['language']), """ """) f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False) - self.assertHTMLEqual(str(f['language']), """ """) @@ -533,12 +549,12 @@ class FormsTestCase(SimpleTestCase): ) f = FrameworkForm(auto_id=False) - self.assertHTMLEqual(str(f['language']), """ """) f = FrameworkForm({'name': 'Django', 'language': 'P'}, auto_id=False) - self.assertHTMLEqual(str(f['language']), """ """) @@ -549,10 +565,10 @@ class FormsTestCase(SimpleTestCase): language = ChoiceField() f = FrameworkForm(auto_id=False) - self.assertHTMLEqual(str(f['language']), """ """) f.fields['language'].choices = [('P', 'Python'), ('J', 'Java')] - self.assertHTMLEqual(str(f['language']), """ """) @@ -565,18 +581,18 @@ class FormsTestCase(SimpleTestCase): f = FrameworkForm(auto_id=False) self.assertHTMLEqual(str(f['language']), """""") - self.assertHTMLEqual(f.as_table(), """Name: + self.assertHTMLEqual(f.as_table(), """Name: Language:""") - self.assertHTMLEqual(f.as_ul(), """
  • Name:
  • + self.assertHTMLEqual(f.as_ul(), """
  • Name:
  • Language:
  • """) # Regarding auto_id and