1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-17 07:41:26 +00:00

Add authentication and registration to seahub

This commit is contained in:
plt
2011-04-30 13:18:32 +08:00
parent 8b357aedae
commit e8d2300473
128 changed files with 4893 additions and 6 deletions

View File

@@ -0,0 +1,4 @@
from registration.tests.backends import *
from registration.tests.forms import *
from registration.tests.models import *
from registration.tests.views import *

View File

@@ -0,0 +1,361 @@
import datetime
from django.conf import settings
from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.core import mail
from django.core.exceptions import ImproperlyConfigured
from django.core.handlers.wsgi import WSGIRequest
from django.test import Client
from django.test import TestCase
from registration import forms
from registration import signals
from registration.admin import RegistrationAdmin
from registration.backends import get_backend
from registration.backends.default import DefaultBackend
from registration.models import RegistrationProfile
class _MockRequestClient(Client):
"""
A ``django.test.Client`` subclass which can return mock
``HttpRequest`` objects.
"""
def request(self, **request):
"""
Rather than issuing a request and returning the response, this
simply constructs an ``HttpRequest`` object and returns it.
"""
environ = {
'HTTP_COOKIE': self.cookies,
'PATH_INFO': '/',
'QUERY_STRING': '',
'REMOTE_ADDR': '127.0.0.1',
'REQUEST_METHOD': 'GET',
'SCRIPT_NAME': '',
'SERVER_NAME': 'testserver',
'SERVER_PORT': '80',
'SERVER_PROTOCOL': 'HTTP/1.1',
'wsgi.version': (1,0),
'wsgi.url_scheme': 'http',
'wsgi.errors': self.errors,
'wsgi.multiprocess': True,
'wsgi.multithread': False,
'wsgi.run_once': False,
}
environ.update(self.defaults)
environ.update(request)
return WSGIRequest(environ)
def _mock_request():
"""
Construct and return a mock ``HttpRequest`` object; this is used
in testing backend methods which expect an ``HttpRequest`` but
which are not being called from views.
"""
return _MockRequestClient().request()
class BackendRetrievalTests(TestCase):
"""
Test that utilities for retrieving the active backend work
properly.
"""
def test_get_backend(self):
"""
Verify that ``get_backend()`` returns the correct value when
passed a valid backend.
"""
self.failUnless(isinstance(get_backend('registration.backends.default.DefaultBackend'),
DefaultBackend))
def test_backend_error_invalid(self):
"""
Test that a nonexistent/unimportable backend raises the
correct exception.
"""
self.assertRaises(ImproperlyConfigured, get_backend,
'registration.backends.doesnotexist.NonExistentBackend')
def test_backend_attribute_error(self):
"""
Test that a backend module which exists but does not have a
class of the specified name raises the correct exception.
"""
self.assertRaises(ImproperlyConfigured, get_backend,
'registration.backends.default.NonexistentBackend')
class DefaultRegistrationBackendTests(TestCase):
"""
Test the default registration backend.
Running these tests successfull will require two templates to be
created for the sending of activation emails; details on these
templates and their contexts may be found in the documentation for
the default backend.
"""
def setUp(self):
"""
Create an instance of the default backend for use in testing,
and set ``ACCOUNT_ACTIVATION_DAYS`` if it's not set already.
"""
from registration.backends.default import DefaultBackend
self.backend = DefaultBackend()
self.old_activation = getattr(settings, 'ACCOUNT_ACTIVATION_DAYS', None)
if self.old_activation is None:
settings.ACCOUNT_ACTIVATION_DAYS = 7
def tearDown(self):
"""
Yank out ``ACCOUNT_ACTIVATION_DAYS`` back out if it wasn't
originally set.
"""
if self.old_activation is None:
settings.ACCOUNT_ACTIVATION_DAYS = self.old_activation
def test_registration(self):
"""
Test the registration process: registration creates a new
inactive account and a new profile with activation key,
populates the correct account data and sends an activation
email.
"""
new_user = self.backend.register(_mock_request(),
username='bob',
email='bob@example.com',
password1='secret')
# Details of the returned user must match what went in.
self.assertEqual(new_user.username, 'bob')
self.failUnless(new_user.check_password('secret'))
self.assertEqual(new_user.email, 'bob@example.com')
# New user must not be active.
self.failIf(new_user.is_active)
# A registration profile was created, and an activation email
# was sent.
self.assertEqual(RegistrationProfile.objects.count(), 1)
self.assertEqual(len(mail.outbox), 1)
def test_registration_no_sites(self):
"""
Test that registration still functions properly when
``django.contrib.sites`` is not installed; the fallback will
be a ``RequestSite`` instance.
"""
Site._meta.installed = False
new_user = self.backend.register(_mock_request(),
username='bob',
email='bob@example.com',
password1='secret')
self.assertEqual(new_user.username, 'bob')
self.failUnless(new_user.check_password('secret'))
self.assertEqual(new_user.email, 'bob@example.com')
self.failIf(new_user.is_active)
self.assertEqual(RegistrationProfile.objects.count(), 1)
self.assertEqual(len(mail.outbox), 1)
Site._meta.installed = True
def test_valid_activation(self):
"""
Test the activation process: activating within the permitted
window sets the account's ``is_active`` field to ``True`` and
resets the activation key.
"""
valid_user = self.backend.register(_mock_request(),
username='alice',
email='alice@example.com',
password1='swordfish')
valid_profile = RegistrationProfile.objects.get(user=valid_user)
activated = self.backend.activate(_mock_request(),
valid_profile.activation_key)
self.assertEqual(activated.username, valid_user.username)
self.failUnless(activated.is_active)
# Fetch the profile again to verify its activation key has
# been reset.
valid_profile = RegistrationProfile.objects.get(user=valid_user)
self.assertEqual(valid_profile.activation_key,
RegistrationProfile.ACTIVATED)
def test_invalid_activation(self):
"""
Test the activation process: trying to activate outside the
permitted window fails, and leaves the account inactive.
"""
expired_user = self.backend.register(_mock_request(),
username='bob',
email='bob@example.com',
password1='secret')
expired_user.date_joined = expired_user.date_joined - datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS)
expired_user.save()
expired_profile = RegistrationProfile.objects.get(user=expired_user)
self.failIf(self.backend.activate(_mock_request(),
expired_profile.activation_key))
self.failUnless(expired_profile.activation_key_expired())
def test_allow(self):
"""
Test that the setting ``REGISTRATION_OPEN`` appropriately
controls whether registration is permitted.
"""
old_allowed = getattr(settings, 'REGISTRATION_OPEN', True)
settings.REGISTRATION_OPEN = True
self.failUnless(self.backend.registration_allowed(_mock_request()))
settings.REGISTRATION_OPEN = False
self.failIf(self.backend.registration_allowed(_mock_request()))
settings.REGISTRATION_OPEN = old_allowed
def test_form_class(self):
"""
Test that the default form class returned is
``registration.forms.RegistrationForm``.
"""
self.failUnless(self.backend.get_form_class(_mock_request()) is forms.RegistrationForm)
def test_post_registration_redirect(self):
"""
Test that the default post-registration redirect is the named
pattern ``registration_complete``.
"""
self.assertEqual(self.backend.post_registration_redirect(_mock_request(), User()),
('registration_complete', (), {}))
def test_registration_signal(self):
"""
Test that registering a user sends the ``user_registered``
signal.
"""
def receiver(sender, **kwargs):
self.failUnless('user' in kwargs)
self.assertEqual(kwargs['user'].username, 'bob')
self.failUnless('request' in kwargs)
self.failUnless(isinstance(kwargs['request'], WSGIRequest))
received_signals.append(kwargs.get('signal'))
received_signals = []
signals.user_registered.connect(receiver, sender=self.backend.__class__)
self.backend.register(_mock_request(),
username='bob',
email='bob@example.com',
password1='secret')
self.assertEqual(len(received_signals), 1)
self.assertEqual(received_signals, [signals.user_registered])
def test_activation_signal_success(self):
"""
Test that successfully activating a user sends the
``user_activated`` signal.
"""
def receiver(sender, **kwargs):
self.failUnless('user' in kwargs)
self.assertEqual(kwargs['user'].username, 'bob')
self.failUnless('request' in kwargs)
self.failUnless(isinstance(kwargs['request'], WSGIRequest))
received_signals.append(kwargs.get('signal'))
received_signals = []
signals.user_activated.connect(receiver, sender=self.backend.__class__)
new_user = self.backend.register(_mock_request(),
username='bob',
email='bob@example.com',
password1='secret')
profile = RegistrationProfile.objects.get(user=new_user)
self.backend.activate(_mock_request(), profile.activation_key)
self.assertEqual(len(received_signals), 1)
self.assertEqual(received_signals, [signals.user_activated])
def test_activation_signal_failure(self):
"""
Test that an unsuccessful activation attempt does not send the
``user_activated`` signal.
"""
receiver = lambda sender, **kwargs: received_signals.append(kwargs.get('signal'))
received_signals = []
signals.user_activated.connect(receiver, sender=self.backend.__class__)
new_user = self.backend.register(_mock_request(),
username='bob',
email='bob@example.com',
password1='secret')
new_user.date_joined -= datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS + 1)
new_user.save()
profile = RegistrationProfile.objects.get(user=new_user)
self.backend.activate(_mock_request(), profile.activation_key)
self.assertEqual(len(received_signals), 0)
def test_email_send_action(self):
"""
Test re-sending of activation emails via admin action.
"""
admin_class = RegistrationAdmin(RegistrationProfile, admin.site)
alice = self.backend.register(_mock_request(),
username='alice',
email='alice@example.com',
password1='swordfish')
admin_class.resend_activation_email(_mock_request(),
RegistrationProfile.objects.all())
self.assertEqual(len(mail.outbox), 2) # One on registering, one more on the resend.
RegistrationProfile.objects.filter(user=alice).update(activation_key=RegistrationProfile.ACTIVATED)
admin_class.resend_activation_email(_mock_request(),
RegistrationProfile.objects.all())
self.assertEqual(len(mail.outbox), 2) # No additional email because the account has activated.
def test_activation_action(self):
"""
Test manual activation of users view admin action.
"""
admin_class = RegistrationAdmin(RegistrationProfile, admin.site)
alice = self.backend.register(_mock_request(),
username='alice',
email='alice@example.com',
password1='swordfish')
admin_class.activate_users(_mock_request(),
RegistrationProfile.objects.all())
self.failUnless(User.objects.get(username='alice').is_active)

View File

@@ -0,0 +1,119 @@
from django.contrib.auth.models import User
from django.test import TestCase
from registration import forms
class RegistrationFormTests(TestCase):
"""
Test the default registration forms.
"""
def test_registration_form(self):
"""
Test that ``RegistrationForm`` enforces username constraints
and matching passwords.
"""
# Create a user so we can verify that duplicate usernames aren't
# permitted.
User.objects.create_user('alice', 'alice@example.com', 'secret')
invalid_data_dicts = [
# Non-alphanumeric username.
{'data': {'username': 'foo/bar',
'email': 'foo@example.com',
'password1': 'foo',
'password2': 'foo'},
'error': ('username', [u"This value must contain only letters, numbers and underscores."])},
# Already-existing username.
{'data': {'username': 'alice',
'email': 'alice@example.com',
'password1': 'secret',
'password2': 'secret'},
'error': ('username', [u"A user with that username already exists."])},
# Mismatched passwords.
{'data': {'username': 'foo',
'email': 'foo@example.com',
'password1': 'foo',
'password2': 'bar'},
'error': ('__all__', [u"The two password fields didn't match."])},
]
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.
"""
# Create a user so we can verify that duplicate addresses
# aren't permitted.
User.objects.create_user('alice', 'alice@example.com', 'secret')
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 forms.RegistrationFormNoFreeEmail.bad_domains:
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())

View File

@@ -0,0 +1,225 @@
import datetime
import re
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.core import mail
from django.core import management
from django.test import TestCase
from django.utils.hashcompat import sha_constructor
from registration.models import RegistrationProfile
class RegistrationModelTests(TestCase):
"""
Test the model and manager used in the default backend.
"""
user_info = {'username': 'alice',
'password': 'swordfish',
'email': 'alice@example.com'}
def setUp(self):
self.old_activation = getattr(settings, 'ACCOUNT_ACTIVATION_DAYS', None)
settings.ACCOUNT_ACTIVATION_DAYS = 7
def tearDown(self):
settings.ACCOUNT_ACTIVATION_DAYS = self.old_activation
def test_profile_creation(self):
"""
Creating a registration profile for a user populates the
profile with the correct user and a SHA1 hash to use as
activation key.
"""
new_user = User.objects.create_user(**self.user_info)
profile = RegistrationProfile.objects.create_profile(new_user)
self.assertEqual(RegistrationProfile.objects.count(), 1)
self.assertEqual(profile.user.id, new_user.id)
self.failUnless(re.match('^[a-f0-9]{40}$', profile.activation_key))
self.assertEqual(unicode(profile),
"Registration information for alice")
def test_activation_email(self):
"""
``RegistrationProfile.send_activation_email`` sends an
email.
"""
new_user = User.objects.create_user(**self.user_info)
profile = RegistrationProfile.objects.create_profile(new_user)
profile.send_activation_email(Site.objects.get_current())
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].to, [self.user_info['email']])
def test_user_creation(self):
"""
Creating a new user populates the correct data, and sets the
user's account inactive.
"""
new_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
**self.user_info)
self.assertEqual(new_user.username, 'alice')
self.assertEqual(new_user.email, 'alice@example.com')
self.failUnless(new_user.check_password('swordfish'))
self.failIf(new_user.is_active)
def test_user_creation_email(self):
"""
By default, creating a new user sends an activation email.
"""
new_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
**self.user_info)
self.assertEqual(len(mail.outbox), 1)
def test_user_creation_no_email(self):
"""
Passing ``send_email=False`` when creating a new user will not
send an activation email.
"""
new_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
send_email=False,
**self.user_info)
self.assertEqual(len(mail.outbox), 0)
def test_unexpired_account(self):
"""
``RegistrationProfile.activation_key_expired()`` is ``False``
within the activation window.
"""
new_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
**self.user_info)
profile = RegistrationProfile.objects.get(user=new_user)
self.failIf(profile.activation_key_expired())
def test_expired_account(self):
"""
``RegistrationProfile.activation_key_expired()`` is ``True``
outside the activation window.
"""
new_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
**self.user_info)
new_user.date_joined -= datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS + 1)
new_user.save()
profile = RegistrationProfile.objects.get(user=new_user)
self.failUnless(profile.activation_key_expired())
def test_valid_activation(self):
"""
Activating a user within the permitted window makes the
account active, and resets the activation key.
"""
new_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
**self.user_info)
profile = RegistrationProfile.objects.get(user=new_user)
activated = RegistrationProfile.objects.activate_user(profile.activation_key)
self.failUnless(isinstance(activated, User))
self.assertEqual(activated.id, new_user.id)
self.failUnless(activated.is_active)
profile = RegistrationProfile.objects.get(user=new_user)
self.assertEqual(profile.activation_key, RegistrationProfile.ACTIVATED)
def test_expired_activation(self):
"""
Attempting to activate outside the permitted window does not
activate the account.
"""
new_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
**self.user_info)
new_user.date_joined -= datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS + 1)
new_user.save()
profile = RegistrationProfile.objects.get(user=new_user)
activated = RegistrationProfile.objects.activate_user(profile.activation_key)
self.failIf(isinstance(activated, User))
self.failIf(activated)
new_user = User.objects.get(username='alice')
self.failIf(new_user.is_active)
profile = RegistrationProfile.objects.get(user=new_user)
self.assertNotEqual(profile.activation_key, RegistrationProfile.ACTIVATED)
def test_activation_invalid_key(self):
"""
Attempting to activate with a key which is not a SHA1 hash
fails.
"""
self.failIf(RegistrationProfile.objects.activate_user('foo'))
def test_activation_already_activated(self):
"""
Attempting to re-activate an already-activated account fails.
"""
new_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
**self.user_info)
profile = RegistrationProfile.objects.get(user=new_user)
RegistrationProfile.objects.activate_user(profile.activation_key)
profile = RegistrationProfile.objects.get(user=new_user)
self.failIf(RegistrationProfile.objects.activate_user(profile.activation_key))
def test_activation_nonexistent_key(self):
"""
Attempting to activate with a non-existent key (i.e., one not
associated with any account) fails.
"""
# Due to the way activation keys are constructed during
# registration, this will never be a valid key.
invalid_key = sha_constructor('foo').hexdigest()
self.failIf(RegistrationProfile.objects.activate_user(invalid_key))
def test_expired_user_deletion(self):
"""
``RegistrationProfile.objects.delete_expired_users()`` only
deletes inactive users whose activation window has expired.
"""
new_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
**self.user_info)
expired_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
username='bob',
password='secret',
email='bob@example.com')
expired_user.date_joined -= datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS + 1)
expired_user.save()
RegistrationProfile.objects.delete_expired_users()
self.assertEqual(RegistrationProfile.objects.count(), 1)
self.assertRaises(User.DoesNotExist, User.objects.get, username='bob')
def test_management_command(self):
"""
The ``cleanupregistration`` management command properly
deletes expired accounts.
"""
new_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
**self.user_info)
expired_user = RegistrationProfile.objects.create_inactive_user(site=Site.objects.get_current(),
username='bob',
password='secret',
email='bob@example.com')
expired_user.date_joined -= datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS + 1)
expired_user.save()
management.call_command('cleanupregistration')
self.assertEqual(RegistrationProfile.objects.count(), 1)
self.assertRaises(User.DoesNotExist, User.objects.get, username='bob')

View File

@@ -0,0 +1,82 @@
"""
URLs used in the unit tests for django-registration.
You should not attempt to use these URLs in any sort of real or
development environment; instead, use
``registration/backends/default/urls.py``. This URLconf includes those
URLs, and also adds several additional URLs which serve no purpose
other than to test that optional keyword arguments are properly
handled.
"""
from django.conf.urls.defaults import *
from django.views.generic.simple import direct_to_template
from registration.views import activate
from registration.views import register
urlpatterns = patterns('',
# Test the 'activate' view with custom template
# name.
url(r'^activate-with-template-name/(?P<activation_key>\w+)/$',
activate,
{'template_name': 'registration/test_template_name.html',
'backend': 'registration.backends.default.DefaultBackend'},
name='registration_test_activate_template_name'),
# Test the 'activate' view with
# extra_context_argument.
url(r'^activate-extra-context/(?P<activation_key>\w+)/$',
activate,
{'extra_context': {'foo': 'bar', 'callable': lambda: 'called'},
'backend': 'registration.backends.default.DefaultBackend'},
name='registration_test_activate_extra_context'),
# Test the 'activate' view with success_url argument.
url(r'^activate-with-success-url/(?P<activation_key>\w+)/$',
activate,
{'success_url': 'registration_test_custom_success_url',
'backend': 'registration.backends.default.DefaultBackend'},
name='registration_test_activate_success_url'),
# Test the 'register' view with custom template
# name.
url(r'^register-with-template-name/$',
register,
{'template_name': 'registration/test_template_name.html',
'backend': 'registration.backends.default.DefaultBackend'},
name='registration_test_register_template_name'),
# Test the'register' view with extra_context
# argument.
url(r'^register-extra-context/$',
register,
{'extra_context': {'foo': 'bar', 'callable': lambda: 'called'},
'backend': 'registration.backends.default.DefaultBackend'},
name='registration_test_register_extra_context'),
# Test the 'register' view with custom URL for
# closed registration.
url(r'^register-with-disallowed-url/$',
register,
{'disallowed_url': 'registration_test_custom_disallowed',
'backend': 'registration.backends.default.DefaultBackend'},
name='registration_test_register_disallowed_url'),
# Set up a pattern which will correspond to the
# custom 'disallowed_url' above.
url(r'^custom-disallowed/$',
direct_to_template,
{'template': 'registration/registration_closed.html'},
name='registration_test_custom_disallowed'),
# Test the 'register' view with custom redirect
# on successful registration.
url(r'^register-with-success_url/$',
register,
{'success_url': 'registration_test_custom_success_url',
'backend': 'registration.backends.default.DefaultBackend'},
name='registration_test_register_success_url'
),
# Pattern for custom redirect set above.
url(r'^custom-success/$',
direct_to_template,
{'template': 'registration/test_template_name.html'},
name='registration_test_custom_success_url'),
(r'', include('registration.backends.default.urls')),
)

View File

@@ -0,0 +1,246 @@
import datetime
from django.conf import settings
from django.contrib.auth.models import User
from django.core import mail
from django.core.urlresolvers import reverse
from django.test import TestCase
from registration import forms
from registration.models import RegistrationProfile
class RegistrationViewTests(TestCase):
"""
Test the registration views.
"""
urls = 'registration.tests.urls'
def setUp(self):
"""
These tests use the default backend, since we know it's
available; that needs to have ``ACCOUNT_ACTIVATION_DAYS`` set.
"""
self.old_activation = getattr(settings, 'ACCOUNT_ACTIVATION_DAYS', None)
if self.old_activation is None:
settings.ACCOUNT_ACTIVATION_DAYS = 7
def tearDown(self):
"""
Yank ``ACCOUNT_ACTIVATION_DAYS`` back out if it wasn't
originally set.
"""
if self.old_activation is None:
settings.ACCOUNT_ACTIVATION_DAYS = self.old_activation
def test_registration_view_initial(self):
"""
A ``GET`` to the ``register`` view uses the appropriate
template and populates the registration form into the context.
"""
response = self.client.get(reverse('registration_register'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response,
'registration/registration_form.html')
self.failUnless(isinstance(response.context['form'],
forms.RegistrationForm))
def test_registration_view_success(self):
"""
A ``POST`` to the ``register`` view with valid data properly
creates a new user and issues a redirect.
"""
response = self.client.post(reverse('registration_register'),
data={'username': 'alice',
'email': 'alice@example.com',
'password1': 'swordfish',
'password2': 'swordfish'})
self.assertRedirects(response,
'http://testserver%s' % reverse('registration_complete'))
self.assertEqual(RegistrationProfile.objects.count(), 1)
self.assertEqual(len(mail.outbox), 1)
def test_registration_view_failure(self):
"""
A ``POST`` to the ``register`` view with invalid data does not
create a user, and displays appropriate error messages.
"""
response = self.client.post(reverse('registration_register'),
data={'username': 'bob',
'email': 'bobe@example.com',
'password1': 'foo',
'password2': 'bar'})
self.assertEqual(response.status_code, 200)
self.failIf(response.context['form'].is_valid())
self.assertFormError(response, 'form', field=None,
errors=u"The two password fields didn't match.")
self.assertEqual(len(mail.outbox), 0)
def test_registration_view_closed(self):
"""
Any attempt to access the ``register`` view when registration
is closed fails and redirects.
"""
old_allowed = getattr(settings, 'REGISTRATION_OPEN', True)
settings.REGISTRATION_OPEN = False
closed_redirect = 'http://testserver%s' % reverse('registration_disallowed')
response = self.client.get(reverse('registration_register'))
self.assertRedirects(response, closed_redirect)
# Even if valid data is posted, it still shouldn't work.
response = self.client.post(reverse('registration_register'),
data={'username': 'alice',
'email': 'alice@example.com',
'password1': 'swordfish',
'password2': 'swordfish'})
self.assertRedirects(response, closed_redirect)
self.assertEqual(RegistrationProfile.objects.count(), 0)
settings.REGISTRATION_OPEN = old_allowed
def test_registration_template_name(self):
"""
Passing ``template_name`` to the ``register`` view will result
in that template being used.
"""
response = self.client.get(reverse('registration_test_register_template_name'))
self.assertTemplateUsed(response,
'registration/test_template_name.html')
def test_registration_extra_context(self):
"""
Passing ``extra_context`` to the ``register`` view will
correctly populate the context.
"""
response = self.client.get(reverse('registration_test_register_extra_context'))
self.assertEqual(response.context['foo'], 'bar')
# Callables in extra_context are called to obtain the value.
self.assertEqual(response.context['callable'], 'called')
def test_registration_disallowed_url(self):
"""
Passing ``disallowed_url`` to the ``register`` view will
result in a redirect to that URL when registration is closed.
"""
old_allowed = getattr(settings, 'REGISTRATION_OPEN', True)
settings.REGISTRATION_OPEN = False
closed_redirect = 'http://testserver%s' % reverse('registration_test_custom_disallowed')
response = self.client.get(reverse('registration_test_register_disallowed_url'))
self.assertRedirects(response, closed_redirect)
settings.REGISTRATION_OPEN = old_allowed
def test_registration_success_url(self):
"""
Passing ``success_url`` to the ``register`` view will result
in a redirect to that URL when registration is successful.
"""
success_redirect = 'http://testserver%s' % reverse('registration_test_custom_success_url')
response = self.client.post(reverse('registration_test_register_success_url'),
data={'username': 'alice',
'email': 'alice@example.com',
'password1': 'swordfish',
'password2': 'swordfish'})
self.assertRedirects(response, success_redirect)
def test_valid_activation(self):
"""
Test that the ``activate`` view properly handles a valid
activation (in this case, based on the default backend's
activation window).
"""
success_redirect = 'http://testserver%s' % reverse('registration_activation_complete')
# First, register an account.
self.client.post(reverse('registration_register'),
data={'username': 'alice',
'email': 'alice@example.com',
'password1': 'swordfish',
'password2': 'swordfish'})
profile = RegistrationProfile.objects.get(user__username='alice')
response = self.client.get(reverse('registration_activate',
kwargs={'activation_key': profile.activation_key}))
self.assertRedirects(response, success_redirect)
self.failUnless(User.objects.get(username='alice').is_active)
def test_invalid_activation(self):
"""
Test that the ``activate`` view properly handles an invalid
activation (in this case, based on the default backend's
activation window).
"""
# Register an account and reset its date_joined to be outside
# the activation window.
self.client.post(reverse('registration_register'),
data={'username': 'bob',
'email': 'bob@example.com',
'password1': 'secret',
'password2': 'secret'})
expired_user = User.objects.get(username='bob')
expired_user.date_joined = expired_user.date_joined - datetime.timedelta(days=settings.ACCOUNT_ACTIVATION_DAYS)
expired_user.save()
expired_profile = RegistrationProfile.objects.get(user=expired_user)
response = self.client.get(reverse('registration_activate',
kwargs={'activation_key': expired_profile.activation_key}))
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['activation_key'],
expired_profile.activation_key)
self.failIf(User.objects.get(username='bob').is_active)
def test_activation_success_url(self):
"""
Passing ``success_url`` to the ``activate`` view and
successfully activating will result in that URL being used for
the redirect.
"""
success_redirect = 'http://testserver%s' % reverse('registration_test_custom_success_url')
self.client.post(reverse('registration_register'),
data={'username': 'alice',
'email': 'alice@example.com',
'password1': 'swordfish',
'password2': 'swordfish'})
profile = RegistrationProfile.objects.get(user__username='alice')
response = self.client.get(reverse('registration_test_activate_success_url',
kwargs={'activation_key': profile.activation_key}))
self.assertRedirects(response, success_redirect)
def test_activation_template_name(self):
"""
Passing ``template_name`` to the ``activate`` view will result
in that template being used.
"""
response = self.client.get(reverse('registration_test_activate_template_name',
kwargs={'activation_key': 'foo'}))
self.assertTemplateUsed(response, 'registration/test_template_name.html')
def test_activation_extra_context(self):
"""
Passing ``extra_context`` to the ``activate`` view will
correctly populate the context.
"""
response = self.client.get(reverse('registration_test_activate_extra_context',
kwargs={'activation_key': 'foo'}))
self.assertEqual(response.context['foo'], 'bar')
# Callables in extra_context are called to obtain the value.
self.assertEqual(response.context['callable'], 'called')