def test_add_param(): @doc.add_param(Param.query('foo')) @api.Operation def a(): pass assert len(a.parameters) == 1 assert Param.query('foo') in a.parameters @api.Operation @doc.add_param(Param.query('foo')) def b(): pass assert len(b.parameters) == 1 assert Param.query('foo') in b.parameters @doc.add_param(Param.query('foo')) @api.Operation @doc.add_param(Param.form('bar')) def c(): pass assert len(c.parameters) == 2 assert Param.query('foo') in c.parameters assert Param.form('bar') in c.parameters
def test_repr(self): target = Param('foo', In.Query, Type.Integer, foo='bar') assert ( repr(target) == "Param('foo', <In.Query: 'query'>, <Type.Integer: 'integer:int32'>, None, {'foo': 'bar'})" )
def test_hash(self): a = Param('foo', In.Query) b = Param('foo', In.Query) assert hash(a) == hash(b) a = Param('foo', In.Query) b = Param('bar', In.Query) assert hash(a) != hash(b) a = Param('foo', In.Query) b = Param('foo', In.Path) assert hash(a) != hash(b)
def test_eq(self, other, expected): assert Param('foo', In.Path).__eq__(other) == expected
def test_str(self): target = Param('foo', In.Query) assert str(target) == 'Query param foo'
class TestParam(object): @pytest.mark.parametrize( 'method, args, expected', ( # Path (Param.path, ('foo', ), { 'name': 'foo', 'in': 'path', 'type': 'string', 'required': True }), (Param.path, ('foo', Type.Boolean, 'eek'), { 'name': 'foo', 'in': 'path', 'type': 'boolean', 'description': 'eek', 'required': True }), (Param.path, ('foo', Type.Integer, None, 1, 0, 2), { 'name': 'foo', 'in': 'path', 'type': 'integer', 'default': 1, 'minimum': 0, 'maximum': 2, 'required': True }), (Param.path, ('foo', Type.Float, None, None, None, None, ('a', 'b')), { 'name': 'foo', 'in': 'path', 'type': 'number', 'enum': ('a', 'b'), 'required': True }), # Query (Param.query, ('foo', ), { 'name': 'foo', 'in': 'query', 'type': 'string' }), (Param.query, ('foo', Type.Boolean), { 'name': 'foo', 'in': 'query', 'type': 'boolean' }), (Param.query, ('foo', Type.Integer), { 'name': 'foo', 'in': 'query', 'type': 'integer' }), (Param.query, ('foo', Type.Float, 'eek'), { 'name': 'foo', 'in': 'query', 'type': 'number', 'description': 'eek' }), (Param.query, ('foo', Type.String, None, False), { 'name': 'foo', 'in': 'query', 'type': 'string', 'required': False }), (Param.query, ('foo', Type.String, None, None, 1, 0, 2), { 'name': 'foo', 'in': 'query', 'type': 'string', 'default': 1, 'minimum': 0, 'maximum': 2 }), (Param.query, ('foo', Type.String, None, None, None, None, None, ('a', 'b')), { 'name': 'foo', 'in': 'query', 'type': 'string', 'enum': ('a', 'b') }), # Header (Param.header, ('foo', ), { 'name': 'foo', 'in': 'header', 'type': 'string' }), (Param.header, ('foo', Type.Boolean, 'eek'), { 'name': 'foo', 'in': 'header', 'type': 'boolean', 'description': 'eek' }), (Param.header, ('foo', Type.Integer, None, 'eek'), { 'name': 'foo', 'in': 'header', 'type': 'integer', 'default': 'eek' }), (Param.header, ('foo', Type.Integer, None, None, True), { 'name': 'foo', 'in': 'header', 'type': 'integer', 'required': True }), # Body (Param.body, (), { 'name': 'body', 'in': 'body', 'required': True }), (Param.body, ('foo', ), { 'name': 'body', 'in': 'body', 'description': 'foo', 'required': True }), (Param.body, ('foo', 'eek'), { 'name': 'body', 'in': 'body', 'description': 'foo', 'default': 'eek', 'required': True }), (Param.body, (None, None, User), { 'name': 'body', 'in': 'body', 'required': True, 'schema': { '$ref': '#/definitions/tests.User' } }), # Form (Param.form, ('foo', ), { 'name': 'foo', 'in': 'formData', 'type': 'string' }), (Param.form, ('foo', Type.Boolean), { 'name': 'foo', 'in': 'formData', 'type': 'boolean' }), (Param.form, ('foo', Type.Integer), { 'name': 'foo', 'in': 'formData', 'type': 'integer' }), (Param.form, ('foo', Type.Float, 'eek'), { 'name': 'foo', 'in': 'formData', 'type': 'number', 'description': 'eek' }), (Param.form, ('foo', Type.String, None, False), { 'name': 'foo', 'in': 'formData', 'type': 'string', 'required': False }), (Param.form, ('foo', Type.String, None, None, 1, 0, 2), { 'name': 'foo', 'in': 'formData', 'type': 'string', 'default': 1, 'minimum': 0, 'maximum': 2 }), (Param.form, ('foo', Type.String, None, None, None, None, None, ('a', 'b')), { 'name': 'foo', 'in': 'formData', 'type': 'string', 'enum': ('a', 'b') }), )) def test_constructors(self, method, args, expected): target = method(*args) actual = target.to_swagger() assert actual == expected @pytest.mark.parametrize('method, args, expected', ( (Param.path, ('foo', Type.String, None, None, 2, 1), ValueError), (Param.query, ('foo', Type.String, None, None, None, 2, 1), ValueError), (Param.form, ('foo', Type.String, None, None, None, 2, 1), ValueError), )) def test_constructors__errors(self, method, args, expected): with pytest.raises(expected): method(*args) def test_hash(self): a = Param('foo', In.Query) b = Param('foo', In.Query) assert hash(a) == hash(b) a = Param('foo', In.Query) b = Param('bar', In.Query) assert hash(a) != hash(b) a = Param('foo', In.Query) b = Param('foo', In.Path) assert hash(a) != hash(b) def test_str(self): target = Param('foo', In.Query) assert str(target) == 'Query param foo' def test_repr(self): target = Param('foo', In.Query, Type.Integer, foo='bar') assert ( repr(target) == "Param('foo', <In.Query: 'query'>, <Type.Integer: 'integer:int32'>, None, {'foo': 'bar'})" ) @pytest.mark.parametrize('other, expected', ( (Param('foo', In.Path), True), (Param('bar', In.Path), False), (Param('foo', In.Body), False), (123, NotImplemented), )) def test_eq(self, other, expected): assert Param('foo', In.Path).__eq__(other) == expected
def test_documentation_applied(self): @decorators.ResourceOperation(resource=User) def my_func(request, user): pass assert Param.body() in my_func.parameters
class TestSwaggerSpec(object): @pytest.mark.parametrize( 'options, title, enabled, enable_ui, host, schemes', ( ({ 'title': 'Test' }, 'Test', True, False, None, set()), ({ 'title': 'Test', 'enabled': False }, 'Test', False, False, None, set()), ({ 'title': 'Test', 'enable_ui': True }, 'Test', True, True, None, set()), ({ 'title': 'Test', 'enabled': False, 'enable_ui': True }, 'Test', False, False, None, set()), ({ 'title': 'Test', 'host': 'localhost' }, 'Test', True, False, 'localhost', set()), ({ 'title': 'Test', 'schemes': ('http', 'https') }, 'Test', True, False, None, {'http', 'https'}), ({ 'title': 'Test', 'schemes': 'http' }, 'Test', True, False, None, {'http'}), )) def test_configure(self, options, title, enabled, enable_ui, host, schemes): target = swagger.SwaggerSpec(**options) assert target.title == title assert target.enabled == enabled assert target.enable_ui == enable_ui assert target.host == host assert target.schemes == schemes def test_base_path(self): target = swagger.SwaggerSpec(title="") ApiInterfaceBase( ApiContainer(ApiContainer(ApiContainer(target), name='b'), name='a')) assert UrlPath.parse("/api/a/b") == target.base_path assert UrlPath.parse("/api/a/b/swagger") == target.swagger_path def test_cenancestor(self): target = swagger.SwaggerSpec(title="") expected = ApiInterfaceBase( ApiContainer(ApiContainer(ApiContainer(), target, name='b'), name='a')) assert target.cenancestor is expected def test_generate_parameters(self): actual = swagger.SwaggerSpec.generate_parameters( UrlPath.parse('/api/a/{b}/c/{d:String}')) assert actual == [{ 'name': 'b', 'in': 'path', 'type': 'integer', 'required': True, }, { 'name': 'd', 'in': 'path', 'type': 'string', 'required': True, }] @pytest.mark.parametrize('node, expected', ( (Param.path('a'), '{a}'), (Param.path('a', Type.String), '{a}'), )) def test_swagger_node_formatter(self, node, expected): actual = swagger.SwaggerSpec.swagger_node_formatter(node) assert actual == expected def test_parse_operations(self): @Operation(path="a/{b:String}", methods=Method.POST, resource=User) def my_func(request, b): pass target = swagger.SwaggerSpec("Example", schemes='http') ApiInterfaceBase(ApiVersion( target, my_func, ), ) actual = target.parse_operations() assert len(actual) == 2 actual_paths, actual_resources = actual # Paths assert len(actual_paths) == 1 assert "/a/{b}" in actual_paths actual_path = actual_paths['/a/{b}'] assert actual_path['parameters'] == [{ 'in': 'path', 'type': 'string', 'name': 'b', 'required': True }] assert 'post' in actual_path actual_operation = actual_path['post'] assert actual_operation == my_func.to_swagger() # Resources assert len(actual_resources) == 3 assert 'tests.User' in actual_resources def test_get_swagger(self, monkeypatch): monkeypatch.setattr( swagger, 'CODECS', { 'application/json': None # Only the Keys are used. }) request = MockRequest() target = swagger.SwaggerSpec("Example", schemes='http') base = ApiInterfaceBase(ApiVersion(target, ), ) base.registered_codecs.clear() base.registered_codecs[ 'application/yaml'] = None # Only the keys are used. actual = target.get_swagger(request) expected = { 'swagger': '2.0', 'info': { 'title': 'Example', 'version': '1' }, 'host': '127.0.0.1', 'schemes': ['http'], 'basePath': '/api/v1', 'consumes': ['application/yaml'], 'produces': ['application/yaml'], 'paths': {}, 'definitions': { 'Error': { 'type': 'object', 'properties': { 'code': { 'description': 'Custom application specific error code that references into the application.', 'type': 'integer', 'format': 'int64', }, 'developer_message': { 'description': 'An error message suitable for the application developer', 'type': 'string' }, 'message': { 'description': 'A message that can be displayed to an end user', 'type': 'string' }, 'meta': { 'description': 'Additional meta information that can help solve errors.', }, 'status': { 'description': 'HTTP status code of the response.', 'type': 'integer', 'format': 'int64', } }, }, 'Listing': { 'type': 'object', 'properties': { 'limit': { 'description': 'Limit or page size of the result set', 'type': 'integer', 'format': 'int64', }, 'offset': { 'description': 'Offset within the result set.', 'type': 'integer', 'format': 'int64', }, 'results': { 'description': 'List of resources.', }, 'total_count': { 'description': 'The total number of items in the result set.', 'type': 'integer', 'format': 'int64', } }, } } } assert actual == expected def test_load_static(self): target = swagger.SwaggerSpec("", enable_ui=True) actual = target.load_static('ui.html') if _compat.PY2: assert actual.startswith('<!DOCTYPE html>') else: assert actual.startswith(b'<!DOCTYPE html>') def test_load_static__not_found_if_not_found(self): target = swagger.SwaggerSpec("") with pytest.raises(HttpError) as ex: target.load_static('eek.html') assert ex.value.status == HTTPStatus.NOT_FOUND def test_load_static__not_found_if_path_breakout_attempted(self): target = swagger.SwaggerSpec("") with pytest.raises(HttpError) as ex: target.load_static('/etc/passwd') assert ex.value.status == HTTPStatus.NOT_FOUND def test_get_ui(self): target = swagger.SwaggerSpec("") actual = target.get_ui(None) assert actual.body.startswith("<!DOCTYPE html>") assert actual.status == HTTPStatus.OK assert actual['Content-Type'] == 'text/html' @pytest.mark.parametrize('file_name, content_type', ( ("ui.css", 'text/css'), ("bundle.js", 'application/javascript'), )) def test_get_static(self, file_name, content_type): target = swagger.SwaggerSpec("") actual = target.get_static(None, file_name) # Can't check the body as it is pre-gzipped assert actual.status == HTTPStatus.OK assert actual['Content-Type'] == content_type assert actual['Content-Encoding'] == 'gzip' def test_get_static__not_found_if_unknown_content_type(self): target = swagger.SwaggerSpec("") with pytest.raises(HttpError) as ex: target.get_static(None, 'ui.html') assert ex.value.status == HTTPStatus.NOT_FOUND