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 = client.get("/test1/") assert response.status_code == 404 response = client.get("/test2/") assert response.status_code == 200 assert response.json == {"response": "OK"}
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(200, 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
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 = client.put('/test/') assert response.status_code == 200 assert response.json == {'Value': 'OK'}
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 = client.get('/test1/') assert response.status_code == 404 response = client.get('/test2/') assert response.status_code == 200 assert response.json == {'response': 'OK'}
def test_blueprint_alt_response_ref(self, app, openapi_version): """Check alternate response passed as reference""" app.config['OPENAPI_VERSION'] = openapi_version api = Api(app) api.spec.components.response('ClientErrorResponse') blp = Blueprint('test', 'test', url_prefix='/test') @blp.route('/') @blp.alt_response(400, "ClientErrorResponse") def func(): pass api.register_blueprint(blp) paths = api.spec.to_dict()['paths'] response_ref = build_ref(api.spec, 'response', 'ClientErrorResponse') assert paths['/test/']['get']['responses']['400'] == response_ref
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
def test_api_register_converter(self, app, view_type, register, openapi_version): app.config['OPENAPI_VERSION'] = openapi_version api = Api(app) blp = Blueprint('test', 'test', url_prefix='/test') class CustomConverter(BaseConverter): pass def converter2paramschema(converter): return {'type': 'custom string', 'format': 'custom format'} app.url_map.converters['custom_str'] = CustomConverter if register: api.register_converter(CustomConverter, converter2paramschema) if view_type == 'function': @blp.route('/<custom_str:val>') def test_func(val): pass else: @blp.route('/<custom_str:val>') class TestMethod(MethodView): def get(self, val): pass api.register_blueprint(blp) spec = api.spec.to_dict() if register: schema = {'type': 'custom string', 'format': 'custom format'} else: schema = {'type': 'string'} parameter = {'in': 'path', 'name': 'val', 'required': True} if openapi_version == '2.0': parameter.update(schema) else: parameter['schema'] = schema assert spec['paths']['/test/{val}']['parameters'] == [parameter]
def test_etag_verify_check_etag_exception( self, app, method, debug, testing): app.config['DEBUG'] = debug app.config['TESTING'] = testing blp = Blueprint('test', __name__) 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()
def test_blueprint_doc_method_view(self, app): api = Api(app) blp = Blueprint('test', __name__, url_prefix='/test') @blp.route('/') class Resource(MethodView): @blp.doc(summary='Dummy put', description='Do dummy put') def put(self): pass @blp.doc(summary='Dummy patch', description='Do dummy patch') def patch(self): pass api.register_blueprint(blp) spec = api.spec.to_dict() path = spec['paths']['/test/'] for method in ('put', 'patch', ): assert path[method]['summary'] == 'Dummy {}'.format(method) assert path[method]['description'] == 'Do dummy {}'.format(method)
def test_blueprint_response_description(self, app): api = Api(app) blp = Blueprint('test', 'test', url_prefix='/test') @blp.route('/route_1') @blp.response(204) def func_1(): pass @blp.route('/route_2') @blp.response(204, description='Test') def func_2(): pass api.register_blueprint(blp) get_1 = api.spec.to_dict()['paths']['/test/route_1']['get'] assert (get_1['responses']['204']['description'] == http.HTTPStatus( 204).phrase) get_2 = api.spec.to_dict()['paths']['/test/route_2']['get'] assert get_2['responses']['204']['description'] == 'Test'
def register_api(app: Flask) -> Api: """Register the smorest Api on the Flask app Arguments: app {Flask} -- Flask app Returns: Api -- Registered Api """ api = Api(app) bp = Blueprint("api", "api", url_prefix="/api", description="Covid-19 Rest API") register_italy_regions_api(bp) register_italy_provinces_api(bp) register_italy_region_case_api(bp) register_italy_province_case_api(bp) api.register_blueprint(bp) return api
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(200, 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
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
def test_blueprint_route_multiple_methods(self, app, schemas, openapi_version): """Test calling route with multiple methods Checks the doc is properly deepcopied between methods """ app.config['OPENAPI_VERSION'] = openapi_version api = Api(app) blp = Blueprint('test', __name__, url_prefix='/test') @blp.route('/', methods=( 'GET', 'POST', )) @blp.arguments(schemas.DocSchema) @blp.response(200, schemas.DocSchema) def func(document, query_args): pass api.register_blueprint(blp) spec = api.spec.to_dict() schema_ref = build_ref(api.spec, 'schema', 'Doc') for method in ('get', 'post'): operation = spec['paths']['/test/'][method] # Check parameters are documented if openapi_version == '2.0': parameter = operation['parameters'][0] assert parameter['in'] == 'body' assert 'schema' in parameter else: assert 'schema' in operation['requestBody']['content'][ 'application/json'] # Check responses are documented response = operation['responses']['200'] if openapi_version == '2.0': assert response['schema'] == schema_ref else: assert (response['content']['application/json']['schema'] == schema_ref)
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(200, schemas.DocSchema(many=False)) def many_false(): pass @blp.route('/schema_many_true') @blp.response(200, 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)
def test_blueprint_arguments_documents_error_response( self, app, schemas, openapi_version, error_code): app.config['OPENAPI_VERSION'] = openapi_version api = Api(app) blp = Blueprint('test', __name__, url_prefix='/test') blp.ARGUMENTS_PARSER.DEFAULT_VALIDATION_STATUS = 400 kwargs = {} if error_code: kwargs['error_status_code'] = error_code @blp.route('/') @blp.arguments(schemas.DocSchema, **kwargs) def func(): """Dummy view func""" api.register_blueprint(blp) spec = api.spec.to_dict() error_code = error_code or 400 assert (spec['paths']['/test/']['get']['responses'][str(error_code)] == build_ref(api.spec, 'response', http.HTTPStatus(error_code).name))
def test_api_unicode_converter(self, app, params, openapi_version): app.config['OPENAPI_VERSION'] = openapi_version api = Api(app) blp = Blueprint('test', 'test', url_prefix='/test') param, output = params @blp.route('/<string{}:val>'.format(param)) def test(val): pass api.register_blueprint(blp) spec = api.spec.to_dict() schema = {'type': 'string'} schema.update(output) parameter = {'in': 'path', 'name': 'val', 'required': True} if openapi_version == '2.0': parameter.update(schema) else: parameter['schema'] = schema assert spec['paths']['/test/{val}']['parameters'] == [parameter]
def test_api_unicode_converter(self, app, params, openapi_version): app.config["OPENAPI_VERSION"] = openapi_version api = Api(app) blp = Blueprint("test", "test", url_prefix="/test") param, output = params @blp.route(f"/<string{param}:val>") def test(val): pass api.register_blueprint(blp) spec = api.spec.to_dict() schema = {"type": "string"} schema.update(output) parameter = {"in": "path", "name": "val", "required": True} if openapi_version == "2.0": parameter.update(schema) else: parameter["schema"] = schema assert spec["paths"]["/test/{val}"]["parameters"] == [parameter]
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(200, 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']
def test_blueprint_etag_documents_responses( self, app, method, decorate, etag_disabled, ): app.config['ETAG_DISABLED'] = etag_disabled api = Api(app) blp = Blueprint('test', 'test', url_prefix='/test') if decorate: @blp.route('/', methods=[method]) @blp.etag def func(): pass else: @blp.route('/', methods=[method]) def func(): pass api.register_blueprint(blp) operation = api.spec.to_dict()['paths']['/test/'][method.lower()] responses = operation.get('responses', {}) if not decorate or etag_disabled: assert '304' not in responses assert '412' not in responses assert '428' not in responses else: assert ('304' in responses) == (method in ['GET', 'HEAD']) assert ('412' in responses) == (method in ['PUT', 'PATCH', 'DELETE']) assert ('428' in responses) == (method in ['PUT', 'PATCH', 'DELETE'])
def test_blueprint_route_path_parameter_default(self, app, as_method_view): api = Api(app) blp = Blueprint('test', __name__, url_prefix='/test') if as_method_view: @blp.route('/<int:user_id>') @blp.route('/', defaults={'user_id': 1}) class Resource(MethodView): def get(self, user_id): pass else: @blp.route('/<int:user_id>') @blp.route('/', defaults={'user_id': 1}) def func(user_id): pass api.register_blueprint(blp) paths = api.spec.to_dict()['paths'] assert 'parameters' not in paths['/test/'] assert paths['/test/{user_id}']['parameters'][0]['name'] == 'user_id'
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 assert params[0] == build_ref(api.spec, 'parameter', 'TestParameter') assert params[1]['description'] == 'Item ID' if openapi_version == '2.0': assert params[1]['type'] == 'integer' else: assert params[1]['schema']['type'] == 'integer'
def test_api_register_converter(self, app, view_type, custom_format, openapi_version): app.config['OPENAPI_VERSION'] = openapi_version api = Api(app) blp = Blueprint('test', 'test', url_prefix='/test') class CustomConverter(BaseConverter): pass app.url_map.converters['custom_str'] = CustomConverter api.register_converter(CustomConverter, 'custom string', custom_format) if view_type == 'function': @blp.route('/<custom_str:val>') def test_func(val): pass else: @blp.route('/<custom_str:val>') class TestMethod(MethodView): def get(self, val): pass api.register_blueprint(blp) spec = api.spec.to_dict() schema = {'type': 'custom string'} # If custom_format is None (default), it does not appear in the spec if custom_format is not None: schema['format'] = 'custom' parameter = {'in': 'path', 'name': 'val', 'required': True} if openapi_version == '2.0': parameter.update(schema) else: parameter['schema'] = schema assert spec['paths']['/test/{val}']['parameters'] == [parameter]
def pagination_blueprint(collection, schemas, as_method_view, custom_params): """Return a basic API sample with pagination""" DocSchema = schemas.DocSchema blp = Blueprint('test', __name__, url_prefix='/test') if custom_params: page, page_size, max_page_size = CUSTOM_PAGINATION_PARAMS else: page, page_size, max_page_size = None, None, None if as_method_view: @blp.route('/') class Resource(MethodView): @blp.response(DocSchema(many=True)) @blp.paginate(page=page, page_size=page_size, max_page_size=max_page_size) def get(self, pagination_parameters): pagination_parameters.item_count = len(collection.items) return collection.items[pagination_parameters.first_item: pagination_parameters.last_item + 1] else: @blp.route('/') @blp.response(DocSchema(many=True)) @blp.paginate(page=page, page_size=page_size, max_page_size=max_page_size) def get_resources(pagination_parameters): pagination_parameters.item_count = len(collection.items) return collection.items[pagination_parameters.first_item: pagination_parameters.last_item + 1] return blp
def test_api_register_converter_before_and_after_init( self, app, openapi_version): app.config['OPENAPI_VERSION'] = 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'
def test_api_lazy_registers_default_error_response(self, app, openapi_version): """Test default error response is registered""" app.config["OPENAPI_VERSION"] = openapi_version api = Api(app) # Declare a dummy response to ensure get_response doesn't fail response_1 = {"description": "Reponse 1"} api.spec.components.response("Response_1", response_1) # No route registered -> default error not registered assert "DEFAULT_ERROR" not in get_responses(api.spec) # Register a route blp = Blueprint("test", "test", url_prefix="/test") @blp.route("/test") def test(val): pass api.register_blueprint(blp) # Default error is now registered assert "DEFAULT_ERROR" in get_responses(api.spec)
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
def test_blueprint_alt_response_schema(self, app, openapi_version, schemas): """Check alternate response schema is correctly documented""" app.config['OPENAPI_VERSION'] = openapi_version api = Api(app) blp = Blueprint('test', 'test', url_prefix='/test') example = {'error_id': 'E1', 'text': 'client error'} examples = { 'example 1': { 'error_id': 'E1', 'text': 'client error 1' }, 'example 2': { 'error_id': 'E2', 'text': 'client error 2' }, } headers = {'X-Custom-Header': 'Header value'} @blp.route('/') @blp.alt_response(400, schemas.ClientErrorSchema) def func(): pass @blp.route('/description') @blp.alt_response(400, schemas.ClientErrorSchema, description='Client error') def func_with_description(): pass @blp.route('/example') @blp.alt_response(400, schemas.ClientErrorSchema, example=example) def func_with_example(): pass if openapi_version == '3.0.2': @blp.route('/examples') @blp.alt_response(400, schemas.ClientErrorSchema, examples=examples) def func_with_examples(): pass @blp.route('/headers') @blp.alt_response(400, schemas.ClientErrorSchema, headers=headers) def func_with_headers(): pass api.register_blueprint(blp) paths = api.spec.to_dict()['paths'] schema_ref = build_ref(api.spec, 'schema', 'ClientError') response = paths['/test/']['get']['responses']['400'] if openapi_version == '2.0': assert response['schema'] == schema_ref else: assert (response['content']['application/json']['schema'] == schema_ref) assert response['description'] == http.HTTPStatus(400).phrase response = paths['/test/description']['get']['responses']['400'] assert response['description'] == 'Client error' response = paths['/test/example']['get']['responses']['400'] if openapi_version == '2.0': assert response['examples']['application/json'] == example else: assert ( response['content']['application/json']['example'] == example) if openapi_version == '3.0.2': response = paths['/test/examples']['get']['responses']['400'] assert (response['content']['application/json']['examples'] == examples) response = paths['/test/headers']['get']['responses']['400'] assert response['headers'] == headers
def test_blueprint_response_tuple(self, app): api = Api(app) blp = Blueprint('test', __name__, url_prefix='/test') client = app.test_client() @blp.route('/response') @blp.response(200) def func_response(): return {} @blp.route('/response_code_int') @blp.response(200) def func_response_code_int(): return {}, 201 @blp.route('/response_code_str') @blp.response(200) def func_response_code_str(): return {}, '201 CREATED' @blp.route('/response_headers') @blp.response(200) def func_response_headers(): return {}, {'X-header': 'test'} @blp.route('/response_code_int_headers') @blp.response(200) def func_response_code_int_headers(): return {}, 201, {'X-header': 'test'} @blp.route('/response_code_str_headers') @blp.response(200) def func_response_code_str_headers(): return {}, '201 CREATED', {'X-header': 'test'} @blp.route('/response_wrong_tuple') @blp.response(200) def func_response_wrong_tuple(): return {}, 201, {'X-header': 'test'}, 'extra' @blp.route('/response_tuple_subclass') @blp.response(200) def func_response_tuple_subclass(): class MyTuple(tuple): pass return MyTuple((1, 2)) api.register_blueprint(blp) response = client.get('/test/response') assert response.status_code == 200 assert response.json == {} response = client.get('/test/response_code_int') assert response.status_code == 201 assert response.status == '201 CREATED' assert response.json == {} response = client.get('/test/response_code_str') assert response.status_code == 201 assert response.status == '201 CREATED' assert response.json == {} response = client.get('/test/response_headers') assert response.status_code == 200 assert response.json == {} assert response.headers['X-header'] == 'test' response = client.get('/test/response_code_int_headers') assert response.status_code == 201 assert response.status == '201 CREATED' assert response.json == {} assert response.headers['X-header'] == 'test' response = client.get('/test/response_code_str_headers') assert response.status_code == 201 assert response.status == '201 CREATED' assert response.json == {} assert response.headers['X-header'] == 'test' response = client.get('/test/response_wrong_tuple') assert response.status_code == 500 response = client.get('/test/response_tuple_subclass') assert response.status_code == 200 assert response.json == [1, 2]
def test_blueprint_pagination_response_tuple(self, app): api = Api(app) blp = Blueprint('test', __name__, url_prefix='/test') client = app.test_client() @blp.route('/response') @blp.response(200) @blp.paginate(Page) def func_response(): return [1, 2] @blp.route('/response_code') @blp.response(200) @blp.paginate(Page) def func_response_code(): return [1, 2], 201 @blp.route('/response_headers') @blp.response(200) @blp.paginate(Page) def func_response_headers(): return [1, 2], {'X-header': 'test'} @blp.route('/response_code_headers') @blp.response(200) @blp.paginate(Page) def func_response_code_headers(): return [1, 2], 201, {'X-header': 'test'} @blp.route('/response_wrong_tuple') @blp.response(200) @blp.paginate(Page) def func_response_wrong_tuple(): return [1, 2], 201, {'X-header': 'test'}, 'extra' @blp.route('/response_tuple_subclass') @blp.response(200) @blp.paginate(Page) def func_response_tuple_subclass(): class MyTuple(tuple): pass return MyTuple((1, 2)) api.register_blueprint(blp) response = client.get('/test/response') assert response.status_code == 200 assert response.json == [1, 2] response = client.get('/test/response_code') assert response.status_code == 201 assert response.json == [1, 2] response = client.get('/test/response_headers') assert response.status_code == 200 assert response.json == [1, 2] assert response.headers['X-header'] == 'test' response = client.get('/test/response_code_headers') assert response.status_code == 201 assert response.json == [1, 2] assert response.headers['X-header'] == 'test' response = client.get('/test/response_wrong_tuple') assert response.status_code == 500 response = client.get('/test/response_tuple_subclass') assert response.status_code == 200 assert response.json == [1, 2]