mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Black 23.1.0 is released which, as the first release of the year,
introduces the 2023 stable style. This incorporates most of last year's
preview style.
https://github.com/psf/black/releases/tag/23.1.0
Backport of 097e3a70c1 from main
		
	
		
			
				
	
	
		
			305 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			305 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from unittest import mock
 | |
| 
 | |
| 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, SimpleTestCase, 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_tests.add_customuser", "auth_tests.change_customuser"]
 | |
|     raise_exception = True
 | |
| 
 | |
| 
 | |
| class StackedMixinsView2(
 | |
|     PermissionRequiredMixin, LoginRequiredMixin, EmptyResponseView
 | |
| ):
 | |
|     permission_required = ["auth_tests.add_customuser", "auth_tests.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_access_mixin_permission_denied_response(self):
 | |
|         user = models.User.objects.create(username="joe", password="qwerty")
 | |
|         # Authenticated users receive PermissionDenied.
 | |
|         request = self.factory.get("/rand")
 | |
|         request.user = user
 | |
|         view = AlwaysFalseView.as_view()
 | |
|         with self.assertRaises(PermissionDenied):
 | |
|             view(request)
 | |
|         # Anonymous users are redirected to the login page.
 | |
|         request.user = AnonymousUser()
 | |
|         response = view(request)
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/accounts/login/?next=/rand")
 | |
| 
 | |
|     def test_access_mixin_permission_denied_remote_login_url(self):
 | |
|         class AView(AlwaysFalseView):
 | |
|             login_url = "https://www.remote.example.com/login"
 | |
| 
 | |
|         view = AView.as_view()
 | |
|         request = self.factory.get("/rand")
 | |
|         request.user = AnonymousUser()
 | |
|         response = view(request)
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(
 | |
|             response.url,
 | |
|             "https://www.remote.example.com/login?next=http%3A//testserver/rand",
 | |
|         )
 | |
| 
 | |
|     @mock.patch.object(models.User, "is_authenticated", False)
 | |
|     def test_stacked_mixins_not_logged_in(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()
 | |
|         with self.assertRaises(PermissionDenied):
 | |
|             view(request)
 | |
| 
 | |
|         view = StackedMixinsView2.as_view()
 | |
|         with self.assertRaises(PermissionDenied):
 | |
|             view(request)
 | |
| 
 | |
| 
 | |
| class UserPassesTestTests(SimpleTestCase):
 | |
|     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()
 | |
|         with 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.assertRaisesMessage(PermissionDenied, msg):
 | |
|             view(request)
 | |
| 
 | |
|     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.assertRaisesMessage(PermissionDenied, msg):
 | |
|             view(request)
 | |
| 
 | |
|     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):
 | |
|         """
 | |
|         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_tests.add_customuser",
 | |
|                 "auth_tests.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_tests.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_tests.add_customuser",
 | |
|                 "auth_tests.change_customuser",
 | |
|                 "nonexistent-permission",
 | |
|             ]
 | |
| 
 | |
|         # Authenticated users receive PermissionDenied.
 | |
|         request = self.factory.get("/rand")
 | |
|         request.user = self.user
 | |
|         with self.assertRaises(PermissionDenied):
 | |
|             AView.as_view()(request)
 | |
|         # Anonymous users are redirected to the login page.
 | |
|         request.user = AnonymousUser()
 | |
|         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_tests.add_customuser",
 | |
|                 "auth_tests.change_customuser",
 | |
|                 "nonexistent-permission",
 | |
|             ]
 | |
|             raise_exception = True
 | |
| 
 | |
|         request = self.factory.get("/rand")
 | |
|         request.user = self.user
 | |
|         with self.assertRaises(PermissionDenied):
 | |
|             AView.as_view()(request)
 |