Как проверить конечную точку API с помощью Django-rest-framework, используя Django-oauth-toolkit для аутентификации

У меня есть представление/маршрутизатор Django-rest-framework для определения конечной точки API. Точка зрения определяется как таковая:

class DocumentViewSet(viewsets.ModelViewSet):
    permission_classes = [permissions.IsAuthenticated, TokenHasReadWriteScope]
    model = Document

И маршрутизатор определяется как

router = DefaultRouter()
router.register(r'documents', viewsets.DocumentViewSet)

с шаблоном url url(r'^api/', include(router.urls))

Я могу быстро удалить эту конечную точку в браузере/через завиток, получив нужный токен доступа и используя его для авторизации. Однако неясно, как писать тесты с этой конечной точкой.

Вот что я пробовал:

class DocumentAPITests(APITestCase):
    def test_get_all_documents(self):
        user = User.objects.create_user('test', '[email protected]', 'test')
        client = APIClient()
        client.credentials(username="test", password="test")
        response = client.get("/api/documents/")
        self.assertEqual(response.status_code, 200) 

Это не выполняется с ответом HTTP 401 от вызова client.get(). Каков правильный способ тестирования конечной точки API в DRF с помощью django-oauth-toolkit для аутентификации oauth2?

Ответы

Ответ 1

Когда вы пишете тесты, вы должны стремиться извлечь все, что вы не тестируете из самого теста, обычно помещая любой код установки в метод setUp теста. В случае тестов API с OAuth это обычно включает в себя тестовый пользователь, приложение OAuth и токен активного доступа.

Для django-oauth-toolkit и других приложений Django я всегда рекомендую посмотреть тесты, чтобы посмотреть, как они это делают. Это позволяет избежать ненужных вызовов API, особенно для многочастных процессов, таких как OAuth, и создавать только несколько требуемых объектов модели.

def setUp(self):
    self.test_user = UserModel.objects.create_user("test_user", "[email protected]", "123456")

    self.application = Application(
        name="Test Application",
        redirect_uris="http://localhost",
        user=self.test_user,
        client_type=Application.CLIENT_CONFIDENTIAL,
        authorization_grant_type=Application.GRANT_AUTHORIZATION_CODE,
    )
    self.application.save()

def test_revoke_access_token(self):
    from datetime import datetime
    from django.utils import timezone

    tok = AccessToken.objects.create(
        user=self.test_user, token='1234567890',
        application=self.application, scope='read write',
        expires=timezone.now() + datetime.timedelta(days=1)
    )

Оттуда вам просто нужно пройти аутентификацию, используя созданный токен. Вы можете сделать это с помощью ввода заголовка Authorization, или вы можете использовать метод force_authenticate по Django REST Framework.