示例#1
0
    async def test_set_etag_method_not_allowed_warning(self, app, method,
                                                       etag_disabled):
        app.config['ETAG_DISABLED'] = etag_disabled
        blp = Blueprint('test', __name__)

        with mock.patch.object(app.logger, 'warning') as mock_warning:
            async with app.test_request_context('/', method=method):
                blp.set_etag(None)
            if method in ['GET', 'HEAD', 'POST', 'PUT', 'PATCH']:
                assert not mock_warning.called
            else:
                assert mock_warning.called
示例#2
0
    async def test_etag_set_etag_in_response(self, app, schemas, paginate):
        blp = Blueprint('test', __name__)
        etag_schema = schemas.DocEtagSchema
        item = {'item_id': 1, 'db_field': 0}
        if paginate:
            extra_data = (('X-Pagination', 'Dummy pagination header'), )
        else:
            extra_data = tuple()
        etag = blp._generate_etag(item, extra_data=extra_data)
        etag_with_schema = blp._generate_etag(item,
                                              etag_schema,
                                              extra_data=extra_data)

        async with app.test_request_context('/'):
            resp = Response([])
            if extra_data:
                resp.headers['X-Pagination'] = 'Dummy pagination header'
            get_appcontext()['result_dump'] = item
            blp._set_etag_in_response(resp, None)
            assert resp.get_etag() == (etag, False)

        async with app.test_request_context('/'):
            resp = Response([])
            if extra_data:
                resp.headers['X-Pagination'] = 'Dummy pagination header'
            get_appcontext()['result_raw'] = item
            blp._set_etag_in_response(resp, etag_schema)
            assert resp.get_etag() == (etag_with_schema, False)
示例#3
0
    def test_blueprint_arguments_content_type(self, app, schemas, location,
                                              content_type, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        content_type = content_type or REQUEST_BODY_CONTENT_TYPE[location]

        @blp.route('/')
        @blp.arguments(schemas.DocSchema,
                       location=location,
                       content_type=content_type)
        def func():
            """Dummy view func"""

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        get = spec['paths']['/test/']['get']
        if openapi_version == '3.0.2':
            assert len(get['requestBody']['content']) == 1
            assert content_type in get['requestBody']['content']
        else:
            if content_type != 'application/json':
                assert get['consumes'] == [content_type]
            else:
                assert 'consumes' not in get
示例#4
0
    def test_blueprint_arguments_examples(self, app, schemas, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        example = {'field': 12}
        examples = {'example 1': {'field': 12}, 'example 2': {'field': 42}}

        @blp.route('/example')
        @blp.arguments(schemas.DocSchema, example=example)
        def func_example():
            """Dummy view func"""

        @blp.route('/examples')
        @blp.arguments(schemas.DocSchema, examples=examples)
        def func_examples():
            """Dummy view func"""

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        get = spec['paths']['/test/example']['get']
        assert (get['requestBody']['content']['application/json']['example'] ==
                example)
        get = spec['paths']['/test/examples']['get']
        assert (get['requestBody']['content']['application/json']['examples']
                == examples)
示例#5
0
    def test_blueprint_response_examples(self, app, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', 'test', url_prefix='/test')

        examples = {
            'example 1': {
                'summary': 'Example 1',
                'value': {
                    'name': 'One'
                }
            },
            'example 2': {
                'summary': 'Example 2',
                'value': {
                    'name': 'Two'
                }
            },
        }

        @blp.route('/')
        @blp.response(examples=examples)
        def func():
            pass

        api.register_blueprint(blp)

        get = api.spec.to_dict()['paths']['/test/']['get']
        assert get['responses']['200']['content']['application/json'][
            'examples'] == examples
示例#6
0
    async def test_blueprint_doc_function(self, app):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        client = app.test_client()

        @blp.route('/', methods=(
            'PUT',
            'PATCH',
        ))
        @blp.doc(summary='Dummy func', description='Do dummy stuff')
        def view_func():
            return {'Value': 'OK'}

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        path = spec['paths']['/test/']
        for method in (
                'put',
                'patch',
        ):
            assert path[method]['summary'] == 'Dummy func'
            assert path[method]['description'] == 'Do dummy stuff'

        response = await client.put('/test/')
        assert response.status_code == 200
        assert await response.json == {'Value': 'OK'}
示例#7
0
    def test_blueprint_response_status_code_cast_to_string(
            self, app, status_code):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        # This is a dummy example. In real-life, use 'description' parameter.
        doc_desc = {'description': 'Description'}

        class ItemSchema(ma.Schema):
            test = ma.fields.Int()

        @blp.route('/')
        class Resource(MethodView):

            # When documenting a response, @blp.doc MUST use the same type
            # to express the status code as the one used in @blp.response.
            # (Default is 200 expressed as int.)
            @blp.doc(**{'responses': {status_code: doc_desc}})
            @blp.arguments(ItemSchema)
            @blp.response(ItemSchema, code=status_code)
            def get(self):
                pass

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        resp = spec['paths']['/test/']['get']['responses']['200']
        assert resp['description'] == 'Description'
        assert 'schema' in resp['content']['application/json']
示例#8
0
    def test_api_register_converter_before_and_after_init(
            self, app, openapi_version):
        api = Api()
        blp = Blueprint('test', 'test', url_prefix='/test')

        class CustomConverter_1(BaseConverter):
            pass

        class CustomConverter_2(BaseConverter):
            pass

        app.url_map.converters['custom_str_1'] = CustomConverter_1
        app.url_map.converters['custom_str_2'] = CustomConverter_2
        api.register_converter(CustomConverter_1, 'custom string 1')
        api.init_app(app)
        api.register_converter(CustomConverter_2, 'custom string 2')

        @blp.route('/1/<custom_str_1:val>')
        def test_func_1(val):
            pass

        @blp.route('/2/<custom_str_2:val>')
        def test_func_2(val):
            pass

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        parameter_1 = spec['paths']['/test/1/{val}']['parameters'][0]
        parameter_2 = spec['paths']['/test/2/{val}']['parameters'][0]
        if 'openapi_version' == '2.0':
            assert parameter_1['type'] == 'custom string 1'
            assert parameter_2['type'] == 'custom string 2'
        else:
            assert parameter_1['schema']['type'] == 'custom string 1'
            assert parameter_2['schema']['type'] == 'custom string 2'
示例#9
0
    def test_blueprint_multiple_routes_per_view(self, app, as_method_view):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        if as_method_view:
            # Blueprint.route ensures a different endpoint is used for each
            # route. Otherwise, this would break in Blueprint.route when
            # calling as_view for the second time with the same endpoint.
            @blp.route('/route_1')
            @blp.route('/route_2')
            class Resource(MethodView):
                def get(self):
                    pass

        else:

            @blp.route('/route_1')
            @blp.route('/route_2')
            def func():
                pass

        api.register_blueprint(blp)
        paths = api.spec.to_dict()['paths']

        assert 'get' in paths['/test/route_1']
        assert 'get' in paths['/test/route_2']
示例#10
0
    async def test_blueprint_arguments_files_multipart(self, app, schemas,
                                                       openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        client = app.test_client()

        class MultipartSchema(ma.Schema):
            file_1 = Upload()
            file_2 = Upload()

        @blp.route('/', methods=['POST'])
        @blp.arguments(MultipartSchema, location='files')
        def func(files):
            return {
                'file_1': files['file_1'].read().decode(),
                'file_2': files['file_2'].read().decode(),
            }

        api.register_blueprint(blp)
        spec = api.spec.to_dict()

        files = {
            'file_1': (io.BytesIO('Test 1'.encode()), 'file_1.txt'),
            'file_2': (io.BytesIO('Test 2'.encode()), 'file_2.txt'),
        }

        response = await client.post('/test/', data=files)
        assert response.json == {'file_1': 'Test 1', 'file_2': 'Test 2'}

        if openapi_version == '2.0':
            for param in spec['paths']['/test/']['post']['parameters']:
                assert param['in'] == 'formData'
                assert param['type'] == 'file'
        else:
            assert (
                spec['paths']['/test/']['post']['requestBody']['content'] == {
                    'multipart/form-data': {
                        'schema': {
                            '$ref': '#/components/schemas/Multipart'
                        }
                    }
                })
            assert (spec['components']['schemas']['Multipart'] == {
                'type': 'object',
                'properties': {
                    'file_1': {
                        'type': 'string',
                        'format': 'binary'
                    },
                    'file_2': {
                        'type': 'string',
                        'format': 'binary'
                    },
                }
            })
示例#11
0
    async def test_etag_response_object(self, app):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        client = app.test_client()

        @blp.route('/')
        @blp.etag
        @blp.response()
        async def func_response_etag():
            # When the view function returns a Response object,
            # the ETag must be specified manually
            blp.set_etag('test')
            return jsonify({})

        api.register_blueprint(blp)

        response = await client.get('/test/')
        assert await response.json == {}
        assert response.get_etag() == (blp._generate_etag('test'), False)
示例#12
0
    def test_etag_is_deterministic(self):
        """Check etag computation is deterministic

           _generate_etag should return the same value everytime the same
           dictionary is passed. This is not obvious since dictionaries
           are unordered by design. We check this by feeding it different
           OrderedDict instances that are equivalent to the same dictionary.
        """

        blp = Blueprint('test', __name__)

        data = OrderedDict([('a', 1), ('b', 2),
                            ('c', OrderedDict([('a', 1), ('b', 2)]))])
        etag = blp._generate_etag(data)

        data_copies = [
            OrderedDict([
                ('b', 2),
                ('a', 1),
                ('c', OrderedDict([('a', 1), ('b', 2)])),
            ]),
            OrderedDict([
                ('a', 1),
                ('b', 2),
                ('c', OrderedDict([('b', 2), ('a', 1)])),
            ]),
            OrderedDict([
                ('a', 1),
                ('c', OrderedDict([('a', 1), ('b', 2)])),
                ('b', 2),
            ]),
            OrderedDict([
                ('c', OrderedDict([('a', 1), ('b', 2)])),
                ('b', 2),
                ('a', 1),
            ]),
        ]

        data_copies_etag = [blp._generate_etag(d) for d in data_copies]
        assert all(e == etag for e in data_copies_etag)
示例#13
0
    async def test_etag_verify_check_etag_warning(self, app, method):
        blp = Blueprint('test', __name__)
        old_item = {'item_id': 1, 'db_field': 0}
        old_etag = blp._generate_etag(old_item)

        with mock.patch.object(app.logger, 'warning') as mock_warning:
            async with app.test_request_context('/',
                                                method=method,
                                                headers={'If-Match':
                                                         old_etag}):
                blp._verify_check_etag()
                if method in ['PUT', 'PATCH', 'DELETE']:
                    assert mock_warning.called
                    mock_warning.reset_mock()
                else:
                    assert not mock_warning.called
                blp.check_etag(old_item)
                blp._verify_check_etag()
                assert not mock_warning.called
示例#14
0
    def test_etag_generate_etag(self, schemas, extra_data):
        blp = Blueprint('test', __name__)
        etag_schema = schemas.DocEtagSchema
        item = {'item_id': 1, 'db_field': 0}
        item_schema_dump = etag_schema().dump(item)
        if MARSHMALLOW_VERSION_MAJOR < 3:
            item_schema_dump = item_schema_dump[0]
        if extra_data is None or extra_data == {}:
            data = item
            data_dump = item_schema_dump
        else:
            data = (item, extra_data)
            data_dump = (item_schema_dump, extra_data)

        etag = blp._generate_etag(item, extra_data=extra_data)
        assert etag == hashlib.sha1(
            bytes(json.dumps(data, sort_keys=True), 'utf-8')).hexdigest()
        etag = blp._generate_etag(item, etag_schema, extra_data=extra_data)
        assert etag == hashlib.sha1(
            bytes(json.dumps(data_dump, sort_keys=True), 'utf-8')).hexdigest()
        etag = blp._generate_etag(item, etag_schema(), extra_data=extra_data)
        assert etag == hashlib.sha1(
            bytes(json.dumps(data_dump, sort_keys=True), 'utf-8')).hexdigest()
示例#15
0
    def test_blueprint_arguments_required(self, app, schemas, required,
                                          location_map, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        location, _ = location_map

        if required is None:

            @blp.route('/')
            @blp.arguments(schemas.DocSchema, location=location)
            def func():
                pass
        else:

            @blp.route('/')
            @blp.arguments(schemas.DocSchema,
                           required=required,
                           location=location)
            def func():
                pass

        api.register_blueprint(blp)
        get = api.spec.to_dict()['paths']['/test/']['get']
        # OAS3 / json, form, files
        if (openapi_version == '3.0.2'
                and location in REQUEST_BODY_CONTENT_TYPE):
            # Body parameter in 'requestBody'
            assert 'requestBody' in get
            # Check required defaults to True
            assert get['requestBody']['required'] == (required is not False)
        # OAS2 / json
        elif location == 'json':
            parameters = get['parameters']
            # One parameter: the schema
            assert len(parameters) == 1
            assert 'schema' in parameters[0]
            assert 'requestBody' not in get
            # Check required defaults to True
            assert parameters[0]['required'] == (required is not False)
        # OAS2-3 / all
        else:
            parameters = get['parameters']
            # One parameter: the 'field' field in DocSchema
            assert len(parameters) == 1
            assert parameters[0]['name'] == 'field'
            assert 'requestBody' not in get
            # Check the required parameter has no impact.
            # Only the required attribute of the field matters
            assert parameters[0]['required'] is False
示例#16
0
    async def test_etag_check_precondition(self, app, method):
        blp = Blueprint('test', __name__)

        async with app.test_request_context('/', method=method):
            if method in ['PUT', 'PATCH', 'DELETE']:
                with pytest.raises(PreconditionRequired):
                    blp._check_precondition()
            else:
                blp._check_precondition()
示例#17
0
    def test_blueprint_response_headers(self, app):
        api = Api(app)
        blp = Blueprint('test', 'test', url_prefix='/test')

        headers = {'X-Header': {'description': 'Custom header'}}

        @blp.route('/')
        @blp.response(headers=headers)
        def func():
            pass

        api.register_blueprint(blp)

        get = api.spec.to_dict()['paths']['/test/']['get']
        assert get['responses']['200']['headers'] == headers
示例#18
0
    def test_blueprint_doc_called_twice(self, app):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/')
        @blp.doc(summary='Dummy func')
        @blp.doc(description='Do dummy stuff')
        def view_func():
            pass

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        path = spec['paths']['/test/']
        assert path['get']['summary'] == 'Dummy func'
        assert path['get']['description'] == 'Do dummy stuff'
示例#19
0
    def test_blueprint_pagination(self, app, schemas, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/')
        @blp.arguments(schemas.QueryArgsSchema, location='query')
        @blp.paginate()
        def func():
            """Dummy view func"""

        api.register_blueprint(blp)
        spec = api.spec.to_dict()

        # Check parameters are documented
        parameters = spec['paths']['/test/']['get']['parameters']
        # Page
        assert parameters[0]['name'] == 'page'
        assert parameters[0]['in'] == 'query'
        assert parameters[0]['required'] is False
        if openapi_version == '2.0':
            assert parameters[0]['type'] == 'integer'
            assert parameters[0]['default'] == 1
            assert parameters[0]['minimum'] == 1
        else:
            assert parameters[0]['schema']['type'] == 'integer'
            assert parameters[0]['schema']['default'] == 1
            assert parameters[0]['schema']['minimum'] == 1
        # Page size
        assert parameters[1]['name'] == 'page_size'
        assert parameters[1]['in'] == 'query'
        assert parameters[1]['required'] is False
        if openapi_version == '2.0':
            assert parameters[1]['type'] == 'integer'
            assert parameters[1]['default'] == 10
            assert parameters[1]['minimum'] == 1
            assert parameters[1]['maximum'] == 100
        else:
            assert parameters[1]['schema']['type'] == 'integer'
            assert parameters[1]['schema']['default'] == 10
            assert parameters[1]['schema']['minimum'] == 1
            assert parameters[1]['schema']['maximum'] == 100
        # Other query string parameters
        assert parameters[1]['in'] == 'query'
        assert parameters[2]['name'] == 'arg1'
        assert parameters[2]['in'] == 'query'
        assert parameters[3]['name'] == 'arg2'
        assert parameters[3]['in'] == 'query'
示例#20
0
    def test_blueprint_route_parameters(self, app, openapi_version):
        """Check path parameters docs are merged with auto docs"""
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/<int:item_id>',
                   parameters=[
                       'TestParameter',
                       {
                           'name': 'item_id',
                           'in': 'path',
                           'description': 'Item ID'
                       },
                   ])
        def get(item_id):
            pass

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        params = spec['paths']['/test/{item_id}']['parameters']
        assert len(params) == 2
        if openapi_version == '2.0':
            assert params == [
                build_ref(api.spec, 'parameter', 'TestParameter'),
                {
                    'name': 'item_id',
                    'in': 'path',
                    'required': True,
                    'description': 'Item ID',
                    'format': 'int32',
                    'type': 'integer'
                },
            ]
        else:
            assert params == [
                build_ref(api.spec, 'parameter', 'TestParameter'),
                {
                    'name': 'item_id',
                    'in': 'path',
                    'required': True,
                    'description': 'Item ID',
                    'schema': {
                        'format': 'int32',
                        'type': 'integer'
                    }
                },
            ]
示例#21
0
    async def test_blueprint_arguments_multiple(self, app, schemas,
                                                openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        client = app.test_client()

        @blp.route('/', methods=('POST', ))
        @blp.arguments(schemas.DocSchema)
        @blp.arguments(schemas.QueryArgsSchema, location='query')
        async def func(document, query_args):
            return {'document': document, 'query_args': query_args}

        api.register_blueprint(blp)
        spec = api.spec.to_dict()

        # Check parameters are documented
        parameters = spec['paths']['/test/']['post']['parameters']
        assert parameters[0]['name'] == 'arg1'
        assert parameters[0]['in'] == 'query'
        assert parameters[1]['name'] == 'arg2'
        assert parameters[1]['in'] == 'query'

        if openapi_version == '2.0':
            assert len(parameters) == 3
            assert parameters[2]['in'] == 'body'
            assert 'schema' in parameters[2]
        else:
            assert len(parameters) == 2
            assert 'schema' in spec['paths']['/test/']['post']['requestBody'][
                'content']['application/json']

        # Check parameters are passed as arguments to view function
        item_data = {'field': 12}
        response = await client.post(
            '/test/',
            data=json.dumps(item_data),
            headers={"Content-Type": "application/json"},
            query_string={'arg1': 'test'})
        assert response.status_code == 200
        assert await response.json == {
            'document': {
                'db_field': 12
            },
            'query_args': {
                'arg1': 'test'
            },
        }
示例#22
0
    async def test_blueprint_response_response_object(self, app, schemas):
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        client = app.test_client()

        @blp.route('/response')
        # Schema is ignored when response object is returned
        @blp.response(schemas.DocSchema, code=200)
        def func_response():
            return {}, 201, {'X-header': 'test'}

        api.register_blueprint(blp)

        response = await client.get('/test/response')
        assert response.status_code == 201
        assert response.status == '201 CREATED'
        assert response.json == {}
        assert response.headers['X-header'] == 'test'
示例#23
0
    async def test_etag_verify_check_etag_exception(self, app, method, debug,
                                                    testing):
        app.config['DEBUG'] = debug
        app.config['TESTING'] = testing
        blp = Blueprint('test', __name__)

        async with app.test_request_context('/', method=method):
            if (debug or testing) and method in ['PUT', 'PATCH', 'DELETE']:
                with pytest.raises(CheckEtagNotCalledError,
                                   match='ETag not checked in endpoint'):
                    blp._verify_check_etag()
            else:
                blp._verify_check_etag()
示例#24
0
    def test_blueprint_response_description(self, app):
        api = Api(app)
        blp = Blueprint('test', 'test', url_prefix='/test')

        @blp.route('/route_1')
        @blp.response()
        def func_1():
            pass

        @blp.route('/route_2')
        @blp.response(description='Test')
        def func_2():
            pass

        api.register_blueprint(blp)

        get_1 = api.spec.to_dict()['paths']['/test/route_1']['get']
        assert 'description' not in get_1['responses']['200']
        get_2 = api.spec.to_dict()['paths']['/test/route_2']['get']
        assert get_2['responses']['200']['description'] == 'Test'
示例#25
0
    def test_blueprint_multiple_registrations(self, app, openapi_version):
        """Check blueprint can be registered multiple times

        The internal doc structure is modified during the reigistration
        process. If it is not deepcopied, the second registration fails.
        """
        app.config['OPENAPI_VERSION'] = openapi_version
        blp = Blueprint('test', __name__, url_prefix='/test')

        @blp.route('/')
        def func():
            pass

        api = Api(app)
        api.register_blueprint(blp)
        spec_1 = api.spec.to_dict()
        api = Api(app)
        api.register_blueprint(blp)
        spec_2 = api.spec.to_dict()
        assert spec_1 == spec_2
示例#26
0
    def test_blueprint_response_example(self, app, openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', 'test', url_prefix='/test')

        example = {'name': 'One'}

        @blp.route('/')
        @blp.response(example=example)
        def func():
            pass

        api.register_blueprint(blp)

        get = api.spec.to_dict()['paths']['/test/']['get']
        if openapi_version == '2.0':
            assert get['responses']['200']['examples'][
                'application/json'] == example
        else:
            assert get['responses']['200']['content']['application/json'][
                'example'] == example
示例#27
0
    async def test_api_register_blueprint_options(self, app):
        api = Api(app)
        blp = Blueprint('test', 'test', url_prefix='/test1')

        @blp.route('/')
        def test_func():
            return {'response': 'OK'}

        api.register_blueprint(blp, url_prefix='/test2')

        spec = api.spec.to_dict()
        assert '/test1/' not in spec['paths']
        assert '/test2/' in spec['paths']

        client = app.test_client()
        response = await client.get('/test1/')
        assert response.status_code == 404
        response = await client.get('/test2/')
        assert response.status_code == 200
        json = await response.json
        assert json == {'response': 'OK'}
示例#28
0
    def test_blueprint_response_schema(self, app, openapi_version, schemas):
        """Check response schema is correctly documented.

        More specifically, check that:
        - plural response is documented as array in the spec
        - schema is document in the right place w.r.t. OpenAPI version
        """
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', 'test', url_prefix='/test')

        @blp.route('/schema_many_false')
        @blp.response(schemas.DocSchema(many=False))
        def many_false():
            pass

        @blp.route('/schema_many_true')
        @blp.response(schemas.DocSchema(many=True))
        def many_true():
            pass

        api.register_blueprint(blp)

        paths = api.spec.to_dict()['paths']

        schema_ref = build_ref(api.spec, 'schema', 'Doc')

        response = paths['/test/schema_many_false']['get']['responses']['200']
        if openapi_version == '2.0':
            assert response['schema'] == schema_ref
        else:
            assert (response['content']['application/json']['schema'] ==
                    schema_ref)

        response = paths['/test/schema_many_true']['get']['responses']['200']
        if openapi_version == '2.0':
            assert response['schema']['items'] == schema_ref
        else:
            assert (response['content']['application/json']['schema']['items']
                    == schema_ref)
示例#29
0
    def test_blueprint_arguments_location(self, app, schemas, location_map,
                                          openapi_version):
        app.config['OPENAPI_VERSION'] = openapi_version
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')
        location, openapi_location = location_map

        if location is not None:

            @blp.route('/')
            @blp.arguments(schemas.DocSchema, location=location)
            def func():
                """Dummy view func"""
        else:

            @blp.route('/')
            @blp.arguments(schemas.DocSchema)
            def func():
                """Dummy view func"""

        location = location or 'json'

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        get = spec['paths']['/test/']['get']
        if (openapi_version == '3.0.2'
                and location in REQUEST_BODY_CONTENT_TYPE):
            assert 'parameters' not in get
            assert 'requestBody' in get
            assert len(get['requestBody']['content']) == 1
            assert REQUEST_BODY_CONTENT_TYPE[location] in get['requestBody'][
                'content']
        else:
            loc = get['parameters'][0]['in']
            assert loc == openapi_location
            assert 'requestBody' not in get
            if location in REQUEST_BODY_CONTENT_TYPE and location != 'json':
                assert get['consumes'] == [REQUEST_BODY_CONTENT_TYPE[location]]
            else:
                assert 'consumes' not in get
示例#30
0
    def test_blueprint_doc_merged_after_prepare_doc(self, app):
        app.config['OPENAPI_VERSION'] = '3.0.2'
        api = Api(app)
        blp = Blueprint('test', __name__, url_prefix='/test')

        # This is a dummy example. In real-life, use 'example' parameter.
        doc_example = {
            'content': {
                'application/json': {
                    'example': {
                        'test': 123
                    }
                }
            }
        }

        class ItemSchema(ma.Schema):
            test = ma.fields.Int()

        @blp.route('/')
        class Resource(MethodView):
            @blp.doc(**{'requestBody': doc_example})
            @blp.doc(**{'responses': {200: doc_example}})
            @blp.arguments(ItemSchema)
            @blp.response(ItemSchema)
            def get(self):
                pass

        api.register_blueprint(blp)
        spec = api.spec.to_dict()
        get = spec['paths']['/test/']['get']
        assert get['requestBody']['content']['application/json'][
            'example'] == {
                'test': 123
            }
        resp = get['responses']['200']
        assert resp['content']['application/json']['example'] == {'test': 123}
        assert 'schema' in resp['content']['application/json']