import unittest from django.conf.urls import include, url from django.test import TestCase, override_settings from rest_framework import filters, pagination, permissions, serializers from rest_framework.compat import coreapi from rest_framework.decorators import detail_route, list_route from rest_framework.response import Response from rest_framework.routers import DefaultRouter from rest_framework.schemas import SchemaGenerator from rest_framework.test import APIClient from rest_framework.views import APIView from rest_framework.viewsets import ModelViewSet class MockUser(object): def is_authenticated(self): return True class ExamplePagination(pagination.PageNumberPagination): page_size = 100 class ExampleSerializer(serializers.Serializer): a = serializers.CharField(required=True, help_text='A field description') b = serializers.CharField(required=False) read_only = serializers.CharField(read_only=True) hidden = serializers.HiddenField(default='hello') class AnotherSerializer(serializers.Serializer): c = serializers.CharField(required=True) d = serializers.CharField(required=False) class ExampleViewSet(ModelViewSet): pagination_class = ExamplePagination permission_classes = [permissions.IsAuthenticatedOrReadOnly] filter_backends = [filters.OrderingFilter] serializer_class = ExampleSerializer @detail_route(methods=['post'], serializer_class=AnotherSerializer) def custom_action(self, request, pk): return super(ExampleSerializer, self).retrieve(self, request) @list_route() def custom_list_action(self, request): return super(ExampleViewSet, self).list(self, request) def get_serializer(self, *args, **kwargs): assert self.request assert self.action return super(ExampleViewSet, self).get_serializer(*args, **kwargs) class ExampleView(APIView): permission_classes = [permissions.IsAuthenticatedOrReadOnly] def get(self, request, *args, **kwargs): return Response() def post(self, request, *args, **kwargs): return Response() router = DefaultRouter(schema_title='Example API' if coreapi else None) router.register('example', ExampleViewSet, base_name='example') urlpatterns = [ url(r'^', include(router.urls)) ] urlpatterns2 = [ url(r'^example-view/$', ExampleView.as_view(), name='example-view') ] @unittest.skipUnless(coreapi, 'coreapi is not installed') @override_settings(ROOT_URLCONF='tests.test_schemas') class TestRouterGeneratedSchema(TestCase): def test_anonymous_request(self): client = APIClient() response = client.get('/', HTTP_ACCEPT='application/vnd.coreapi+json') self.assertEqual(response.status_code, 200) expected = coreapi.Document( url='', title='Example API', content={ 'example': { 'list': coreapi.Link( url='/example/', action='get', fields=[ coreapi.Field('page', required=False, location='query'), coreapi.Field('ordering', required=False, location='query') ] ), 'custom_list_action': coreapi.Link( url='/example/custom_list_action/', action='get' ), 'retrieve': coreapi.Link( url='/example/{pk}/', action='get', fields=[ coreapi.Field('pk', required=True, location='path') ] ) } } ) self.assertEqual(response.data, expected) def test_authenticated_request(self): client = APIClient() client.force_authenticate(MockUser()) response = client.get('/', HTTP_ACCEPT='application/vnd.coreapi+json') self.assertEqual(response.status_code, 200) expected = coreapi.Document( url='', title='Example API', content={ 'example': { 'list': coreapi.Link( url='/example/', action='get', fields=[ coreapi.Field('page', required=False, location='query'), coreapi.Field('ordering', required=False, location='query') ] ), 'create': coreapi.Link( url='/example/', action='post', encoding='application/json', fields=[ coreapi.Field('a', required=True, location='form', description='A field description'), coreapi.Field('b', required=False, location='form') ] ), 'retrieve': coreapi.Link( url='/example/{pk}/', action='get', fields=[ coreapi.Field('pk', required=True, location='path') ] ), 'custom_action': coreapi.Link( url='/example/{pk}/custom_action/', action='post', encoding='application/json', fields=[ coreapi.Field('pk', required=True, location='path'), coreapi.Field('c', required=True, location='form'), coreapi.Field('d', required=False, location='form'), ] ), 'custom_list_action': coreapi.Link( url='/example/custom_list_action/', action='get' ), 'update': coreapi.Link( url='/example/{pk}/', action='put', encoding='application/json', fields=[ coreapi.Field('pk', required=True, location='path'), coreapi.Field('a', required=True, location='form', description='A field description'), coreapi.Field('b', required=False, location='form') ] ), 'partial_update': coreapi.Link( url='/example/{pk}/', action='patch', encoding='application/json', fields=[ coreapi.Field('pk', required=True, location='path'), coreapi.Field('a', required=False, location='form', description='A field description'), coreapi.Field('b', required=False, location='form') ] ), 'destroy': coreapi.Link( url='/example/{pk}/', action='delete', fields=[ coreapi.Field('pk', required=True, location='path') ] ) } } ) self.assertEqual(response.data, expected) @unittest.skipUnless(coreapi, 'coreapi is not installed') class TestSchemaGenerator(TestCase): def test_view(self): schema_generator = SchemaGenerator(title='Test View', patterns=urlpatterns2) schema = schema_generator.get_schema() expected = coreapi.Document( url='', title='Test View', content={ 'example-view': { 'create': coreapi.Link( url='/example-view/', action='post', fields=[] ), 'read': coreapi.Link( url='/example-view/', action='get', fields=[] ) } } ) self.assertEquals(schema, expected)