Esempio n. 1
0
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)
Esempio n. 3
0
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'}
Esempio n. 4
0
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']
Esempio n. 5
0
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)
Esempio n. 6
0
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']
Esempio n. 7
0
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)
Esempio n. 8
0
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']
Esempio n. 9
0
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'
Esempio n. 10
0
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"
Esempio n. 12
0
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']
Esempio n. 13
0
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
Esempio n. 16
0
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]'
Esempio n. 17
0
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)
Esempio n. 23
0
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'
Esempio n. 24
0
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'}
Esempio n. 25
0
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']
Esempio n. 26
0
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)
Esempio n. 27
0
    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)
Esempio n. 28
0
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)
Esempio n. 29
0
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']
Esempio n. 30
0
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)