在 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)