From b15535995fd6234feb4ffe13fbf26291aa095359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristi=20V=C3=AEjdea?= Date: Sun, 23 Dec 2018 15:32:06 +0200 Subject: [PATCH] Add assertion against TYPE_ARRAY with no items --- src/drf_yasg/openapi.py | 35 ++++++++++++++++++----------------- testproj/users/views.py | 2 ++ tests/reference.yaml | 8 ++++++++ 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/src/drf_yasg/openapi.py b/src/drf_yasg/openapi.py index e2ac52f..51c526d 100644 --- a/src/drf_yasg/openapi.py +++ b/src/drf_yasg/openapi.py @@ -373,6 +373,17 @@ class Operation(SwaggerDict): self._insert_extras__() +def _check_type(type, format, enum, pattern, items, _obj_type): + if items and type != TYPE_ARRAY: + raise AssertionError("items can only be used when type is array") + if type == TYPE_ARRAY and not items: + raise AssertionError("TYPE_ARRAY requires the items attribute") + if pattern and type != TYPE_STRING: + raise AssertionError("pattern can only be used when type is string") + if (format or enum or pattern) and type in (TYPE_OBJECT, TYPE_ARRAY, None): + raise AssertionError("[format, enum, pattern] can only be applied to primitive " + _obj_type) + + class Items(SwaggerDict): def __init__(self, type=None, format=None, enum=None, pattern=None, items=None, **extra): """Used when defining an array :class:`.Parameter` to describe the array elements. @@ -391,10 +402,7 @@ class Items(SwaggerDict): self.pattern = pattern self.items = items self._insert_extras__() - if items and type != TYPE_ARRAY: - raise AssertionError("items can only be used when type is array") - if pattern and type != TYPE_STRING: - raise AssertionError("pattern can only be used when type is string") + _check_type(type, format, enum, pattern, items, self.__class__) class Parameter(SwaggerDict): @@ -439,12 +447,9 @@ class Parameter(SwaggerDict): self.required = True if self['in'] != IN_BODY and schema is not None: raise AssertionError("schema can only be applied to a body Parameter, not %s" % type) - if (format or enum or pattern or default) and not type: - raise AssertionError("[format, enum, pattern, default] can only be applied to non-body Parameter") - if items and type != TYPE_ARRAY: - raise AssertionError("items can only be used when type is array") - if pattern and type != TYPE_STRING: - raise AssertionError("pattern can only be used when type is string") + if default and not type: + raise AssertionError("default can only be applied to a non-body Parameter") + _check_type(type, format, enum, pattern, items, self.__class__) class Schema(SwaggerDict): @@ -493,12 +498,7 @@ class Schema(SwaggerDict): self._insert_extras__() if (properties or (additional_properties is not None)) and type != TYPE_OBJECT: raise AssertionError("only object Schema can have properties") - if (format or enum or pattern) and type in (TYPE_OBJECT, TYPE_ARRAY): - raise AssertionError("[format, enum, pattern] can only be applied to primitive Schema") - if items and type != TYPE_ARRAY: - raise AssertionError("items can only be used when type is array") - if pattern and type != TYPE_STRING: - raise AssertionError("pattern can only be used when type is string") + _check_type(type, format, enum, pattern, items, self.__class__) def _remove_read_only(self): # readOnly is only valid for Schemas inside another Schema's properties; @@ -595,7 +595,8 @@ class Response(SwaggerDict): :param str description: response description :param schema: sturcture of the response body - :type schema: Schema or SchemaRef + :type schema: Schema or SchemaRef or rest_framework.serializers.Serializer + or type[rest_framework.serializers.Serializer] :param dict examples: example bodies mapped by mime type """ super(Response, self).__init__(**extra) diff --git a/testproj/users/views.py b/testproj/users/views.py index d7251f4..1b1f065 100644 --- a/testproj/users/views.py +++ b/testproj/users/views.py @@ -49,6 +49,8 @@ class UserList(APIView): @swagger_auto_schema(method='put', request_body=UserSerializerrr, tags=['Users']) @swagger_auto_schema(methods=['get'], manual_parameters=[ openapi.Parameter('test', openapi.IN_QUERY, "test manual param", type=openapi.TYPE_BOOLEAN), + openapi.Parameter('test_array', openapi.IN_QUERY, "test query array arg", type=openapi.TYPE_ARRAY, + items=openapi.Items(type=openapi.TYPE_STRING), required=True, collection_format='multi'), ], responses={ 200: openapi.Response('response description', UserSerializerrr), }, tags=['Users']) diff --git a/tests/reference.yaml b/tests/reference.yaml index 95800b8..c0d8d7e 100644 --- a/tests/reference.yaml +++ b/tests/reference.yaml @@ -814,6 +814,14 @@ paths: in: query description: test manual param type: boolean + - name: test_array + in: query + description: test query array arg + required: true + type: array + items: + type: string + collectionFormat: multi responses: '200': description: response description