def test_validators(): @handle_default_optional_desc() def even_validator(): def validator(value): try: i = int(value) except: raise Invalid("invalid int") if i % 2 == 0: return i else: raise Invalid("not even number") return validator app = Flask(__name__) api = Api(app, validators={"even": even_validator}) class Test: def get(self, number): """ $input: number?even: even number """ return { "number": number } api.add_resource(Test) with app.test_client() as c: resp = c.get("/test?number=2") assert resp.status_code == 200 resp = c.get("/test?number=3") assert resp.status_code == 400 assert resp_json(resp)["error"] == "InvalidData"
def test_shared_schema_override(): docs = """ Hello World $shared: x: int&min=0 """ app = Flask(__name__) api = Api(app, docs=docs) class Hello: """ $shared: x: int&max=0 """ def get(self, x): """ $input: x@x: x """ return {'x': x} api.add_resource(Hello) with app.test_client() as c: resp = c.get("/hello?x=1") assert resp.status_code == 400 resp = c.get("/hello?x=-1") assert resp.status_code == 200 assert resp_json(resp) == {"x": -1}
def app(): app = Flask(__name__) api = Api(app) class Hello: def get(self): return 'hello' def get_error(self): raise ValueError('error') api.add_resource(Hello) return app.test_client()
def test_schema_error_message_output(): app = Flask(__name__) api = Api(app) class Hello: def get(self): """ $output: message: xxx """ pass with pytest.raises(SchemaError) as exinfo: api.add_resource(Hello) assert exinfo.value.position == "Hello.get.$output.message"
def test_schema_error_message_shared(): app = Flask(__name__) api = Api(app) class Hello: """ $shared: message: xxx """ def get(self): pass with pytest.raises(SchemaError) as exinfo: api.add_resource(Hello) assert exinfo.value.position == "Hello.$shared.message"
def test_export_json_unicode(): app = Flask(__name__) api = Api(app) class Hello: def get(self): return {"message": "中文"} api.add_resource(Hello) # json content is encoded by utf-8, not unicode escape with app.test_client() as c: resp = c.get("/hello") assert resp.status_code == 200 assert "\\u" not in resp.data.decode("utf-8")
def test_input_output_schema(): app = Flask(__name__) api = Api(app) class Welcome: def __init__(self, userid): self.userid = userid self.message = "Hi, %d" % userid class Hello: def get(self, userid): """Get hello $input: userid?int: UserID $output: message?str: Welcome message """ return {"message": "Hi, %d" % userid} def post(self, userid): """Get hello $input: userid?int: UserID $output: message?str: Welcome message """ return Welcome(userid) api.add_resource(Hello) with app.test_client() as c: resp = c.get("/hello?userid=123") assert resp.status_code == 200 assert resp_json(resp) == {"message": "Hi, 123"} resp = c.post("/hello", data={"userid": 123}) assert resp.status_code == 200 assert resp_json(resp) == {"message": "Hi, 123"} headers = {"Content-Type": "application/json"} resp = c.post("/hello", data='{"userid": 123}', headers=headers) assert resp.status_code == 200 assert resp_json(resp) == {"message": "Hi, 123"}
def test_docs_and_shared_schema(): docs = """ Hello World $shared: userid: int&min=0 """ app = Flask(__name__) api = Api(app, docs=docs) assert api.meta["$desc"] == "Hello World" assert api.meta["$shared"] == {"userid": "int&min=0"} class Hello: """ docstring for Hello $shared: name: str """ def get(self, userid, name): """ Test shared schema $input: userid@userid: UserID name@name: UserName """ return { "userid": userid, "name": name } api.add_resource(Hello) with app.test_client() as c: resp = c.get("/hello?userid=123&name=kk") assert resp.status_code == 200 assert resp_json(resp) == { "userid": 123, "name": "kk" } resp = c.get("/hello?userid=abc&name=kk") assert resp.status_code == 400 assert resp_json(resp)["error"] == "InvalidData" assert "userid" in resp_json(resp)["message"]
def test_error_handler(): app = Flask(__name__) api = Api(app) class Hello: def get(self): raise ValueError("bug") api.add_resource(Hello) @api.error_handler def error_handler(ex): return "error_handler %s" % ex.args[0] with app.test_client() as c: resp = c.get("/hello") assert resp.status_code == 200 assert resp_json(resp) == "error_handler bug"
def test_after_request(): app = Flask(__name__) api = Api(app) class Hello: def get(self): return "Hello World" api.add_resource(Hello) @api.after_request def after_request(rv, code, headers): return "%s after_request" % rv, code, headers with app.test_client() as c: resp = c.get("/hello") assert resp.status_code == 200 assert resp_json(resp) == "Hello World after_request"
def test_before_request(): app = Flask(__name__) api = Api(app) class Hello: def get(self): return "Hello World" api.add_resource(Hello) @api.before_request def before_request(): return "before_request" with app.test_client() as c: resp = c.get("/hello") assert resp.status_code == 200 assert resp_json(resp) == "before_request"
def test_meta(): app = Flask(__name__) api = Api(app) # builtin keys assert '$desc' in api.meta assert '$title' in api.meta assert '$auth' in api.meta assert '$shared' in api.meta assert '$error' in api.meta
def test_no_schema(): app = Flask(__name__) api = Api(app) class Hello: def get(self): """ Get hello Welcome """ return {} api.add_resource(Hello) with app.test_client() as c: resp = c.get("/hello?name=kk") assert resp.status_code == 200 assert resp_json(resp) == {}
def test_no_input_schema(): app = Flask(__name__) api = Api(app) class Hello: def get(self): """ Get hello $output: message?str: welcome message """ return {} api.add_resource(Hello) with app.test_client() as c: resp = c.get("/hello?name=kk") assert resp.status_code == 500 assert resp_json(resp)["error"] == "ServerError"
def test_api_shared_schema_error_message(): docs = """" $shared: name: - key?xxx: desc """ app = Flask(__name__) with pytest.raises(SchemaError) as exinfo: Api(app, docs=docs) assert exinfo.value.position == "$shared.name[].key"
def test_meta_view(): app = Flask(__name__) api = Api(app) app.route('/')(api.meta_view) with app.test_client() as c: resp = c.get("/") assert resp.status_code == 200 assert resp.mimetype == 'text/html' resp = c.get("/?json") assert resp.status_code == 200 assert resp.mimetype == 'application/json'
def test_metafile(tmpdir): metafile = tmpdir.join("meta.json") json.dump({"$xxx": "test", "$roles": {}}, metafile.open("w")) app = Flask(__name__) api = Api(app, metafile=metafile.strpath) class Hello: """docstring for Hello""" def get(self): """Get hello""" api.add_resource(Hello) app.route('/')(api.meta_view) with app.test_client() as c: resp = c.get("/", headers={'Accept': 'application/json'}) assert resp.status_code == 200 assert resp_json(resp)["$xxx"] == "test" assert resp_json(resp)["$roles"] == {} assert resp_json(resp)["hello"]["$desc"] == "docstring for Hello" assert resp_json(resp)["hello"]["get"]["$desc"] == "Get hello"
def test_blueprint(): class Hello: """Blueprint test""" def get(self, name): """ Get Hello world message $input: name?str: Your name """ return {'message': 'Hello %s' % name} def get_message(self): pass app = Flask(__name__) bp = Blueprint('blueprint', __name__) api = Api(bp) api.add_resource(Hello) app.register_blueprint(bp, url_prefix='/api') with app.test_request_context('/api/hello'): assert request.endpoint == 'blueprint.hello' assert url_for('blueprint.hello') == '/api/hello' with app.test_request_context('/api/hello/message'): assert request.endpoint == 'blueprint.hello@message' assert url_for('blueprint.hello@message') == '/api/hello/message' with app.test_client() as c: resp = c.get('/api/hello?name=kk') assert resp.status_code == 200 assert resp_json(resp) == { "message": "Hello kk" } resp = c.get('/api/hello') assert resp.status_code == 400 assert resp_json(resp)["error"] == "InvalidData"
def test_shared_schema_order(): docs = """ Hello World $shared: a: int b: "@a" """ app = Flask(__name__) api = Api(app, docs=docs) class Hello: """ $shared: c: str d: "@c" e: "@b" """ def get(self, x, y, z): """ $input: x@b: x y@d: y z@e: z """ return {'x': x, 'y': y, 'z': z} api.add_resource(Hello) with app.test_client() as c: resp = c.get("/hello?x=123&y=kk&z=321") assert resp.status_code == 200 assert resp_json(resp) == { "x": 123, "y": "kk", "z": 321 }
def test_no_output_schema(): app = Flask(__name__) api = Api(app) class Hello: def get(self, userid): """Get hello $input: userid?int: UserID """ return {"message": userid} api.add_resource(Hello) with app.test_client() as c: resp = c.get("/hello?userid=123") assert resp.status_code == 200 assert resp_json(resp) == { "message": 123 } resp = c.get("/hello?userid=kk") assert resp.status_code == 400 assert resp_json(resp)["error"] == "InvalidData"
def test_authorize(tmpdir): metafile = tmpdir.join("meta.json") json.dump({ "$roles": { "admin": { "hello": ["get", "post"] }, "guest": { "hello": ["post"] } } }, metafile.open("w")) app = Flask(__name__) api = Api(app, metafile=metafile.strpath) class Hello: def get(self): pass def post(self): pass api.add_resource(Hello) with app.test_request_context("/hello", method="GET"): api.authorize("admin") with app.test_request_context("/hello", method="POST"): api.authorize("admin") with app.test_request_context("/hello", method="PUT"): with pytest.raises(ValueError): api.authorize("admin") with app.test_request_context("/hello/world", method="GET"): with pytest.raises(ValueError): api.authorize("admin") with app.test_request_context("/helloworld", method="POST"): with pytest.raises(ValueError): api.authorize("admin") with app.test_request_context("/helo", method="PUT"): with pytest.raises(ValueError): api.authorize("admin") with app.test_request_context("/hello", method="GET"): with pytest.raises(Forbidden): api.authorize("guest") with app.test_request_context("/hello", method="POST"): api.authorize("guest") with app.test_request_context("/hello", method="PUT"): with pytest.raises(ValueError): api.authorize("guest")
def test_helloworld(): class Hello: """Hello world test""" def get(self, name): """Get Hello world message $input: name?str&escape&default="world": Your name $output: message?str&maxlen=60: welcome message """ return { 'message': 'Hello {}'.format(name) } def get_message(self): pass def post(self, name): """Post message $input: name?str&escape&default="unknown": name $output: message?str&maxlen=60: post echo """ return { 'message': 'post by {}'.format(name) } def put(self, name): """Put message $input: name?str&escape&default="unknown": name $output: message?str&maxlen=60: put echo """ return { 'message': 'put by {}'.format(name) } app = Flask(__name__) api = Api(app) api.add_resource(Hello) with app.test_request_context('/hello'): assert request.endpoint == 'hello' assert url_for('hello') == '/hello' with app.test_request_context('/hello/message'): assert request.endpoint == 'hello@message' assert url_for('hello@message') == '/hello/message' with app.test_client() as c: headers = {'Content-Type': 'application/json'} good_params = dict(data='{"name":"tester"}', headers=headers) null_params = dict(data='{"name":null}', headers=headers) bad_params = dict(data='x', headers=headers) empty_params = dict(data='null', headers=headers) assert c.get('hello').status_code == 200 assert b'world' in c.get('hello').data assert b'tester' in c.get('hello?name=tester').data assert c.post('hello', **good_params).status_code == 200 assert c.post('hello', **null_params).status_code == 200 assert b'unknown' in c.post('hello', **null_params).data assert c.post('hello', **bad_params).status_code == 400 assert c.post('hello', **empty_params).status_code == 400 assert c.put('hello', **good_params).status_code == 200