How to enable unit test permissions in django-rest-framework?

This is the sample resolution that I want unit test.

# permissions.py

from myapp.models import Membership

class IsOrganizationOwner(permissions.BasePermission):
    """
    Custom permission to allow only owner of the organization to do a certian task.
    """
    def has_object_permission(self, request, view, obj):
        try:
            membership = Membership.objects.get(user = request.user, organization = obj)
        except Membership.DoesNotExist:
            return False

        return membership.is_admin

and this is how it is applied

# viewsets.py
class OrganizationViewSet(viewsets.ModelViewSet):
    """
    API endpoint that allows Organizations to be viewed or edited.
    """
    permission_classes = (permissions.IsAuthenticated, IsOrganizationOwner,)
    queryset = Organization.objects.all().order_by('name')
    serializer_class = OrganizationSerializer

Now I am very new to testing in django, and I do not know how to check this permission. Any help would be appreciated.

+4
source share
1 answer

Here is one approach:

from django_mock_queries.query import MockSet
from mock import patch, MagicMock
from unittest import TestCase


class TestPermissions(TestCase):
    memberships = MockSet()
    patch_memberships = patch('myapp.models.Membership.objects', memberships)

    def setUp(self):
        self.permission = IsOrganizationOwner()

        self.memberships.clear()
        self.request = MagicMock(user=MagicMock())
        self.view = MagicMock()

    def create_membership(self, organization, is_admin):
        self.request.user.is_admin = is_admin
        self.memberships.add(
            MagicMock(user=self.request.user, organization=organization)
        )

    @patch_memberships
    def test_permissions_is_organization_owner_returns_false_when_membership_does_not_exist(self):
        org = MagicMock()
        self.assertFalse(self.permission.has_object_permission(self.request, self.view, org))

    @patch_memberships
    def test_permissions_is_organization_owner_returns_false_when_membership_is_not_admin(self):
        org = MagicMock()
        self.create_membership(org, False)
        self.assertFalse(self.permission.has_object_permission(self.request, self.view, org))

    @patch_memberships
    def test_permissions_is_organization_owner_returns_true_when_membership_is_admin(self):
        org = MagicMock()
        self.create_membership(org, True)
        self.assertTrue(self.permission.has_object_permission(self.request, self.view, org))

I used the library in which I wrote that it executes mocks django queryset to make the tests more compact and readable. But if you prefer to use Mockor MagicMockto fix only what you need.

. , OrganizationViewSet, :

from django.contrib.auth.models import User
from django.test import TestCase, Client
from model_mommy import mommy


class TestOrganizationViewSet(TestCase):
    url = '/organizations/'

    def create_user(self, is_admin):
        password = 'password'

        user = mommy.prepare(User, is_admin=is_admin)
        user.set_password(password)
        user.save()

        return user, password

    def get_organizations_as(self, user=None, password=None):
        api = Client()

        if user:
            mommy.make(Membership, user=user, organization=mommy.make(Organization))
            api.login(username=user.username, password=password)

        return api.get(self.url)

    def test_organizations_viewset_returns_200_for_admins(self):
        response = self.get_organizations_as(*self.create_user(True))
        self.assertEqual(response.status_code, 200)

    def test_organizations_viewset_returns_403_for_non_admins(self):
        response = self.get_organizations_as(*self.create_user(False))
        self.assertEqual(response.status_code, 403)

    def test_organizations_viewset_returns_403_for_anonymous(self):
        response = self.get_organizations_as()
        self.assertEqual(response.status_code, 403)

, , . , .. CI - , - .

+5

All Articles