Beispiel #1
0
    def test_unit__exception_handler__error__error_content_malformed(self):
        class MyException(Exception):
            pass

        class MyErrorBuilder(MarshmallowDefaultErrorBuilder):
            def build_from_exception(
                self, exception: Exception, include_traceback: bool = False
            ) -> dict:
                # this is not matching with DefaultErrorBuilder schema
                return {}

        context = AgnosticContext(app=None)
        error_builder = MyErrorBuilder()
        wrapper = ExceptionHandlerControllerWrapper(
            MyException,
            context,
            error_builder=error_builder,
            processor_factory=lambda schema_: MarshmallowProcessor(error_builder.get_schema()),
        )

        def raise_it():
            raise MyException()

        wrapper = wrapper.get_wrapper(raise_it)
        with pytest.raises(OutputValidationException):
            wrapper()
    async def test_unit__handle_exception_with_default_error_builder__ok__serpyco(
            self, test_client):
        from hapic.error.serpyco import SerpycoDefaultErrorBuilder
        from hapic.processor.serpyco import SerpycoProcessor

        app = AgnosticApp()
        hapic = Hapic()
        hapic.set_processor_class(SerpycoProcessor)
        hapic.set_context(
            AgnosticContext(
                app, default_error_builder=SerpycoDefaultErrorBuilder()))

        @hapic.with_api_doc()
        @hapic.handle_exception(ZeroDivisionError, http_code=400)
        def my_view():
            1 / 0

        response = my_view()
        json_ = json.loads(response.body)
        assert {
            "code": None,
            "details": {
                "error_detail": {}
            },
            "message": "division by zero",
        } == json_
Beispiel #3
0
    def test_unit__exception_handled__ok__exception_error_dict(self):
        class MyException(Exception):
            def __init__(self, *args, **kwargs):
                super().__init__(*args, **kwargs)
                self.error_dict = {}

        context = AgnosticContext(app=None)
        error_builder = MarshmallowDefaultErrorBuilder()
        wrapper = ExceptionHandlerControllerWrapper(
            MyException,
            context,
            error_builder=error_builder,
            http_code=HTTPStatus.INTERNAL_SERVER_ERROR,
            processor_factory=lambda schema_: MarshmallowProcessor(error_builder.get_schema()),
        )

        @wrapper.get_wrapper
        def func(foo):
            exc = MyException("We are testing")
            exc.error_detail = {"foo": "bar"}
            raise exc

        response = func(42)
        assert response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR
        assert {
            "message": "We are testing",
            "details": {"error_detail": {"foo": "bar"}},
            "code": None,
        } == json.loads(response.body)
Beispiel #4
0
    def test_func__schema_in_doc__ok__many_case(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MySchema(marshmallow.Schema):
            name = marshmallow.fields.String(required=True)

        @hapic.with_api_doc()
        @hapic.input_body(MySchema(many=True))
        def my_controller():
            return {"name": "test"}

        app.route("/paper", method="POST", callback=my_controller)
        doc = hapic.generate_doc()

        assert doc.get("definitions", {}).get("MySchema", {})
        schema_def = doc.get("definitions", {}).get("MySchema", {})
        assert schema_def.get("properties", {}).get("name", {}).get("type")

        assert doc.get("paths").get("/paper").get("post").get("parameters")[0]
        schema_ref = doc.get("paths").get("/paper").get("post").get(
            "parameters")[0]
        assert schema_ref.get("in") == "body"
        assert schema_ref.get("name") == "body"
        assert schema_ref["schema"] == {
            "items": {
                "$ref": "#/definitions/MySchema"
            },
            "type": "array",
        }
Beispiel #5
0
    def test_func__schema_with_many__ok__with_exclude(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MySchema(marshmallow.Schema):
            first_name = marshmallow.fields.String(required=True)
            last_name = marshmallow.fields.String(required=False)

        @hapic.with_api_doc()
        @hapic.output_body(MySchema(many=True, exclude=("last_name", )))
        def my_controller(hapic_data=None):
            pass

        app.route("/", method="GET", callback=my_controller)
        doc = hapic.generate_doc()

        assert {
            "MySchema_without_last_name": {
                "type": "object",
                "properties": {
                    "first_name": {
                        "type": "string"
                    }
                },
                "required": ["first_name"],
            }
        } == doc["definitions"]
    def test_unit__input_files__ok__file_is_not_present(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        hapic.set_context(
            AgnosticContext(
                app=None,
                files_parameters={
                    # No file here
                },
            )
        )

        class MySchema(marshmallow.Schema):
            file_abc = marshmallow.fields.Raw(required=True)

        @hapic.input_files(MySchema())
        def my_controller(hapic_data=None):
            assert hapic_data
            assert hapic_data.files
            return "OK"

        result = my_controller()
        assert HTTPStatus.BAD_REQUEST == result.status_code
        assert {
            "http_code": 400,
            "original_error": {
                "details": {"file_abc": ["Missing data for required field"]},
                "message": "Validation error of input data",
            },
        } == json.loads(result.body)
Beispiel #7
0
    def test_func__errors__http_status_as_int_description(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MyException(Exception):
            pass

        @hapic.with_api_doc()
        @hapic.handle_exception(MyException, http_code=400)
        def my_controller(hapic_data=None):
            assert hapic_data

        app.route("/upload", method="POST", callback=my_controller)
        doc = hapic.generate_doc()

        assert doc.get("paths")
        assert "/upload" in doc["paths"]
        assert "post" in doc["paths"]["/upload"]
        assert "responses" in doc["paths"]["/upload"]["post"]
        assert "400" in doc["paths"]["/upload"]["post"]["responses"]
        assert {
            "description": "400",
            "schema": {
                "$ref": "#/definitions/DefaultErrorSchema"
            },
        } == doc["paths"]["/upload"]["post"]["responses"]["400"]
Beispiel #8
0
    def test_func_schema_in_doc__ok__additionals_fields__file(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MySchema(marshmallow.Schema):
            category = marshmallow.fields.Raw(required=True,
                                              description="a description",
                                              example="00010")

        @hapic.with_api_doc()
        @hapic.input_files(MySchema())
        def my_controller():
            return

        app.route("/upload", method="POST", callback=my_controller)
        doc = hapic.generate_doc()
        assert doc
        assert "/upload" in doc["paths"]
        assert "consumes" in doc["paths"]["/upload"]["post"]
        assert "multipart/form-data" in doc["paths"]["/upload"]["post"][
            "consumes"]
        assert doc.get("paths").get("/upload").get("post").get("parameters")[0]
        field = doc.get("paths").get("/upload").get("post").get(
            "parameters")[0]
        assert field[
            "description"] == "a description\n\n*example value: 00010*"
        # INFO - G.M - 01-06-2018 - Field example not allowed here,
        # added in description instead
        assert "example" not in field
        assert field["in"] == "formData"
        assert field["type"] == "file"
        assert field["required"] is True
Beispiel #9
0
    def test_func__input_files_doc__ok__one_file(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MySchema(marshmallow.Schema):
            file_abc = marshmallow.fields.Raw(required=True)

        @hapic.with_api_doc()
        @hapic.input_files(MySchema())
        def my_controller(hapic_data=None):
            assert hapic_data
            assert hapic_data.files

        app.route("/upload", method="POST", callback=my_controller)
        doc = hapic.generate_doc()

        assert doc
        assert "/upload" in doc["paths"]
        assert "consumes" in doc["paths"]["/upload"]["post"]
        assert "multipart/form-data" in doc["paths"]["/upload"]["post"][
            "consumes"]
        assert "parameters" in doc["paths"]["/upload"]["post"]
        assert {
            "name": "file_abc",
            "required": True,
            "in": "formData",
            "type": "file"
        } in doc["paths"]["/upload"]["post"]["parameters"]
Beispiel #10
0
    def test_unit__base_controller_wrapper__ok__no_behaviour(self):
        context = AgnosticContext(app=None)
        processor = MyProcessor()
        wrapper = InputOutputControllerWrapper(context, lambda: processor)

        @wrapper.get_wrapper
        def func(foo):
            return foo

        result = func(42)
        assert result == 42
Beispiel #11
0
    def test_func__errors__multiple_same_http_status_description(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MyFirstException(Exception):
            pass

        class MySecondException(Exception):
            "Just a docstring"

        class MyThirdException(Exception):
            "Docstring not used"
            pass

        class MyFourthException(Exception):
            pass

        @hapic.with_api_doc()
        @hapic.handle_exception(MyFirstException,
                                http_code=HTTPStatus.BAD_REQUEST)
        @hapic.handle_exception(MySecondException,
                                http_code=HTTPStatus.BAD_REQUEST)
        @hapic.handle_exception(MyThirdException,
                                http_code=HTTPStatus.BAD_REQUEST,
                                description="explicit description")
        @hapic.handle_exception(MyFourthException, http_code=400)
        def my_controller(hapic_data=None):
            assert hapic_data

        app.route("/upload", method="POST", callback=my_controller)
        doc = hapic.generate_doc()

        assert doc.get("paths")
        assert "/upload" in doc["paths"]
        assert "post" in doc["paths"]["/upload"]
        assert "responses" in doc["paths"]["/upload"]["post"]
        assert "400" in doc["paths"]["/upload"]["post"]["responses"]
        assert "description"

        assert doc["paths"]["/upload"]["post"]["responses"]["400"][
            "description"]
        descriptions = doc["paths"]["/upload"]["post"]["responses"]["400"][
            "description"].split("\n\n")
        assert "BAD_REQUEST: Bad request syntax or unsupported method" in descriptions
        assert "explicit description" in descriptions
        assert "400" in descriptions
        assert "Just a docstring" in descriptions
        assert "Docstring not used" not in descriptions
        assert doc["paths"]["/upload"]["post"]["responses"]["400"]["schema"]
        assert {
            "$ref": "#/definitions/DefaultErrorSchema"
        } == doc["paths"]["/upload"]["post"]["responses"]["400"]["schema"]
Beispiel #12
0
    def test_unit__base_controller__ok__replaced_response(self):
        context = AgnosticContext(app=None)
        processor = MyProcessor()
        wrapper = MyControllerWrapper(context, lambda: processor)

        @wrapper.get_wrapper
        def func(foo):
            return foo

        # see MyControllerWrapper#before_wrapped_func
        result = func(666)
        # result have been replaced by MyControllerWrapper#before_wrapped_func
        assert {"error_response": "we are testing"} == result
Beispiel #13
0
    def test_unit__controller_wrapper__ok__overload_input(self):
        context = AgnosticContext(app=None)
        processor = MyProcessor()
        wrapper = MyControllerWrapper(context, lambda: processor)

        @wrapper.get_wrapper
        def func(foo, added_parameter=None):
            # see MyControllerWrapper#before_wrapped_func
            assert added_parameter == "a value"
            return foo

        result = func(42)
        # See MyControllerWrapper#after_wrapped_function
        assert result == 84
Beispiel #14
0
    def test_unit__output_data_wrapping__ok__nominal_case(self):
        context = AgnosticContext(app=None)
        processor = MyProcessor()
        wrapper = OutputControllerWrapper(context, lambda: processor)

        @wrapper.get_wrapper
        def func(foo, hapic_data=None):
            # If no use of input wrapper, no hapic_data is given
            assert not hapic_data
            return foo

        result = func(42)
        assert HTTPStatus.OK == result.status_code
        assert "43" == result.body
    def test_unit__input_files__ok__file_is_present(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        hapic.set_context(AgnosticContext(app=None, files_parameters={"file_abc": "10101010101"}))

        class MySchema(marshmallow.Schema):
            file_abc = marshmallow.fields.Raw(required=True)

        @hapic.input_files(MySchema())
        def my_controller(hapic_data=None):
            assert hapic_data
            assert hapic_data.files
            return "OK"

        result = my_controller()
        assert "OK" == result
Beispiel #16
0
    def test_unit__input_data_wrapping__ok__nominal_case(self):
        context = AgnosticContext(app=None, query_parameters=MultiDict((("foo", "bar"),)))
        processor = MyProcessor()
        wrapper = MyInputQueryControllerWrapper(context, lambda: processor)

        @wrapper.get_wrapper
        def func(foo, hapic_data=None):
            assert hapic_data
            assert isinstance(hapic_data, HapicData)
            # see MyControllerWrapper#before_wrapped_func
            assert hapic_data.query == {"foo": "bar"}
            return foo

        result = func(42)
        assert result == 42
Beispiel #17
0
    def test_func_schema_in_doc__ok__additionals_fields__forms__string(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MySchema(marshmallow.Schema):
            category = marshmallow.fields.String(
                required=True,
                description="a description",
                example="00010",
                format="binary",
                enum=["01000", "11111"],
                maxLength=5,
                minLength=5,
                # Theses none string specific parameters should disappear
                # in query/path
                maximum=400,
                # exclusiveMaximun=False,
                # minimum=0,
                # exclusiveMinimum=True,
                # multipleOf=1,
            )

        @hapic.with_api_doc()
        @hapic.input_forms(MySchema())
        def my_controller():
            return

        app.route("/paper", method="POST", callback=my_controller)
        doc = hapic.generate_doc()
        assert "multipart/form-data" in doc["paths"]["/paper"]["post"][
            "consumes"]
        assert doc.get("paths").get("/paper").get("post").get("parameters")[0]
        field = doc.get("paths").get("/paper").get("post").get("parameters")[0]
        assert field[
            "description"] == "a description\n\n*example value: 00010*"
        # INFO - G.M - 01-06-2018 - Field example not allowed here,
        # added in description instead
        assert "example" not in field
        assert field["format"] == "binary"
        assert field["in"] == "formData"
        assert field["type"] == "string"
        assert field["maxLength"] == 5
        assert field["minLength"] == 5
        assert field["required"] is True
        assert field["enum"] == ["01000", "11111"]
        assert "maximum" not in field
Beispiel #18
0
    def test_unit__multi_query_param_values__ok__without_as_list(self):
        context = AgnosticContext(
            app=None, query_parameters=MultiDict((("user_id", "abc"), ("user_id", "def")))
        )
        processor = MySimpleProcessor()
        wrapper = InputQueryControllerWrapper(context, lambda: processor)

        @wrapper.get_wrapper
        def func(hapic_data=None):
            assert hapic_data
            assert isinstance(hapic_data, HapicData)
            # see MyControllerWrapper#before_wrapped_func
            assert "abc" == hapic_data.query.get("user_id")
            return hapic_data.query.get("user_id")

        result = func()
        assert result == "abc"
Beispiel #19
0
    def test_func__output_file_doc__ok__nominal_case(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        @hapic.with_api_doc()
        @hapic.output_file(["image/jpeg"])
        def my_controller():
            return b"101010100101"

        app.route("/avatar", method="GET", callback=my_controller)
        doc = hapic.generate_doc()

        assert doc
        assert "/avatar" in doc["paths"]
        assert "produces" in doc["paths"]["/avatar"]["get"]
        assert "image/jpeg" in doc["paths"]["/avatar"]["get"]["produces"]
        assert "200" in doc["paths"]["/avatar"]["get"]["responses"]
Beispiel #20
0
    def test_func__tags__ok__nominal_case(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        @hapic.with_api_doc(tags=["foo", "bar"])
        def my_controller(hapic_data=None):
            assert hapic_data
            assert hapic_data.files

        app.route("/upload", method="POST", callback=my_controller)
        doc = hapic.generate_doc()

        assert doc.get("paths")
        assert "/upload" in doc["paths"]
        assert "post" in doc["paths"]["/upload"]
        assert "tags" in doc["paths"]["/upload"]["post"]
        assert ["foo", "bar"] == doc["paths"]["/upload"]["post"]["tags"]
Beispiel #21
0
    def test_func_schema_in_doc__ok__additionals_fields__path__number(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MySchema(marshmallow.Schema):
            category = marshmallow.fields.Integer(
                required=True,
                description="a number",
                example="12",
                format="int64",
                enum=[4, 6],
                # Theses none string specific parameters should disappear
                # in query/path
                maximum=14,
                exclusiveMaximun=False,
                minimum=0,
                exclusiveMinimum=True,
                multipleOf=2,
            )

        @hapic.with_api_doc()
        @hapic.input_path(MySchema())
        def my_controller():
            return

        app.route("/paper", method="POST", callback=my_controller)
        doc = hapic.generate_doc()
        assert doc.get("paths").get("/paper").get("post").get("parameters")[0]
        field = doc.get("paths").get("/paper").get("post").get("parameters")[0]
        assert field["description"] == "a number\n\n*example value: 12*"
        # INFO - G.M - 01-06-2018 - Field example not allowed here,
        # added in description instead
        assert "example" not in field
        assert field["format"] == "int64"
        assert field["in"] == "path"
        assert field["type"] == "integer"
        assert field["maximum"] == 14
        assert field["minimum"] == 0
        assert field["exclusiveMinimum"] is True
        assert field["required"] is True
        assert field["enum"] == [4, 6]
        assert field["multipleOf"] == 2
Beispiel #22
0
    def test_unit__output_data_wrapping__fail__error_response(self):
        context = AgnosticContext(app=None)
        processor = MarshmallowProcessor()
        processor.set_schema(MySchema())
        wrapper = OutputControllerWrapper(context, lambda: processor)

        @wrapper.get_wrapper
        def func(foo):
            return "wrong result format"

        result = func(42)
        assert HTTPStatus.INTERNAL_SERVER_ERROR == result.status_code
        assert {
            "original_error": {
                "details": {"name": ["Missing data for required field."]},
                "message": "Validation error of output data",
            },
            "http_code": 500,
        } == json.loads(result.body)
Beispiel #23
0
    def test_func_schema_in_doc__ok__additionals_fields__body__number(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MySchema(marshmallow.Schema):
            category = marshmallow.fields.Integer(
                required=True,
                description="a number",
                example="12",
                format="int64",
                enum=[4, 6],
                # Theses none string specific parameters should disappear
                # in query/path
                maximum=14,
                exclusiveMaximun=False,
                minimum=0,
                exclusiveMinimum=True,
                multipleOf=2,
            )

        @hapic.with_api_doc()
        @hapic.input_body(MySchema())
        def my_controller():
            return

        app.route("/paper", method="POST", callback=my_controller)
        doc = hapic.generate_doc()

        schema_field = (doc.get("definitions",
                                {}).get("MySchema",
                                        {}).get("properties",
                                                {}).get("category", {}))
        assert schema_field
        assert schema_field["description"] == "a number"
        assert schema_field["example"] == "12"
        assert schema_field["format"] == "int64"
        assert schema_field["type"] == "integer"
        assert schema_field["maximum"] == 14
        assert schema_field["minimum"] == 0
        assert schema_field["exclusiveMinimum"] is True
        assert schema_field["enum"] == [4, 6]
        assert schema_field["multipleOf"] == 2
Beispiel #24
0
    def test_func__docstring__ok__simple_case(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        @hapic.with_api_doc()
        def my_controller(hapic_data=None):
            """
            Hello doc
            """
            assert hapic_data
            assert hapic_data.files

        app.route("/upload", method="POST", callback=my_controller)
        doc = hapic.generate_doc()

        assert doc.get("paths")
        assert "/upload" in doc["paths"]
        assert "post" in doc["paths"]["/upload"]
        assert "description" in doc["paths"]["/upload"]["post"]
        assert "Hello doc" == doc["paths"]["/upload"]["post"]["description"]
Beispiel #25
0
    def test_func__schema_in_doc__ok__many_and_exclude_case(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MySchema(marshmallow.Schema):
            name = marshmallow.fields.String(required=True)
            name2 = marshmallow.fields.String(required=True)

        @hapic.with_api_doc()
        @hapic.input_body(MySchema(exclude=("name2", ), many=True))
        def my_controller():
            return {"name": "test"}

        app.route("/paper", method="POST", callback=my_controller)
        doc = hapic.generate_doc()

        definitions = doc.get("definitions", {})
        # TODO - G-M - Find better way to find our new schema
        # Do Better test when we were able to set correctly schema name
        # according to content
        schema_name = None
        for elem in definitions.keys():
            if elem != "MySchema":
                schema_name = elem
                break
        assert schema_name
        schema_def = definitions[schema_name]
        assert schema_def.get("properties", {}).get("name",
                                                    {}).get("type") == "string"
        assert doc.get("paths").get("/paper").get("post").get("parameters")[0]
        schema_ref = doc.get("paths").get("/paper").get("post").get(
            "parameters")[0]
        assert schema_ref.get("in") == "body"
        assert schema_ref["schema"] == {
            "items": {
                "$ref": "#/definitions/{}".format(schema_name)
            },
            "type": "array",
        }
Beispiel #26
0
    def test_unit__exception_handled__ok__nominal_case(self):
        context = AgnosticContext(app=None)
        error_builder = MarshmallowDefaultErrorBuilder()
        wrapper = ExceptionHandlerControllerWrapper(
            ZeroDivisionError,
            context,
            error_builder=error_builder,
            http_code=HTTPStatus.INTERNAL_SERVER_ERROR,
            processor_factory=lambda schema_: MarshmallowProcessor(error_builder.get_schema()),
        )

        @wrapper.get_wrapper
        def func(foo):
            raise ZeroDivisionError("We are testing")

        response = func(42)
        assert HTTPStatus.INTERNAL_SERVER_ERROR == response.status_code
        assert {
            "details": {"error_detail": {}},
            "message": "We are testing",
            "code": None,
        } == json.loads(response.body)
Beispiel #27
0
    def test_func__enum__nominal_case(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MySchema(marshmallow.Schema):
            category = marshmallow.fields.String(
                validate=OneOf(["foo", "bar"]))

        @hapic.with_api_doc()
        @hapic.input_body(MySchema())
        def my_controller():
            return

        app.route("/paper", method="POST", callback=my_controller)
        doc = hapic.generate_doc()

        assert ["foo",
                "bar"] == doc.get("definitions",
                                  {}).get("MySchema",
                                          {}).get("properties",
                                                  {}).get("category",
                                                          {}).get("enum")
    def test_unit__handle_exception_with_default_error_builder__ok__marshmallow(
            self):
        app = AgnosticApp()
        hapic = Hapic()
        hapic.set_processor_class(MarshmallowProcessor)
        hapic.set_context(
            AgnosticContext(
                app, default_error_builder=MarshmallowDefaultErrorBuilder()))

        @hapic.with_api_doc()
        @hapic.handle_exception(ZeroDivisionError, http_code=400)
        def my_view():
            1 / 0

        response = my_view()
        json_ = json.loads(response.body)
        assert {
            "code": None,
            "details": {
                "error_detail": {}
            },
            "message": "division by zero",
        } == json_
Beispiel #29
0
    def test_func__errors__nominal_case(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        @hapic.with_api_doc()
        @hapic.handle_exception()
        def my_controller(hapic_data=None):
            assert hapic_data

        app.route("/upload", method="POST", callback=my_controller)
        doc = hapic.generate_doc()

        assert doc.get("paths")
        assert "/upload" in doc["paths"]
        assert "post" in doc["paths"]["/upload"]
        assert "responses" in doc["paths"]["/upload"]["post"]
        assert "500" in doc["paths"]["/upload"]["post"]["responses"]
        assert {
            "description": Exception.__doc__,
            "schema": {
                "$ref": "#/definitions/DefaultErrorSchema"
            },
        } == doc["paths"]["/upload"]["post"]["responses"]["500"]
Beispiel #30
0
    def test_func_schema_in_doc__ok__additionals_fields__body__string(self):
        hapic = Hapic(processor_class=MarshmallowProcessor)
        app = AgnosticApp()
        hapic.set_context(AgnosticContext(app=app))

        class MySchema(marshmallow.Schema):
            category = marshmallow.fields.String(
                required=True,
                description="a description",
                example="00010",
                format="binary",
                enum=["01000", "11111"],
                maxLength=5,
                minLength=5,
            )

        @hapic.with_api_doc()
        @hapic.input_body(MySchema())
        def my_controller():
            return

        app.route("/paper", method="POST", callback=my_controller)
        doc = hapic.generate_doc()

        schema_field = (doc.get("definitions",
                                {}).get("MySchema",
                                        {}).get("properties",
                                                {}).get("category", {}))
        assert schema_field
        assert schema_field["description"] == "a description"
        assert schema_field["example"] == "00010"
        assert schema_field["format"] == "binary"
        assert schema_field["type"] == "string"
        assert schema_field["maxLength"] == 5
        assert schema_field["minLength"] == 5
        assert schema_field["enum"] == ["01000", "11111"]