unittest_registration.py 6.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'

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

    def setup_database(self):
22
        self.config.global_set_option('registration-cypher-seed', u'dummy cypher key')
23
24
25
26
27
28
29
30
        super(RegistrationTC, self).setup_database()

    def test_registration_form(self):
        req = self.request()
        req.form = {'firstname': u'Toto'}
        pageinfo = self.view('registration', req=req, rset=None)
        ns = {'ns': pageinfo.default_ns}
        # check form field names
31
        names = pageinfo.etree.xpath('//ns:form[@id="registrationForm"]//ns:input[@type!="hidden"]/@name',
32
                                           namespaces=ns)
Florent's avatar
Florent committed
33
        self.assertEquals(set(names), set(self.data))
34
        # check form field value
Sylvain Thénault's avatar
0.1    
Sylvain Thénault committed
35
36
        firstname = pageinfo.etree.xpath('//ns:input[@name="firstname"]/@value',
                                         namespaces=ns)
37
38
39
40
        self.assertEquals(firstname, [req.form['firstname']])

    def _check_redirect(self, ctrl, urlpath, **urlparams):
        try:
Sylvain Thénault's avatar
Sylvain Thénault committed
41
            ctrl._cw.set_session_data('captcha', self.captcha_value)
42
            ctrl.publish()
Sylvain Thénault's avatar
Sylvain Thénault committed
43
44
45
            self.fail('should redirect to ' + urlpath)
        except Redirect, ex:
            url, params = (ex.location.split('?')+[''])[:2]
46
47
48
49
            self.assertEquals(url, self.config['base-url'] + urlpath)
            self.assertDictEquals(dict(cgi.parse_qsl(params)), urlparams)

    def test_send_mail_ok(self):
Florent's avatar
Florent committed
50
        self.login('anon')
51
52
        req = self.request()
        req.form = self.data.copy()
Sylvain Thénault's avatar
Sylvain Thénault committed
53
54
        ctrl = self.vreg['controllers'].select('registration_sendmail', req,
                                               appli=self.app)
55
        # check redirect
Sylvain Thénault's avatar
Sylvain Thénault committed
56
        self._check_redirect(ctrl, '', __message='Your registration email has been sent. Follow instructions in there to activate your account.')
57
58
        # check email contains activation url...
        URL_RE = re.compile('(%s[^.]+)\.' % self.config['base-url'])
Sylvain Thénault's avatar
Sylvain Thénault committed
59
        text = MAILBOX[-1].message.get_payload(decode=True)
60
61
62
63
        url = URL_RE.search(text).group(1)
        # ... and the registration key contains all data
        key = dict(cgi.parse_qsl(urlparse.urlsplit(url)[3]))['key']
        d = self.data.copy()
Sylvain Thénault's avatar
Sylvain Thénault committed
64
        d.pop('upassword-confirm')
65
        self.assertDictEquals(decrypt(key, self.config['registration-cypher-seed']), d)
66
67
68

    def test_send_mail_failure(self):
        req = self.request()
Sylvain Thénault's avatar
Sylvain Thénault committed
69
70
71
72
        for param, msg in (('login', 'required attribute'),
                           ('captcha', 'incorrect captcha value')):
            req.form = self.data.copy()
            req.form.pop(param)
Sylvain Thénault's avatar
Sylvain Thénault committed
73
74
75
            ctrl = self.vreg['controllers'].select('registration_sendmail',
                                                       req, appli=self.app)
            ctrl._cw.set_session_data('captcha', self.captcha_value)
Sylvain Thénault's avatar
Sylvain Thénault committed
76
77
78
79
80
81
            try:
                ctrl.publish()
                self.fail('should raise ValidationError')
            except ValidationError, e:
                self.assertDictEquals(e.errors, {param: msg})
                # check captcha has expired
Sylvain Thénault's avatar
Sylvain Thénault committed
82
                self.assertEquals(ctrl._cw.get_session_data('captcha'), None)
83

Florent's avatar
Florent committed
84
    def _confirm_ctrl(self, key=None):
85
86
        self.login('anon')
        req = self.request()
87
        req.form = {'key': key or encrypt(self.data, self.config['registration-cypher-seed'])}
Sylvain Thénault's avatar
Sylvain Thénault committed
88
89
        return self.vreg['controllers'].select('registration_confirm', req,
                                               appli=self.app)
Florent's avatar
Florent committed
90
91
92

    def test_confirm_ok(self):
        ctrl = self._confirm_ctrl()
93
        self._check_redirect(ctrl, '', __message=u'Congratulations, your registration is complete. Welcome %(firstname)s %(surname)s !' % self.data)
Sylvain Thénault's avatar
Sylvain Thénault committed
94
95
        ctrl._cw.cnx.commit()
        ctrl._cw.cnx.close()
96
97
        self.restore_connection()
        rset = self.execute('Any U WHERE U login %(login)s, U firstname %(firstname)s, '
Sylvain Thénault's avatar
Sylvain Thénault committed
98
                            'U surname %(surname)s, U use_email M, M address %(use_email)s',
Florent's avatar
Florent committed
99
                            self.data)
100
101
        self.failUnless(rset.rowcount)

Florent's avatar
Florent committed
102
103
    def _check_user_not_created(self):
        self.restore_connection()
Florent's avatar
Florent committed
104
        self.failIf(self.execute('CWUser X WHERE X login %(login)s', self.data).rowcount)
Florent's avatar
Florent committed
105
106

    def test_confirm_failure_login_already_used(self):
107
108
        self.create_user(self.data['login'])
        self.commit()
Florent's avatar
Florent committed
109
        ctrl = self._confirm_ctrl()
110
111
        # check user is redirected to a url without its password in the url params
        d = self.data.copy()
Sylvain Thénault's avatar
Sylvain Thénault committed
112
        d.pop('login'), d.pop('upassword'), d.pop('upassword-confirm')
Florent's avatar
Florent committed
113
        d['__message'] = u'login : the value "%(login)s" is already used, use another one' % self.data
114
115
116
        self._check_redirect(ctrl, 'register', **d)

    def test_confirm_failure_invalid_data(self):
Florent's avatar
Florent committed
117
        ctrl = self._confirm_ctrl(u'dummykey')
118
        self._check_redirect(ctrl, 'register', __message=u'Invalid registration data. Please try registering again.')
Florent's avatar
Florent committed
119
120
121
122
        self._check_user_not_created()

    def test_confirm_failure_email_already_used(self):
        self.create_user('test')
Sylvain Thénault's avatar
Sylvain Thénault committed
123
        self.execute('INSERT EmailAddress X: U use_email X, X address %(use_email)s '
Florent's avatar
Florent committed
124
125
126
127
                     'WHERE U login "test"', self.data)
        self.commit()
        ctrl = self._confirm_ctrl()
        d = self.data.copy()
Sylvain Thénault's avatar
Sylvain Thénault committed
128
129
        d.pop('login'), d.pop('upassword'), d.pop('upassword-confirm')
        d['__message'] = u'address : the value "%(use_email)s" is already used, use another one' % self.data
Florent's avatar
Florent committed
130
131
        self._check_redirect(ctrl, 'register', **d)
        self._check_user_not_created()
Sylvain Thénault's avatar
Sylvain Thénault committed
132
133

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