summaryrefslogtreecommitdiffstats
path: root/registration/tests.py
diff options
context:
space:
mode:
Diffstat (limited to 'registration/tests.py')
-rw-r--r--registration/tests.py355
1 files changed, 355 insertions, 0 deletions
diff --git a/registration/tests.py b/registration/tests.py
new file mode 100644
index 0000000..0f26553
--- /dev/null
+++ b/registration/tests.py
@@ -0,0 +1,355 @@
+"""
+Unit tests for django-registration.
+
+These tests assume that you've completed all the prerequisites for
+getting django-registration running in the default setup, to wit:
+
+1. You have ``registration`` in your ``INSTALLED_APPS`` setting.
+
+2. You have created all of the templates mentioned in this
+ application's documentation.
+
+3. You have added the setting ``ACCOUNT_ACTIVATION_DAYS`` to your
+ settings file.
+
+4. You have URL patterns pointing to the registration and activation
+ views, with the names ``registration_register`` and
+ ``registration_activate``, respectively, and a URL pattern named
+ 'registration_complete'.
+
+"""
+
+import datetime
+import sha
+
+from django.conf import settings
+from django.contrib.auth.models import User
+from django.core import mail
+from django.core import management
+from django.core.urlresolvers import reverse
+from django.test import TestCase
+
+from registration import forms
+from registration.models import RegistrationProfile
+from registration import signals
+
+
+class RegistrationTestCase(TestCase):
+ """
+ Base class for the test cases; this sets up two users -- one
+ expired, one not -- which are used to exercise various parts of
+ the application.
+
+ """
+ def setUp(self):
+ self.sample_user = RegistrationProfile.objects.create_inactive_user(username='alice',
+ password='secret',
+ email='alice@example.com')
+ self.expired_user = RegistrationProfile.objects.create_inactive_user(username='bob',
+ password='swordfish',
+ email='bob@example.com')
+ self.expired_user.date_joined -= datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS + 1)
+ self.expired_user.save()
+
+
+class RegistrationModelTests(RegistrationTestCase):
+ """
+ Tests for the model-oriented functionality of django-registration,
+ including ``RegistrationProfile`` and its custom manager.
+
+ """
+ def test_new_user_is_inactive(self):
+ """
+ Test that a newly-created user is inactive.
+
+ """
+ self.failIf(self.sample_user.is_active)
+
+ def test_registration_profile_created(self):
+ """
+ Test that a ``RegistrationProfile`` is created for a new user.
+
+ """
+ self.assertEqual(RegistrationProfile.objects.count(), 2)
+
+ def test_activation_email(self):
+ """
+ Test that user signup sends an activation email.
+
+ """
+ self.assertEqual(len(mail.outbox), 2)
+
+ def test_activation_email_disable(self):
+ """
+ Test that activation email can be disabled.
+
+ """
+ RegistrationProfile.objects.create_inactive_user(username='noemail',
+ password='foo',
+ email='nobody@example.com',
+ send_email=False)
+ self.assertEqual(len(mail.outbox), 2)
+
+ def test_activation(self):
+ """
+ Test that user activation actually activates the user and
+ properly resets the activation key, and fails for an
+ already-active or expired user, or an invalid key.
+
+ """
+ # Activating a valid user returns the user.
+ self.failUnlessEqual(RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user=self.sample_user).activation_key).pk,
+ self.sample_user.pk)
+
+ # The activated user must now be active.
+ self.failUnless(User.objects.get(pk=self.sample_user.pk).is_active)
+
+ # The activation key must now be reset to the "already activated" constant.
+ self.failUnlessEqual(RegistrationProfile.objects.get(user=self.sample_user).activation_key,
+ RegistrationProfile.ACTIVATED)
+
+ # Activating an expired user returns False.
+ self.failIf(RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user=self.expired_user).activation_key))
+
+ # Activating from a key that isn't a SHA1 hash returns False.
+ self.failIf(RegistrationProfile.objects.activate_user('foo'))
+
+ # Activating from a key that doesn't exist returns False.
+ self.failIf(RegistrationProfile.objects.activate_user(sha.new('foo').hexdigest()))
+
+ def test_account_expiration_condition(self):
+ """
+ Test that ``RegistrationProfile.activation_key_expired()``
+ returns ``True`` for expired users and for active users, and
+ ``False`` otherwise.
+
+ """
+ # Unexpired user returns False.
+ self.failIf(RegistrationProfile.objects.get(user=self.sample_user).activation_key_expired())
+
+ # Expired user returns True.
+ self.failUnless(RegistrationProfile.objects.get(user=self.expired_user).activation_key_expired())
+
+ # Activated user returns True.
+ RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user=self.sample_user).activation_key)
+ self.failUnless(RegistrationProfile.objects.get(user=self.sample_user).activation_key_expired())
+
+ def test_expired_user_deletion(self):
+ """
+ Test that
+ ``RegistrationProfile.objects.delete_expired_users()`` deletes
+ only inactive users whose activation window has expired.
+
+ """
+ RegistrationProfile.objects.delete_expired_users()
+ self.assertEqual(RegistrationProfile.objects.count(), 1)
+
+ def test_management_command(self):
+ """
+ Test that ``manage.py cleanupregistration`` functions
+ correctly.
+
+ """
+ management.call_command('cleanupregistration')
+ self.assertEqual(RegistrationProfile.objects.count(), 1)
+
+ def test_signals(self):
+ """
+ Test that the ``user_registered`` and ``user_activated``
+ signals are sent, and that they send the ``User`` as an
+ argument.
+
+ """
+ def receiver(sender, **kwargs):
+ self.assert_('user' in kwargs)
+ self.assertEqual(kwargs['user'].username, u'signal_test')
+ received_signals.append(kwargs.get('signal'))
+
+ received_signals = []
+ expected_signals = [signals.user_registered, signals.user_activated]
+ for signal in expected_signals:
+ signal.connect(receiver)
+
+ RegistrationProfile.objects.create_inactive_user(username='signal_test',
+ password='foo',
+ email='nobody@example.com',
+ send_email=False)
+ RegistrationProfile.objects.activate_user(RegistrationProfile.objects.get(user__username='signal_test').activation_key)
+
+ self.assertEqual(received_signals, expected_signals)
+
+
+class RegistrationFormTests(RegistrationTestCase):
+ """
+ Tests for the forms and custom validation logic included in
+ django-registration.
+
+ """
+ def test_registration_form(self):
+ """
+ Test that ``RegistrationForm`` enforces username constraints
+ and matching passwords.
+
+ """
+ invalid_data_dicts = [
+ # Non-alphanumeric username.
+ {
+ 'data':
+ { 'username': 'foo/bar',
+ 'email': 'foo@example.com',
+ 'password1': 'foo',
+ 'password2': 'foo' },
+ 'error':
+ ('username', [u"Enter a valid value."])
+ },
+ # Already-existing username.
+ {
+ 'data':
+ { 'username': 'alice',
+ 'email': 'alice@example.com',
+ 'password1': 'secret',
+ 'password2': 'secret' },
+ 'error':
+ ('username', [u"This username is already taken. Please choose another."])
+ },
+ # Mismatched passwords.
+ {
+ 'data':
+ { 'username': 'foo',
+ 'email': 'foo@example.com',
+ 'password1': 'foo',
+ 'password2': 'bar' },
+ 'error':
+ ('__all__', [u"You must type the same password each time"])
+ },
+ ]
+
+ for invalid_dict in invalid_data_dicts:
+ form = forms.RegistrationForm(data=invalid_dict['data'])
+ self.failIf(form.is_valid())
+ self.assertEqual(form.errors[invalid_dict['error'][0]], invalid_dict['error'][1])
+
+ form = forms.RegistrationForm(data={ 'username': 'foo',
+ 'email': 'foo@example.com',
+ 'password1': 'foo',
+ 'password2': 'foo' })
+ self.failUnless(form.is_valid())
+
+ def test_registration_form_tos(self):
+ """
+ Test that ``RegistrationFormTermsOfService`` requires
+ agreement to the terms of service.
+
+ """
+ form = forms.RegistrationFormTermsOfService(data={ 'username': 'foo',
+ 'email': 'foo@example.com',
+ 'password1': 'foo',
+ 'password2': 'foo' })
+ self.failIf(form.is_valid())
+ self.assertEqual(form.errors['tos'], [u"You must agree to the terms to register"])
+
+ form = forms.RegistrationFormTermsOfService(data={ 'username': 'foo',
+ 'email': 'foo@example.com',
+ 'password1': 'foo',
+ 'password2': 'foo',
+ 'tos': 'on' })
+ self.failUnless(form.is_valid())
+
+ def test_registration_form_unique_email(self):
+ """
+ Test that ``RegistrationFormUniqueEmail`` validates uniqueness
+ of email addresses.
+
+ """
+ form = forms.RegistrationFormUniqueEmail(data={ 'username': 'foo',
+ 'email': 'alice@example.com',
+ 'password1': 'foo',
+ 'password2': 'foo' })
+ self.failIf(form.is_valid())
+ self.assertEqual(form.errors['email'], [u"This email address is already in use. Please supply a different email address."])
+
+ form = forms.RegistrationFormUniqueEmail(data={ 'username': 'foo',
+ 'email': 'foo@example.com',
+ 'password1': 'foo',
+ 'password2': 'foo' })
+ self.failUnless(form.is_valid())
+
+ def test_registration_form_no_free_email(self):
+ """
+ Test that ``RegistrationFormNoFreeEmail`` disallows
+ registration with free email addresses.
+
+ """
+ base_data = { 'username': 'foo',
+ 'password1': 'foo',
+ 'password2': 'foo' }
+ for domain in ('aim.com', 'aol.com', 'email.com', 'gmail.com',
+ 'googlemail.com', 'hotmail.com', 'hushmail.com',
+ 'msn.com', 'mail.ru', 'mailinator.com', 'live.com'):
+ invalid_data = base_data.copy()
+ invalid_data['email'] = u"foo@%s" % domain
+ form = forms.RegistrationFormNoFreeEmail(data=invalid_data)
+ self.failIf(form.is_valid())
+ self.assertEqual(form.errors['email'], [u"Registration using free email addresses is prohibited. Please supply a different email address."])
+
+ base_data['email'] = 'foo@example.com'
+ form = forms.RegistrationFormNoFreeEmail(data=base_data)
+ self.failUnless(form.is_valid())
+
+
+class RegistrationViewTests(RegistrationTestCase):
+ """
+ Tests for the views included in django-registration.
+
+ """
+ def test_registration_view(self):
+ """
+ Test that the registration view rejects invalid submissions,
+ and creates a new user and redirects after a valid submission.
+
+ """
+ # Invalid data fails.
+ response = self.client.post(reverse('registration_register'),
+ data={ 'username': 'alice', # Will fail on username uniqueness.
+ 'email': 'foo@example.com',
+ 'password1': 'foo',
+ 'password2': 'foo' })
+ self.assertEqual(response.status_code, 200)
+ self.failUnless(response.context['form'])
+ self.failUnless(response.context['form'].errors)
+
+ response = self.client.post(reverse('registration_register'),
+ data={ 'username': 'foo',
+ 'email': 'foo@example.com',
+ 'password1': 'foo',
+ 'password2': 'foo' })
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(response['Location'], 'http://testserver%s' % reverse('registration_complete'))
+ self.assertEqual(RegistrationProfile.objects.count(), 3)
+
+ def test_activation_view(self):
+ """
+ Test that the activation view activates the user from a valid
+ key and fails if the key is invalid or has expired.
+
+ """
+ # Valid user puts the user account into the context.
+ response = self.client.get(reverse('registration_activate',
+ kwargs={ 'activation_key': RegistrationProfile.objects.get(user=self.sample_user).activation_key }))
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.context['account'].pk, self.sample_user.pk)
+
+ # Expired user sets the account to False.
+ response = self.client.get(reverse('registration_activate',
+ kwargs={ 'activation_key': RegistrationProfile.objects.get(user=self.expired_user).activation_key }))
+ self.failIf(response.context['account'])
+
+ # Invalid key gets to the view, but sets account to False.
+ response = self.client.get(reverse('registration_activate',
+ kwargs={ 'activation_key': 'foo' }))
+ self.failIf(response.context['account'])
+
+ # Nonexistent key sets the account to False.
+ response = self.client.get(reverse('registration_activate',
+ kwargs={ 'activation_key': sha.new('foo').hexdigest() }))
+ self.failIf(response.context['account'])