mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-29 13:04:03 +03:00
d54df8c438
* Initial Refactor Step
* Add descriptor class
* call from generator
* proxy back to generator for implementation.
* Move `get_link` to descriptor
* Move `get_description` to descriptor
* Remove need for generator in get_description
* Move get_path_fields to descriptor
* Move `get_serializer_fields` to descriptor
* Move `get_pagination_fields` to descriptor
* Move `get_filter_fields` to descriptor
* Move `get_encoding` to descriptor.
* Pass just `url` from SchemaGenerator to descriptor
* Make `view` a property
Encapsulates check for a view instance.
* Adjust API Reference docs
* Add `ManualSchema` class
* Refactor to `ViewInspector` plus `AutoSchema`
The interface then is **just** `get_link()`
* Add `manual_fields` kwarg to AutoSchema
* Add schema decorator for FBVs
* Adjust comments
* Docs: Provide full params in example
Ref feedback b52e372f8f (r137254795)
* Add docstring for ViewInstpector.__get__ descriptor method.
Ref https://github.com/encode/django-rest-framework/pull/5354#discussion_r137265022
* Make `schemas` a package.
* Split generators, inspectors, views.
* Adjust imports
* Rename to EndpointEnumerator
* Adjust ManualSchema to take `fields`
… and `description`.
Allows `url` and `action` to remain dynamic
* Add package/module docstrings
169 lines
4.9 KiB
Python
169 lines
4.9 KiB
Python
from __future__ import unicode_literals
|
|
|
|
from django.test import TestCase
|
|
|
|
from rest_framework import status
|
|
from rest_framework.authentication import BasicAuthentication
|
|
from rest_framework.decorators import (
|
|
api_view, authentication_classes, parser_classes, permission_classes,
|
|
renderer_classes, schema, throttle_classes
|
|
)
|
|
from rest_framework.parsers import JSONParser
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from rest_framework.renderers import JSONRenderer
|
|
from rest_framework.response import Response
|
|
from rest_framework.schemas import AutoSchema
|
|
from rest_framework.test import APIRequestFactory
|
|
from rest_framework.throttling import UserRateThrottle
|
|
from rest_framework.views import APIView
|
|
|
|
|
|
class DecoratorTestCase(TestCase):
|
|
|
|
def setUp(self):
|
|
self.factory = APIRequestFactory()
|
|
|
|
def _finalize_response(self, request, response, *args, **kwargs):
|
|
response.request = request
|
|
return APIView.finalize_response(self, request, response, *args, **kwargs)
|
|
|
|
def test_api_view_incorrect(self):
|
|
"""
|
|
If @api_view is not applied correct, we should raise an assertion.
|
|
"""
|
|
|
|
@api_view
|
|
def view(request):
|
|
return Response()
|
|
|
|
request = self.factory.get('/')
|
|
self.assertRaises(AssertionError, view, request)
|
|
|
|
def test_api_view_incorrect_arguments(self):
|
|
"""
|
|
If @api_view is missing arguments, we should raise an assertion.
|
|
"""
|
|
|
|
with self.assertRaises(AssertionError):
|
|
@api_view('GET')
|
|
def view(request):
|
|
return Response()
|
|
|
|
def test_calling_method(self):
|
|
|
|
@api_view(['GET'])
|
|
def view(request):
|
|
return Response({})
|
|
|
|
request = self.factory.get('/')
|
|
response = view(request)
|
|
assert response.status_code == status.HTTP_200_OK
|
|
|
|
request = self.factory.post('/')
|
|
response = view(request)
|
|
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
|
|
|
|
def test_calling_put_method(self):
|
|
|
|
@api_view(['GET', 'PUT'])
|
|
def view(request):
|
|
return Response({})
|
|
|
|
request = self.factory.put('/')
|
|
response = view(request)
|
|
assert response.status_code == status.HTTP_200_OK
|
|
|
|
request = self.factory.post('/')
|
|
response = view(request)
|
|
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
|
|
|
|
def test_calling_patch_method(self):
|
|
|
|
@api_view(['GET', 'PATCH'])
|
|
def view(request):
|
|
return Response({})
|
|
|
|
request = self.factory.patch('/')
|
|
response = view(request)
|
|
assert response.status_code == status.HTTP_200_OK
|
|
|
|
request = self.factory.post('/')
|
|
response = view(request)
|
|
assert response.status_code == status.HTTP_405_METHOD_NOT_ALLOWED
|
|
|
|
def test_renderer_classes(self):
|
|
|
|
@api_view(['GET'])
|
|
@renderer_classes([JSONRenderer])
|
|
def view(request):
|
|
return Response({})
|
|
|
|
request = self.factory.get('/')
|
|
response = view(request)
|
|
assert isinstance(response.accepted_renderer, JSONRenderer)
|
|
|
|
def test_parser_classes(self):
|
|
|
|
@api_view(['GET'])
|
|
@parser_classes([JSONParser])
|
|
def view(request):
|
|
assert len(request.parsers) == 1
|
|
assert isinstance(request.parsers[0], JSONParser)
|
|
return Response({})
|
|
|
|
request = self.factory.get('/')
|
|
view(request)
|
|
|
|
def test_authentication_classes(self):
|
|
|
|
@api_view(['GET'])
|
|
@authentication_classes([BasicAuthentication])
|
|
def view(request):
|
|
assert len(request.authenticators) == 1
|
|
assert isinstance(request.authenticators[0], BasicAuthentication)
|
|
return Response({})
|
|
|
|
request = self.factory.get('/')
|
|
view(request)
|
|
|
|
def test_permission_classes(self):
|
|
|
|
@api_view(['GET'])
|
|
@permission_classes([IsAuthenticated])
|
|
def view(request):
|
|
return Response({})
|
|
|
|
request = self.factory.get('/')
|
|
response = view(request)
|
|
assert response.status_code == status.HTTP_403_FORBIDDEN
|
|
|
|
def test_throttle_classes(self):
|
|
class OncePerDayUserThrottle(UserRateThrottle):
|
|
rate = '1/day'
|
|
|
|
@api_view(['GET'])
|
|
@throttle_classes([OncePerDayUserThrottle])
|
|
def view(request):
|
|
return Response({})
|
|
|
|
request = self.factory.get('/')
|
|
response = view(request)
|
|
assert response.status_code == status.HTTP_200_OK
|
|
|
|
response = view(request)
|
|
assert response.status_code == status.HTTP_429_TOO_MANY_REQUESTS
|
|
|
|
def test_schema(self):
|
|
"""
|
|
Checks CustomSchema class is set on view
|
|
"""
|
|
class CustomSchema(AutoSchema):
|
|
pass
|
|
|
|
@api_view(['GET'])
|
|
@schema(CustomSchema())
|
|
def view(request):
|
|
return Response({})
|
|
|
|
assert isinstance(view.cls.schema, CustomSchema)
|