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:
4
thirdpart/registration/tests/__init__.py
Normal file
4
thirdpart/registration/tests/__init__.py
Normal 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 *
|
361
thirdpart/registration/tests/backends.py
Normal file
361
thirdpart/registration/tests/backends.py
Normal 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)
|
119
thirdpart/registration/tests/forms.py
Normal file
119
thirdpart/registration/tests/forms.py
Normal 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())
|
225
thirdpart/registration/tests/models.py
Normal file
225
thirdpart/registration/tests/models.py
Normal 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')
|
82
thirdpart/registration/tests/urls.py
Normal file
82
thirdpart/registration/tests/urls.py
Normal 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')),
|
||||
)
|
246
thirdpart/registration/tests/views.py
Normal file
246
thirdpart/registration/tests/views.py
Normal 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')
|
Reference in New Issue
Block a user