source: products/quintagroup.plonecaptchas/trunk/quintagroup/plonecaptchas/tests/testForms.py @ 3270

Last change on this file since 3270 was 3270, checked in by vmaksymiv, 13 years ago

compatibility with plone.app.discussion added

  • Property svn:eol-style set to native
File size: 8.1 KB
Line 
1import unittest
2import doctest
3import re
4from urllib import urlencode
5from StringIO import StringIO
6
7from Products.PloneTestCase.PloneTestCase import portal_owner
8from Products.PloneTestCase.PloneTestCase import default_password
9
10from quintagroup.plonecaptchas.tests.base import FunctionalTestCase, ztc
11from quintagroup.plonecaptchas.config import PRODUCT_NAME, HAS_APP_DISCUSSION
12
13from quintagroup.captcha.core.tests.testWidget import IMAGE_PATT, NOT_VALID
14from quintagroup.captcha.core.tests.testWidget import addTestLayer
15from quintagroup.captcha.core.tests.base import testPatch
16from quintagroup.captcha.core.utils import getWord, decrypt, parseKey
17
18from plone.app.controlpanel.security import ISecuritySchema
19
20# BBB for plone v<3.1, where plone.protect not used yet
21PROTECT_SUPPORT = True
22try:
23    from plone import protect
24    # pyflakes fix (pyflakes message: 'protect' imported but unused)
25    protect
26except ImportError:
27    PROTECT_SUPPORT = False
28
29# USE PATCH FROM quintagroup.captcha.core
30# patch to use test images and dictionary
31testPatch()
32
33
34class TestFormMixin(FunctionalTestCase):
35
36    formkey_key = "key"
37    formkey_hashkey = "hashkey"
38
39    def afterSetUp(self):
40        self.loginAsPortalOwner()
41        self.addProduct(PRODUCT_NAME)
42        # Add test_captcha layer from quintagroup.captcah.core
43        addTestLayer(self)
44        # Prepare form data
45        self.basic_auth = ':'.join((portal_owner, default_password))
46        self.form_url = ''
47        self.form_method = "POST"
48        self.hasAuthenticator = False
49        self.form_data = self.getFormData()
50        # Prepare captcha related test data
51        self.captcha_key = self.portal.captcha_key
52        self.hashkey = self.portal.getCaptcha()
53        self.form_data[self.formkey_hashkey] = self.hashkey
54        self.form_data[self.formkey_key] = ''
55
56    def getFormData(self):
57        raise NotImplementedError(
58            "getFormData not implemented")
59
60    def publishForm(self):
61        stdin_data = None
62        form_url = self.portal.absolute_url(1) + self.form_url
63        # Prepare form data
64        if PROTECT_SUPPORT and self.hasAuthenticator:
65            self.form_data['_authenticator'] = self._getauth()
66        form_data = urlencode(self.form_data)
67        if self.form_method.upper() == 'GET':
68            form_url += "?%s" % form_data
69        else:
70            stdin_data = StringIO(form_data)
71        # Publish form and get response
72        response = self.publish(form_url, self.basic_auth,
73            request_method=self.form_method, stdin=stdin_data)
74        return response
75
76    def _getauth(self):
77        # Fix authenticator for the form
78        authenticator = self.portal.restrictedTraverse("@@authenticator")
79        html = authenticator.authenticator()
80        handle = re.search('value="(.*)"', html).groups()[0]
81        return handle
82
83    def elog(self, name="", response=""):
84        open("/tmp/test.%s.html" % name, "w").write(response)
85        logs = self.portal.error_log.getLogEntries()
86        if len(logs) > 0:
87            i = 0
88            while logs:
89                l = logs.pop()
90                i += 1
91                open("/tmp/test.%s.error.%d.html" % (l["id"], i),
92                                                     "w").write(l["tb_html"])
93
94    def testImage(self):
95        self.form_data = {}
96        self.form_method = "GET"
97        response = self.publishForm().getBody()
98        patt = re.compile(IMAGE_PATT % self.portal.absolute_url())
99        match_obj = patt.search(response)
100        self.elog("image", response)
101        img_url = match_obj.group(1)
102
103        content_type = self.publish(
104                            '/plone' + img_url).getHeader('content-type')
105        self.assertTrue(content_type.startswith('image'),
106            "Wrong captcha image content type")
107
108    def testSubmitRightCaptcha(self):
109        key = getWord(int(parseKey(decrypt(self.captcha_key,
110                                           self.hashkey))['key']) - 1)
111        self.form_data[self.formkey_key] = key
112
113        response = self.publishForm().getBody()
114        self.elog("right", response)
115        self.assertFalse(NOT_VALID.search(response))
116
117    def testSubmitWrongCaptcha(self):
118        self.form_data[self.formkey_key] = 'wrong word'
119        response = self.publishForm().getBody()
120        self.elog("wrong", response)
121        self.assertTrue(NOT_VALID.search(response))
122
123    def testSubmitRightCaptchaTwice(self):
124        key = getWord(int(parseKey(decrypt(self.captcha_key,
125                                           self.hashkey))['key']) - 1)
126        self.form_data[self.formkey_key] = key
127
128        response1 = self.publishForm().getBody()
129        self.elog("right1", response1)
130        response2 = self.publishForm().getBody()
131        self.elog("right2", response2)
132        self.assertTrue(NOT_VALID.search(response2))
133
134
135class TestDiscussionForm(TestFormMixin):
136
137    def afterSetUp(self):
138        TestFormMixin.afterSetUp(self)
139        self.portal.invokeFactory('Document', 'index_html')
140        self.portal['index_html'].allowDiscussion(True)
141        self.form_url = '/index_html/discussion_reply_form'
142
143    def getFormData(self):
144        return {'form.submitted': '1',
145                'subject': 'testing',
146                'Creator': portal_owner,
147                'body_text': 'Text in Comment',
148                'discussion_reply:method': 'Save',
149                'form.button.form_submit': 'Save'}
150
151
152class TestRegisterForm(TestFormMixin):
153
154    formkey_key = "form.captcha"
155    formkey_hashkey = "form..hashkey"
156
157    def afterSetUp(self):
158        TestFormMixin.afterSetUp(self)
159        ISecuritySchema(self.portal).enable_self_reg = True
160        self.portal._updateProperty('validate_email', False)
161        self.hasAuthenticator = True
162        self.form_url = '/@@register'
163        self.basic_auth = ":"
164        self.logout()
165
166    def getFormData(self):
167        return {"form.fullname": "Tester",
168                "form.username": "tester",
169                "form.email": "tester@test.com",
170                "form.password": "123456",
171                "form.password_ctl": "123456",
172                'form.actions.register': 'Register'}
173
174
175class TestSendtoForm(TestFormMixin):
176
177    def afterSetUp(self):
178        TestFormMixin.afterSetUp(self)
179        self.portal.invokeFactory('Document', 'index_html')
180        self.portal['index_html'].allowDiscussion(True)
181        self.form_url = '/index_html/sendto_form'
182
183    def getFormData(self):
184        return {'form.submitted': '1',
185                "send_to_address": "recipient@test.com",
186                "send_from_address": "sender@test.com",
187                'comment': 'Text in Comment',
188                'form.button.Send': 'Save'}
189
190
191def send_patch(self, *args, **kwargs):
192    """This patch prevent breakage on sending."""
193
194
195class TestContactInfo(TestFormMixin):
196
197    def afterSetUp(self):
198        TestFormMixin.afterSetUp(self)
199        # preparation to form correct working
200        self.portal._updateProperty('email_from_address', 'manager@test.com')
201        self.logout()
202        self.form_url = '/contact-info'
203        self.orig_mh_send = self.portal.MailHost.send
204        self.portal.MailHost.send = send_patch
205
206    def beforeTearDown(self):
207        self.portal.MailHost.send = self.orig_mh_send
208
209    def getFormData(self):
210        return {'form.submitted': '1',
211                "sender_fullname": "tester",
212                "sender_from_address": "sender@test.com",
213                'subject': 'Subject',
214                'message': 'Message',
215                'form.button.Send': 'Save'}
216
217
218def test_suite():
219    suite = unittest.TestSuite()
220    if HAS_APP_DISCUSSION:
221        suite.addTest(unittest.TestSuite([
222            ztc.FunctionalDocFileSuite(
223                'discussion.txt', package='quintagroup.plonecaptchas.tests',
224                test_class=FunctionalTestCase, globs=globals(),
225                optionflags=doctest.REPORT_ONLY_FIRST_FAILURE |
226                    doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS),
227            ]))
228
229    else:
230        suite.addTest(unittest.makeSuite(TestDiscussionForm))
231    suite.addTest(unittest.makeSuite(TestRegisterForm))
232    suite.addTest(unittest.makeSuite(TestSendtoForm))
233    suite.addTest(unittest.makeSuite(TestContactInfo))
234    return suite
Note: See TracBrowser for help on using the repository browser.