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

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

Sylvain Thénault's avatar
Sylvain Thénault committed
7
from cubes.registration.views import RegistrationSendMailController, decrypt, encrypt
8
9


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

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

Sylvain Thénault's avatar
Sylvain Thénault committed
14
15
16
17
    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
18
            'captcha': captcha_value}
19
20

    def setup_database(self):
Sylvain Thénault's avatar
Sylvain Thénault committed
21
        self.config.global_set_option('cypher-seed', u'dummy cypher key')
22
23
24
25
26
27
28
29
30
31
        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
        names = pageinfo.etree.xpath('//ns:form[@id="form"]//ns:input[@type!="hidden"]/@name',
                                           namespaces=ns)
Florent's avatar
Florent committed
32
        self.assertEquals(set(names), set(self.data))
33
        # check form field value
Sylvain Thénault's avatar
0.1    
Sylvain Thénault committed
34
35
        firstname = pageinfo.etree.xpath('//ns:input[@name="firstname"]/@value',
                                         namespaces=ns)
36
37
38
39
        self.assertEquals(firstname, [req.form['firstname']])

    def _check_redirect(self, ctrl, urlpath, **urlparams):
        try:
Sylvain Thénault's avatar
Sylvain Thénault committed
40
            ctrl._cw.set_session_data('captcha', self.captcha_value)
41
            ctrl.publish()
Sylvain Thénault's avatar
Sylvain Thénault committed
42
43
44
            self.fail('should redirect to ' + urlpath)
        except Redirect, ex:
            url, params = (ex.location.split('?')+[''])[:2]
45
46
47
48
            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
49
        self.login('anon')
50
51
        req = self.request()
        req.form = self.data.copy()
Sylvain Thénault's avatar
Sylvain Thénault committed
52
53
        ctrl = self.vreg['controllers'].select('registration_sendmail', req,
                                               appli=self.app)
54
        # check redirect
Sylvain Thénault's avatar
Sylvain Thénault committed
55
        self._check_redirect(ctrl, '', __message='Your registration email has been sent. Follow instructions in there to activate your account.')
56
57
        # check email contains activation url...
        URL_RE = re.compile('(%s[^.]+)\.' % self.config['base-url'])
Sylvain Thénault's avatar
Sylvain Thénault committed
58
        text = MAILBOX[-1].message.get_payload(decode=True)
59
60
61
62
        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
63
64
        d.pop('upassword-confirm')
        self.assertDictEquals(decrypt(key, self.config['cypher-seed']), d)
65
66
67

    def test_send_mail_failure(self):
        req = self.request()
Sylvain Thénault's avatar
Sylvain Thénault committed
68
69
70
71
        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
72
73
74
            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
75
76
77
78
79
80
            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
81
                self.assertEquals(ctrl._cw.get_session_data('captcha'), None)
82

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

    def test_confirm_ok(self):
        ctrl = self._confirm_ctrl()
92
        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
93
94
        ctrl._cw.cnx.commit()
        ctrl._cw.cnx.close()
95
96
        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
97
                            'U surname %(surname)s, U use_email M, M address %(use_email)s',
Florent's avatar
Florent committed
98
                            self.data)
99
100
        self.failUnless(rset.rowcount)

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

    def test_confirm_failure_login_already_used(self):
106
107
        self.create_user(self.data['login'])
        self.commit()
Florent's avatar
Florent committed
108
        ctrl = self._confirm_ctrl()
109
110
        # 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
111
        d.pop('login'), d.pop('upassword'), d.pop('upassword-confirm')
Florent's avatar
Florent committed
112
        d['__message'] = u'login : the value "%(login)s" is already used, use another one' % self.data
113
114
115
        self._check_redirect(ctrl, 'register', **d)

    def test_confirm_failure_invalid_data(self):
Florent's avatar
Florent committed
116
        ctrl = self._confirm_ctrl(u'dummykey')
117
        self._check_redirect(ctrl, 'register', __message=u'Invalid registration data. Please try registering again.')
Florent's avatar
Florent committed
118
119
120
121
        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
122
        self.execute('INSERT EmailAddress X: U use_email X, X address %(use_email)s '
Florent's avatar
Florent committed
123
124
125
126
                     '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
127
128
        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
129
130
        self._check_redirect(ctrl, 'register', **d)
        self._check_user_not_created()