def test_no_form_parameters_with_non_form_parsers(): # see https://github.com/axnsan12/drf-yasg/issues/270 # test that manual form parameters for views that haven't set # all their parsers classes to form parsers are not allowed # even when the request body is empty @method_decorator( name='post', decorator=swagger_auto_schema( operation_description="Logins a user and returns a token", manual_parameters=[ openapi.Parameter( "username", openapi.IN_FORM, required=True, type=openapi.TYPE_STRING, description="Valid username or email for authentication"), ])) class CustomObtainAuthToken(ObtainAuthToken): throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES urlpatterns = [ url(r'token/$', CustomObtainAuthToken.as_view()), ] generator = OpenAPISchemaGenerator(info=openapi.Info( title="Test generator", default_version="v1"), patterns=urlpatterns) with pytest.raises(SwaggerGenerationError): generator.get_schema(None, True)
def test_basepath_only(mock_schema_request): with pytest.raises(SwaggerGenerationError): generator = OpenAPISchemaGenerator( info=openapi.Info(title="Test generator", default_version="v1"), version="v2", url='/basepath/', ) generator.get_schema(mock_schema_request, public=True)
def test_post__mark_as_required(): class ProjectSerializer(serializers.ModelSerializer): class Meta: model = Project fields = ('id', 'name', 'archived', 'members') extra_kwargs = { 'name': {'required': True}, 'archived': {'required': False}, 'members': {'required': True}, } class ProjectViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet): queryset = Project.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = BasicSwaggerAutoSchema router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(None, True) request_body_schema = swagger['paths']['/projects/']['post']['parameters'][0]['schema']['properties'] assert set(request_body_schema['data']['required']) == {'type', 'attributes', 'relationships'} assert request_body_schema['data']['properties']['attributes']['required'] == ['name'] assert request_body_schema['data']['properties']['relationships']['required'] == ['members'] members_schema = request_body_schema['data']['properties']['relationships']['properties']['members'] assert members_schema['required'] == ['data'] assert set(members_schema['properties']['data']['items']['required']) == {'type', 'id'}
def test_post__strip_read_only_fields(): class ProjectSerializer(serializers.ModelSerializer): class Meta: model = Project fields = ('id', 'name', 'archived', 'members') read_only_fields = ['archived', 'members'] class ProjectViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet): queryset = Project.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = BasicSwaggerAutoSchema router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(None, True) request_body_schema = swagger['paths']['/projects/']['post']['parameters'][0]['schema']['properties'] assert 'id' not in request_body_schema['data']['properties'] assert 'type' in request_body_schema['data']['properties'] assert 'attributes' in request_body_schema['data']['properties'] assert list(request_body_schema['data']['properties']['attributes']['properties'].keys()) == ['name'] assert 'relationships' not in request_body_schema['data']['properties']
def test_optional_return_type(py_type, expected_type): class OptionalMethodSerializer(serializers.Serializer): x = serializers.SerializerMethodField() def get_x(self, instance): pass # Add the type annotation here in order to avoid a SyntaxError in py27 get_x.__annotations__["return"] = typing.Optional[py_type] class OptionalMethodViewSet(viewsets.ViewSet): @swagger_auto_schema( responses={200: openapi.Response("OK", OptionalMethodSerializer)}) def retrieve(self, request, pk=None): return Response({'optional': None}) router = routers.DefaultRouter() router.register(r'optional', OptionalMethodViewSet, **_basename_or_base_name('optional')) generator = OpenAPISchemaGenerator(info=openapi.Info( title='Test optional parameter', default_version='v1'), patterns=router.urls) swagger = generator.get_schema(None, True) property_schema = swagger["definitions"]["OptionalMethod"]["properties"][ "x"] assert property_schema == openapi.Schema(title='X', type=expected_type, readOnly=True)
def test_data_links_self(): class ProjectSerializer(serializers.ModelSerializer): obj_url = serializers.HyperlinkedIdentityField(view_name='any') class Meta: model = test_models.Project fields = ('id', 'obj_url') class ProjectViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): queryset = test_models.Project.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = base.BasicSwaggerAutoSchema router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(request=None, public=True) response_schema = swagger['paths']['/projects/{id}/']['get']['responses'][ '200']['schema']['properties'] assert 'id' in response_schema['data']['properties'] assert 'type' in response_schema['data']['properties'] assert 'links' in response_schema['data']['properties'] assert list(response_schema['data']['properties']['links'] ['properties'].keys()) == ['self']
def test_nested_choice_in_array_field(choices, field, expected_type): # Create a model class on the fly to avoid warnings about using the several # model class name several times model_class = type( "%sModel" % field.__name__, (fake_models.FakeModel, ), { "array": postgres_fields.ArrayField( field(choices=((i, "choice %s" % i) for i in choices))), "__module__": "test_models", }) class ArraySerializer(serializers.ModelSerializer): class Meta: model = model_class fields = ("array", ) class ArrayViewSet(viewsets.ModelViewSet): serializer_class = ArraySerializer router = routers.DefaultRouter() router.register(r'arrays', ArrayViewSet, **_basename_or_base_name('arrays')) generator = OpenAPISchemaGenerator(info=openapi.Info( title='Test array model generator', default_version='v1'), patterns=router.urls) swagger = generator.get_schema(None, True) property_schema = swagger['definitions']['Array']['properties']['array'][ 'items'] assert property_schema == openapi.Schema(title='Array', type=expected_type, enum=choices)
def test_non_model_many__responses_override(): class ProjectSerializer(serializers.Serializer): id = serializers.IntegerField() name = serializers.CharField() class ProjectViewSet(viewsets.ViewSet): renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = base.BasicSwaggerAutoSchema resource_name = 'projects' @swagger_auto_schema(responses={200: ProjectSerializer(many=True)}) def list(self, request): pass router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(request=None, public=True) response_schema = swagger['paths']['/projects/']['get']['responses'][ '200']['schema']['properties'] assert 'items' in response_schema['data'] assert 'id' in response_schema['data']['items']['properties'] assert 'type' in response_schema['data']['items']['properties'] assert list(response_schema['data']['items']['properties']['attributes'] ['properties'].keys()) == ['name']
def test_get(): class ProjectSerializer(serializers.ModelSerializer): class Meta: model = Project fields = ('id', 'name', 'archived', 'members') class ProjectViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): queryset = Project.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = BasicSwaggerAutoSchema router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(None, True) response_schema = swagger['paths']['/projects/{id}/']['get']['responses']['200']['schema']['properties'] assert 'id' in response_schema['data']['properties'] assert response_schema['data']['properties']['id']['type'] == 'string' assert 'type' in response_schema['data']['properties'] assert response_schema['data']['properties']['type']['pattern'] == 'projects' assert 'attributes' in response_schema['data']['properties'] assert list(response_schema['data']['properties']['attributes']['properties'].keys()) == ['name', 'archived'] assert 'relationships' in response_schema['data']['properties'] assert list(response_schema['data']['properties']['relationships']['properties'].keys()) == ['members'] members_schema = response_schema['data']['properties']['relationships']['properties']['members']['properties'] assert members_schema['data']['items']['properties']['id']['type'] == 'string' assert members_schema['data']['items']['properties']['type']['pattern'] == 'members'
def test_action_mapping(): class ActionViewSet(viewsets.ViewSet): @swagger_auto_schema(method='get', operation_id='mapping_get') @swagger_auto_schema(method='delete', operation_id='mapping_delete') @action(detail=False, methods=['get', 'delete'], url_path='test') def action_main(self, request): """mapping docstring get/delete""" pass @swagger_auto_schema(operation_id='mapping_post') @action_main.mapping.post def action_post(self, request): """mapping docstring post""" pass router = routers.DefaultRouter() router.register(r'action', ActionViewSet, **_basename_or_base_name('action')) generator = OpenAPISchemaGenerator( info=openapi.Info(title="Test generator", default_version="v1"), version="v2", url='', patterns=router.urls ) for _ in range(3): swagger = generator.get_schema(None, True) action_ops = swagger['paths']['/test/'] methods = ['get', 'post', 'delete'] assert all(mth in action_ops for mth in methods) assert all(action_ops[mth]['operationId'] == 'mapping_' + mth for mth in methods) assert action_ops['post']['description'] == 'mapping docstring post' assert action_ops['get']['description'] == 'mapping docstring get/delete' assert action_ops['delete']['description'] == 'mapping docstring get/delete'
def test_replaced_serializer(): class DetailSerializer(serializers.Serializer): detail = serializers.CharField() class DetailViewSet(viewsets.ViewSet): serializer_class = DetailSerializer @swagger_auto_schema(responses={ 404: openapi.Response("Not found or Not accessible", DetailSerializer) }) def retrieve(self, request, pk=None): serializer = DetailSerializer({'detail': None}) return Response(serializer.data) router = routers.DefaultRouter() router.register(r'details', DetailViewSet, base_name='details') generator = OpenAPISchemaGenerator(info=openapi.Info( title="Test generator", default_version="v1"), version="v2", url='', patterns=router.urls) for _ in range(3): swagger = generator.get_schema(None, True) assert 'Detail' in swagger['definitions'] assert 'detail' in swagger['definitions']['Detail']['properties'] responses = swagger['paths']['/details/{id}/']['get']['responses'] assert '404' in responses assert responses['404']['schema']['$ref'] == "#/definitions/Detail"
def test_fallback_to_rest_api(): class ProjectSerializer(serializers.ModelSerializer): class Meta: model = test_models.Project fields = ('id', 'name', 'archived', 'members') class ProjectViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): queryset = test_models.Project.objects.all() serializer_class = ProjectSerializer swagger_schema = base.BasicSwaggerAutoSchema router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(request=None, public=True) response_schema = swagger['paths']['/projects/{id}/']['get']['responses'][ '200']['schema']['properties'] assert list( response_schema.keys()) == ['id', 'name', 'archived', 'members']
class DrfYasgSchemaLoader(BaseSchemaLoader): """ Loads OpenAPI schema generated by drf_yasg. """ def __init__(self, field_key_map: Optional[Dict[str, str]] = None) -> None: super().__init__(field_key_map=field_key_map) from drf_yasg.generators import OpenAPISchemaGenerator from drf_yasg.openapi import Info self.schema_generator = OpenAPISchemaGenerator( info=Info(title="", default_version="")) def load_schema(self) -> dict: """ Loads generated schema from drf-yasg and returns it as a dict. """ odict_schema = self.schema_generator.get_schema(None, True) return loads(dumps(odict_schema.as_odict())) def resolve_path(self, endpoint_path: str, method: str) -> Tuple[str, ResolverMatch]: de_parameterized_path, resolved_path = super().resolve_path( endpoint_path=endpoint_path, method=method) path_prefix = self.schema_generator.determine_path_prefix( self.endpoints) trim_length = len(path_prefix) if path_prefix != "/" else 0 return de_parameterized_path[trim_length:], resolved_path
def test_id_based_on_pk(): class ProjectSerializer(serializers.ModelSerializer): class Meta: model = ProjectWithCustomID fields = ['name'] class ProjectViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): queryset = ProjectWithCustomID.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = base.BasicSwaggerAutoSchema router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(request=None, public=True) response_schema = swagger['paths']['/projects/{custom_id}/']['get'][ 'responses']['200']['schema']['properties'] assert 'id' in response_schema['data']['properties'] assert response_schema['data']['properties']['id']['type'] == 'string' assert 'type' in response_schema['data']['properties'] assert 'attributes' in response_schema['data']['properties'] assert list(response_schema['data']['properties']['attributes'] ['properties'].keys()) == ['name']
def test_url_order(): # this view with description override should show up in the schema ... @swagger_auto_schema(method='get', operation_description="description override") @api_view() def test_override(request, pk=None): return Response({"message": "Hello, world!"}) # ... instead of this view which appears later in the url patterns @api_view() def test_view(request, pk=None): return Response({"message": "Hello, world!"}) patterns = [ url(r'^/test/$', test_override), url(r'^/test/$', test_view), ] generator = OpenAPISchemaGenerator(info=openapi.Info( title="Test generator", default_version="v1"), version="v2", url='', patterns=patterns) # description override is successful swagger = generator.get_schema(None, True) assert swagger['paths']['/test/']['get'][ 'description'] == 'description override' # get_endpoints only includes one endpoint assert len(generator.get_endpoints(None)['/test/'][1]) == 1
def test_get__filter(): class FilterSwaggerAutoSchema(BasicSwaggerAutoSchema): filter_inspectors = [drf_yasg_json_api.inspectors.DjangoFilterInspector] class ProjectSerializer(serializers.ModelSerializer): class Meta: model = Project fields = ('id', 'name', 'archived', 'members') class ProjectViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): queryset = Project.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = FilterSwaggerAutoSchema filter_backends = (filters.QueryParameterValidationFilter, django_filters.DjangoFilterBackend) filterset_fields = { 'archived': ('exact',), } router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(None, True) request_parameters_schema = swagger['paths']['/projects/']['get']['parameters'] assert request_parameters_schema[0]['name'] == 'filter[archived]'
def test_noop_inspectors(swagger_settings, mock_schema_request, codec_json, reference_schema, compare_schemas): from drf_yasg import app_settings def set_inspectors(inspectors, setting_name): existing = swagger_settings.get( setting_name, app_settings.SWAGGER_DEFAULTS[setting_name]) inspectors = [ __name__ + '.' + inspector.__name__ for inspector in inspectors ] swagger_settings[setting_name] = inspectors + existing set_inspectors([NoOpFieldInspector, NoOpSerializerInspector], 'DEFAULT_FIELD_INSPECTORS') set_inspectors([NoOpFilterInspector], 'DEFAULT_FILTER_INSPECTORS') set_inspectors([NoOpPaginatorInspector], 'DEFAULT_PAGINATOR_INSPECTORS') generator = OpenAPISchemaGenerator( info=openapi.Info(title="Test generator", default_version="v1"), version="v2", ) swagger = generator.get_schema(mock_schema_request, True) json_bytes = codec_json.encode(swagger) swagger_dict = json.loads(json_bytes.decode('utf-8'), object_pairs_hook=OrderedDict) compare_schemas(swagger_dict, reference_schema)
def test_force_related_resource(serializer_field, expect_array): """ Support off combinations of related resources fields – they do supply models or don't. """ class ProjectSerializer(serializers.ModelSerializer): member_relation = serializer_field class Meta: model = ProjectWithCustomIDAndExtraProperties fields = ['name', 'archived', 'member_relation'] def get_member(self): pass def get_members(self): pass class ProjectViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): queryset = ProjectWithCustomID.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = base.BasicSwaggerAutoSchema router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(request=None, public=True) response_schema = swagger['paths']['/projects/{custom_id}/']['get'][ 'responses']['200']['schema']['properties'] assert 'id' in response_schema['data']['properties'] assert response_schema['data']['properties']['id']['type'] == "string" assert response_schema['data']['properties']['id']['format'] == "int32" assert 'type' in response_schema['data']['properties'] assert 'attributes' in response_schema['data']['properties'] assert list(response_schema['data']['properties']['attributes'] ['properties'].keys()) == ['name', 'archived'] assert 'relationships' in response_schema['data']['properties'] relation_schema = response_schema['data']['properties']['relationships'][ 'properties']['member-relation'] if expect_array: assert 'items' in relation_schema['properties']['data'] data_schema = relation_schema['properties']['data']['items'][ 'properties'] else: assert 'properties' in relation_schema['properties']['data'] data_schema = relation_schema['properties']['data']['properties'] assert data_schema['id']['type'] == 'string' assert data_schema['id']['format'] == 'int64'
def test_no_netloc(mock_schema_request): generator = OpenAPISchemaGenerator( info=openapi.Info(title="Test generator", default_version="v1"), version="v2", url='', ) swagger = generator.get_schema(mock_schema_request, public=True) assert 'host' not in swagger and 'schemes' not in swagger assert swagger['info']['version'] == 'v2'
def test_securiy_requirements(swagger_settings, mock_schema_request): generator = OpenAPISchemaGenerator( info=openapi.Info(title="Test generator", default_version="v1"), version="v2", url='', ) swagger_settings['SECURITY_REQUIREMENTS'] = [] swagger = generator.get_schema(mock_schema_request, public=True) assert swagger['security'] == []
def test_related_resource(read_only): """ Correctly select id from non default pk field for both model and related models """ class ProjectSerializer(serializers.ModelSerializer): class Meta: model = ProjectWithCustomID fields = ('custom_id', 'name', 'archived', 'members', 'owner_member') read_only_fields = ['members', 'owner_member'] if read_only else [] class ProjectViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): queryset = ProjectWithCustomID.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = base.BasicSwaggerAutoSchema router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(request=None, public=True) response_schema = swagger['paths']['/projects/{custom_id}/']['get'][ 'responses']['200']['schema']['properties'] assert 'id' in response_schema['data']['properties'] assert response_schema['data']['properties']['id']['type'] == 'string' assert response_schema['data']['properties']['id']['format'] == 'int32' assert 'type' in response_schema['data']['properties'] assert 'attributes' in response_schema['data']['properties'] assert list(response_schema['data']['properties']['attributes'] ['properties'].keys()) == ['name', 'archived'] assert 'relationships' in response_schema['data']['properties'] relationships_schema = response_schema['data']['properties'][ 'relationships']['properties'] assert list(relationships_schema.keys()) == ['members', 'owner-member'] members_schema = relationships_schema['members']['properties'] assert members_schema['data']['items']['properties']['id'][ 'type'] == 'string' assert members_schema['data']['items']['properties']['id'][ 'format'] == 'int64' assert members_schema['data']['items']['properties']['type'][ 'pattern'] == 'member-with-custom-ids' owner_member_schema = relationships_schema['owner-member']['properties'] assert owner_member_schema['data']['properties']['id']['type'] == 'string' assert owner_member_schema['data']['properties']['id']['format'] == 'int64' assert owner_member_schema['data']['properties']['type'][ 'pattern'] == 'member-with-custom-ids'
def test_invalid_schema_fails(codec_json, mock_schema_request): # noinspection PyTypeChecker bad_generator = OpenAPISchemaGenerator( info=openapi.Info(title="Test generator", default_version="v1", contact=openapi.Contact(name=69, email=[])), version="v2", ) swagger = bad_generator.get_schema(mock_schema_request, True) with pytest.raises(codecs.SwaggerValidationError): codec_json.encode(swagger)
def test_basepath_only(mock_schema_request): generator = OpenAPISchemaGenerator( info=openapi.Info(title="Test generator", default_version="v1"), version="v2", url='/basepath/', ) swagger = generator.get_schema(mock_schema_request, public=True) assert 'host' not in swagger assert 'schemes' not in swagger assert swagger['basePath'] == '/' # base path is not implemented for now assert swagger['info']['version'] == 'v2'
def test_pagination(): class SwaggerAutoSchemaWithPagination(base.BasicSwaggerAutoSchema): paginator_inspectors = [ drf_yasg_json_api.inspectors.DjangoRestResponsePagination, drf_yasg.inspectors.DjangoRestResponsePagination, drf_yasg.inspectors.CoreAPICompatInspector, ] class ProjectSerializer(serializers.ModelSerializer): class Meta: model = test_models.Project fields = ('id', 'name', 'archived', 'members') class ProjectViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): queryset = test_models.Project.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = SwaggerAutoSchemaWithPagination pagination_class = pagination.JsonApiPageNumberPagination router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(request=None, public=True) request_parameters_schema = swagger['paths']['/projects/']['get'][ 'parameters'] assert set( map(operator.itemgetter('name'), request_parameters_schema)) == {'page[number]', 'page[size]'} response_schema = swagger['paths']['/projects/']['get']['responses'][ '200']['schema']['properties'] assert 'id' in response_schema['data']['items']['properties'] assert 'type' in response_schema['data']['items']['properties'] assert 'attributes' in response_schema['data']['items']['properties'] assert 'relationships' in response_schema['data']['items']['properties'] assert 'links' in response_schema assert set(response_schema['links']['properties'].keys()) == { 'first', 'next', 'last', 'prev' } assert 'meta' in response_schema assert 'pagination' in response_schema['meta']['properties'] pagination_response_schema = response_schema['meta']['properties'][ 'pagination']['properties'] assert set(pagination_response_schema.keys()) == {'page', 'pages', 'count'}
def test_post__x_properties(): class XPropertiesSwaggerAutoSchema(drf_yasg_json_api.inspectors.SwaggerAutoSchema): field_inspectors = [ drf_yasg_json_api.inspectors.NamesFormatFilter, drf_yasg_json_api.inspectors.XPropertiesFilter, drf_yasg_json_api.inspectors.InlineSerializerInspector, drf_yasg_json_api.inspectors.IntegerIDFieldInspector, drf_yasg_json_api.inspectors.ManyRelatedFieldInspector, drf_yasg.inspectors.RelatedFieldInspector, drf_yasg.inspectors.SimpleFieldInspector, drf_yasg.inspectors.StringDefaultFieldInspector, ] class ProjectSerializer(serializers.ModelSerializer): class Meta: model = Project fields = ('id', 'name', 'archived', 'members') extra_kwargs = { 'name': {'read_only': True}, 'archived': {'read_only': True}, 'members': {'write_only': True}, } class ProjectViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet): queryset = Project.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = XPropertiesSwaggerAutoSchema router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(None, True) request_body_schema = swagger['paths']['/projects/']['post']['parameters'][0]['schema']['properties'] # TODO: add support for marking whole data/relationships if all children write only # assert 'x-writeOnly' in request_body_schema['data']['properties']['relationships'] members_schema = request_body_schema['data']['properties']['relationships']['properties']['members']['properties'] assert 'x-writeOnly' in members_schema['data']['items']['properties']['id'] response_schema = swagger['paths']['/projects/']['post']['responses']['201']['schema']['properties'] # TODO: add support for marking whole attributes key read_only if all children read only # assert 'x-readOnly' in response_schema['data']['properties']['attributes'] assert 'readOnly' in response_schema['data']['properties']['attributes']['properties']['name'] assert 'readOnly' in response_schema['data']['properties']['attributes']['properties']['archived']
def test_deprecate_universal_inline_serializer(recwarn): import drf_yasg.inspectors import drf_yasg_json_api.inspectors class SwaggerAutoSchema(drf_yasg_json_api.inspectors.SwaggerAutoSchema): field_inspectors = [ drf_yasg_json_api.inspectors.NamesFormatFilter, drf_yasg_json_api.inspectors.InlineSerializerSmartInspector, drf_yasg_json_api.inspectors.IntegerIDFieldInspector, drf_yasg_json_api.inspectors. IntegerPrimaryKeyRelatedFieldInspector, drf_yasg_json_api.inspectors.ManyRelatedFieldInspector, drf_yasg.inspectors.RelatedFieldInspector, drf_yasg.inspectors.SimpleFieldInspector, drf_yasg.inspectors.StringDefaultFieldInspector, ] class ProjectSerializer(serializers.ModelSerializer): class Meta: model = test_models.Project fields = ('id', 'name', 'archived', 'members') class ProjectViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): queryset = test_models.Project.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = SwaggerAutoSchema router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(request=None, public=True) response_schema = swagger['paths']['/projects/{id}/']['get']['responses'][ '200']['schema']['properties'] assert 'id' in response_schema['data']['properties'] assert 'type' in response_schema['data']['properties'] assert 'attributes' in response_schema['data']['properties'] recwarn.pop(DrfYasgJsonApiDeprecationWarning)
def get_schema(self): schema = OpenAPISchemaGenerator( openapi.Info( title="Snippets API", default_version="self.version", description="Test description", terms_of_service="https://www.google.com/policies/terms/", contact=openapi.Contact(email="*****@*****.**"), license=openapi.License(name="BSD License"), ), patterns=self.patterns, version="next", ) request = Request(self.request) schema_obj = schema.get_schema(request=request, public=True) return self._sort_ordered_dict_by_keys(schema_obj)
def test_json_field(): class TestJSONFieldSerializer(serializers.Serializer): json = serializers.JSONField() class JSONViewSet(viewsets.ModelViewSet): serializer_class = TestJSONFieldSerializer router = routers.DefaultRouter() router.register(r'jsons', JSONViewSet, **_basename_or_base_name('jsons')) generator = OpenAPISchemaGenerator(info=openapi.Info( title='Test json field generator', default_version='v1'), patterns=router.urls) swagger = generator.get_schema(None, True) property_schema = swagger["definitions"]["TestJSONField"]["properties"][ "json"] assert property_schema == openapi.Schema(title='Json', type=openapi.TYPE_OBJECT)
def test_strip_write_only(): class ProjectSerializer(serializers.ModelSerializer): class Meta: model = test_models.Project fields = ('id', 'name', 'archived', 'members') extra_kwargs = { 'name': { 'write_only': False }, 'archived': { 'write_only': True }, 'members': { 'write_only': True }, } class ProjectViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): queryset = test_models.Project.objects.all() serializer_class = ProjectSerializer renderer_classes = [renderers.JSONRenderer] parser_classes = [parsers.JSONParser] swagger_schema = base.BasicSwaggerAutoSchema router = routers.DefaultRouter() router.register(r'projects', ProjectViewSet, **compatibility._basename_or_base_name('projects')) generator = OpenAPISchemaGenerator(info=openapi.Info(title="", default_version=""), patterns=router.urls) swagger = generator.get_schema(request=None, public=True) response_schema = swagger['paths']['/projects/{id}/']['get']['responses'][ '200']['schema']['properties'] assert 'id' in response_schema['data']['properties'] assert 'type' in response_schema['data']['properties'] assert list(response_schema['data']['properties']['attributes'] ['properties'].keys()) == ['name'] assert 'relationships' not in response_schema['data']['properties']
def test_choice_field(choices, expected_type): class DetailSerializer(serializers.Serializer): detail = serializers.ChoiceField(choices) class DetailViewSet(viewsets.ViewSet): @swagger_auto_schema(responses={200: openapi.Response("OK", DetailSerializer)}) def retrieve(self, request, pk=None): return Response({'detail': None}) router = routers.DefaultRouter() router.register(r'details', DetailViewSet, **_basename_or_base_name('details')) generator = OpenAPISchemaGenerator( info=openapi.Info(title="Test generator", default_version="v1"), patterns=router.urls ) swagger = generator.get_schema(None, True) property_schema = swagger['definitions']['Detail']['properties']['detail'] assert property_schema == openapi.Schema(title='Detail', type=expected_type, enum=choices)