|
0
|
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): |
|
29
|
150 |
return http.HttpResponse("") |
|
0
|
151 |
|
|
|
152 |
def done(self, request, cleaned_data): |
|
|
153 |
return http.HttpResponse(success_string) |
|
|
154 |
|
|
29
|
155 |
class DummyRequest(http.HttpRequest): |
|
0
|
156 |
def __init__(self, POST=None): |
|
29
|
157 |
super(DummyRequest, self).__init__() |
|
0
|
158 |
self.method = POST and "POST" or "GET" |
|
29
|
159 |
if POST is not None: |
|
|
160 |
self.POST.update(POST) |
|
|
161 |
self._dont_enforce_csrf_checks = True |
|
0
|
162 |
|
|
|
163 |
class WizardTests(TestCase): |
|
|
164 |
def test_step_starts_at_zero(self): |
|
|
165 |
""" |
|
|
166 |
step should be zero for the first form |
|
|
167 |
""" |
|
|
168 |
wizard = WizardClass([WizardPageOneForm, WizardPageTwoForm]) |
|
|
169 |
request = DummyRequest() |
|
|
170 |
wizard(request) |
|
|
171 |
self.assertEquals(0, wizard.step) |
|
|
172 |
|
|
|
173 |
def test_step_increments(self): |
|
|
174 |
""" |
|
|
175 |
step should be incremented when we go to the next page |
|
|
176 |
""" |
|
|
177 |
wizard = WizardClass([WizardPageOneForm, WizardPageTwoForm]) |
|
|
178 |
request = DummyRequest(POST={"0-field":"test", "wizard_step":"0"}) |
|
|
179 |
response = wizard(request) |
|
|
180 |
self.assertEquals(1, wizard.step) |
|
|
181 |
|