# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.forms import ( CharField, ChoiceField, Form, HiddenInput, IntegerField, ModelForm, ModelMultipleChoiceField, MultipleChoiceField, RadioSelect, Select, TextInput, ) from django.test import TestCase, ignore_warnings from django.utils import translation from django.utils.translation import gettext_lazy, ugettext_lazy from ..models import Cheese class FormsRegressionsTestCase(TestCase): def test_class(self): # Tests to prevent against recurrences of earlier bugs. extra_attrs = {'class': 'special'} class TestForm(Form): f1 = CharField(max_length=10, widget=TextInput(attrs=extra_attrs)) f2 = CharField(widget=TextInput(attrs=extra_attrs)) self.assertHTMLEqual( TestForm(auto_id=False).as_p(), '

F1:

\n' '

F2:

' ) def test_regression_3600(self): # Tests for form i18n # # There were some problems with form translations in #3600 class SomeForm(Form): username = CharField(max_length=10, label=ugettext_lazy('username')) f = SomeForm() self.assertHTMLEqual( f.as_p(), '

' '

' ) # Translations are done at rendering time, so multi-lingual apps can define forms) with translation.override('de'): self.assertHTMLEqual( f.as_p(), '

' '

' ) with translation.override('pl'): self.assertHTMLEqual( f.as_p(), '

' '

' ) def test_regression_5216(self): # There was some problems with form translations in #5216 class SomeForm(Form): field_1 = CharField(max_length=10, label=ugettext_lazy('field_1')) field_2 = CharField( max_length=10, label=ugettext_lazy('field_2'), widget=TextInput(attrs={'id': 'field_2_id'}), ) f = SomeForm() self.assertHTMLEqual(f['field_1'].label_tag(), '') self.assertHTMLEqual(f['field_2'].label_tag(), '') # Unicode decoding problems... GENDERS = (('\xc5', 'En tied\xe4'), ('\xf8', 'Mies'), ('\xdf', 'Nainen')) class SomeForm(Form): somechoice = ChoiceField(choices=GENDERS, widget=RadioSelect(), label='\xc5\xf8\xdf') f = SomeForm() self.assertHTMLEqual( f.as_p(), '

' '

' ) # Translated error messages used to be buggy. with translation.override('ru'): f = SomeForm({}) self.assertHTMLEqual( f.as_p(), '\n' '

' '

' ) # Deep copying translated text shouldn't raise an error) class CopyForm(Form): degree = IntegerField(widget=Select(choices=((1, gettext_lazy('test')),))) f = CopyForm() @ignore_warnings(category=UnicodeWarning) def test_regression_5216_b(self): # Testing choice validation with UTF-8 bytestrings as input (these are the # Russian abbreviations "мес." and "шт.". UNITS = ((b'\xd0\xbc\xd0\xb5\xd1\x81.', b'\xd0\xbc\xd0\xb5\xd1\x81.'), (b'\xd1\x88\xd1\x82.', b'\xd1\x88\xd1\x82.')) f = ChoiceField(choices=UNITS) self.assertEqual(f.clean('\u0448\u0442.'), '\u0448\u0442.') self.assertEqual(f.clean(b'\xd1\x88\xd1\x82.'), '\u0448\u0442.') def test_misc(self): # There once was a problem with Form fields called "data". Let's make sure that # doesn't come back. class DataForm(Form): data = CharField(max_length=10) f = DataForm({'data': 'xyzzy'}) self.assertTrue(f.is_valid()) self.assertEqual(f.cleaned_data, {'data': 'xyzzy'}) # A form with *only* hidden fields that has errors is going to be very unusual. class HiddenForm(Form): data = IntegerField(widget=HiddenInput) f = HiddenForm({}) self.assertHTMLEqual( f.as_p(), '\n

' '

' ) self.assertHTMLEqual( f.as_table(), '' '' ) def test_xss_error_messages(self): ################################################### # Tests for XSS vulnerabilities in error messages # ################################################### # The forms layer doesn't escape input values directly because error messages # might be presented in non-HTML contexts. Instead, the message is just marked # for escaping by the template engine. So we'll need to construct a little # silly template to trigger the escaping. from django.template import Template, Context t = Template('{{ form.errors }}') class SomeForm(Form): field = ChoiceField(choices=[('one', 'One')]) f = SomeForm({'field': '