Django REST Framework: Странное поведение в модульных тестах
Добрый вечер,
На данный момент я создаю юнит-тесты для довольно базовой модели в сочетании с аутентификацией по веб-токену json. Также я использую пользовательскую модель пользователя. Обратите внимание: несколько строк кода будут вырезаны для лучшего обзора - они не важны для моего вопроса
models.py:
USER = get_user_model()
class MainTask(models.Model):
id = models.BigAutoField(primary_key=True, unique=True)
title = models.CharField(max_length=50, null=False, blank=False, unique=True)
active = models.BooleanField(default=True)
slug = models.SlugField(null=False, blank=False, unique=True)
created_by = models.ForeignKey(USER, null=False, blank=False, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
views.py:
class MainTaskListCreateView(ListCreateAPIView):
queryset = MainTask.objects.all()
serializer_class = MainTaskSerializer
pagination_class = PageNumberPagination
urls.py:
urlpatterns = [
path('maintask/', MainTaskListCreateView.as_view(), name='maintask-list'),
path('token/', MyTokenObtainPairView.as_view(), name='token_obtain_pair'),
]
settings.py:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAdminUser',
'rest_framework.permissions.IsAuthenticated',
],
}
test_views.py:
USER = get_user_model()
class MainTaskTest(APITestCase):
url_verification = reverse('token_obtain_pair')
url_maintasks = reverse('maintask-list')
def setUp(self):
self.email = 'johndoe@email.com'
self.password = 'johndoepassword'
self.data = {
'email': self.email,
'password': self.password
}
USER.objects.create_user(email=self.email, password=self.password)
def test_auth_user(self):
response = self.client.post(self.url_verification, self.data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertTrue('access' in response.data)
self.assertTrue('refresh' in response.data)
def test_get_obj(self):
response_verification = self.client.post(self.url_verification, self.data, format='json')
token = response_verification.data['access']
self.client.credentials(HTTP_AUTHORIZATION=f"JWT {token}")
response = self.client.get(self.url_maintasks, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertNotEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)
self.assertNotEqual(response.status_code, status.HTTP_403_FORBIDDEN)
Проблема:
При выполнении приведенного выше теста я получаю ошибку 403, разрешение запрещено. Но при добавлении permission_classes к моему представлению следующим образом...
permission_classes = (IsAuthenticated,)
... все работает нормально и тест проходит. Но - дополнительно - при добавлении еще одного разрешения...
permission_classes = (IsAdminUser, IsAuthenticated,)
... ошибка 403 появляется снова. У кого-нибудь еще была такая проблема, я что-то упускаю или что происходит? То же самое касается изменения default-settings только на IsAuthenticated!
Ок, я упустил из виду то, что называется Составные разрешения. Но если честно, это действительно задокументировано в Анонсе версии 3.9. В любом случае... все, что мне нужно было сделать, это ...
permission_classes = [IsAdminUser | IsAuthenticated]