unittest_registration.py 6.96 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
16
17
18
19
    data = {'firstname-subject': u'Toto', 'surname-subject': u'Toto',
            'address-subject': u'toto@secondweb.fr',
            '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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
    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,
                     expected_params=None,
                     expected_formvalues=None):
        path, params = self.expect_redirect_publish(req, path)
        self.assertEquals(path, expected_path)
        self.assertEquals(params, expected_params or {})
        forminfo = req.get_session_data('registration')
        if forminfo is None:
            self.failIf(expected_errors or expected_formvalues)
        else:
            self.assertEquals(forminfo['eidmap'], {})
            self.assertEquals(forminfo['values'], expected_formvalues or {})
            error = forminfo['error']
            self.assertEquals(error.entity, None)
            self.assertEquals(error.errors, expected_errors or {})

    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

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

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

    def test_send_mail_failure(self):
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
        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
            req.set_session_data('captcha', self.captcha_value)
            #expected
            self._check_error(req, 'registration_sendmail',
                              expected_formvalues=req.form,
                              expected_errors={param: msg})
            self.assertEquals(req.get_session_data('captcha'), None)

    def _confirm_req(self, key=None):
107
108
        self.login('anon')
        req = self.request()
109
110
111
112
113
114
115
        data = self._posted_form('upassword-subject-confirm')
        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
116
117

    def test_confirm_ok(self):
118
119
120
121
        req = self._confirm_req()
        path, params = self.expect_redirect_publish(req, 'registration_confirm')
        self.assertEquals(path, '')
        self.assertEquals(params, {'__message': u'Congratulations, your registration is complete. Welcome %(firstname-subject)s %(surname-subject)s !' % self.data})
122
123
        self.restore_connection()
        rset = self.execute('Any U WHERE U login %(login)s, U firstname %(firstname)s, '
124
125
126
                            'U surname %(surname)s, U use_email M, M address %(address)s',
                            dict((k.replace('-subject', ''), v)
                                 for k, v in self.data.items()))
127
128
        self.failUnless(rset.rowcount)

Florent's avatar
Florent committed
129
    def test_confirm_failure_login_already_used(self):
130
        self.create_user(self.data['login-subject'])
131
        self.commit()
132
133
134
135
136
        req = self._confirm_req()
        self._check_error(req, 'registration_confirm',
                          expected_formvalues=self._posted_form('upassword-subject',
                                                                'upassword-subject-confirm'),
                          expected_errors={'login-subject': 'the value "%(login-subject)s" is already used, use another one' % self.data})
137
138

    def test_confirm_failure_invalid_data(self):
139
140
141
142
        req = self._confirm_req('dummykey')
        self._check_error(req, 'registration_confirm', 'register',
                          expected_params={'__message': 'Invalid registration data. '
                                           'Please try registering again.'})
Florent's avatar
Florent committed
143
144
145
146
        self._check_user_not_created()

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

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