def test_non_blueprint_rest_error_routing(self, app, mocker): blueprint = Blueprint('test', __name__) api = restplus.Api(blueprint) api.add_resource(HelloWorld, '/hi', endpoint="hello") api.add_resource(GoodbyeWorld(404), '/bye', endpoint="bye") app.register_blueprint(blueprint, url_prefix='/blueprint') api2 = restplus.Api(app) api2.add_resource(HelloWorld(api), '/hi', endpoint="hello") api2.add_resource(GoodbyeWorld(404), '/bye', endpoint="bye") with app.test_request_context('/hi', method='POST'): assert api._should_use_fr_error_handler() is False assert api2._should_use_fr_error_handler() is True assert api._has_fr_route() is False assert api2._has_fr_route() is True with app.test_request_context('/blueprint/hi', method='POST'): assert api._should_use_fr_error_handler() is True assert api2._should_use_fr_error_handler() is False assert api._has_fr_route() is True assert api2._has_fr_route() is False api._should_use_fr_error_handler = mocker.Mock(return_value=False) api2._should_use_fr_error_handler = mocker.Mock(return_value=False) with app.test_request_context('/bye'): assert api._has_fr_route() is False assert api2._has_fr_route() is True with app.test_request_context('/blueprint/bye'): assert api._has_fr_route() is True assert api2._has_fr_route() is False
async def test_errorhandler_with_namespace_from_api(self, app, client): api = sanic_restplus.Api(app) ns = api.namespace("ExceptionHandler", path="/") class CustomException(RuntimeError): pass @ns.route('/test/', endpoint='test') class TestResource(sanic_restplus.Resource): async def get(self, request): raise CustomException('error') @ns.errorhandler(CustomException) def handle_custom_exception(error): return {'message': str(error), 'test': 'value'}, 400 response = await client.get('/test/') assert response.status_code == 400 assert response.content_type == 'application/json' data = json.loads(response.data.decode('utf8')) assert data == { 'message': 'error', 'test': 'value', }
def test_api_payload(self, app, client): api = restplus.Api(app, validate=True) fields = api.model('Person', { 'name': restplus.fields.String(required=True), 'age': restplus.fields.Integer, 'birthdate': restplus.fields.DateTime, }) @api.route('/validation/') class Payload(restplus.Resource): payload = None @api.expect(fields) def post(self, request): Payload.payload = api.payload(request) return {} data = { 'name': 'John Doe', 'age': 15, } client.post_json('/validation/', data) assert Payload.payload == data
def test_validation_with_inheritance(self, app, client): '''It should perform validation with inheritance (allOf/$ref)''' api = restplus.Api(app, validate=True) fields = api.model('Parent', { 'name': restplus.fields.String(required=True), }) child_fields = api.inherit('Child', fields, { 'age': restplus.fields.Integer, }) @api.route('/validation/') class Inheritance(restplus.Resource): @api.expect(child_fields) def post(self): return {} client.post_json('/validation/', { 'name': 'John Doe', 'age': 15, }) self.assert_errors(client, '/validation/', { 'age': '15', }, 'name', 'age')
def test_accept_application_json_by_default(self, app, client): api = restplus.Api(app) api.add_resource(Foo, '/test/') res = client.get('/test/', headers=[('Accept', 'application/json')]) assert res.status_code == 200 assert res.content_type == 'application/json'
def test_accept_no_default_no_match_not_acceptable(self, app, client): api = restplus.Api(app, default_mediatype=None) api.add_resource(Foo, '/test/') res = client.get('/test/', headers=[('Accept', 'text/plain')]) assert res.status_code == 406 assert res.content_type == 'application/json'
def test_api_payload(self, app, client): api = restplus.Api(app, validate=True) ns = restplus.Namespace('apples') api.add_namespace(ns) fields = ns.model('Person', { 'name': restplus.fields.String(required=True), 'age': restplus.fields.Integer, 'birthdate': restplus.fields.DateTime, }) @ns.route('/validation/') class Payload(restplus.Resource): payload = None @ns.expect(fields) def post(self): Payload.payload = ns.payload return {} data = { 'name': 'John Doe', 'age': 15, } client.post_json('/apples/validation/', data) assert Payload.payload == data
def test_validation_on_list(self, app, client): '''It should perform validation on lists''' api = restplus.Api(app, validate=True) person = api.model( 'Person', { 'name': restplus.fields.String(required=True), 'age': restplus.fields.Integer(required=True), }) family = api.model( 'Family', { 'name': restplus.fields.String(required=True), 'members': restplus.fields.List(restplus.fields.Nested(person)) }) @api.route('/validation/') class List(restplus.Resource): @api.expect(family) def post(self): return {} self.assert_errors(client, '/validation/', { 'name': 'Doe', 'members': [{ 'name': 'Jonn' }, { 'age': 42 }] }, 'members.0.age', 'members.1.name')
def test_add_resource_endpoint(self, app, mocker): view = mocker.Mock(**{'as_view.return_value.__name__': str('test_view')}) api = restplus.Api(app) api.add_resource(view, '/foo', endpoint='bar') view.as_view.assert_called_with('bar', api)
def test_errorhandler_lazy(self, app, client): api = restplus.Api() class CustomException(RuntimeError): pass @api.route('/test/', endpoint='test') class TestResource(restplus.Resource): def get(self): raise CustomException('error') @api.errorhandler(CustomException) def handle_custom_exception(error): return {'message': str(error), 'test': 'value'}, 400 api.init_app(app) response = client.get('/test/') assert response.status_code == 400 assert response.content_type == 'application/json' data = json.loads(response.data.decode('utf8')) assert data == { 'message': 'error', 'test': 'value', }
def test_root_endpoint(self, app): api = restplus.Api(app, version='1.0') with app.test_request_context(): url = url_for('root') assert url == '/' assert api.base_url == 'http://localhost/'
def test_media_types_method(self, app, mocker): api = restplus.Api(app) with app.test_request_context("/foo", headers={ 'Accept': 'application/xml; q=.5' }): assert api.mediatypes_method()(mocker.Mock()) == ['application/xml', 'application/json']
def test_registration_prefix_overrides_blueprint_prefix(self, app): blueprint = Blueprint('test', __name__, url_prefix='/bp') api = restplus.Api(blueprint) api.add_resource(HelloWorld, '/hi', endpoint='hello') app.register_blueprint(blueprint, url_prefix='/reg') with app.test_request_context('/reg/hi'): assert request.endpoint == 'test.hello'
def test_export_with_namespace(self, app): api = restplus.Api(app) ns = api.namespace('test', 'A test namespace') @ns.route('/test') class Test(restplus.Resource): @api.doc('test_post') def post(self): '''A test post''' pass data = api.as_postman() validate(data, schema) assert len(data['requests']) == 1 request = data['requests'][0] assert request['name'] == 'test_post' assert request['description'] == 'A test post' assert len(data['folders']) == 2 folder = data['folders'][1] assert folder['name'] == 'test' assert folder['description'] == 'A test namespace' assert request['folder'] == folder['id']
def test_api_base(self, app): blueprint = Blueprint('test', __name__) api = restplus.Api(blueprint) app.register_blueprint(blueprint) assert api.urls == {} assert api.prefix == '' assert api.default_mediatype == 'application/json'
def test_handle_smart_errors(self, app): api = restplus.Api(app) view = restplus.Resource api.add_resource(view, '/foo', endpoint='bor') api.add_resource(view, '/fee', endpoint='bir') api.add_resource(view, '/fii', endpoint='ber') with app.test_request_context("/faaaaa"): response = api.handle_error(NotFound()) assert response.status_code == 404 assert json.loads(response.data.decode()) == { 'message': NotFound.description, } with app.test_request_context("/fOo"): response = api.handle_error(NotFound()) assert response.status_code == 404 assert 'did you mean /foo ?' in response.data.decode() app.config['ERROR_404_HELP'] = False response = api.handle_error(NotFound()) assert response.status_code == 404 assert json.loads(response.data.decode()) == { 'message': NotFound.description }
def test_method_security_headers(self, app): api = restplus.Api(app, authorizations={ 'apikey': { 'type': 'apiKey', 'in': 'header', 'name': 'X-API' } }) @api.route('/secure/') class Secure(restplus.Resource): @api.doc('secure', security='apikey') def get(self): pass @api.route('/unsecure/') class Unsecure(restplus.Resource): @api.doc('unsecure') def get(self): pass data = api.as_postman() validate(data, schema) requests = dict((r['name'], r['headers']) for r in data['requests']) assert requests['unsecure'] == '' assert requests['secure'] == 'X-API:'
def test_add_resource_endpoint_after_registration(self, app, mocker): blueprint = Blueprint('test', __name__) api = sanic_restplus.Api(blueprint) app.register_blueprint(blueprint) view = mocker.Mock(**{'as_view.return_value.__name__': str('test_view')}) api.add_resource(view, '/foo', endpoint='bar') view.as_view.assert_called_with('bar', api)
async def test_accept_default_application_json(self, app, client): api = sanic_restplus.Api(app) api.add_resource(Foo, '/test/') res = await client.get('/test/', headers={'Accept': ''}) assert res.status == 200 assert res.content_type == 'application/json'
async def test_accept_default_override_accept(self, app, client): api = sanic_restplus.Api(app) api.add_resource(Foo, '/test/') res = await client.get('/test/', headers=[('Accept', 'text/plain')]) assert res.status == 200 assert res.content_type == 'application/json'
def test_media_types_q(self, app): api = restplus.Api(app) with app.test_request_context("/foo", headers={ 'Accept': 'application/json; q=1, application/xml; q=.5' }): assert api.mediatypes() == ['application/json', 'application/xml']
def test_url_with_api_and_blueprint_prefix(self, app): blueprint = Blueprint('test', __name__, url_prefix='/bp') api = restplus.Api(blueprint, prefix='/api') api.add_resource(HelloWorld, '/hi', endpoint='hello') app.register_blueprint(blueprint) with app.test_request_context('/bp/api/hi'): assert request.endpoint == 'test.hello'
def test_url_variables_enabled(self, app): api = restplus.Api(app) parser = api.parser() parser.add_argument('int', type=int) parser.add_argument('default', type=int, default=5) parser.add_argument('str', type=str) @api.route('/test/') class Test(restplus.Resource): @api.expect(parser) def get(self): pass data = api.as_postman(urlvars=True) validate(data, schema) assert len(data['requests']) == 1 request = data['requests'][0] qs = parse_qs(urlparse(request['url']).query, keep_blank_values=True) assert 'int' in qs assert qs['int'][0] == '0' assert 'default' in qs assert qs['default'][0] == '5' assert 'str' in qs assert qs['str'][0] == ''
def test_disabled_apidoc(self, app, client): restplus.Api(app, version='1.0', doc=False) with pytest.raises(BuildError): url_for('doc') response = client.get(url_for('root')) assert response.status_code == 404
def test_id_is_the_same(self, app): api = restplus.Api(app) first = api.as_postman() second = api.as_postman() assert first['id'] == second['id']
def test_basic_export(self, app): api = restplus.Api(app) data = api.as_postman() validate(data, schema) assert len(data['requests']) == 0
async def test_accept_no_default_match_acceptable(self, app, client): api = sanic_restplus.Api(app, default_mediatype=None) api.add_resource(Foo, '/test/') res = await client.get('/test/', headers=[('Accept', 'application/json')]) assert res.status == 200 assert res.content_type == 'application/json'
def test_handle_server_error(self, app): api = restplus.Api(app) resp = api.handle_error(Exception()) assert resp.status_code == 500 assert json.loads(resp.data.decode()) == { 'message': "Internal Server Error" }
def test_root_endpoint_lazy(self, app): api = sanic_restplus.Api(version='1.0') api.init_app(app) with app.test_request_context(): url = url_for('root') assert url == '/' assert api.base_url == 'http://localhost/'
def test_handle_error(self, app): api = restplus.Api(app) response = api.handle_error(BadRequest()) assert response.status_code == 400 assert json.loads(response.data.decode()) == { 'message': BadRequest.description, }