0

I am writing a DRF API for an educational website where users can access data based on the permission groups and object level permissions they have. When I started writing the tests, I wondered whether it is necessary to test requests with all possible permission combinations. For example, say one endpoint of the API needs three permissions to give access to its data, then you could write a lot of test methods to test all possible combinations of permissions the user could have. Only one combination, the one where the user has all three permissions, will result in data and the rest will most likely result in a 403 Forbidden Response.

As an example, the three permissions could be something like IsAuthenticated, IsOwner and IsTeacher. The user needs to have all three permissions, so the 403 Forbidden Response combinations would be:

IsOwner    IsAuthenticated    IsTeacher
False      False              False,
False      False              True,
False      True               True,
True       False              False,
True       True               False,
True       False              True,
False      True               False,

The valid response which gives the user access to the data would be:

IsOwner    IsAuthenticated    IsTeacher
True       True               True

Is it necessary to test all of them? Should I test it in another way?

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
DJN
  • 51
  • 9

1 Answers1

1

You dont need to test all combinations, though it is better to cover all test cases if you feel this much should do. You can do it in one test case like this. You can alter permission sequence and writing new case here if you want all combination tested.

from rest_framework import status
from django.contrib.auth.models import Permission,User

class MyTest(APITestCase):
    client = APIClient()
    url = "/my/url/"

    def setUp(self):
            self.user = User.objects.create(username="hellouser")

    def test_user_permissions(self):
            res = self.client.post(self.url, data={"some": "data"}, format="json")
            self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
            #now give permission
            permission = Permission.objects.get(name='isOwner')
            self.user.user_permissions.add(permission) 
            res = self.client.post(self.url, data={"some": "data"}, format="json")
            self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
            #give another
            permission = Permission.objects.get(name='isTeacher')
            self.user.user_permissions.add(permission) 
            res = self.client.post(self.url, data={"some": "data"}, format="json")

            self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
            #last one should pass
            permission = Permission.objects.get(name='isAuthenticated')
            self.user.user_permissions.add(permission) 
            res = self.client.post(self.url, data={"some": "data"}, format="json")

            self.assertEqual(res.status_code, status.HTTP_200_OK)
Yugandhar Chaudhari
  • 3,831
  • 3
  • 24
  • 40
  • Thank you, I understand that you can avoid some combinations. I wanted to know whether you should test it so rigorously, which I now see is a matter of how thorough I want to test it. Thank you for your help and the clear example! –  DJN Mar 26 '19 at 07:33
  • Where is self.user even used in these requests? I dont see how self.client will know who the user is. – Mark Jan 29 '21 at 17:09
  • @Mark `def setUp(self): self.user = User.objects.create(username="hellouser")` runs first while running test it is assigned there . – Yugandhar Chaudhari Jan 30 '21 at 05:24