Commits

Chris Beaven  committed d6091d3

Move the tests into the app, and add tests for AuthForm

  • Participants
  • Parent commits 11f714b

Comments (0)

Files changed (18)

File lockdown/forms.py

 
     def clean(self):
         cleaned_data = super(AuthForm, self).clean()
-        if self.staff_only and not self.get_user().is_staff:
+        user = self.get_user()
+        if self.staff_only and (not user or not user.is_staff):
             raise forms.ValidationError('Sorry, only staff are allowed.')
-        if self.superusers_only and not self.get_user().is_superuser:
+        if self.superusers_only and (not user or not user.is_superuser):
             raise forms.ValidationError('Sorry, only superusers are allowed.')
         return cleaned_data
 

File lockdown/models.py

Empty file added.

File lockdown/tests/__init__.py

+from lockdown.tests.tests import DecoratorTests, MiddlewareTests, AuthFormTests

File lockdown/tests/forms.py

+from django import forms
+
+class CustomLockdownForm(forms.Form):
+    answer = forms.IntegerField()
+
+    def clean_answer(self):
+        if self.cleaned_data['answer'] == 42:
+            return 42
+        raise forms.ValidationError('Wrong answer.')

File lockdown/tests/templates/lockdown/form.html

+<html>
+<head>
+<title>Coming soon...</title>
+</head>
+
+<body>
+  <h2>Coming soon...</h2>
+
+  <p>This is not yet available to the public.</p>
+
+  {% if form %}
+
+  <form action="" method="post">
+    {{ form.as_p }}
+    <p><input type="submit" value="Preview"></p>
+  </form>
+
+  {% endif %}
+
+</div>
+</body>

File lockdown/tests/tests.py

+import os
+
+from django.conf import settings as django_settings, global_settings
+from django.test import TestCase
+
+from lockdown import settings, middleware
+from lockdown.forms import AuthForm
+
+
+class LockdownTestCase(TestCase):
+    urls = 'lockdown.tests.urls'
+
+    def setUp(self):
+        self._old_middleware_classes = django_settings.MIDDLEWARE_CLASSES
+        django_settings.MIDDLEWARE_CLASSES = \
+                                        global_settings.MIDDLEWARE_CLASSES
+
+        self._old_template_dirs = django_settings.TEMPLATE_DIRS
+        django_settings.TEMPLATE_DIRS = [os.path.join(
+                os.path.dirname(os.path.realpath(__file__)), 'templates')]
+
+        self._old_pw = settings.PASSWORDS
+        settings.PASSWORDS = ('letmein',)
+
+        self._old_form = settings.FORM
+        settings.FORM = 'lockdown.forms.LockdownForm'
+        middleware._default_form = middleware.get_lockdown_form(settings.FORM)
+
+    def tearDown(self):
+        django_settings.MIDDLEWARE_CLASSES = self._old_middleware_classes
+        django_settings.TEMPLATE_DIRS = self._old_template_dirs
+        settings.PASSWORDS = self._old_pw
+        settings.FORM = self._old_form
+        middleware._default_form = middleware.get_lockdown_form(settings.FORM)
+
+
+class BaseTests(LockdownTestCase):
+    """
+    Base tests for lockdown functionality (whether via a decorator or
+    middleware).
+    
+    Subclasses should provide ``locked_url`` and ``locked_contents``
+    attributes. 
+    
+    """
+
+    def test_lockdown_template_used(self):
+        response = self.client.get(self.locked_url)
+        self.assertTemplateUsed(response, 'lockdown/form.html')
+
+    def test_form_in_context(self):
+        response = self.client.get(self.locked_url)
+        form = response.context['form']
+        self.failUnless('password' in form.fields)
+
+    def test_url_exceptions(self):
+        _old_url_exceptions = settings.URL_EXCEPTIONS
+        settings.URL_EXCEPTIONS = (r'/view/$',)
+        middleware._default_url_exceptions = \
+                middleware.compile_url_exceptions(settings.URL_EXCEPTIONS)
+
+        try:
+            response = self.client.get(self.locked_url)
+            self.assertContains(response, self.locked_contents)
+        finally:
+            settings.URL_EXCEPTIONS = _old_url_exceptions
+            middleware._default_url_exceptions = \
+                    middleware.compile_url_exceptions(settings.URL_EXCEPTIONS)
+
+    def test_submit_password(self):
+        response = self.client.post(self.locked_url, {'password': 'letmein'},
+                                    follow=True)
+        self.assertContains(response, self.locked_contents)
+
+    def test_submit_wrong_password(self):
+        response = self.client.post(self.locked_url, {'password': 'imacrook'})
+        self.assertContains(response, 'Incorrect password.')
+
+    def test_custom_form(self):
+        _old_form = settings.FORM
+        settings.FORM = 'lockdown.tests.forms.CustomLockdownForm'
+        middleware._default_form = middleware.get_lockdown_form(settings.FORM)
+
+        try:
+            response = self.client.post(self.locked_url, {'answer': '42'},
+                                        follow=True)
+            self.assertContains(response, self.locked_contents)
+        finally:
+            settings.FORM = _old_form
+            middleware._default_form = middleware.get_lockdown_form(
+                                                                settings.FORM)
+
+
+class DecoratorTests(BaseTests):
+    locked_url = '/locked/view/'
+    locked_contents = 'A locked view.'
+
+    def test_overridden_settings(self):
+        url = '/overridden/locked/view/'
+
+        response = self.client.post(url, {'password': 'letmein'}, follow=True)
+        self.assertTemplateUsed(response, 'lockdown/form.html')
+
+        response = self.client.post(url, {'password': 'squirrel'}, follow=True)
+        self.assertTemplateNotUsed(response, 'lockdown/form.html')
+
+
+class MiddlewareTests(BaseTests):
+    locked_url = '/a/view/'
+    locked_contents = 'A view.'
+
+    def setUp(self):
+        super(MiddlewareTests, self).setUp()
+        # Don't need to worry about fixing MIDDLEWARE_CLASSES on tearDown, it's
+        # done by the base class.
+        self._old_middleware_classes = django_settings.MIDDLEWARE_CLASSES
+        django_settings.MIDDLEWARE_CLASSES += (
+            'lockdown.middleware.LockdownMiddleware',
+        )
+
+
+class AuthFormTests(LockdownTestCase):
+    def test_using_form(self):
+        url = '/auth/user/locked/view/'
+        response = self.client.get(url)
+
+        self.assertTemplateUsed(response, 'lockdown/form.html')
+
+        form = response.context.get('form')
+        self.assert_(isinstance(form, AuthForm))
+
+    def add_user(self, username='test', password='pw', **kwargs):
+        from django.contrib.auth.models import User
+        user = User(username=username, **kwargs)
+        user.set_password(password)
+        user.save()
+
+    def test_user(self):
+        # Skip this test if auth isn't an installed app.
+        if 'django.contrib.auth' not in django_settings.INSTALLED_APPS:
+            return
+        
+        url = '/auth/user/locked/view/'
+        self.add_user()
+
+        # Incorrect password.
+        post_data = {'username': 'test', 'password': 'bad'}
+        response = self.client.post(url, post_data, follow=True)
+        self.assertTemplateUsed(response, 'lockdown/form.html')
+
+        # Correct password.
+        post_data = {'username': 'test', 'password': 'pw'}
+        response = self.client.post(url, post_data, follow=True)
+        self.assertTemplateNotUsed(response, 'lockdown/form.html')
+
+    def test_staff(self):
+        # Skip this test if auth isn't an installed app.
+        if 'django.contrib.auth' not in django_settings.INSTALLED_APPS:
+            return
+        
+        url = '/auth/staff/locked/view/'
+        self.add_user(username='user')
+        self.add_user(username='staff', is_staff=True)
+
+        # Non-staff member.
+        post_data = {'username': 'user', 'password': 'pw'}
+        response = self.client.post(url, post_data, follow=True)
+        self.assertTemplateUsed(response, 'lockdown/form.html')
+
+        # Incorrect password.
+        post_data = {'username': 'staff', 'password': 'bad'}
+        response = self.client.post(url, post_data, follow=True)
+        self.assertTemplateUsed(response, 'lockdown/form.html')
+
+        # Correct password.
+        post_data = {'username': 'staff', 'password': 'pw'}
+        response = self.client.post(url, post_data, follow=True)
+        self.assertTemplateNotUsed(response, 'lockdown/form.html')
+
+    def test_superuser(self):
+        # Skip this test if auth isn't an installed app.
+        if 'django.contrib.auth' not in django_settings.INSTALLED_APPS:
+            return
+        
+        url = '/auth/superuser/locked/view/'
+        self.add_user(username='staff', is_staff=True)
+        self.add_user(username='superuser', is_staff=True, is_superuser=True)
+
+        # Non-superuser.
+        post_data = {'username': 'staff', 'password': 'pw'}
+        response = self.client.post(url, post_data, follow=True)
+        self.assertTemplateUsed(response, 'lockdown/form.html')
+
+        # Incorrect password.
+        post_data = {'username': 'superuser', 'password': 'bad'}
+        response = self.client.post(url, post_data, follow=True)
+        self.assertTemplateUsed(response, 'lockdown/form.html')
+
+        # Correct password.
+        post_data = {'username': 'superuser', 'password': 'pw'}
+        response = self.client.post(url, post_data, follow=True)
+        self.assertTemplateNotUsed(response, 'lockdown/form.html')

File lockdown/tests/urls.py

+from django.conf.urls.defaults import *
+
+urlpatterns = patterns('lockdown.tests.views',
+    (r'^a/view/$', 'a_view'),
+    (r'^locked/view/$', 'locked_view'),
+    (r'^overridden/locked/view/$', 'overridden_locked_view'),
+    (r'^auth/user/locked/view/$', 'user_locked_view'),
+    (r'^auth/staff/locked/view/$', 'staff_locked_view'),
+    (r'^auth/superuser/locked/view/$', 'superuser_locked_view'),
+)

File lockdown/tests/views.py

+from django.http import HttpResponse
+
+from lockdown.decorators import lockdown
+from lockdown.forms import AuthForm
+
+
+def a_view(request):
+    return HttpResponse('A view.')
+
+
+@lockdown()
+def locked_view(request):
+    return HttpResponse('A locked view.')
+
+
+@lockdown(passwords=('squirrel',))
+def overridden_locked_view(request):
+    return HttpResponse('A locked view.')
+
+
+@lockdown(form=AuthForm, staff_only=False)
+def user_locked_view(request):
+    return HttpResponse('A locked view.')
+
+
+@lockdown(form=AuthForm)
+def staff_locked_view(request):
+    return HttpResponse('A locked view.')
+
+
+@lockdown(form=AuthForm, superusers_only=True)
+def superuser_locked_view(request):
+    return HttpResponse('A locked view.')
+#!/usr/bin/env python
+
+import os, sys
+
+from django.conf import settings
+
+
+def runtests(*test_args):
+    if not test_args:
+        test_args = ['lockdown']
+    parent = os.path.dirname(os.path.abspath(__file__))
+    sys.path.insert(0, parent)
+    settings.configure(
+        DATABASE_ENGINE='sqlite3',
+        INSTALLED_APPS = ('django.contrib.sessions', 'lockdown'),
+        ROOT_URLCONF='lockdown.tests.urls',
+    )
+    from django.test.utils import get_runner
+    test_runner = get_runner(settings)
+    failures = test_runner(test_args, verbosity=1, interactive=True)
+    sys.exit(failures)
+
+
+if __name__ == '__main__':
+    runtests(*sys.argv[1:])
         'Framework :: Django',
     ],
     zip_safe=False,
-    test_suite='tests.runtests.runtests',
+    test_suite='runtests.runtests',
     package_data={'lockdown': ['templates/lockdown/*.html']}
 )

File tests/__init__.py

Empty file removed.

File tests/forms.py

-from django import forms
-
-class CustomLockdownForm(forms.Form):
-    answer = forms.IntegerField()
-
-    def clean_answer(self):
-        if self.cleaned_data['answer'] == 42:
-            return 42
-        raise forms.ValidationError('Wrong answer.')

File tests/models.py

Empty file removed.

File tests/runtests.py

-#!/usr/bin/env python
-
-import os, sys
-
-parent = os.path.dirname(os.path.dirname(
-            os.path.abspath(__file__)))
-sys.path.insert(0, parent)
-
-os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.test_settings'
-
-from django.test.utils import get_runner
-from django.conf import settings
-
-def runtests():
-    test_runner = get_runner(settings)
-    failures = test_runner(['tests'], verbosity=1, interactive=True)
-    sys.exit(failures)
-
-if __name__ == '__main__':
-    runtests()

File tests/test_settings.py

-INSTALLED_APPS = ('django.contrib.sessions', 'lockdown', 'tests')
-DATABASE_ENGINE = 'sqlite3'
-
-ROOT_URLCONF = 'tests.urls'

File tests/tests.py

-from django.test import TestCase, Client
-from django.conf import settings as django_settings
-
-from lockdown import settings, middleware
-
-
-class DecoratorTests(TestCase):
-    _url = '/locked/view/'
-    _contents = 'A locked view.'
-
-    def setUp(self):
-        self._old_pw = settings.PASSWORDS
-        settings.PASSWORDS = ('letmein',)
-        self._old_form = settings.FORM
-        settings.FORM = 'lockdown.forms.LockdownForm'
-        middleware._default_form = middleware.get_lockdown_form(settings.FORM)
-        self.client = Client()
-
-    def tearDown(self):
-        settings.PASSWORDS = self._old_pw
-        settings.FORM = self._old_form
-        middleware._default_form = middleware.get_lockdown_form(settings.FORM)
-
-    def test_lockdown_template_used(self):
-        response = self.client.get(self._url)
-        template_name = ''
-        if response.template:
-            try:
-                template_name = response.template.name
-            except AttributeError:
-                template_name = response.template[0].name
-        self.assertEquals(template_name, 'lockdown/form.html')
-
-    def test_form_in_context(self):
-        response = self.client.get(self._url)
-        form = response.context['form']
-        self.failUnless('password' in form.fields)
-
-    def test_url_exceptions(self):
-        _old_url_exceptions = settings.URL_EXCEPTIONS
-        settings.URL_EXCEPTIONS = (r'/view/$',)
-        middleware._default_url_exceptions = \
-                middleware.compile_url_exceptions(settings.URL_EXCEPTIONS)
-
-        try:
-            response = self.client.get(self._url)
-            self.assertContains(response, self._contents)
-        finally:
-            settings.URL_EXCEPTIONS = _old_url_exceptions
-            middleware._default_url_exceptions = \
-                    middleware.compile_url_exceptions(settings.URL_EXCEPTIONS)
-
-    def test_submit_password(self):
-        response = self.client.post(self._url, {'password': 'letmein'},
-                                    follow=True)
-        self.assertContains(response, self._contents)
-
-    def test_submit_wrong_password(self):
-        response = self.client.post(self._url, {'password': 'imacrook'})
-        self.assertContains(response, 'Incorrect password.')
-
-    def test_custom_form(self):
-        _old_form = settings.FORM
-        settings.FORM = 'tests.forms.CustomLockdownForm'
-        middleware._default_form = middleware.get_lockdown_form(settings.FORM)
-
-        try:
-            response = self.client.post(self._url, {'answer': '42'},
-                                        follow=True)
-            self.assertContains(response, self._contents)
-        finally:
-            settings.FORM = _old_form
-            middleware._default_form = middleware.get_lockdown_form(
-                                                                settings.FORM)
-
-
-class MiddlewareTests(DecoratorTests):
-    _url = '/a/view/'
-    _contents = 'A view.'
-
-    def setUp(self):
-        self._old_middleware_classes = django_settings.MIDDLEWARE_CLASSES
-        django_settings.MIDDLEWARE_CLASSES += (
-            'lockdown.middleware.LockdownMiddleware',
-        )
-        super(MiddlewareTests, self).setUp()
-
-    def tearDown(self):
-        django_settings.MIDDLEWARE_CLASSES = self._old_middleware_classes
-        super(MiddlewareTests, self).tearDown()

File tests/urls.py

-from django.conf.urls.defaults import *
-
-urlpatterns = patterns('tests.views',
-    (r'^a/view/$', 'aview'),
-    (r'^locked/view/$', 'lockedview'),
-)

File tests/views.py

-from django.http import HttpResponse
-
-from lockdown.decorators import lockdown
-
-
-def aview(request):
-    return HttpResponse('A view.')
-
-
-@lockdown()
-def lockedview(request):
-    return HttpResponse('A locked view.')
-
-
-@lockdown(passwords=('squirrel',))
-def nutcracker(request):
-    return HttpResponse('A locked view.')