def test_mapped_resource_routes(self): # Test non-standard URL routes ("mapped") function as expected class MappedResource(flask_restful.Resource): def post(self): rbac_enforcer.enforcer.RBACEnforcer().enforce_call( action='example:allowed') post_body = flask.request.get_json() return {'post_body': post_body}, 201 resource_map = flask_common.construct_resource_map( resource=MappedResource, url='test_api', alternate_urls=[], resource_kwargs={}, rel='test', status=json_home.Status.STABLE, path_vars=None, resource_relation_func=json_home.build_v3_resource_relation) restful_api = _TestRestfulAPI(resource_mapping=[resource_map], resources=[]) self.public_app.app.register_blueprint(restful_api.blueprint) token = self._get_token() with self.test_client() as c: body = {'test_value': uuid.uuid4().hex} resp = c.post('/v3/test_api', json=body, headers={'X-Auth-Token': token}) self.assertEqual(body, resp.json['post_body'])
def test_unenforced_api_decorator(self): # Test unenforced decorator works as expected class MappedResource(flask_restful.Resource): @flask_common.unenforced_api def post(self): post_body = flask.request.get_json() return {'post_body': post_body}, 201 resource_map = flask_common.construct_resource_map( resource=MappedResource, url='test_api', alternate_urls=[], resource_kwargs={}, rel='test', status=json_home.Status.STABLE, path_vars=None, resource_relation_func=json_home.build_v3_resource_relation) restful_api = _TestRestfulAPI(resource_mapping=[resource_map], resources=[]) self.public_app.app.register_blueprint(restful_api.blueprint) token = self._get_token() with self.test_client() as c: body = {'test_value': uuid.uuid4().hex} # Works with token resp = c.post('/v3/test_api', json=body, headers={'X-Auth-Token': token}) self.assertEqual(body, resp.json['post_body']) # Works without token resp = c.post('/v3/test_api', json=body) self.assertEqual(body, resp.json['post_body'])
def test_construct_resource_map(self): param_relation = json_home.build_v3_parameter_relation( 'argument_id') url = '/v3/arguments/<string:argument_id>' old_url = ['/v3/old_arguments/<string:argument_id>'] resource_name = 'arguments' mapping = flask_common.construct_resource_map( resource=_TestResourceWithCollectionInfo, url=url, resource_kwargs={}, alternate_urls=old_url, rel=resource_name, status=json_home.Status.EXPERIMENTAL, path_vars={'argument_id': param_relation}, resource_relation_func=json_home.build_v3_resource_relation) self.assertEqual(_TestResourceWithCollectionInfo, mapping.resource) self.assertEqual(url, mapping.url) self.assertEqual(old_url, mapping.alternate_urls) self.assertEqual(json_home.build_v3_resource_relation(resource_name), mapping.json_home_data.rel) self.assertEqual(json_home.Status.EXPERIMENTAL, mapping.json_home_data.status) self.assertEqual({'argument_id': param_relation}, mapping.json_home_data.path_vars)
def test_correct_json_home_document(self): class MappedResource(flask_restful.Resource): def post(self): rbac_enforcer.enforcer.RBACEnforcer().enforce_call( action='example:allowed') post_body = flask.request.get_json() return {'post_body': post_body} # NOTE(morgan): totally fabricated json_home data based upon our TEST # restful_apis. json_home_data = { 'https://docs.openstack.org/api/openstack-identity/3/' 'rel/argument': { 'href-template': '/v3/arguments/{argument_id}', 'href-vars': { 'argument_id': 'https://docs.openstack.org/api/' 'openstack-identity/3/param/argument_id' } }, 'https://docs.openstack.org/api/openstack-identity/3/' 'rel/arguments': { 'href': '/v3/arguments' }, 'https://docs.openstack.org/api/openstack-identity/3/' 'rel/test': { 'href': '/v3/test_api' }, } resource_map = flask_common.construct_resource_map( resource=MappedResource, url='test_api', alternate_urls=[], resource_kwargs={}, rel='test', status=json_home.Status.STABLE, path_vars=None, resource_relation_func=json_home.build_v3_resource_relation) restful_api = _TestRestfulAPI(resource_mapping=[resource_map]) self.public_app.app.register_blueprint(restful_api.blueprint) with self.test_client() as c: headers = {'Accept': 'application/json-home'} resp = c.get('/', headers=headers) resp_data = jsonutils.loads(resp.data) for rel in json_home_data: self.assertThat(resp_data['resources'][rel], matchers.Equals(json_home_data[rel]))
def test_construct_resource_map(self): resource_name = 'arguments' param_relation = json_home.build_v3_parameter_relation( 'argument_id') alt_rel_func = functools.partial( json_home.build_v3_extension_resource_relation, extension_name='extension', extension_version='1.0') url = '/v3/arguments/<string:argument_id>' old_url = [dict( url='/v3/old_arguments/<string:argument_id>', json_home=flask_common.construct_json_home_data( rel='arguments', resource_relation_func=alt_rel_func) )] mapping = flask_common.construct_resource_map( resource=_TestResourceWithCollectionInfo, url=url, resource_kwargs={}, alternate_urls=old_url, rel=resource_name, status=json_home.Status.EXPERIMENTAL, path_vars={'argument_id': param_relation}, resource_relation_func=json_home.build_v3_resource_relation) self.assertEqual(_TestResourceWithCollectionInfo, mapping.resource) self.assertEqual(url, mapping.url) self.assertEqual(json_home.build_v3_resource_relation(resource_name), mapping.json_home_data.rel) self.assertEqual(json_home.Status.EXPERIMENTAL, mapping.json_home_data.status) self.assertEqual({'argument_id': param_relation}, mapping.json_home_data.path_vars) # Check the alternate URL data is populated sanely self.assertEqual(1, len(mapping.alternate_urls)) alt_url_data = mapping.alternate_urls[0] self.assertEqual(old_url[0]['url'], alt_url_data['url']) self.assertEqual(old_url[0]['json_home'], alt_url_data['json_home'])
def test_HTTP_OPTIONS_is_unenforced(self): # Standup a test mapped resource and call OPTIONS on it. This will # return a header "Allow" with the valid methods, in this case # OPTIONS and POST. Ensure that the response otherwise conforms # as expected. class MappedResource(flask_restful.Resource): def post(self): # we don't actually use this or call it. pass resource_map = flask_common.construct_resource_map( resource=MappedResource, url='test_api', alternate_urls=[], resource_kwargs={}, rel='test', status=json_home.Status.STABLE, path_vars=None, resource_relation_func=json_home.build_v3_resource_relation) restful_api = _TestRestfulAPI(resource_mapping=[resource_map], resources=[]) self.public_app.app.register_blueprint(restful_api.blueprint) with self.test_client() as c: r = c.options('/v3/test_api') # make sure we split the data and left/right strip off whitespace # The use of a SET here is to ensure the exact values are in place # even if hash-seeds change order. `r.data` will be an empty # byte-string. `Content-Length` will be 0. self.assertEqual( set(['OPTIONS', 'POST']), set([ v.lstrip().rstrip() for v in r.headers['Allow'].split(',') ])) self.assertEqual(r.headers['Content-Length'], '0') self.assertEqual(r.data, b'')