Skip to content

Commit e7af8d6

Browse files
authored
tests for #5127 (#7715)
* tests for #5127 * Resolves #5127
1 parent f8a03b0 commit e7af8d6

File tree

5 files changed

+64
-1
lines changed

5 files changed

+64
-1
lines changed

tests/browsable_api/no_auth_urls.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
from django.urls import path
22

3-
from .views import MockView
3+
from .views import BasicModelWithUsersViewSet, MockView
44

55
urlpatterns = [
66
path('', MockView.as_view()),
7+
path('basicviewset', BasicModelWithUsersViewSet.as_view({'get': 'list'})),
78
]

tests/browsable_api/serializers.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
from rest_framework.serializers import ModelSerializer
2+
from tests.models import BasicModelWithUsers
3+
4+
5+
class BasicSerializer(ModelSerializer):
6+
class Meta:
7+
model = BasicModelWithUsers
8+
fields = '__all__'

tests/browsable_api/test_browsable_api.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,35 @@
11
from django.contrib.auth.models import User
22
from django.test import TestCase, override_settings
33

4+
from rest_framework.permissions import IsAuthenticated
45
from rest_framework.test import APIClient
56

7+
from .views import BasicModelWithUsersViewSet, OrganizationPermissions
8+
9+
10+
@override_settings(ROOT_URLCONF='tests.browsable_api.no_auth_urls')
11+
class AnonymousUserTests(TestCase):
12+
"""Tests correct handling of anonymous user request on endpoints with IsAuthenticated permission class."""
13+
14+
def setUp(self):
15+
self.client = APIClient(enforce_csrf_checks=True)
16+
17+
def tearDown(self):
18+
self.client.logout()
19+
20+
def test_get_raises_typeerror_when_anonymous_user_in_queryset_filter(self):
21+
with self.assertRaises(TypeError):
22+
self.client.get('/basicviewset')
23+
24+
def test_get_returns_http_forbidden_when_anonymous_user(self):
25+
old_permissions = BasicModelWithUsersViewSet.permission_classes
26+
BasicModelWithUsersViewSet.permission_classes = [IsAuthenticated, OrganizationPermissions]
27+
28+
response = self.client.get('/basicviewset')
29+
30+
BasicModelWithUsersViewSet.permission_classes = old_permissions
31+
self.assertEqual(response.status_code, 403)
32+
633

734
@override_settings(ROOT_URLCONF='tests.browsable_api.auth_urls')
835
class DropdownWithAuthTests(TestCase):

tests/browsable_api/views.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
from rest_framework import authentication, renderers
2+
from rest_framework.permissions import BasePermission
23
from rest_framework.response import Response
34
from rest_framework.views import APIView
5+
from rest_framework.viewsets import ModelViewSet
6+
7+
from ..models import BasicModelWithUsers
8+
from .serializers import BasicSerializer
9+
10+
11+
class OrganizationPermissions(BasePermission):
12+
def has_object_permission(self, request, view, obj):
13+
return request.user.is_staff or (request.user == obj.owner.organization_user.user)
414

515

616
class MockView(APIView):
@@ -9,3 +19,15 @@ class MockView(APIView):
919

1020
def get(self, request):
1121
return Response({'a': 1, 'b': 2, 'c': 3})
22+
23+
24+
class BasicModelWithUsersViewSet(ModelViewSet):
25+
queryset = BasicModelWithUsers.objects.all()
26+
serializer_class = BasicSerializer
27+
permission_classes = [OrganizationPermissions]
28+
# permission_classes = [IsAuthenticated, OrganizationPermissions]
29+
renderer_classes = (renderers.BrowsableAPIRenderer, renderers.JSONRenderer)
30+
31+
def get_queryset(self):
32+
qs = super().get_queryset().filter(users=self.request.user)
33+
return qs

tests/models.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import uuid
22

3+
from django.contrib.auth.models import User
34
from django.db import models
45
from django.utils.translation import gettext_lazy as _
56

@@ -33,6 +34,10 @@ class ManyToManySource(RESTFrameworkModel):
3334
targets = models.ManyToManyField(ManyToManyTarget, related_name='sources')
3435

3536

37+
class BasicModelWithUsers(RESTFrameworkModel):
38+
users = models.ManyToManyField(User)
39+
40+
3641
# ForeignKey
3742
class ForeignKeyTarget(RESTFrameworkModel):
3843
name = models.CharField(max_length=100)

0 commit comments

Comments
 (0)