|
1 import unittest |
|
2 from django import forms |
|
3 from django.contrib.formtools import preview, wizard, utils |
|
4 from django import http |
|
5 from django.test import TestCase |
|
6 |
|
7 success_string = "Done was called!" |
|
8 |
|
9 class TestFormPreview(preview.FormPreview): |
|
10 |
|
11 def done(self, request, cleaned_data): |
|
12 return http.HttpResponse(success_string) |
|
13 |
|
14 class TestForm(forms.Form): |
|
15 field1 = forms.CharField() |
|
16 field1_ = forms.CharField() |
|
17 bool1 = forms.BooleanField(required=False) |
|
18 |
|
19 class PreviewTests(TestCase): |
|
20 urls = 'django.contrib.formtools.test_urls' |
|
21 |
|
22 def setUp(self): |
|
23 # Create a FormPreview instance to share between tests |
|
24 self.preview = preview.FormPreview(TestForm) |
|
25 input_template = '<input type="hidden" name="%s" value="%s" />' |
|
26 self.input = input_template % (self.preview.unused_name('stage'), "%d") |
|
27 self.test_data = {'field1':u'foo', 'field1_':u'asdf'} |
|
28 |
|
29 def test_unused_name(self): |
|
30 """ |
|
31 Verifies name mangling to get uniue field name. |
|
32 """ |
|
33 self.assertEqual(self.preview.unused_name('field1'), 'field1__') |
|
34 |
|
35 def test_form_get(self): |
|
36 """ |
|
37 Test contrib.formtools.preview form retrieval. |
|
38 |
|
39 Use the client library to see if we can sucessfully retrieve |
|
40 the form (mostly testing the setup ROOT_URLCONF |
|
41 process). Verify that an additional hidden input field |
|
42 is created to manage the stage. |
|
43 |
|
44 """ |
|
45 response = self.client.get('/test1/') |
|
46 stage = self.input % 1 |
|
47 self.assertContains(response, stage, 1) |
|
48 |
|
49 def test_form_preview(self): |
|
50 """ |
|
51 Test contrib.formtools.preview form preview rendering. |
|
52 |
|
53 Use the client library to POST to the form to see if a preview |
|
54 is returned. If we do get a form back check that the hidden |
|
55 value is correctly managing the state of the form. |
|
56 |
|
57 """ |
|
58 # Pass strings for form submittal and add stage variable to |
|
59 # show we previously saw first stage of the form. |
|
60 self.test_data.update({'stage': 1}) |
|
61 response = self.client.post('/test1/', self.test_data) |
|
62 # Check to confirm stage is set to 2 in output form. |
|
63 stage = self.input % 2 |
|
64 self.assertContains(response, stage, 1) |
|
65 |
|
66 def test_form_submit(self): |
|
67 """ |
|
68 Test contrib.formtools.preview form submittal. |
|
69 |
|
70 Use the client library to POST to the form with stage set to 3 |
|
71 to see if our forms done() method is called. Check first |
|
72 without the security hash, verify failure, retry with security |
|
73 hash and verify sucess. |
|
74 |
|
75 """ |
|
76 # Pass strings for form submittal and add stage variable to |
|
77 # show we previously saw first stage of the form. |
|
78 self.test_data.update({'stage':2}) |
|
79 response = self.client.post('/test1/', self.test_data) |
|
80 self.failIfEqual(response.content, success_string) |
|
81 hash = self.preview.security_hash(None, TestForm(self.test_data)) |
|
82 self.test_data.update({'hash': hash}) |
|
83 response = self.client.post('/test1/', self.test_data) |
|
84 self.assertEqual(response.content, success_string) |
|
85 |
|
86 def test_bool_submit(self): |
|
87 """ |
|
88 Test contrib.formtools.preview form submittal when form contains: |
|
89 BooleanField(required=False) |
|
90 |
|
91 Ticket: #6209 - When an unchecked BooleanField is previewed, the preview |
|
92 form's hash would be computed with no value for ``bool1``. However, when |
|
93 the preview form is rendered, the unchecked hidden BooleanField would be |
|
94 rendered with the string value 'False'. So when the preview form is |
|
95 resubmitted, the hash would be computed with the value 'False' for |
|
96 ``bool1``. We need to make sure the hashes are the same in both cases. |
|
97 |
|
98 """ |
|
99 self.test_data.update({'stage':2}) |
|
100 hash = self.preview.security_hash(None, TestForm(self.test_data)) |
|
101 self.test_data.update({'hash':hash, 'bool1':u'False'}) |
|
102 response = self.client.post('/test1/', self.test_data) |
|
103 self.assertEqual(response.content, success_string) |
|
104 |
|
105 class SecurityHashTests(unittest.TestCase): |
|
106 |
|
107 def test_textfield_hash(self): |
|
108 """ |
|
109 Regression test for #10034: the hash generation function should ignore |
|
110 leading/trailing whitespace so as to be friendly to broken browsers that |
|
111 submit it (usually in textareas). |
|
112 """ |
|
113 f1 = HashTestForm({'name': 'joe', 'bio': 'Nothing notable.'}) |
|
114 f2 = HashTestForm({'name': ' joe', 'bio': 'Nothing notable. '}) |
|
115 hash1 = utils.security_hash(None, f1) |
|
116 hash2 = utils.security_hash(None, f2) |
|
117 self.assertEqual(hash1, hash2) |
|
118 |
|
119 def test_empty_permitted(self): |
|
120 """ |
|
121 Regression test for #10643: the security hash should allow forms with |
|
122 empty_permitted = True, or forms where data has not changed. |
|
123 """ |
|
124 f1 = HashTestBlankForm({}) |
|
125 f2 = HashTestForm({}, empty_permitted=True) |
|
126 hash1 = utils.security_hash(None, f1) |
|
127 hash2 = utils.security_hash(None, f2) |
|
128 self.assertEqual(hash1, hash2) |
|
129 |
|
130 class HashTestForm(forms.Form): |
|
131 name = forms.CharField() |
|
132 bio = forms.CharField() |
|
133 |
|
134 class HashTestBlankForm(forms.Form): |
|
135 name = forms.CharField(required=False) |
|
136 bio = forms.CharField(required=False) |
|
137 |
|
138 # |
|
139 # FormWizard tests |
|
140 # |
|
141 |
|
142 class WizardPageOneForm(forms.Form): |
|
143 field = forms.CharField() |
|
144 |
|
145 class WizardPageTwoForm(forms.Form): |
|
146 field = forms.CharField() |
|
147 |
|
148 class WizardClass(wizard.FormWizard): |
|
149 def render_template(self, *args, **kw): |
|
150 return "" |
|
151 |
|
152 def done(self, request, cleaned_data): |
|
153 return http.HttpResponse(success_string) |
|
154 |
|
155 class DummyRequest(object): |
|
156 def __init__(self, POST=None): |
|
157 self.method = POST and "POST" or "GET" |
|
158 self.POST = POST |
|
159 |
|
160 class WizardTests(TestCase): |
|
161 def test_step_starts_at_zero(self): |
|
162 """ |
|
163 step should be zero for the first form |
|
164 """ |
|
165 wizard = WizardClass([WizardPageOneForm, WizardPageTwoForm]) |
|
166 request = DummyRequest() |
|
167 wizard(request) |
|
168 self.assertEquals(0, wizard.step) |
|
169 |
|
170 def test_step_increments(self): |
|
171 """ |
|
172 step should be incremented when we go to the next page |
|
173 """ |
|
174 wizard = WizardClass([WizardPageOneForm, WizardPageTwoForm]) |
|
175 request = DummyRequest(POST={"0-field":"test", "wizard_step":"0"}) |
|
176 response = wizard(request) |
|
177 self.assertEquals(1, wizard.step) |
|
178 |