예제 #1
0
def test_should_register_resource_with_subresource_with_same_method_names():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='parent')
    class SomeResource:
        @get('/')
        def get(self):
            return dict()

    @resource(name='child', parent=SomeResource)
    class SomeResource2:
        @get('/')
        def get(self, **kwargs):
            return dict()

    with app.app_context():
        SomeResource()
        SomeResource2()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/parent')
        assert response.status_code == 200
        assert response.get_json() == {}

        response = client.get('/api/rest/v1/parent/1/child')
        assert response.status_code == 200
        assert response.get_json() == {}
예제 #2
0
def test_should_register_different_api_version_resources_with_same_method_names(
):
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/')
        def get(self):
            return dict()

    @resource(name='test', version=2)
    class SomeResource2:
        @get('/')
        def get(self):
            return dict()

    with app.app_context():
        SomeResource()
        SomeResource2()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        assert response.status_code == 200
        assert response.get_json() == {}

        response = client.get('/api/rest/v2/test')
        assert response.status_code == 200
        assert response.get_json() == {}
예제 #3
0
def test_should_register_subresource():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='parent')
    class ParentResource:
        @get('/')
        def get_parent(self):
            return dict()

    @resource(name='child', parent=ParentResource)
    class ChildResource:
        @get('/')
        def get_child(self, parent_id):
            return dict(parent_id=int(parent_id))

    with app.app_context():
        ChildResource()
        ParentResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/parent/1/child')
        assert response.status_code == 200
        data = response.get_json()
        assert data['parent_id'] == 1
예제 #4
0
def test_should_inject_proper_headers():
    app = Flask(__name__)
    FlaskRestly(app)

    requests_limit = 2
    time_window = 2

    _data = dict()
    now = int(time())

    @rate.resolver
    def view_rate_limit(key, window, _):
        requests = _data.get(key, 0)
        _data[key] = requests + 1

        return _data.get(key, 0), now + window

    @resource(name='test')
    class SomeResource:
        @rate.limit(requests=requests_limit, window=time_window)
        @get('/<int:id>')
        def get_entity(self, id):
            return dict(id=id)

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test/1')
        assert response.headers.get('X-RateLimit-Limit',
                                    type=int) == requests_limit
        assert response.headers.get('X-RateLimit-Remaining',
                                    type=int) == requests_limit - 1
        assert response.headers.get('X-RateLimit-Reset',
                                    type=int) == now + time_window
예제 #5
0
def test_should_use_custom_group_name():
    app = Flask(__name__)
    FlaskRestly(app)

    requests_limit = 2
    group_name = 'test'
    data_group_name = '127.0.0.1__' + group_name

    _data = {
        data_group_name: requests_limit,
    }

    @rate.resolver
    def view_rate_limit(key, window, _):
        requests = _data.get(key, 0)
        _data[key] = requests + 1

        return _data.get(key, 0), time() + window

    @resource(name='test')
    class SomeResource:
        @rate.limit(requests=requests_limit, group=group_name)
        @get('/<int:id>')
        def get_entity(self, id):
            return dict(id=id)

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test/1')
        assert response.status_code == 429
예제 #6
0
def test_should_use_default_serializer_when_custom_serializer_not_provided():
    app = Flask(__name__)

    class SomeSerializer(SerializerBase):
        def serialize(self, response, _):
            return response.get('foo')

        def deserialize(self, request, _):
            pass

    app.config['RESTLY_SERIALIZER'] = SomeSerializer()

    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/')
        def get(self):
            return dict(foo='bar')

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        data = response.get_data()
        assert data == bytes('bar', 'utf8')
예제 #7
0
def test_should_return_429_code_if_too_much_requests():
    app = Flask(__name__)
    FlaskRestly(app)

    requests_limit = 2
    _data = dict()

    @rate.resolver
    def view_rate_limit(key, window, _):
        requests = _data.get(key, 0)
        _data[key] = requests + 1

        return _data.get(key, 0), time() + window

    @resource(name='test')
    class SomeResource:
        @rate.limit(requests=requests_limit)
        @get('/<int:id>')
        def get_entity(self, id):
            return dict(id=id)

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        for _ in range(requests_limit):
            response = client.get('/api/rest/v1/test/1')
            assert response.status_code == 200

        response = client.get('/api/rest/v1/test/1')
        assert response.status_code == 429
예제 #8
0
def test_should_return_200_code_with_content():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/<int:id>')
        def get_entity(self, id):
            return dict(id=id)

        @get('/')
        def get_entities(self):
            return dict()

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        assert response.status_code == 200
        assert response.get_json() == {}

        response = client.get('/api/rest/v1/test/1')
        assert response.status_code == 200
        assert response.get_json() == {'id': 1}
예제 #9
0
def test_should_register_nested_subresources():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='resource')
    class Resource:
        @get('/')
        def get(self):
            return dict()

    @resource(name='subresource1', parent=Resource)
    class Subresource1:
        @get('/')
        def get(self, **kwargs):
            pass

    @resource(name='subresource2', parent=Subresource1)
    class Subresource2:
        @get('/')
        def get(self, **kwargs):
            pass

    @resource(name='subresource3', parent=Subresource2)
    class Subresource3:
        @get('/')
        def get(self, **kwargs):
            pass

    @resource(name='subresource4', parent=Subresource3)
    class Subresource4:
        @get('/')
        def get(self, resource_id, subresource1_id, subresource2_id,
                subresource3_id):
            return dict(
                resource_id=int(resource_id),
                subresource1_id=int(subresource1_id),
                subresource2_id=int(subresource2_id),
                subresource3_id=int(subresource3_id),
            )

    with app.app_context():
        Resource()
        Subresource1()
        Subresource2()
        Subresource3()
        Subresource4()

    with app.test_client() as client:
        response = client.get(
            '/api/rest/v1/resource/1/subresource1/23/subresource2/45/subresource3/67/subresource4'
        )
        assert response.status_code == 200
        data = response.get_json()
        assert data['resource_id'] == 1
        assert data['subresource1_id'] == 23
        assert data['subresource2_id'] == 45
        assert data['subresource3_id'] == 67
예제 #10
0
def test_should_return_original_error_when_not_api_resource():
    app = Flask(__name__)
    FlaskRestly(app)

    @app.route('/some/url')
    def some_url():
        raise Exception("Some error")

    with app.test_client() as client:
        try:
            client.get('/some/url')
        except Exception as e:
            assert str(e) == 'Some error'
예제 #11
0
def test_should_not_raise_api_error_when_requested_not_api_resource():
    app = Flask(__name__)
    FlaskRestly(app)

    @app.route('/some/url')
    def some_url():
        raise Exception("Some error")

    with app.test_client() as client:
        try:
            client.get('/some/url')
        except Exception as e:
            assert not isinstance(e, InternalServerError)
예제 #12
0
def test_should_serialize_given_response_to_protobuf(data, expected_data):
    app = Flask(__name__)
    api = FlaskRestly()

    app.config['RESTLY_SERIALIZER'] = protobuf

    api.init_app(app)

    @resource(name='test')
    class SomeResource:
        @get('/')
        @body(Entity)
        def get(self):
            return data

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        data = response.get_data().strip(bytes('\n', 'utf8'))
        assert response.headers.get('Content-Type') == 'application/x-protobuf'
        assert data == expected_data
예제 #13
0
def test_should_deserialize_given_request_data_to_dictionary(request_data, expected_data):
    app = Flask(__name__)
    api = FlaskRestly()

    app.config['RESTLY_SERIALIZER'] = protobuf

    api.init_app(app)

    @resource(name='test')
    class SomeResource:
        @post('/')
        @body(incoming=Entity, outgoing=Entity)
        def get(self, body):
            print(body)
            return dict(id=body.get('id'))

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.post('/api/rest/v1/test', data=request_data)
        data = response.get_data()
        assert data == expected_data
예제 #14
0
def test_should_fail_when_identity_provider_not_defined_and_kwarg_required():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/')
        def get_entity(self, *, identity):
            return dict()

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        assert response.status_code == 500
예제 #15
0
def test_should_return_400_code_when_body_declared_but_not_provided():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @post('/')
        def get_entity(self, body):
            return dict()

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.post('/api/rest/v1/test')
        assert response.status_code == 400
예제 #16
0
def test_should_return_204_code_when_content_is_not_provided():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @patch('/')
        def create(self):
            pass

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.patch('/api/rest/v1/test', json=dict())
        assert response.status_code == 204
        assert response.get_json() is None
예제 #17
0
def test_should_serialize_given_response_to_json(data, expected_data):
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/')
        def get(self):
            return data

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        data = response.get_data().strip(bytes('\n', 'utf8'))
        assert data == expected_data
예제 #18
0
def test_should_use_custom_serialize_method_when_provided():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/', serialize=lambda r, _: r.get('foo'))
        def get(self):
            return dict(foo='bar')

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        data = response.get_data()
        assert data == bytes('bar', 'utf8')
예제 #19
0
def test_should_return_200_code_when_content_is_provided():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @delete('/')
        def delete(self):
            return dict()

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.delete('/api/rest/v1/test')
        assert response.status_code == 200
        assert response.get_json() == {}
예제 #20
0
def test_should_register_resource():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/')
        def get(self):
            return dict()

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        assert response.status_code == 200
        assert response.get_json() == {}
예제 #21
0
def test_should_return_json_when_http_error_raised(error, expected_error_code, expected_message):
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/')
        def get(self):
            raise error

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        assert response.status_code == expected_error_code
        data = response.get_json()
        assert data['error'] == expected_message
예제 #22
0
def test_should_return_202_code_with_content_when_action_is_queued():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/')
        @queued
        def get(self):
            return dict()

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        assert response.status_code == 202
        assert response.get_json() == {}
예제 #23
0
def test_should_serialize_given_response_to_json(api_prefix, route):
    app = Flask(__name__)

    app.config['RESTLY_API_PREFIX'] = api_prefix

    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/')
        def get(self):
            return dict()

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get(route)
        assert response.status_code == 200
예제 #24
0
def test_should_return_200_code_and_given_body_when_body_declared_and_provided():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @post('/')
        def get_entity(self, body):
            return body

    with app.app_context():
        SomeResource()

    body = {'foo': 'bar'}

    with app.test_client() as client:
        response = client.post('/api/rest/v1/test', json=body)
        assert response.status_code == 200
        assert response.get_json() == body
예제 #25
0
def test_should_return_403_code_if_not_authorized():
    app = Flask(__name__)
    FlaskRestly(app)

    @auth.provider
    def authorize():
        return False

    @resource(name='test')
    class SomeResource:
        @get('/<int:id>')
        def get_entity(self, id):
            return dict(id=id)

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test/1')
        assert response.status_code == 403
예제 #26
0
def test_should_not_serialize_when_response_object_provided():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/')
        def get(self):
            res = make_response('some response')
            res.status_code = 201
            return res

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        data = response.get_data()
        assert data == bytes('some response', 'utf8')
        assert response.status_code == 201
예제 #27
0
def test_should_return_201_code_when_content_provided_and_code_not_provided():
    app = Flask(__name__)
    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @put('/<int:id>')
        def replace(self, id):
            return dict(
                id=id,
                foo='foo',
                bar='bar',
            )

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.put('/api/rest/v1/test/1', json=dict())
        assert response.status_code == 201
        assert response.get_json() == {'id': 1, 'foo': 'foo', 'bar': 'bar'}
예제 #28
0
def test_should_return_200_code_if_authorization_is_skipped():
    app = Flask(__name__)
    FlaskRestly(app)

    @auth.provider
    def authorize():
        return False

    @resource(name='test')
    class SomeResource:
        @get('/<int:id>')
        @auth.unauthorized
        def get_entity(self, id):
            return dict(id=id)

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test/1')
        assert response.status_code == 200
        assert response.get_json() == {'id': 1}
예제 #29
0
def test_should_inject_identity_when_provider_defined_and_has_arg(mocker):
    app = Flask(__name__)
    FlaskRestly(app)

    stub = mocker.stub(name='identity_provider_stub')

    @identity.provider
    def identity_provider():
        stub()

    @resource(name='test')
    class SomeResource:
        @get('/')
        def get_entity(self, identity):
            return identity

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        assert response.status_code == 200
        assert stub.call_count == 1
예제 #30
0
def test_should_use_custom_protobuf_mime_type():
    expected_type = 'application/pb'

    app = Flask(__name__)

    app.config['RESTLY_SERIALIZER'] = protobuf
    app.config['RESTLY_PROTOBUF_MIMETYPE'] = expected_type

    FlaskRestly(app)

    @resource(name='test')
    class SomeResource:
        @get('/')
        @body(Entity)
        def get(self):
            return dict()

    with app.app_context():
        SomeResource()

    with app.test_client() as client:
        response = client.get('/api/rest/v1/test')
        assert response.headers.get('Content-Type') == expected_type