如何测试用户是否具有查看权限

时间:2019-03-24 11:51:44

标签: python django testing django-rest-framework

我为视图及其工作创建了权限,但是我不知道如何测试补丁请求是否可以在未经许可的情况下与用户一起使用。

permission.py

class IsObjectCreator(permissions.BasePermission):

def has_object_permission(self, request, view, obj):
    if request.method in permissions.SAFE_METHODS:
        return True
    return request.user == obj.user

views.py

class TaskDetailAPIView(APIView):
permission_classes = [IsObjectCreator]

def get_object(self, id):
    try:
        return Task.objects.get(id=id)
    except Task.DoesNotExist:
        raise Http404

def get(self, request, id):
    task = self.get_object(id)
    serializer = TaskSerializer(task)
    return Response(serializer.data)

def patch(self, request, id):
    task = self.get_object(id)
    serializer = StatusSerializer(task, data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

在普通的Django视图中,我可以检查响应是否包含表单,但是我不知道如何在API中测试响应是否包含补丁方法。

2 个答案:

答案 0 :(得分:1)

我提出了一个问题,我只将视图分为2个通用视图,一个用于获取,一个用于修补和使用。

#api_views

class TaskDetailAPIView(generics.RetrieveAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer


class TaskUpdateStatusAPIView(generics.RetrieveUpdateAPIView):
    queryset = Task.objects.all()
    serializer_class = StatusSerializer
    permission_classes = [IsOwnerOrReadOnly]

然后我编写了此测试:

#api_tests

class TaskUpdateStatusAPI(APITestCase):
    def setUp(self):
        self.client = APIClient()
        self.user = User.objects.create_user(username='test', password='test123')
        self.user2 = User.objects.create_user(username='test2', password='test123')
        user = self.user2
        Task.objects.create(name='Task for test', user=user, status='New', date=date(2019, 4, 9),
                        description='This is description for test purposes')

    def test_access_unauthenticated_user(self):
        task = Task.objects.get(id=1)
        login = self.client.login()
        data = {"status": "DONE"}
        response = self.client.post(reverse('edit_status', kwargs={'pk': task.id}), data, format='json')
        self.assertFalse(login)
        self.assertEqual(response.status_code, 405, f'expected Response code 405, instead get {response.status_code}')

    def test_access_authenticated_user_without_permission(self):
        task = Task.objects.get(id=1)
        login = self.client.login(username='test', password='test123')
        data = {"status": "DONE"}
        response = self.client.post(reverse('edit_status', kwargs={'pk': task.id}), data, format='json')
        self.assertTrue(login)
        self.assertEqual(response.status_code, 405, f'expected Response code 405, instead get {response.status_code}')

    def test_access_authenticated_user_with_permission(self):
        task = Task.objects.get(id=1)
        login = self.client.login(username='test2', password='test123')
        data = {"status": "DONE"}
        response = self.client.post(reverse('edit_status', kwargs={'pk': task.id}), data, format='json')
        self.assertTrue(login)
        self.assertEqual(response.status_code, 405, f'expected Response code 405, instead get {response.status_code}')

答案 1 :(得分:1)

有多种方法可以对DRF中的视图进行写权限测试,如此处所述:https://www.django-rest-framework.org/api-guide/testing/。 您可以使用API​​Client进行操作,如下所述:

from django.test import TestCase
from rest_framework import status
from rest_framework.test import APIClient
from django.contrib.auth.models import User
from django.contrib.auth.hashers import make_password

class TaskDetailAPITestCase(TestCase):

    def setUp(self):
        self.client = APIClient()
        self.user = User(username='alice', password=make_password('123'),)
        self.task = Task(name="first task", user=self.user)
        self.task.save()

    def test_patch_with_logged_in_user(self):
        self.client.login(username='alice', password='123')
        url = '/tasks/{id}/'.format(id=self.task.id) # change url to match urlpattern.
        response = self.client.patch(self.url, {'name': 'some task'}, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_patch_without_logged_in_user(self):
        url = '/tasks/{id}/'.format(id=self.task.id) # change url to match urlpattern.
        response = self.client.patch(self.url, {'name': 'some task'}, format='json')
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)