2
2
import time
3
3
from unittest import mock
4
4
from unittest .mock import patch
5
+ from urllib .parse import quote_plus as urlquote
6
+ from urllib .parse import unquote_plus as urlunquote
7
+ from urllib .parse import urlparse
5
8
6
9
from django .test .utils import override_settings
7
10
from rest_framework import status
8
11
9
12
from rest_registration .api .views .register import RegisterSigner
10
13
from rest_registration .settings import registration_settings
11
- from tests .utils import shallow_merge_dicts
14
+ from tests .utils import TestCase , shallow_merge_dicts
12
15
13
16
from .base import APIViewTestCase
14
17
36
39
37
40
38
41
@override_settings (REST_REGISTRATION = REST_REGISTRATION_WITH_VERIFICATION )
39
- class RegisterViewTestCase (APIViewTestCase ):
40
- VIEW_NAME = 'register'
42
+ class RegisterSerializerTestCase (TestCase ):
41
43
42
- def test_register_serializer_ok (self ):
44
+ def test_ok (self ):
43
45
serializer_class = registration_settings .REGISTER_SERIALIZER_CLASS
44
46
serializer = serializer_class (data = {})
45
47
field_names = {f for f in serializer .get_fields ()}
@@ -56,7 +58,7 @@ def test_register_serializer_ok(self):
56
58
},
57
59
),
58
60
)
59
- def test_register_serializer_no_password_ok (self ):
61
+ def test_no_password_ok (self ):
60
62
serializer_class = registration_settings .REGISTER_SERIALIZER_CLASS
61
63
serializer = serializer_class (data = {})
62
64
field_names = {f for f in serializer .get_fields ()}
@@ -65,6 +67,52 @@ def test_register_serializer_no_password_ok(self):
65
67
{'id' , 'username' , 'first_name' , 'last_name' , 'email' , 'password' },
66
68
)
67
69
70
+
71
+ def build_custom_verification_url (signer ):
72
+ base_url = signer .get_base_url ()
73
+ signed_data = signer .get_signed_data ()
74
+ if signer .USE_TIMESTAMP :
75
+ timestamp = signed_data .pop (signer .TIMESTAMP_FIELD )
76
+ else :
77
+ timestamp = None
78
+ signature = signed_data .pop (signer .SIGNATURE_FIELD )
79
+ segments = [signed_data [k ] for k in sorted (signed_data .keys ())]
80
+ segments .append (signature )
81
+ if timestamp :
82
+ segments .append (timestamp )
83
+ quoted_segments = [urlquote (str (s )) for s in segments ]
84
+
85
+ url = base_url
86
+ if not url .endswith ('/' ):
87
+ url += '/'
88
+ url += '/' .join (quoted_segments )
89
+ url += '/'
90
+ if signer .request :
91
+ url = signer .request .build_absolute_uri (url )
92
+
93
+ return url
94
+
95
+
96
+ def parse_custom_verification_url (url , verification_field_names ):
97
+ parsed_url = urlparse (url )
98
+ num_of_fields = len (verification_field_names )
99
+ url_path = parsed_url .path .rstrip ('/' )
100
+ url_segments = url_path .rsplit ('/' , num_of_fields )
101
+ if len (url_segments ) != num_of_fields + 1 :
102
+ raise ValueError ("Could not parse {url}" .format (url = url ))
103
+
104
+ data_segments = url_segments [1 :]
105
+ url_path = url_segments [0 ] + '/'
106
+ verification_data = {
107
+ name : urlunquote (value )
108
+ for name , value in zip (verification_field_names , data_segments )}
109
+ return url_path , verification_data
110
+
111
+
112
+ @override_settings (REST_REGISTRATION = REST_REGISTRATION_WITH_VERIFICATION )
113
+ class RegisterViewTestCase (APIViewTestCase ):
114
+ VIEW_NAME = 'register'
115
+
68
116
def test_register_ok (self ):
69
117
data = self ._get_register_user_data (password = 'testpassword' )
70
118
request = self .create_post_request (data )
@@ -88,7 +136,48 @@ def test_register_ok(self):
88
136
verification_data = self .assert_valid_verification_url (
89
137
url ,
90
138
expected_path = REGISTER_VERIFICATION_URL ,
91
- expected_query_keys = {'signature' , 'user_id' , 'timestamp' },
139
+ expected_fields = {'signature' , 'user_id' , 'timestamp' },
140
+ )
141
+ url_user_id = int (verification_data ['user_id' ])
142
+ self .assertEqual (url_user_id , user_id )
143
+ url_sig_timestamp = int (verification_data ['timestamp' ])
144
+ self .assertGreaterEqual (url_sig_timestamp , time_before )
145
+ self .assertLessEqual (url_sig_timestamp , time_after )
146
+ signer = RegisterSigner (verification_data )
147
+ signer .verify ()
148
+
149
+ @override_settings (
150
+ REST_REGISTRATION = shallow_merge_dicts (
151
+ REST_REGISTRATION_WITH_VERIFICATION , {
152
+ 'VERIFICATION_URL_BUILDER' : build_custom_verification_url ,
153
+ },
154
+ ),
155
+ )
156
+ def test_register_with_custom_verification_url_ok (self ):
157
+ data = self ._get_register_user_data (password = 'testpassword' )
158
+ request = self .create_post_request (data )
159
+ time_before = math .floor (time .time ())
160
+ with self .assert_one_mail_sent () as sent_emails :
161
+ response = self .view_func (request )
162
+ time_after = math .ceil (time .time ())
163
+ self .assert_valid_response (response , status .HTTP_201_CREATED )
164
+ user_id = response .data ['id' ]
165
+ # Check database state.
166
+ user = self .user_class .objects .get (id = user_id )
167
+ self .assertEqual (user .username , data ['username' ])
168
+ self .assertTrue (user .check_password (data ['password' ]))
169
+ self .assertFalse (user .is_active )
170
+ # Check verification e-mail.
171
+ sent_email = sent_emails [0 ]
172
+ self .assertEqual (sent_email .from_email , VERIFICATION_FROM_EMAIL )
173
+ self .assertListEqual (sent_email .to , [data ['email' ]])
174
+ url = self .assert_one_url_line_in_text (sent_email .body )
175
+
176
+ verification_data = self .assert_valid_verification_url (
177
+ url ,
178
+ expected_path = REGISTER_VERIFICATION_URL ,
179
+ expected_fields = ['user_id' , 'signature' , 'timestamp' ],
180
+ url_parser = parse_custom_verification_url ,
92
181
)
93
182
url_user_id = int (verification_data ['user_id' ])
94
183
self .assertEqual (url_user_id , user_id )
@@ -98,7 +187,6 @@ def test_register_ok(self):
98
187
signer = RegisterSigner (verification_data )
99
188
signer .verify ()
100
189
101
- # TODO: unskip this test when × entity problem will be fixed.
102
190
@override_settings (
103
191
REST_REGISTRATION = REST_REGISTRATION_WITH_HTML_EMAIL_VERIFICATION ,
104
192
)
@@ -125,7 +213,7 @@ def test_register_with_html_email_ok(self):
125
213
verification_data = self .assert_valid_verification_url (
126
214
url ,
127
215
expected_path = REGISTER_VERIFICATION_URL ,
128
- expected_query_keys = {'signature' , 'user_id' , 'timestamp' },
216
+ expected_fields = {'signature' , 'user_id' , 'timestamp' },
129
217
)
130
218
url_user_id = int (verification_data ['user_id' ])
131
219
self .assertEqual (url_user_id , user_id )
@@ -166,7 +254,7 @@ def test_register_no_password_confirm_ok(self):
166
254
verification_data = self .assert_valid_verification_url (
167
255
url ,
168
256
expected_path = REGISTER_VERIFICATION_URL ,
169
- expected_query_keys = {'signature' , 'user_id' , 'timestamp' },
257
+ expected_fields = {'signature' , 'user_id' , 'timestamp' },
170
258
)
171
259
url_user_id = int (verification_data ['user_id' ])
172
260
self .assertEqual (url_user_id , user_id )
0 commit comments