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_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)
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
    endpoints = generator.get_endpoints(None)
    assert len(endpoints["/test/"][1]) == 1
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,
                    **_basename_or_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"
Example #5
0
def test_noop_inspectors(
    swagger_settings, mock_schema_request, codec_json, reference_schema, compare_schemas
):
    from drf_yasg2 import app_settings

    def set_inspectors(inspectors, setting_name):
        inspectors = [__name__ + "." + inspector.__name__ for inspector in inspectors]
        swagger_settings[setting_name] = (
            inspectors + app_settings.SWAGGER_DEFAULTS[setting_name]
        )

    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)
Example #6
0
def test_no_form_parameters_with_non_form_parsers():
    # see https://github.com/joellefkowitz/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_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_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"
Example #10
0
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)
Example #11
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)
Example #12
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)
Example #13
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"""

        @swagger_auto_schema(operation_id="mapping_post")
        @action_main.mapping.post
        def action_post(self, request):
            """mapping docstring post"""

    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"
Example #14
0
def swagger(mock_schema_request):
    generator = OpenAPISchemaGenerator(
        info=openapi.Info(title="Test generator", default_version="v1"),
        version="v2",
    )
    return generator.get_schema(mock_schema_request, True)
Example #15
0
    Finding, JIRA_Instance, JIRA_Issue, DojoMeta, Note_Type, Notes, Product_Type, Product, Regulation, \
    ScanSettings, Scan, Sonarqube_Issue, Sonarqube_Product, Sonarqube_Issue_Transition, \
    Stub_Finding, System_Settings, Test_Type, Test, Tool_Configuration, Tool_Product_Settings, \
    Tool_Type, Dojo_User, JIRA_Project, App_Analysis

from dojo.api_v2.serializers import \
    DevelopmentEnvironmentSerializer, EndpointStatusSerializer, EndpointSerializer, \
    EngagementSerializer, FindingTemplateSerializer, FindingSerializer, \
    JIRAInstanceSerializer, JIRAIssueSerializer, JIRAProjectSerializer, MetaSerializer, NoteTypeSerializer, \
    ProductSerializer, RegulationSerializer, ScanSettingsSerializer,  \
    ScanSerializer, SonarqubeIssueSerializer, SonarqubeProductSerializer, SonarqubeIssueTransitionSerializer, \
    StubFindingSerializer, SystemSettingsSerializer, TestTypeSerializer, TestSerializer, ToolConfigurationSerializer, \
    ToolProductSettingsSerializer, ToolTypeSerializer, UserSerializer, NoteSerializer, ProductTypeSerializer, \
    AppAnalysisSerializer

SWAGGER_SCHEMA_GENERATOR = OpenAPISchemaGenerator(Info("defectdojo", "v2"))
BASE_API_URL = "/api/v2"


def testIsBroken(method):
    return tag("broken")(method)


def skipIfNotSubclass(baseclass):
    def decorate(f):
        def wrapper(self, *args, **kwargs):
            if not issubclass(self.viewset, baseclass):
                self.skipTest('This view is not %s' % baseclass)
            else:
                f(self, *args, **kwargs)
        return wrapper