unittest_registration.py 7.02 KB
Newer Older
Sylvain Thénault's avatar
Sylvain Thénault committed
1
import re, cgi, urlparse
2
3

from cubicweb import ValidationError
4
from cubicweb.crypto import encrypt, decrypt
5
from cubicweb.web import Redirect
Sylvain Thénault's avatar
Sylvain Thénault committed
6
from cubicweb.devtools.testlib import MAILBOX, CubicWebTC
7

8
from cubes.registration.views import RegistrationSendMailController
9
10


Sylvain Thénault's avatar
Sylvain Thénault committed
11
class RegistrationTC(CubicWebTC):
12

Florent's avatar
Florent committed
13
14
    captcha_value = u'captcha value'

15
    data = {'firstname-subject': u'Toto', 'surname-subject': u'Toto',
16
            'email_address-subject': u'toto@secondweb.fr',
17
18
19
            'login-subject': u'toto',
            'upassword-subject': 'toto',
            'upassword-subject-confirm': 'toto',
Florent's avatar
Florent committed
20
            'captcha': captcha_value}
21
22

    def setup_database(self):
23
        self.config.global_set_option('registration-cypher-seed', u'dummy cypher key')
24
25
        super(RegistrationTC, self).setup_database()

26
27
28
29
30
31
32
33
34
    def _check_user_not_created(self):
        self.restore_connection()
        rset = self.execute('CWUser X WHERE X login %(login)s',
                            {'login': self.data['login-subject']})
        self.failIf(rset)

    def _check_error(self, req, path,
                     expected_path='registration',
                     expected_errors=None,
35
                     expected_msg=None,
36
37
                     expected_formvalues=None):
        path, params = self.expect_redirect_publish(req, path)
Sylvain Thénault's avatar
Sylvain Thénault committed
38
        self.assertEqual(path, expected_path)
39
40
41
        if expected_msg:
            self.assertMessageEqual(req, params, expected_msg)
        forminfo = req.session.data.get('registration')
42
43
44
        if forminfo is None:
            self.failIf(expected_errors or expected_formvalues)
        else:
Sylvain Thénault's avatar
Sylvain Thénault committed
45
46
            self.assertEqual(forminfo['eidmap'], {})
            self.assertEqual(forminfo['values'], expected_formvalues or {})
47
            error = forminfo['error']
Sylvain Thénault's avatar
Sylvain Thénault committed
48
49
            self.assertEqual(error.entity, None)
            self.assertEqual(error.errors, expected_errors or {})
50
51
52
53
54
55
56
57
58

    def _posted_form(self, *skipkeys):
        data = self.data.copy()
        for key in skipkeys:
            data.pop(key, None)
        if not '__errorurl' in skipkeys:
            data['__errorurl'] = 'registration'
        return data

59
60
    def test_registration_form(self):
        req = self.request()
61
        req.form = {'firstname-subject': u'Toto'}
62
63
64
        pageinfo = self.view('registration', req=req, rset=None)
        ns = {'ns': pageinfo.default_ns}
        # check form field names
65
        names = pageinfo.etree.xpath('//ns:form[@id="registrationForm"]//ns:input[@type!="hidden"]/@name',
66
                                     namespaces=ns)
Sylvain Thénault's avatar
Sylvain Thénault committed
67
        self.assertEqual(set(names), set(self.data))
68
        # check form field value
69
        firstname = pageinfo.etree.xpath('//ns:input[@name="firstname-subject"]/@value',
Sylvain Thénault's avatar
0.1    
Sylvain Thénault committed
70
                                         namespaces=ns)
Sylvain Thénault's avatar
Sylvain Thénault committed
71
        self.assertEqual(firstname, [req.form['firstname-subject']])
72
73

    def test_send_mail_ok(self):
Florent's avatar
Florent committed
74
        self.login('anon')
75
        req = self.request()
76
        req.form = self._posted_form()
77
        req.session.data['captcha'] = self.captcha_value
78
        path, params = self.expect_redirect_publish(req, 'registration_sendmail')
Sylvain Thénault's avatar
Sylvain Thénault committed
79
        self.assertEqual(path, '')
80
        self.assertMessageEqual(req, params, 'Your registration email has been sent. Follow instructions in there to activate your account.')
81
82
        # check email contains activation url...
        URL_RE = re.compile('(%s[^.]+)\.' % self.config['base-url'])
Sylvain Thénault's avatar
Sylvain Thénault committed
83
        text = MAILBOX[-1].message.get_payload(decode=True)
84
85
86
        url = URL_RE.search(text).group(1)
        # ... and the registration key contains all data
        key = dict(cgi.parse_qsl(urlparse.urlsplit(url)[3]))['key']
87
        d = self._posted_form('upassword-subject-confirm')
Sylvain Thénault's avatar
Sylvain Thénault committed
88
        self.assertDictEqual(decrypt(key, self.config['registration-cypher-seed']), d)
89
90

    def test_send_mail_failure(self):
91
92
93
94
95
96
97
98
99
        for param, msg, val in (('login-subject', 'required field', None),
                                ('captcha', 'required field', None),
                                ('captcha', 'incorrect captcha value', 'abc')):
            req = self.request()
            if val is None:
                req.form = self._posted_form(param)
            else:
                req.form = self._posted_form()
                req.form[param] = val
100
            req.session.data['captcha'] = self.captcha_value
101
102
103
104
            #expected
            self._check_error(req, 'registration_sendmail',
                              expected_formvalues=req.form,
                              expected_errors={param: msg})
Sylvain Thénault's avatar
Sylvain Thénault committed
105
            self.assertEqual(req.session.data.get('captcha'), None)
106

107
    def _confirm_req(self, key=None, overriden={}):
108
109
        self.login('anon')
        req = self.request()
110
        data = self._posted_form('upassword-subject-confirm')
111
        data.update(overriden)
112
113
114
115
116
117
        if key is None:
            key = encrypt(data, self.config['registration-cypher-seed'])
        req.form = {'key': key}
        return req
    #self.vreg['controllers'].select('registration_confirm', req,
    #appli=self.app)
Florent's avatar
Florent committed
118
119

    def test_confirm_ok(self):
120
121
        req = self._confirm_req()
        path, params = self.expect_redirect_publish(req, 'registration_confirm')
Sylvain Thénault's avatar
Sylvain Thénault committed
122
        self.assertEqual(path, '')
123
        self.assertMessageEqual(req, params, 'Congratulations, your registration is complete. Welcome %(firstname-subject)s %(surname-subject)s !' % self.data)
124
125
        self.restore_connection()
        rset = self.execute('Any U WHERE U login %(login)s, U firstname %(firstname)s, '
126
                            'U surname %(surname)s, U use_email M, M address %(email_address)s',
127
128
                            dict((k.replace('-subject', ''), v)
                                 for k, v in self.data.items()))
129
130
        self.failUnless(rset.rowcount)

Florent's avatar
Florent committed
131
    def test_confirm_failure_login_already_used(self):
132
133
134
135
136
        # try to recreate a 'admin' user.
        req = self._confirm_req(overriden={'login-subject': 'admin'})
        formvalues = self._posted_form('upassword-subject',
                                       'upassword-subject-confirm')
        formvalues['login-subject'] = 'admin'
137
        self._check_error(req, 'registration_confirm',
138
139
                          expected_formvalues=formvalues,
                          expected_errors={'login-subject': 'the value "admin" is already used, use another one'})
140
141

    def test_confirm_failure_invalid_data(self):
142
143
        req = self._confirm_req('dummykey')
        self._check_error(req, 'registration_confirm', 'register',
144
                          expected_msg='Invalid registration data. Please try registering again.')
Florent's avatar
Florent committed
145
146
147
        self._check_user_not_created()

    def test_confirm_failure_email_already_used(self):
Sylvain Thénault's avatar
Sylvain Thénault committed
148
        self.create_user(self.request(), 'test')
149
150
        self.execute('INSERT EmailAddress X: U use_email X, X address %(email_address)s '
                     'WHERE U login "test"', {'email_address': self.data['email_address-subject']})
Florent's avatar
Florent committed
151
        self.commit()
152
153
        req = self._confirm_req()
        req.form['__errorurl'] = 'registration'
Florent's avatar
Florent committed
154
        self._check_user_not_created()
Sylvain Thénault's avatar
Sylvain Thénault committed
155
156

if __name__ == '__main__':
Sylvain Thénault's avatar
Sylvain Thénault committed
157
    from logilab.common.testlib import unittest_main
Sylvain Thénault's avatar
Sylvain Thénault committed
158
    unittest_main()