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() == {}
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() == {}
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
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
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
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')
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
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}
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
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'
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)
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
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
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
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
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
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
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')
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() == {}
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() == {}
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
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() == {}
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
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
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
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
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'}
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}
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
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