summaryrefslogtreecommitdiff
path: root/tests/auth_tests/test_mixins.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auth_tests/test_mixins.py')
-rw-r--r--tests/auth_tests/test_mixins.py251
1 files changed, 251 insertions, 0 deletions
diff --git a/tests/auth_tests/test_mixins.py b/tests/auth_tests/test_mixins.py
new file mode 100644
index 0000000000..c04715dc8f
--- /dev/null
+++ b/tests/auth_tests/test_mixins.py
@@ -0,0 +1,251 @@
+from django.contrib.auth import models
+from django.contrib.auth.mixins import (
+ LoginRequiredMixin, PermissionRequiredMixin, UserPassesTestMixin,
+)
+from django.contrib.auth.models import AnonymousUser
+from django.core.exceptions import PermissionDenied
+from django.http import HttpResponse
+from django.test import RequestFactory, TestCase
+from django.views.generic import View
+
+
+class AlwaysTrueMixin(UserPassesTestMixin):
+
+ def test_func(self):
+ return True
+
+
+class AlwaysFalseMixin(UserPassesTestMixin):
+
+ def test_func(self):
+ return False
+
+
+class EmptyResponseView(View):
+ def get(self, request, *args, **kwargs):
+ return HttpResponse()
+
+
+class AlwaysTrueView(AlwaysTrueMixin, EmptyResponseView):
+ pass
+
+
+class AlwaysFalseView(AlwaysFalseMixin, EmptyResponseView):
+ pass
+
+
+class StackedMixinsView1(LoginRequiredMixin, PermissionRequiredMixin, EmptyResponseView):
+ permission_required = ['auth.add_customuser', 'auth.change_customuser']
+ raise_exception = True
+
+
+class StackedMixinsView2(PermissionRequiredMixin, LoginRequiredMixin, EmptyResponseView):
+ permission_required = ['auth.add_customuser', 'auth.change_customuser']
+ raise_exception = True
+
+
+class AccessMixinTests(TestCase):
+
+ factory = RequestFactory()
+
+ def test_stacked_mixins_success(self):
+ user = models.User.objects.create(username='joe', password='qwerty')
+ perms = models.Permission.objects.filter(codename__in=('add_customuser', 'change_customuser'))
+ user.user_permissions.add(*perms)
+ request = self.factory.get('/rand')
+ request.user = user
+
+ view = StackedMixinsView1.as_view()
+ response = view(request)
+ self.assertEqual(response.status_code, 200)
+
+ view = StackedMixinsView2.as_view()
+ response = view(request)
+ self.assertEqual(response.status_code, 200)
+
+ def test_stacked_mixins_missing_permission(self):
+ user = models.User.objects.create(username='joe', password='qwerty')
+ perms = models.Permission.objects.filter(codename__in=('add_customuser',))
+ user.user_permissions.add(*perms)
+ request = self.factory.get('/rand')
+ request.user = user
+
+ view = StackedMixinsView1.as_view()
+ with self.assertRaises(PermissionDenied):
+ view(request)
+
+ view = StackedMixinsView2.as_view()
+ with self.assertRaises(PermissionDenied):
+ view(request)
+
+ def test_stacked_mixins_not_logged_in(self):
+ user = models.User.objects.create(username='joe', password='qwerty')
+ user.is_authenticated = lambda: False
+ perms = models.Permission.objects.filter(codename__in=('add_customuser', 'change_customuser'))
+ user.user_permissions.add(*perms)
+ request = self.factory.get('/rand')
+ request.user = user
+
+ view = StackedMixinsView1.as_view()
+ with self.assertRaises(PermissionDenied):
+ view(request)
+
+ view = StackedMixinsView2.as_view()
+ with self.assertRaises(PermissionDenied):
+ view(request)
+
+
+class UserPassesTestTests(TestCase):
+
+ factory = RequestFactory()
+
+ def _test_redirect(self, view=None, url='/accounts/login/?next=/rand'):
+ if not view:
+ view = AlwaysFalseView.as_view()
+ request = self.factory.get('/rand')
+ request.user = AnonymousUser()
+ response = view(request)
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual(response.url, url)
+
+ def test_default(self):
+ self._test_redirect()
+
+ def test_custom_redirect_url(self):
+ class AView(AlwaysFalseView):
+ login_url = '/login/'
+
+ self._test_redirect(AView.as_view(), '/login/?next=/rand')
+
+ def test_custom_redirect_parameter(self):
+ class AView(AlwaysFalseView):
+ redirect_field_name = 'goto'
+
+ self._test_redirect(AView.as_view(), '/accounts/login/?goto=/rand')
+
+ def test_no_redirect_parameter(self):
+ class AView(AlwaysFalseView):
+ redirect_field_name = None
+
+ self._test_redirect(AView.as_view(), '/accounts/login/')
+
+ def test_raise_exception(self):
+ class AView(AlwaysFalseView):
+ raise_exception = True
+
+ request = self.factory.get('/rand')
+ request.user = AnonymousUser()
+ self.assertRaises(PermissionDenied, AView.as_view(), request)
+
+ def test_raise_exception_custom_message(self):
+ msg = "You don't have access here"
+
+ class AView(AlwaysFalseView):
+ raise_exception = True
+ permission_denied_message = msg
+
+ request = self.factory.get('/rand')
+ request.user = AnonymousUser()
+ view = AView.as_view()
+ with self.assertRaises(PermissionDenied) as cm:
+ view(request)
+ self.assertEqual(cm.exception.args[0], msg)
+
+ def test_raise_exception_custom_message_function(self):
+ msg = "You don't have access here"
+
+ class AView(AlwaysFalseView):
+ raise_exception = True
+
+ def get_permission_denied_message(self):
+ return msg
+
+ request = self.factory.get('/rand')
+ request.user = AnonymousUser()
+ view = AView.as_view()
+ with self.assertRaises(PermissionDenied) as cm:
+ view(request)
+ self.assertEqual(cm.exception.args[0], msg)
+
+ def test_user_passes(self):
+ view = AlwaysTrueView.as_view()
+ request = self.factory.get('/rand')
+ request.user = AnonymousUser()
+ response = view(request)
+ self.assertEqual(response.status_code, 200)
+
+
+class LoginRequiredMixinTests(TestCase):
+
+ factory = RequestFactory()
+
+ @classmethod
+ def setUpTestData(cls):
+ cls.user = models.User.objects.create(username='joe', password='qwerty')
+
+ def test_login_required(self):
+ """
+ Check that login_required works on a simple view wrapped in a
+ login_required decorator.
+ """
+ class AView(LoginRequiredMixin, EmptyResponseView):
+ pass
+
+ view = AView.as_view()
+
+ request = self.factory.get('/rand')
+ request.user = AnonymousUser()
+ response = view(request)
+ self.assertEqual(response.status_code, 302)
+ self.assertEqual('/accounts/login/?next=/rand', response.url)
+ request = self.factory.get('/rand')
+ request.user = self.user
+ response = view(request)
+ self.assertEqual(response.status_code, 200)
+
+
+class PermissionsRequiredMixinTests(TestCase):
+
+ factory = RequestFactory()
+
+ @classmethod
+ def setUpTestData(cls):
+ cls.user = models.User.objects.create(username='joe', password='qwerty')
+ perms = models.Permission.objects.filter(codename__in=('add_customuser', 'change_customuser'))
+ cls.user.user_permissions.add(*perms)
+
+ def test_many_permissions_pass(self):
+ class AView(PermissionRequiredMixin, EmptyResponseView):
+ permission_required = ['auth.add_customuser', 'auth.change_customuser']
+
+ request = self.factory.get('/rand')
+ request.user = self.user
+ resp = AView.as_view()(request)
+ self.assertEqual(resp.status_code, 200)
+
+ def test_single_permission_pass(self):
+ class AView(PermissionRequiredMixin, EmptyResponseView):
+ permission_required = 'auth.add_customuser'
+
+ request = self.factory.get('/rand')
+ request.user = self.user
+ resp = AView.as_view()(request)
+ self.assertEqual(resp.status_code, 200)
+
+ def test_permissioned_denied_redirect(self):
+ class AView(PermissionRequiredMixin, EmptyResponseView):
+ permission_required = ['auth.add_customuser', 'auth.change_customuser', 'non-existent-permission']
+
+ request = self.factory.get('/rand')
+ request.user = self.user
+ resp = AView.as_view()(request)
+ self.assertEqual(resp.status_code, 302)
+
+ def test_permissioned_denied_exception_raised(self):
+ class AView(PermissionRequiredMixin, EmptyResponseView):
+ permission_required = ['auth.add_customuser', 'auth.change_customuser', 'non-existent-permission']
+ raise_exception = True
+
+ request = self.factory.get('/rand')
+ request.user = self.user
+ self.assertRaises(PermissionDenied, AView.as_view(), request)