def test_get_for_nested_obj(drone_doc_parsed_classes, drone_doc, session, constants): """Test CRUD get operation for object that can contain other objects.""" expanded_base_url = DocUrl.doc_url for class_ in drone_doc_parsed_classes: for prop in drone_doc.parsed_classes[class_][ 'class'].supportedProperty: if not isinstance(prop.prop, HydraLink): if expanded_base_url in prop.prop: dummy_obj = gen_dummy_object(class_, drone_doc) nested_class = prop.prop.split(expanded_base_url)[1] obj_id = str(uuid.uuid4()) response = crud.insert(object_=dummy_obj, id_=obj_id, session=session) object_ = crud.get(id_=obj_id, type_=class_, session=session, api_name='api') assert prop.title in object_ nested_obj_id = object_[prop.title] nested_obj = crud.get(id_=nested_obj_id, type_=nested_class, session=session, api_name='api') assert nested_obj['@id'].split('/')[-1] == nested_obj_id break
def on_get(self, req, resp, id_, type_): """GET object with id = id_ from the database.""" if get_authentication(resp): if req.auth is None: return failed_authentication(resp) else: try: auth = check_authorization(req, get_session(resp)) if auth is False: return failed_authentication(resp) except Exception as e: status_code, message = e.get_HTTP() # type: ignore resp.media = message return set_response_headers(resp, status_code=status_code) class_type = get_doc(resp).collections[type_]["collection"].class_.title if checkClassOp(resp, class_type, "GET"): try: resp.media = hydrafy(resp, crud.get(id_, class_type, api_name=get_api_name(resp), session=get_session(resp))) return set_response_headers(resp) except Exception as e: status_code, message = e.get_HTTP() resp.media = message return set_response_headers(resp, status_code= status_code) resp.status = falcon.HTTP_405
def test_delete_multiple_id(drone_doc_parsed_classes, drone_doc, session): """Test CRUD insert when multiple ID's are given """ objects = list() ids = '{},{}'.format(str(uuid.uuid4()), str(uuid.uuid4())) random_class = random.choice(drone_doc_parsed_classes) for index in range(len(ids.split(','))): object = gen_dummy_object(random_class, drone_doc) objects.append(object) insert_response = crud.insert_multiple(objects_=objects, session=session, id_=ids) delete_response = crud.delete_multiple(id_=ids, type_=random_class, session=session) response_code = None id_list = ids.split(',') try: for index in range(len(id_list)): get_response = crud.get(id_=id_list[index], type_=objects[index]['@type'], session=session, api_name='api') except Exception as e: error = e.get_HTTP() response_code = error.code assert 404 == response_code
def finalize_response(path: str, obj: Dict[str, Any]) -> Dict[str, Any]: """ finalize response objects by removing properties which are not readable and correcting path of nested objects. :param path: Path of the collection or non-collection class. :param obj: object being finalized :return: An object not containing any `readable=False` properties and having proper path of any nested object's url. """ for prop in get_doc().parsed_classes[path]["class"].supportedProperty: # Skip not required properties which are not inserted yet. if not prop.required and prop.title not in obj: continue if prop.read is False: obj.pop(prop.title, None) elif isinstance(prop.prop, HydraLink): hydra_link = prop.prop range_class = hydra_link.range.replace("vocab:", "") nested_path, is_collection = get_nested_class_path(range_class) if is_collection: id = obj[prop.title] obj[prop.title] = "/{}/{}/{}".format(get_api_name(), nested_path, id) else: obj[prop.title] = "/{}/{}".format(get_api_name(), nested_path) elif 'vocab:' in prop.prop: prop_class = prop.prop.replace("vocab:", "") id = obj[prop.title] obj[prop.title] = crud.get(id, prop_class, get_api_name(), get_session()) return obj
def get(self, id_, type_): """GET object with id = id_ from the database.""" if get_authentication(): if request.authorization is None: return failed_authentication() else: auth = check_authorization(request, get_session()) if auth is False: return failed_authentication() class_type = get_doc().collections[type_]["collection"].class_.title if checkClassOp(class_type, "GET"): try: response = crud.get(id_, class_type, api_name=get_api_name(), session=get_session()) return set_response_headers(jsonify(hydrafy(response))) except Exception as e: status_code, message = e.get_HTTP() return set_response_headers(jsonify(message), status_code=status_code) abort(405)
def get(self, id_: str, path: str) -> Response: """ GET object with id = id_ from the database. :param id : Item ID :param path : Path for Item ( Specified in APIDoc @id) """ id_ = str(id_) auth_response = check_authentication_response() if isinstance(auth_response, Response): return auth_response class_type = get_doc().collections[path]["collection"].class_.title if checkClassOp(class_type, "GET"): # Check if class_type supports GET operation try: # Try getting the Item based on ID and Class type response = crud.get(id_, class_type, api_name=get_api_name(), session=get_session()) return set_response_headers( jsonify(hydrafy(response, path=path))) except (ClassNotFound, InstanceNotFound) as e: status_code, message = e.get_HTTP() return set_response_headers(jsonify(message), status_code=status_code) abort(405)
def get(self, id_: int, type_: str) -> Response: """ GET object with id = id_ from the database. :param id : Item ID :param type_ : Item type """ auth_response = check_authentication_response() if type(auth_response) == Response: return auth_response class_type = get_doc().collections[type_]["collection"].class_.title if checkClassOp(class_type, "GET"): # Check if class_type supports GET operation try: # Try getting the Item based on ID and Class type response = crud.get(id_, class_type, api_name=get_api_name(), session=get_session()) return set_response_headers(jsonify(hydrafy(response))) except Exception as e: status_code, message = e.get_HTTP() # type: ignore return set_response_headers(jsonify(message), status_code=status_code) abort(405)
def test_delete_ids(self): objects = list() ids = "1,2,3" for index in range(len(ids.split(','))): object = gen_dummy_object( random.choice(self.doc_collection_classes), self.doc) objects.append(object) insert_response = crud.insert_multiple(objects_=objects, session=self.session, id_=ids) delete_response = crud.delete_multiple(id_=ids, type_=objects[0]["@type"], session=self.session) response_code = None id_list = ids.split(',') try: for index in range(len(id_list)): get_response = crud.get(id_=id_list[index], type_=objects[index]["@type"], session=self.session, api_name="api") except Exception as e: response_code, message = e.get_HTTP() assert 404 == response_code
def test_get(self): """Test CRUD get.""" object_ = gen_dummy_object("dummyClass", self.doc) id_ = 2 response = crud.insert(object_=object_, id_=id_, session=self.session) object_ = crud.get(id_=id_, type_=object_["@type"], session=self.session, api_name="api") assert type(response) is int assert int(object_["@id"].split("/")[-1]) == id_
def finalize_response(path: str, obj: Dict[str, Any]) -> Dict[str, Any]: """ finalize response objects by removing properties which are not readable and correcting path of nested objects. :param path: Path of the collection or non-collection class. :param obj: object being finalized :return: An object not containing any `readable=False` properties and having proper path of any nested object's url. """ collections, parsed_classes = get_collections_and_parsed_classes() expanded_base_url = DocUrl.doc_url if path in collections: members = list() for member in obj["members"]: member_id = member[0] member_type = member[1] member_path = get_path_from_type(member_type) member = { "@type": "hydra:Link", "@id": f"{get_host_domain()}/{get_api_name()}/{member_path}/{member_id}", } members.append(member) obj['members'] = members return obj else: # path is of a non-collection class supported_properties = get_doc( ).parsed_classes[path]["class"].supportedProperty expanded_base_url = DocUrl.doc_url for prop in supported_properties: # Skip not required properties which are not inserted yet. if not prop.required and prop.title not in obj: continue # if prop.read is False: # obj.pop(prop.title, None) elif isinstance(prop.prop, HydraLink): hydra_link = prop.prop range_class = hydra_link.range.split(expanded_base_url)[1] nested_path, is_collection = get_nested_class_path(range_class) if is_collection: id = obj[prop.title] obj[prop.title] = f"/{get_api_name()}/{nested_path}/{id}" else: obj[prop.title] = f"/{get_api_name()}/{nested_path}" elif expanded_base_url in prop.prop: prop_class = prop.prop.split(expanded_base_url)[1] prop_class_path = parsed_classes[prop_class]['class'].path id = obj[prop.title] class_resp = crud.get(id, prop_class, get_api_name(), get_session(), path=prop_class_path) obj[prop.title] = finalize_response(prop_class_path, class_resp) return obj
def test_get_id(self): """Test CRUD get when wrong/undefined ID is given.""" id_ = 999 type_ = "dummyClass" response_code = None try: get_response = crud.get(id_=id_, type_=type_, session=self.session, api_name="api") except Exception as e: response_code, message = e.get_HTTP() assert 404 == response_code
def test_get_for_nested_obj(self): """Test get operation for object that can contain other objects.""" for class_ in self.doc_collection_classes: for prop in self.doc.parsed_classes[class_][ "class"].supportedProperty: if isinstance(prop.prop, HydraLink) or "vocab:" in prop.prop: link_props = {} dummy_obj = gen_dummy_object(class_, self.doc) if isinstance(prop.prop, HydraLink): nested_class = prop.prop.range.replace("vocab:", "") for collection_path in self.doc.collections: coll_class = self.doc.collections[collection_path][ 'collection'].class_.title if nested_class == coll_class: id_ = str(uuid.uuid4()) crud.insert(gen_dummy_object( nested_class, self.doc), id_=id_, session=self.session) link_props[prop.title] = id_ dummy_obj[prop.title] = "{}/{}/{}".format( self.API_NAME, collection_path, id_) else: nested_class = prop.prop.replace("vocab:", "") obj_id = str(uuid.uuid4()) response = crud.insert(object_=dummy_obj, id_=obj_id, link_props=link_props, session=self.session) object_ = crud.get(id_=obj_id, type_=class_, session=self.session, api_name="api") assert prop.title in object_ nested_obj_id = object_[prop.title] nested_obj = crud.get(id_=nested_obj_id, type_=nested_class, session=self.session, api_name="api") assert nested_obj["@id"].split("/")[-1] == nested_obj_id break
def test_get(self): """Test CRUD get.""" object_ = gen_dummy_object(random.choice(self.doc_collection_classes), self.doc) id_ = "2" response = crud.insert(object_=object_, id_=id_, session=self.session) object_ = crud.get(id_=id_, type_=object_["@type"], session=self.session, api_name="api") assert isinstance(response, str) assert object_["@id"].split("/")[-1] == id_
def test_update(self): """Test CRUD update.""" object_ = gen_dummy_object("dummyClass", self.doc) new_object = gen_dummy_object("dummyClass", self.doc) id_ = 30 insert_response = crud.insert(object_=object_, id_=id_, session=self.session) update_response = crud.update(id_=id_, type_=object_["@type"], object_=new_object, session=self.session, api_name="api") test_object = crud.get(id_=id_, type_=object_["@type"], session=self.session, api_name="api") assert type(insert_response) is int assert type(update_response) is int assert insert_response == update_response assert int(test_object["@id"].split("/")[-1]) == id_
def test_delete(self): """Test CRUD delete.""" object_ = gen_dummy_object("dummyClass", self.doc) id_ = 4 insert_response = crud.insert(object_=object_, id_=id_, session=self.session) delete_response = crud.delete(id_=id_, type_=object_["@type"], session=self.session) assert type(insert_response) is int response_code = None try: get_response = crud.get(id_=id_, type_=object_["@type"], session=self.session, api_name="api") except Exception as e: response_code, message = e.get_HTTP() assert 404 == response_code
def test_get_id(self): """Test CRUD get when wrong/undefined ID is given.""" id_ = "999" type_ = random.choice(self.doc_collection_classes) response_code = None try: get_response = crud.get(id_=id_, type_=type_, session=self.session, api_name="api") except Exception as e: response_code, message = e.get_HTTP() assert 404 == response_code
def test_get_type(self): """Test CRUD get when wrong/undefined class is given.""" id_ = str(uuid.uuid4()) type_ = "otherClass" response_code = None try: get_response = crud.get(id_=id_, type_=type_, session=self.session, api_name="api") except Exception as e: error = e.get_HTTP() assert 400 == error.code
def test_crud_get_returns_correct_object(drone_doc_parsed_classes, drone_doc, session): """Test CRUD get returns correct object""" object_ = gen_dummy_object(random.choice(drone_doc_parsed_classes), drone_doc) id_ = str(uuid.uuid4()) response = crud.insert(object_=object_, id_=id_, session=session) object_ = crud.get(id_=id_, type_=object_['@type'], session=session, api_name='api') assert isinstance(response, str) assert object_['@id'].split('/')[-1] == id_
def test_get_on_wrong_id(drone_doc_parsed_classes, drone_doc, session): """Test CRUD get when wrong/undefined ID is given.""" id_ = str(uuid.uuid4()) type_ = random.choice(drone_doc_parsed_classes) response_code = None try: get_response = crud.get(id_=id_, type_=type_, session=session, api_name='api') except Exception as e: error = e.get_HTTP() response_code = error.code assert 404 == response_code
def items_get_check_support(id_, class_type, class_path, path, is_collection=False): """Check if class_type supports GET operation""" try: # Try getting the Item based on ID and Class type response = crud.get( id_, class_type, api_name=get_api_name(), session=get_session(), path=path, collection=is_collection) response = finalize_response(class_path, response) return set_response_headers( jsonify(hydrafy(response, path=path))) except (ClassNotFound, InstanceNotFound) as e: error = e.get_HTTP() return error_response(error)
def test_update_on_object(drone_doc_parsed_classes, drone_doc, session): """Test CRUD update on object""" random_class = random.choice(drone_doc_parsed_classes) object_ = gen_dummy_object(random_class, drone_doc) new_object = gen_dummy_object(random_class, drone_doc) id_ = str(uuid.uuid4()) insert_response = crud.insert(object_=object_, id_=id_, session=session) update_response = crud.update(id_=id_, type_=object_['@type'], object_=new_object, session=session, api_name='api') test_object = crud.get(id_=id_, type_=object_['@type'], session=session, api_name='api') assert isinstance(insert_response, str) assert isinstance(update_response, str) assert insert_response == update_response assert test_object['@id'].split('/')[-1] == id_
def test_delete_on_object(drone_doc_parsed_classes, drone_doc, session): """Test CRUD delete on object""" object_ = gen_dummy_object(random.choice(drone_doc_parsed_classes), drone_doc) id_ = str(uuid.uuid4()) insert_response = crud.insert(object_=object_, id_=id_, session=session) assert isinstance(insert_response, str) delete_response = crud.delete(id_=id_, type_=object_['@type'], session=session) response_code = None try: get_response = crud.get(id_=id_, type_=object_['@type'], session=session, api_name='api') except Exception as e: error = e.get_HTTP() response_code = error.code assert 404 == response_code
def test_delete(self): """Test CRUD delete.""" object_ = gen_dummy_object(random.choice(self.doc_collection_classes), self.doc) id_ = "4" insert_response = crud.insert(object_=object_, id_=id_, session=self.session) delete_response = crud.delete(id_=id_, type_=object_["@type"], session=self.session) assert isinstance(insert_response, str) response_code = None try: get_response = crud.get(id_=id_, type_=object_["@type"], session=self.session, api_name="api") except Exception as e: response_code, message = e.get_HTTP() assert 404 == response_code
def test_update(self): """Test CRUD update.""" random_class = random.choice(self.doc_collection_classes) object_ = gen_dummy_object(random_class, self.doc) new_object = gen_dummy_object(random_class, self.doc) id_ = "30" insert_response = crud.insert(object_=object_, id_=id_, session=self.session) update_response = crud.update(id_=id_, type_=object_["@type"], object_=new_object, session=self.session, api_name="api") test_object = crud.get(id_=id_, type_=object_["@type"], session=self.session, api_name="api") assert isinstance(insert_response, str) assert isinstance(update_response, str) assert insert_response == update_response assert test_object["@id"].split("/")[-1] == id_