django-views - Django UnitTest 在 test_views.py 中使用 self.user.has_perm 检查权限(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.py和urls.py中查看相应的 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_context
,self.assertFalse(self.user.has_perm('view_context', self.user.user_permissions))
但我不断收到类似的错误bool/user object/ XYZ has no Attribute profile/userprofile/user/user_permissions
我还研究了这个:https ://stackoverflow.com/a/10103291/4238752和这个https://stackoverflow.com/a/33294746/4238752 但无论我尝试什么,它都会继续抛出相同的异常和错误。
解决方案
我想我明白了现在这样工作: 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):
推荐阅读
- java - 使用 ExoPlayer 的 getPlayWhenReady 不起作用
- shopify - Shopify - 抑制主页元素
- javascript - 如何在某个字符之前和之后应用正则表达式
- matlab - 如何绘制复杂传递函数的根轨迹?
- arrays - 特定数组元素组合
- load-testing - VSTS 负载测试作为 CD 管道的一部分
- .net - 如何将 Azure KeyVault 中的证书与 HttpClient 一起使用,而不将其从 HSM 中提取出来?
- c++ - 为什么不能在类中引用转发声明的朋友类?
- c# - 将具有多个相关表的数据集批量插入 SQL Server C#
- html - 我的图像没有改变大小