bgneal@565: """ bgneal@565: View tests for the accounts application. bgneal@565: bgneal@565: """ bgneal@565: import datetime bgneal@762: import re bgneal@565: bgneal@565: from django.test import TestCase bgneal@565: from django.core.urlresolvers import reverse bgneal@659: from django.core import mail bgneal@576: from django.contrib.auth.models import User bgneal@576: from django.contrib.auth.hashers import check_password bgneal@565: bgneal@565: from accounts.models import PendingUser bgneal@565: from accounts.models import IllegalUsername bgneal@565: from accounts.models import IllegalEmail bgneal@565: bgneal@565: bgneal@565: class RegistrationTest(TestCase): bgneal@565: bgneal@565: def setUp(self): bgneal@565: u = User.objects.create_user('existing_user', 'existing_user@example.com', 'pw') bgneal@565: u.save() bgneal@565: bgneal@565: # a 2nd user has the same email as another bgneal@565: u = User.objects.create_user('existing_user2', 'existing_user@example.com', 'pw') bgneal@565: u.save() bgneal@565: bgneal@565: PendingUser.objects.create(username='pending_user', bgneal@565: email='pending_user@example.com', bgneal@565: password='pw', bgneal@565: date_joined=datetime.datetime.now(), bgneal@565: key='key') bgneal@565: bgneal@565: IllegalUsername.objects.create(username='illegalusername') bgneal@565: IllegalEmail.objects.create(email='illegal@example.com') bgneal@565: bgneal@565: def test_get_view(self): bgneal@565: """ bgneal@565: Test a simple get of the registration view bgneal@565: bgneal@565: """ bgneal@565: response = self.client.get(reverse('accounts-register')) bgneal@565: self.assertEqual(response.status_code, 200) bgneal@565: bgneal@565: def test_existing_user(self): bgneal@565: """ bgneal@565: Ensure we can't register with an existing username. bgneal@565: bgneal@565: """ bgneal@565: response = self.client.post(reverse('accounts-register'), { bgneal@565: 'username': 'existing_user', bgneal@565: 'email': 'test@example.com', bgneal@565: 'password1': 'my_password', bgneal@565: 'password2': 'my_password', bgneal@565: 'agree_age': 'on', bgneal@565: 'agree_tos': 'on', bgneal@565: 'agree_privacy': 'on', bgneal@565: 'question1': '101', bgneal@565: 'question2': '', bgneal@565: }) bgneal@565: bgneal@565: self.assertEqual(response.status_code, 200) bgneal@565: self.assertContains(response, 'A user with that username already exists') bgneal@565: bgneal@565: def test_pending_user(self): bgneal@565: """ bgneal@565: Ensure we can't register with a pending username. bgneal@565: bgneal@565: """ bgneal@565: response = self.client.post(reverse('accounts-register'), { bgneal@565: 'username': 'pending_user', bgneal@565: 'email': 'test@example.com', bgneal@565: 'password1': 'my_password', bgneal@565: 'password2': 'my_password', bgneal@565: 'agree_age': 'on', bgneal@565: 'agree_tos': 'on', bgneal@565: 'agree_privacy': 'on', bgneal@565: 'question1': '101', bgneal@565: 'question2': '', bgneal@565: }) bgneal@565: bgneal@565: self.assertEqual(response.status_code, 200) bgneal@565: self.assertContains(response, 'A pending user with that username already exists') bgneal@565: bgneal@565: def test_illegal_username(self): bgneal@565: """ bgneal@565: Ensure we can't register with a banned username. bgneal@565: bgneal@565: """ bgneal@565: response = self.client.post(reverse('accounts-register'), { bgneal@565: 'username': 'illegalusername', bgneal@565: 'email': 'test@example.com', bgneal@565: 'password1': 'my_password', bgneal@565: 'password2': 'my_password', bgneal@565: 'agree_age': 'on', bgneal@565: 'agree_tos': 'on', bgneal@565: 'agree_privacy': 'on', bgneal@565: 'question1': '101', bgneal@565: 'question2': '', bgneal@565: }) bgneal@565: bgneal@565: self.assertEqual(response.status_code, 200) bgneal@565: self.assertContains(response, 'That username is not allowed') bgneal@565: bgneal@565: def test_duplicate_existing_email(self): bgneal@565: """ bgneal@565: Ensure we can't register with a duplicate email address. bgneal@565: bgneal@565: """ bgneal@565: response = self.client.post(reverse('accounts-register'), { bgneal@565: 'username': 'a_new_user', bgneal@565: 'email': 'existing_user@example.com', bgneal@565: 'password1': 'my_password', bgneal@565: 'password2': 'my_password', bgneal@565: 'agree_age': 'on', bgneal@565: 'agree_tos': 'on', bgneal@565: 'agree_privacy': 'on', bgneal@565: 'question1': '101', bgneal@565: 'question2': '', bgneal@565: }) bgneal@565: bgneal@565: self.assertEqual(response.status_code, 200) bgneal@565: self.assertContains(response, 'A user with that email address already exists') bgneal@565: bgneal@565: def test_duplicate_pending_email(self): bgneal@565: """ bgneal@565: Ensure we can't register with a duplicate email address. bgneal@565: bgneal@565: """ bgneal@565: response = self.client.post(reverse('accounts-register'), { bgneal@565: 'username': 'a_new_user', bgneal@565: 'email': 'pending_user@example.com', bgneal@565: 'password1': 'my_password', bgneal@565: 'password2': 'my_password', bgneal@565: 'agree_age': 'on', bgneal@565: 'agree_tos': 'on', bgneal@565: 'agree_privacy': 'on', bgneal@565: 'question1': '101', bgneal@565: 'question2': '', bgneal@565: }) bgneal@565: bgneal@565: self.assertEqual(response.status_code, 200) bgneal@565: self.assertContains(response, 'A pending user with that email address already exists') bgneal@565: bgneal@565: def test_illegal_email(self): bgneal@565: """ bgneal@565: Ensure we can't register with a banned email address. bgneal@565: bgneal@565: """ bgneal@565: response = self.client.post(reverse('accounts-register'), { bgneal@565: 'username': 'a_new_user', bgneal@565: 'email': 'illegal@example.com', bgneal@565: 'password1': 'my_password', bgneal@565: 'password2': 'my_password', bgneal@565: 'agree_age': 'on', bgneal@565: 'agree_tos': 'on', bgneal@565: 'agree_privacy': 'on', bgneal@565: 'question1': '101', bgneal@565: 'question2': '', bgneal@565: }) bgneal@565: bgneal@565: self.assertEqual(response.status_code, 200) bgneal@565: self.assertContains(response, 'That email address is not allowed') bgneal@565: bgneal@565: def test_password_match(self): bgneal@565: """ bgneal@565: Ensure the passwords match. bgneal@565: bgneal@565: """ bgneal@565: response = self.client.post(reverse('accounts-register'), { bgneal@565: 'username': 'a_new_user', bgneal@565: 'email': 'test@example.com', bgneal@565: 'password1': 'my_password', bgneal@565: 'password2': 'my_password_doesnt match', bgneal@565: 'agree_age': 'on', bgneal@565: 'agree_tos': 'on', bgneal@565: 'agree_privacy': 'on', bgneal@565: 'question1': '101', bgneal@565: 'question2': '', bgneal@565: }) bgneal@565: bgneal@565: self.assertEqual(response.status_code, 200) bgneal@565: self.assertContains(response, "The two password fields didn't match") bgneal@565: bgneal@565: def test_question1(self): bgneal@565: """ bgneal@565: Ensure our anti-spam question is answered. bgneal@565: bgneal@565: """ bgneal@565: response = self.client.post(reverse('accounts-register'), { bgneal@565: 'username': 'a_new_user', bgneal@565: 'email': 'test@example.com', bgneal@565: 'password1': 'my_password', bgneal@565: 'password2': 'my_password_doesnt match', bgneal@565: 'agree_age': 'on', bgneal@565: 'agree_tos': 'on', bgneal@565: 'agree_privacy': 'on', bgneal@565: 'question1': 'huh', bgneal@565: 'question2': '', bgneal@565: }) bgneal@565: bgneal@565: self.assertEqual(response.status_code, 200) bgneal@565: self.assertContains(response, "Incorrect answer to our anti-spam question") bgneal@565: bgneal@565: def test_question2(self): bgneal@565: """ bgneal@565: Ensure our honeypot question check works. bgneal@565: bgneal@565: """ bgneal@565: response = self.client.post(reverse('accounts-register'), { bgneal@565: 'username': 'a_new_user', bgneal@565: 'email': 'test@example.com', bgneal@565: 'password1': 'my_password', bgneal@565: 'password2': 'my_password_doesnt match', bgneal@565: 'agree_age': 'on', bgneal@565: 'agree_tos': 'on', bgneal@565: 'agree_privacy': 'on', bgneal@565: 'question1': '101', bgneal@565: 'question2': 'non blank', bgneal@565: }) bgneal@565: bgneal@690: self.assertEqual(response.status_code, 200) bgneal@565: bgneal@565: def test_success(self): bgneal@565: """ bgneal@565: Ensure we can successfully register. bgneal@565: bgneal@565: """ bgneal@565: response = self.client.post(reverse('accounts-register'), { bgneal@565: 'username': 'a_new_user', bgneal@565: 'email': 'test@example.com', bgneal@565: 'password1': 'my_password', bgneal@565: 'password2': 'my_password', bgneal@565: 'agree_age': 'on', bgneal@565: 'agree_tos': 'on', bgneal@565: 'agree_privacy': 'on', bgneal@565: 'question1': '101', bgneal@565: 'question2': '', bgneal@565: }) bgneal@565: bgneal@565: self.assertEqual(response.status_code, 302) bgneal@565: bgneal@565: try: bgneal@565: pending = PendingUser.objects.get(username='a_new_user') bgneal@565: except PendingUser.DoesNotExist: bgneal@565: self.fail("PendingUser was not created") bgneal@565: bgneal@565: self.assertEqual(pending.email, 'test@example.com') bgneal@565: self.assertTrue(datetime.datetime.now() - pending.date_joined < bgneal@565: datetime.timedelta(minutes=1)) bgneal@565: self.assertTrue(check_password('my_password', pending.password)) bgneal@659: bgneal@659: bgneal@659: class ForgotUsernameTest(TestCase): bgneal@659: bgneal@659: def setUp(self): bgneal@659: u = User.objects.create_user('existing_user', 'existing_user@example.com', 'pw') bgneal@659: u.save() bgneal@659: bgneal@659: def test_get_query_view(self): bgneal@659: """Test a simple get of the username query view""" bgneal@659: response = self.client.get(reverse('accounts-username_query')) bgneal@659: self.assertEqual(response.status_code, 200) bgneal@659: bgneal@659: def test_get_username_sent_view(self): bgneal@659: """Test a simple get of the username sent view""" bgneal@659: response = self.client.get(reverse('accounts-username_sent')) bgneal@659: self.assertEqual(response.status_code, 200) bgneal@659: bgneal@659: def test_invalid_email(self): bgneal@659: """Test form submittal of unknown email address.""" bgneal@659: response = self.client.post(reverse('accounts-username_query'), { bgneal@659: 'email': 'bad_address@example.com', bgneal@659: }, bgneal@659: follow=True) bgneal@659: bgneal@659: self.assertRedirects(response, reverse('accounts-username_sent')) bgneal@659: bgneal@659: self.assertEqual(len(mail.outbox), 0) bgneal@659: bgneal@659: def test_valid_email(self): bgneal@659: """Test form submittal of valid email address.""" bgneal@659: response = self.client.post(reverse('accounts-username_query'), { bgneal@659: 'email': 'existing_user@example.com', bgneal@659: }, bgneal@659: follow=True) bgneal@659: bgneal@659: self.assertRedirects(response, reverse('accounts-username_sent')) bgneal@659: bgneal@659: self.assertEqual(len(mail.outbox), 1) bgneal@659: if len(mail.outbox): bgneal@659: self.assertTrue(mail.outbox[0].subject.startswith('Forgotten username')) bgneal@762: bgneal@762: bgneal@762: class ForgotEmailTest(TestCase): bgneal@762: """Because we use a custom URL its important to test this. This got broken bgneal@762: in Django 1.6 when the URL pattern changed. bgneal@762: bgneal@762: """ bgneal@762: bgneal@762: def setUp(self): bgneal@762: u = User.objects.create_user('user1', 'user1@example.com', 'pw') bgneal@762: u.save() bgneal@762: bgneal@762: def test_nominal_case(self): bgneal@762: """Test a full forgot password scenario.""" bgneal@762: bgneal@762: # GET password reset page bgneal@762: response = self.client.get(reverse('accounts-password_reset')) bgneal@762: self.assertEqual(response.status_code, 200) bgneal@762: bgneal@762: # POST email address bgneal@762: args = {'email': 'user1@example.com'} bgneal@762: response = self.client.post(reverse('accounts-password_reset'), args, bgneal@762: follow=True) bgneal@762: self.assertRedirects(response, reverse('accounts-password_reset_sent')) bgneal@762: bgneal@762: # Ensure the email was sent bgneal@762: self.assertEqual(len(mail.outbox), 1) bgneal@762: if (len(mail.outbox)): bgneal@762: msg = mail.outbox[0] bgneal@762: self.assertTrue(msg.subject.startswith('Password reset')) bgneal@762: self.assertTrue(len(msg.to) == 1 and msg.to[0] == 'user1@example.com') bgneal@762: msg_text = msg.message().as_string() bgneal@762: m = re.search(r'http://example.com/accounts/password/reset/confirm/' bgneal@762: r'(?P[0-9A-Za-z_\-]+)/(?P[0-9a-z]+-\w+)/', bgneal@762: msg_text) bgneal@762: self.assertTrue(m is not None) bgneal@762: if m: bgneal@762: uidb64, token = m.group('uidb64'), m.group('token') bgneal@762: bgneal@762: # visit the password reset page bgneal@762: response = self.client.get( bgneal@762: reverse('accounts-password_reset_confirm', bgneal@762: kwargs={'uidb64': uidb64, 'token': token})) bgneal@762: self.assertEqual(response.status_code, 200) bgneal@762: bgneal@762: # POST new password bgneal@762: args = {'new_password1': 'pw2', 'new_password2': 'pw2'} bgneal@762: response = self.client.post( bgneal@762: reverse('accounts-password_reset_confirm', bgneal@762: kwargs={'uidb64': uidb64, 'token': token}), bgneal@762: args, follow=True) bgneal@762: self.assertRedirects(response, bgneal@762: reverse('accounts-password_reset_success')) bgneal@762: self.assertEqual(response.status_code, 200) bgneal@762: bgneal@762: # Check new password bgneal@762: u = User.objects.get(username='user1') bgneal@762: self.assertTrue(check_password('pw2', u.password))