示例#1
0
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"
示例#2
0
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}
示例#3
0
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()
示例#4
0
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"
示例#5
0
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"
示例#6
0
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")
示例#7
0
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"}
示例#8
0
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"]
示例#9
0
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"
示例#10
0
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"
示例#11
0
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"
示例#12
0
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
示例#13
0
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) == {}
示例#14
0
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"
示例#15
0
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"
示例#16
0
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'
示例#17
0
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"
示例#18
0
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"
示例#19
0
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
        }
示例#20
0
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"
示例#21
0
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")
示例#22
0
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