Django UnitTest 在 test_views.py 中使用 self.user.has_perm 检查 View 的权限(LoginRequiredMixin,PermissionRequiredMixin,ListView)

Django UnitTest check for Permission with self.user.has_perm in test_views.py for View(LoginRequiredMixin, PermissionRequiredMixin, ListView)

我基本上遵循了 Mozilla 操作方法:https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Testing#Views_that_are_restricted_to_logged_in_users

要在此处获取完整图片,您可以在 views.pyurls.py[=44= 中查看相应的 url 和视图] 下面:

path('contexts/', views.ContextListView.as_view(), name='contexts'),
class ContextListView(LoginRequiredMixin, PermissionRequiredMixin, ListView):
    model = Context
    paginate_by = 10
    permission_required = 'catalog.view_context'
    def get_queryset(self):
        if self.request.user.is_staff:
            queryset = Context.objects.all()
        else:
            user = self.request.user
            queryset = Context.objects.filter(name=user)
        return queryset

我已经用两种不同的方式创建了两个用户,应该做同样的事情。
其中一种方式被注释掉了。

class ContextListViewTest(TestCase):
    def setUp(self):
        number_of_contexts = 25
        number_of_extensions = 25
        # test_user1 = User.objects.create_user(username='testuser1')
        # test_user2 = User.objects.create_user(username='testuser2')
        # test_user1.set_password('1X<ISRUkw+tuK')
        # test_user2.set_password('2HJ1vRV0Z&3iD')
        test_user1 = User.objects.create_user(username='testuser1', password='1X<ISRUkw+tuK')
        test_user2 = User.objects.create_user(username='testuser2', password='2HJ1vRV0Z&3iD')
        test_user1.save()
        test_user2.save()

虽然简单登录测试似乎有效:

    def test_login(self):
        c = Client()  # Login
        login = c.login(username='testuser1', password='1X<ISRUkw+tuK')
        self.assertTrue(login)

测试特定权限不:

    def test_logged_in_uses_correct_template(self):
        self.c = Client()  # Login
        self.user = User.objects.get(username="testuser1")
        login = self.c.login(username='testuser1', password='1X<ISRUkw+tuK')
        response = self.c.get(reverse('contexts'))

        # Check for HTTPResponseForbidden
        self.assertEqual(response.status_code, 403)

        # Check for Permission the User don't have but need to display that view.
        # self.assertFalse(self.user.has_perm('view_context', self.user.userprofile))
        # self.assertFalse(self.user.has_perm('view_context', self.user.profile))
        # self.assertFalse(self.user.has_perm('view_context', self.user))
        # self.assertFalse(self.user.has_perm('view_context', self.user.user_permissions))
        self.assertFalse(self.user.has_perm('view_context', self.user.user_permissions))

测试self.assertEqual(response.status_code, 403)将通过,因为登录用户没有权限catalog.view_context

之后,我想明确检查用户是否没有 catalog.view_contextself.assertFalse(self.user.has_perm('view_context', self.user.user_permissions)) 的权限,但我经常收到 bool/user object/ XYZ has no Attribute profile/userprofile/user/user_permissions

之类的错误

我也调查了这个: and this 但无论我尝试什么,它都会继续抛出相同的异常和错误。

我想我明白了 现在像这样工作: test_views.py

#!/usr/bin/python3
from django.test import TestCase
from django.urls import reverse
from catalog.models import Extension, Context
from django.contrib.auth.models import User, Permission
from django.test import Client


class ContextListViewTest(TestCase):
    def setUp(self):
        number_of_contexts = 25
        number_of_extensions = 25
        test_user1 = User.objects.create_user(username='testuser1', password='1X<ISRUkw+tuK')
        test_user2 = User.objects.create_user(username='testuser2', password='2HJ1vRV0Z&3iD')
        test_user1.save()
        test_user2.save()
        # Create 25 Contexts
        for context_id in range(number_of_contexts):
            Context.objects.create(
                name=f'test{context_id}.de',
                countryprefix=f'{context_id}',
                cityprefix=f'{context_id}',
                number=f'90096{context_id}',
                extensionsfrom=f'0',
                extensionstill=f'Surname {context_id}',
                portscount=f'Surname {context_id}',
            )
            # Create 25 Extensions per Context
            for extension_id in range(number_of_extensions):
                Extension.objects.create(
                    username=f'test{context_id}.de_{extension_id}',
                    password=f'Password{context_id}',
                    firstname=f'Max{context_id}',
                    lastname=f'Mustermann{context_id}',
                    callerid=f'Max Msutermann <{context_id}>',
                    extension=f'{context_id}',
                    )

    def test__for_login_restriction_permission_and_template(self):
        # Create Client
        self.c = Client()
        # Try to call the Restricted View as Anonymous
        response = self.c.get(reverse('contexts'))
        # Check for Login Promt Redirection
        self.assertRedirects(response, '/accounts/login/?next=/catalog/contexts/')

        # Get Userobject
        self.user = User.objects.get(username="testuser1")
        # Login with the Client
        login = self.c.login(username='testuser1', password='1X<ISRUkw+tuK')
        # Check our user is logged in
        self.assertTrue(login)
        # Check for our username
        self.assertEqual(self.user.username, 'testuser1')

        # Try to call the Restricted View as logged in User again but without Permission
        response = self.c.get(reverse('contexts'))
        # Check for HTTPResponseForbidden
        self.assertEqual(response.status_code, 403)

        # Check for view_context Permission the User don't have but need to display that view.
        self.assertFalse(self.user.has_perm('catalog.view_context'))
        # now add the permission
        self.user.user_permissions.add(Permission.objects.get(codename='view_context'))
        # refetch user from the database
        self.user = User.objects.get(pk=self.user.pk)
        # Print all Permissions to Console / Should now include view_context
        # print(self.user.get_all_permissions())
        # Check for view_context Permission the User should now have
        self.assertTrue(self.user.has_perm('catalog.view_context'))

        # Try to call the Restricted View again but with Permission this time
        response = self.c.get(reverse('contexts'))
        # Check that we got a response "success"
        self.assertEqual(response.status_code, 200)

        # Check we used correct template
        self.assertTemplateUsed(response, 'catalog/context_list.html')

    # def test_pagination(self):