bgneal@565
|
1 """
|
bgneal@565
|
2 View tests for the accounts application.
|
bgneal@565
|
3
|
bgneal@565
|
4 """
|
bgneal@565
|
5 import datetime
|
bgneal@762
|
6 import re
|
bgneal@565
|
7
|
bgneal@565
|
8 from django.test import TestCase
|
bgneal@565
|
9 from django.core.urlresolvers import reverse
|
bgneal@659
|
10 from django.core import mail
|
bgneal@576
|
11 from django.contrib.auth.models import User
|
bgneal@576
|
12 from django.contrib.auth.hashers import check_password
|
bgneal@565
|
13
|
bgneal@565
|
14 from accounts.models import PendingUser
|
bgneal@565
|
15 from accounts.models import IllegalUsername
|
bgneal@565
|
16 from accounts.models import IllegalEmail
|
bgneal@565
|
17
|
bgneal@565
|
18
|
bgneal@565
|
19 class RegistrationTest(TestCase):
|
bgneal@565
|
20
|
bgneal@565
|
21 def setUp(self):
|
bgneal@565
|
22 u = User.objects.create_user('existing_user', 'existing_user@example.com', 'pw')
|
bgneal@565
|
23 u.save()
|
bgneal@565
|
24
|
bgneal@565
|
25 # a 2nd user has the same email as another
|
bgneal@565
|
26 u = User.objects.create_user('existing_user2', 'existing_user@example.com', 'pw')
|
bgneal@565
|
27 u.save()
|
bgneal@565
|
28
|
bgneal@565
|
29 PendingUser.objects.create(username='pending_user',
|
bgneal@565
|
30 email='pending_user@example.com',
|
bgneal@565
|
31 password='pw',
|
bgneal@565
|
32 date_joined=datetime.datetime.now(),
|
bgneal@565
|
33 key='key')
|
bgneal@565
|
34
|
bgneal@565
|
35 IllegalUsername.objects.create(username='illegalusername')
|
bgneal@565
|
36 IllegalEmail.objects.create(email='illegal@example.com')
|
bgneal@565
|
37
|
bgneal@782
|
38 self.post_vals = {
|
bgneal@782
|
39 'username': 'a_new_user',
|
bgneal@782
|
40 'email': 'test@example.com',
|
bgneal@782
|
41 'password1': 'my_password',
|
bgneal@782
|
42 'password2': 'my_password',
|
bgneal@782
|
43 'agree_age': 'on',
|
bgneal@782
|
44 'agree_tos': 'on',
|
bgneal@782
|
45 'agree_privacy': 'on',
|
bgneal@782
|
46 'question1': '101',
|
bgneal@782
|
47 'question2': '',
|
bgneal@782
|
48 'question3': '',
|
bgneal@782
|
49 }
|
bgneal@782
|
50
|
bgneal@565
|
51 def test_get_view(self):
|
bgneal@565
|
52 """
|
bgneal@565
|
53 Test a simple get of the registration view
|
bgneal@565
|
54
|
bgneal@565
|
55 """
|
bgneal@565
|
56 response = self.client.get(reverse('accounts-register'))
|
bgneal@565
|
57 self.assertEqual(response.status_code, 200)
|
bgneal@565
|
58
|
bgneal@565
|
59 def test_existing_user(self):
|
bgneal@565
|
60 """
|
bgneal@565
|
61 Ensure we can't register with an existing username.
|
bgneal@565
|
62
|
bgneal@565
|
63 """
|
bgneal@565
|
64 response = self.client.post(reverse('accounts-register'), {
|
bgneal@565
|
65 'username': 'existing_user',
|
bgneal@565
|
66 'email': 'test@example.com',
|
bgneal@565
|
67 'password1': 'my_password',
|
bgneal@565
|
68 'password2': 'my_password',
|
bgneal@565
|
69 'agree_age': 'on',
|
bgneal@565
|
70 'agree_tos': 'on',
|
bgneal@565
|
71 'agree_privacy': 'on',
|
bgneal@565
|
72 'question1': '101',
|
bgneal@565
|
73 'question2': '',
|
bgneal@905
|
74 'question3': '',
|
bgneal@565
|
75 })
|
bgneal@565
|
76
|
bgneal@565
|
77 self.assertEqual(response.status_code, 200)
|
bgneal@565
|
78 self.assertContains(response, 'A user with that username already exists')
|
bgneal@565
|
79
|
bgneal@565
|
80 def test_pending_user(self):
|
bgneal@565
|
81 """
|
bgneal@565
|
82 Ensure we can't register with a pending username.
|
bgneal@565
|
83
|
bgneal@565
|
84 """
|
bgneal@782
|
85 self.post_vals['username'] = 'pending_user'
|
bgneal@782
|
86 response = self.client.post(reverse('accounts-register'),
|
bgneal@782
|
87 self.post_vals)
|
bgneal@565
|
88 self.assertEqual(response.status_code, 200)
|
bgneal@565
|
89 self.assertContains(response, 'A pending user with that username already exists')
|
bgneal@565
|
90
|
bgneal@565
|
91 def test_illegal_username(self):
|
bgneal@565
|
92 """
|
bgneal@565
|
93 Ensure we can't register with a banned username.
|
bgneal@565
|
94
|
bgneal@565
|
95 """
|
bgneal@782
|
96 self.post_vals['username'] = 'illegalusername'
|
bgneal@782
|
97 response = self.client.post(reverse('accounts-register'),
|
bgneal@782
|
98 self.post_vals)
|
bgneal@565
|
99 self.assertEqual(response.status_code, 200)
|
bgneal@565
|
100 self.assertContains(response, 'That username is not allowed')
|
bgneal@565
|
101
|
bgneal@565
|
102 def test_duplicate_existing_email(self):
|
bgneal@565
|
103 """
|
bgneal@565
|
104 Ensure we can't register with a duplicate email address.
|
bgneal@565
|
105
|
bgneal@565
|
106 """
|
bgneal@782
|
107 self.post_vals['email'] = 'existing_user@example.com'
|
bgneal@782
|
108 response = self.client.post(reverse('accounts-register'),
|
bgneal@782
|
109 self.post_vals)
|
bgneal@565
|
110 self.assertEqual(response.status_code, 200)
|
bgneal@565
|
111 self.assertContains(response, 'A user with that email address already exists')
|
bgneal@565
|
112
|
bgneal@565
|
113 def test_duplicate_pending_email(self):
|
bgneal@565
|
114 """
|
bgneal@565
|
115 Ensure we can't register with a duplicate email address.
|
bgneal@565
|
116
|
bgneal@565
|
117 """
|
bgneal@782
|
118 self.post_vals['email'] = 'pending_user@example.com'
|
bgneal@782
|
119 response = self.client.post(reverse('accounts-register'),
|
bgneal@782
|
120 self.post_vals)
|
bgneal@565
|
121 self.assertEqual(response.status_code, 200)
|
bgneal@565
|
122 self.assertContains(response, 'A pending user with that email address already exists')
|
bgneal@565
|
123
|
bgneal@565
|
124 def test_illegal_email(self):
|
bgneal@565
|
125 """
|
bgneal@565
|
126 Ensure we can't register with a banned email address.
|
bgneal@565
|
127
|
bgneal@565
|
128 """
|
bgneal@782
|
129 self.post_vals['email'] = 'illegal@example.com'
|
bgneal@782
|
130 response = self.client.post(reverse('accounts-register'),
|
bgneal@782
|
131 self.post_vals)
|
bgneal@565
|
132 self.assertEqual(response.status_code, 200)
|
bgneal@565
|
133 self.assertContains(response, 'That email address is not allowed')
|
bgneal@565
|
134
|
bgneal@565
|
135 def test_password_match(self):
|
bgneal@565
|
136 """
|
bgneal@565
|
137 Ensure the passwords match.
|
bgneal@565
|
138
|
bgneal@565
|
139 """
|
bgneal@782
|
140 self.post_vals['password2'] = "doesn't match"
|
bgneal@782
|
141 response = self.client.post(reverse('accounts-register'),
|
bgneal@782
|
142 self.post_vals)
|
bgneal@565
|
143 self.assertEqual(response.status_code, 200)
|
bgneal@565
|
144 self.assertContains(response, "The two password fields didn't match")
|
bgneal@565
|
145
|
bgneal@565
|
146 def test_question1(self):
|
bgneal@565
|
147 """
|
bgneal@565
|
148 Ensure our anti-spam question is answered.
|
bgneal@565
|
149
|
bgneal@565
|
150 """
|
bgneal@782
|
151 self.post_vals['question1'] = 'huh'
|
bgneal@782
|
152 response = self.client.post(reverse('accounts-register'),
|
bgneal@782
|
153 self.post_vals)
|
bgneal@565
|
154 self.assertEqual(response.status_code, 200)
|
bgneal@565
|
155 self.assertContains(response, "Incorrect answer to our anti-spam question")
|
bgneal@565
|
156
|
bgneal@565
|
157 def test_question2(self):
|
bgneal@565
|
158 """
|
bgneal@565
|
159 Ensure our honeypot question check works.
|
bgneal@565
|
160
|
bgneal@565
|
161 """
|
bgneal@782
|
162 self.post_vals['question2'] = 'non blank'
|
bgneal@782
|
163 response = self.client.post(reverse('accounts-register'),
|
bgneal@782
|
164 self.post_vals)
|
bgneal@782
|
165 self.assertEqual(response.status_code, 200)
|
bgneal@565
|
166
|
bgneal@782
|
167 def test_question3(self):
|
bgneal@782
|
168 """
|
bgneal@782
|
169 Ensure our non-hidden honeypot question check works.
|
bgneal@782
|
170
|
bgneal@782
|
171 """
|
bgneal@782
|
172 self.post_vals['question3'] = 'non blank'
|
bgneal@782
|
173 response = self.client.post(reverse('accounts-register'),
|
bgneal@782
|
174 self.post_vals)
|
bgneal@782
|
175 self.assertEqual(response.status_code, 200)
|
bgneal@782
|
176
|
bgneal@565
|
177 def test_success(self):
|
bgneal@565
|
178 """
|
bgneal@565
|
179 Ensure we can successfully register.
|
bgneal@565
|
180
|
bgneal@565
|
181 """
|
bgneal@782
|
182 response = self.client.post(reverse('accounts-register'),
|
bgneal@782
|
183 self.post_vals)
|
bgneal@905
|
184 self.assertRedirects(response, reverse('accounts-register1'))
|
bgneal@905
|
185
|
bgneal@905
|
186 # No pending user should exist yet
|
bgneal@905
|
187 try:
|
bgneal@905
|
188 pending = PendingUser.objects.get(username='a_new_user')
|
bgneal@905
|
189 except PendingUser.DoesNotExist:
|
bgneal@905
|
190 pass
|
bgneal@905
|
191 else:
|
bgneal@905
|
192 self.fail("PendingUser was created early")
|
bgneal@905
|
193
|
bgneal@905
|
194 # Should have created a reg_info dict in the session
|
bgneal@905
|
195 reg_info = self.client.session.get('reg_info')
|
bgneal@905
|
196 self.assertEqual(reg_info, {
|
bgneal@905
|
197 'username': self.post_vals['username'],
|
bgneal@905
|
198 'email': self.post_vals['email'],
|
bgneal@905
|
199 'password': self.post_vals['password1'],
|
bgneal@905
|
200 'code': reg_info['code'],
|
bgneal@905
|
201 })
|
bgneal@905
|
202 code = reg_info['code']
|
bgneal@905
|
203 match = re.match(r'\w+-\d{3}', code)
|
bgneal@905
|
204 self.assertIsNotNone(match)
|
bgneal@905
|
205
|
bgneal@905
|
206 # Get the next page
|
bgneal@905
|
207 response = self.client.get(reverse('accounts-register2'))
|
bgneal@905
|
208 self.assertEqual(response.status_code, 200)
|
bgneal@905
|
209
|
bgneal@905
|
210 # No pending user should exist yet
|
bgneal@905
|
211 try:
|
bgneal@905
|
212 pending = PendingUser.objects.get(username='a_new_user')
|
bgneal@905
|
213 except PendingUser.DoesNotExist:
|
bgneal@905
|
214 pass
|
bgneal@905
|
215 else:
|
bgneal@905
|
216 self.fail("PendingUser was created early")
|
bgneal@905
|
217
|
bgneal@905
|
218 # Try bad code
|
bgneal@905
|
219 response = self.client.post(reverse('accounts-register2'),
|
bgneal@905
|
220 {'code': code + code })
|
bgneal@905
|
221 self.assertEqual(response.status_code, 200)
|
bgneal@905
|
222 self.assertContains(response, "The registration code does not match")
|
bgneal@905
|
223
|
bgneal@905
|
224 # No pending user should exist yet
|
bgneal@905
|
225 try:
|
bgneal@905
|
226 pending = PendingUser.objects.get(username='a_new_user')
|
bgneal@905
|
227 except PendingUser.DoesNotExist:
|
bgneal@905
|
228 pass
|
bgneal@905
|
229 else:
|
bgneal@905
|
230 self.fail("PendingUser was created early")
|
bgneal@905
|
231
|
bgneal@905
|
232 # Try good code
|
bgneal@905
|
233 response = self.client.post(reverse('accounts-register2'),
|
bgneal@905
|
234 {'code': code })
|
bgneal@905
|
235 self.assertRedirects(response, reverse('accounts-register_thanks'))
|
bgneal@905
|
236 self.assertIsNone(self.client.session.get('reg_info'))
|
bgneal@565
|
237
|
bgneal@565
|
238 try:
|
bgneal@565
|
239 pending = PendingUser.objects.get(username='a_new_user')
|
bgneal@565
|
240 except PendingUser.DoesNotExist:
|
bgneal@565
|
241 self.fail("PendingUser was not created")
|
bgneal@565
|
242
|
bgneal@565
|
243 self.assertEqual(pending.email, 'test@example.com')
|
bgneal@565
|
244 self.assertTrue(datetime.datetime.now() - pending.date_joined <
|
bgneal@565
|
245 datetime.timedelta(minutes=1))
|
bgneal@565
|
246 self.assertTrue(check_password('my_password', pending.password))
|
bgneal@659
|
247
|
bgneal@905
|
248 self.assertEqual(len(mail.outbox), 1)
|
bgneal@905
|
249 msg = mail.outbox[0]
|
bgneal@905
|
250 self.assertTrue(msg.subject.startswith('Registration Confirmation'))
|
bgneal@905
|
251 self.assertTrue(len(msg.to) == 1 and msg.to[0] == pending.email)
|
bgneal@905
|
252 msg_text = msg.message().as_string()
|
bgneal@905
|
253
|
bgneal@905
|
254 activation_link = 'http://example.com%s' % (
|
bgneal@905
|
255 reverse('accounts-register_confirm',
|
bgneal@905
|
256 kwargs={'username': pending.username,
|
bgneal@905
|
257 'key': pending.key}))
|
bgneal@905
|
258 self.assertTrue(activation_link in msg_text)
|
bgneal@905
|
259
|
bgneal@905
|
260 # Vist confirm link
|
bgneal@905
|
261 response = self.client.get(reverse('accounts-register_confirm',
|
bgneal@905
|
262 kwargs={'username': pending.username,
|
bgneal@905
|
263 'key': pending.key}))
|
bgneal@905
|
264 self.assertEqual(response.status_code, 200)
|
bgneal@905
|
265
|
bgneal@905
|
266 try:
|
bgneal@905
|
267 pending = PendingUser.objects.get(username='a_new_user')
|
bgneal@905
|
268 except PendingUser.DoesNotExist:
|
bgneal@905
|
269 pass
|
bgneal@905
|
270 else:
|
bgneal@905
|
271 self.fail("PendingUser was not deleted upon confirmation")
|
bgneal@905
|
272
|
bgneal@905
|
273 user = User.objects.get(username=pending.username)
|
bgneal@905
|
274 self.assertEqual(user.email, pending.email)
|
bgneal@905
|
275 now = datetime.datetime.now()
|
bgneal@905
|
276 delta = datetime.timedelta(seconds=10)
|
bgneal@905
|
277 self.assertTrue(now - user.last_login < delta)
|
bgneal@905
|
278 self.assertTrue(now - user.date_joined < delta)
|
bgneal@905
|
279 self.assertEqual(user.password, pending.password)
|
bgneal@905
|
280 self.assertEqual(user.first_name, '')
|
bgneal@905
|
281 self.assertEqual(user.last_name, '')
|
bgneal@905
|
282 self.assertFalse(user.is_staff)
|
bgneal@905
|
283 self.assertTrue(user.is_active)
|
bgneal@905
|
284 self.assertFalse(user.is_superuser)
|
bgneal@905
|
285
|
bgneal@659
|
286
|
bgneal@659
|
287 class ForgotUsernameTest(TestCase):
|
bgneal@659
|
288
|
bgneal@659
|
289 def setUp(self):
|
bgneal@659
|
290 u = User.objects.create_user('existing_user', 'existing_user@example.com', 'pw')
|
bgneal@659
|
291 u.save()
|
bgneal@659
|
292
|
bgneal@659
|
293 def test_get_query_view(self):
|
bgneal@659
|
294 """Test a simple get of the username query view"""
|
bgneal@659
|
295 response = self.client.get(reverse('accounts-username_query'))
|
bgneal@659
|
296 self.assertEqual(response.status_code, 200)
|
bgneal@659
|
297
|
bgneal@659
|
298 def test_get_username_sent_view(self):
|
bgneal@659
|
299 """Test a simple get of the username sent view"""
|
bgneal@659
|
300 response = self.client.get(reverse('accounts-username_sent'))
|
bgneal@659
|
301 self.assertEqual(response.status_code, 200)
|
bgneal@659
|
302
|
bgneal@659
|
303 def test_invalid_email(self):
|
bgneal@659
|
304 """Test form submittal of unknown email address."""
|
bgneal@659
|
305 response = self.client.post(reverse('accounts-username_query'), {
|
bgneal@659
|
306 'email': 'bad_address@example.com',
|
bgneal@659
|
307 },
|
bgneal@659
|
308 follow=True)
|
bgneal@659
|
309
|
bgneal@659
|
310 self.assertRedirects(response, reverse('accounts-username_sent'))
|
bgneal@659
|
311
|
bgneal@659
|
312 self.assertEqual(len(mail.outbox), 0)
|
bgneal@659
|
313
|
bgneal@659
|
314 def test_valid_email(self):
|
bgneal@659
|
315 """Test form submittal of valid email address."""
|
bgneal@659
|
316 response = self.client.post(reverse('accounts-username_query'), {
|
bgneal@659
|
317 'email': 'existing_user@example.com',
|
bgneal@659
|
318 },
|
bgneal@659
|
319 follow=True)
|
bgneal@659
|
320
|
bgneal@659
|
321 self.assertRedirects(response, reverse('accounts-username_sent'))
|
bgneal@659
|
322
|
bgneal@659
|
323 self.assertEqual(len(mail.outbox), 1)
|
bgneal@659
|
324 if len(mail.outbox):
|
bgneal@659
|
325 self.assertTrue(mail.outbox[0].subject.startswith('Forgotten username'))
|
bgneal@762
|
326
|
bgneal@762
|
327
|
bgneal@762
|
328 class ForgotEmailTest(TestCase):
|
bgneal@762
|
329 """Because we use a custom URL its important to test this. This got broken
|
bgneal@762
|
330 in Django 1.6 when the URL pattern changed.
|
bgneal@762
|
331
|
bgneal@762
|
332 """
|
bgneal@762
|
333
|
bgneal@762
|
334 def setUp(self):
|
bgneal@762
|
335 u = User.objects.create_user('user1', 'user1@example.com', 'pw')
|
bgneal@762
|
336 u.save()
|
bgneal@762
|
337
|
bgneal@762
|
338 def test_nominal_case(self):
|
bgneal@762
|
339 """Test a full forgot password scenario."""
|
bgneal@762
|
340
|
bgneal@762
|
341 # GET password reset page
|
bgneal@762
|
342 response = self.client.get(reverse('accounts-password_reset'))
|
bgneal@762
|
343 self.assertEqual(response.status_code, 200)
|
bgneal@762
|
344
|
bgneal@762
|
345 # POST email address
|
bgneal@762
|
346 args = {'email': 'user1@example.com'}
|
bgneal@762
|
347 response = self.client.post(reverse('accounts-password_reset'), args,
|
bgneal@762
|
348 follow=True)
|
bgneal@762
|
349 self.assertRedirects(response, reverse('accounts-password_reset_sent'))
|
bgneal@762
|
350
|
bgneal@762
|
351 # Ensure the email was sent
|
bgneal@762
|
352 self.assertEqual(len(mail.outbox), 1)
|
bgneal@762
|
353 if (len(mail.outbox)):
|
bgneal@762
|
354 msg = mail.outbox[0]
|
bgneal@762
|
355 self.assertTrue(msg.subject.startswith('Password reset'))
|
bgneal@762
|
356 self.assertTrue(len(msg.to) == 1 and msg.to[0] == 'user1@example.com')
|
bgneal@762
|
357 msg_text = msg.message().as_string()
|
bgneal@762
|
358 m = re.search(r'http://example.com/accounts/password/reset/confirm/'
|
bgneal@762
|
359 r'(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9a-z]+-\w+)/',
|
bgneal@762
|
360 msg_text)
|
bgneal@762
|
361 self.assertTrue(m is not None)
|
bgneal@762
|
362 if m:
|
bgneal@762
|
363 uidb64, token = m.group('uidb64'), m.group('token')
|
bgneal@762
|
364
|
bgneal@762
|
365 # visit the password reset page
|
bgneal@762
|
366 response = self.client.get(
|
bgneal@762
|
367 reverse('accounts-password_reset_confirm',
|
bgneal@762
|
368 kwargs={'uidb64': uidb64, 'token': token}))
|
bgneal@762
|
369 self.assertEqual(response.status_code, 200)
|
bgneal@762
|
370
|
bgneal@762
|
371 # POST new password
|
bgneal@762
|
372 args = {'new_password1': 'pw2', 'new_password2': 'pw2'}
|
bgneal@762
|
373 response = self.client.post(
|
bgneal@762
|
374 reverse('accounts-password_reset_confirm',
|
bgneal@762
|
375 kwargs={'uidb64': uidb64, 'token': token}),
|
bgneal@762
|
376 args, follow=True)
|
bgneal@762
|
377 self.assertRedirects(response,
|
bgneal@762
|
378 reverse('accounts-password_reset_success'))
|
bgneal@762
|
379 self.assertEqual(response.status_code, 200)
|
bgneal@762
|
380
|
bgneal@762
|
381 # Check new password
|
bgneal@762
|
382 u = User.objects.get(username='user1')
|
bgneal@762
|
383 self.assertTrue(check_password('pw2', u.password))
|