在 Django 视图中测试访问控制
tl; dr :创建一个定义两个用户对象的基类(比如 user
和 another_user
)。创建其他模型并定义三个 Client
实例。
self.client
:代表user
登录浏览器self.another_client
:代表another_user
的客户self.unlogged_client
:代表未登记的人
现在,从这三个客户端对象访问所有公共和私有 URL,并指示你期望的响应。下面我展示了 Book
对象的策略,该对象可以是 private
(由少数特权用户拥有)或 public
(每个人都可见)。
from django.test import TestCase, RequestFactory, Client
from django.core.urlresolvers import reverse
class BaseViewTestCase(TestCase):
@classmethod
def setUpClass(cls):
super(BaseViewTestCase, cls).setUpClass()
cls.client = Client()
cls.another_client = Client()
cls.unlogged_client = Client()
cls.user = User.objects.create_user(
'dummy',password='dummy'
)
cls.user.save()
cls.another_user = User.objects.create_user(
'dummy2', password='dummy2'
)
cls.another_user.save()
cls.first_book = Book.objects.create(
name='first',
private = true
)
cls.first_book.readers.add(cls.user)
cls.first_book.save()
cls.public_book = Template.objects.create(
name='public',
private=False
)
cls.public_book.save()
def setUp(self):
self.client.login(username=self.user.username, password=self.user.username)
self.another_client.login(username=self.another_user.username, password=self.another_user.username)
"""
Only cls.user owns the first_book and thus only he should be able to see it.
Others get 403(Forbidden) error
"""
class PrivateBookAccessTestCase(BaseViewTestCase):
def setUp(self):
super(PrivateBookAccessTestCase, self).setUp()
self.url = reverse('view_book',kwargs={'book_id':str(self.first_book.id)})
def test_user_sees_own_book(self):
response = self.client.get(self.url)
self.assertEqual(200, response.status_code)
self.assertEqual(self.first_book.name,response.context['book'].name)
self.assertTemplateUsed('myapp/book/view_template.html')
def test_user_cant_see_others_books(self):
response = self.another_client.get(self.url)
self.assertEqual(403, response.status_code)
def test_unlogged_user_cant_see_private_books(self):
response = self.unlogged_client.get(self.url)
self.assertEqual(403, response.status_code)
"""
Since book is public all three clients should be able to see the book
"""
class PublicBookAccessTestCase(BaseViewTestCase):
def setUp(self):
super(PublicBookAccessTestCase, self).setUp()
self.url = reverse('view_book',kwargs={'book_id':str(self.public_book.id)})
def test_user_sees_book(self):
response = self.client.get(self.url)
self.assertEqual(200, response.status_code)
self.assertEqual(self.public_book.name,response.context['book'].name)
self.assertTemplateUsed('myapp/book/view_template.html')
def test_another_user_sees_public_books(self):
response = self.another_client.get(self.url)
self.assertEqual(200, response.status_code)
def test_unlogged_user_sees_public_books(self):
response = self.unlogged_client.get(self.url)
self.assertEqual(200, response.status_code)