def test_langstring_tojson(self) -> None: """Test converting a LangString to JSON and JSON-LD""" ls = LangString(self.simple_string_de) json = ls.toJsonObj() self.assertEqual(json, self.simple_string_de) json = ls.toJsonLdObj() self.assertEqual(json, self.simple_string_de) ls = LangString({ Languages.DE: self.simple_string_de, Languages.FR: self.simple_string_fr }) json = ls.toJsonObj() expected = [{ 'language': 'de', 'value': self.simple_string_de }, { 'language': 'fr', 'value': self.simple_string_fr }] self.assertEqual(json, expected) jsonld = ls.toJsonLdObj() expected = [{ '@language': 'de', '@value': self.simple_string_de }, { '@language': 'fr', '@value': self.simple_string_fr }] self.assertEqual(jsonld, expected)
def test_ListNode_create(self) -> None: """ Create a list node :return: None """ node = ListNode(con=self.con, project=self.project, label=LangString({Languages.DE: "root node 1"}), comments=LangString({Languages.DE: "first root node"}), name="test_node_1").create() self.assertIsNotNone(node.id) self.assertEqual(node.project, self.project) self.assertEqual(node.label['de'], "root node 1") self.assertEqual(node.comments['de'], "first root node") self.assertEqual(node.name, "test_node_1") self.assertTrue(node.isRootNode)
def test_project_update(self) -> None: project = Project(con=self.con, shortcode='0FF1', shortname="update_project", longname="Update Project", description=LangString({ Languages.EN: 'Project to be updated', Languages.DE: 'Update-Projekt' }), keywords={'test', 'project'}, selfjoin=False, status=True, logo=self.logo_file).create() project.shortname = "update_project" project.longname = "Update Project" project.addDescription('fr', 'Projet modifié') project.rmDescription('de') project.selfjoin = True project.status = False project.rmKeyword('project') project.addKeyword('updated') updated_project = project.update() self.assertEqual(updated_project.shortcode, '0FF1') self.assertEqual(updated_project.shortname, 'update_project') self.assertEqual(updated_project.longname, 'Update Project') self.assertEqual(updated_project.description['en'], 'Project to be updated') self.assertEqual(updated_project.description['fr'], 'Projet modifié') self.assertEqual(updated_project.selfjoin, True) self.assertEqual(updated_project.status, False) self.assertEqual(updated_project.keywords, {'test', 'updated'})
def test_Project(self) -> None: project = Project(con=self.con, id='http://rdfh.ch/test', shortcode='0FF0', shortname="test_project", longname="Test Project", description=LangString({ Languages.EN: 'This is a test project', Languages.DE: 'Das ist ein Testprojekt' }), keywords={'test', 'project'}, selfjoin=False, status=True, logo=self.logo_file) self.assertIsNotNone(project) self.assertEqual(project.id, 'http://rdfh.ch/test') self.assertEqual(project.shortcode, '0FF0') self.assertEqual(project.shortname, 'test_project') self.assertEqual(project.longname, 'Test Project') self.assertEqual(project.description['en'], 'This is a test project') self.assertEqual(project.description['de'], 'Das ist ein Testprojekt') self.assertEqual(project.selfjoin, False) self.assertEqual(project.status, True) self.assertEqual(project.keywords, {'test', 'project'})
def test_project_delete(self) -> None: project = Project(con=self.con, shortcode='0FF2', shortname="delete_project", longname="Delete Project", description=LangString({ Languages.EN: 'Project to be deleted', Languages.DE: 'Lösch-Projekt' }), keywords={'test', 'project', 'delete'}, selfjoin=False, status=True, logo=self.logo_file).create() deleted_project = project.delete() self.assertEqual(deleted_project.shortcode, '0FF2') self.assertEqual(deleted_project.shortname, 'delete_project') self.assertEqual(deleted_project.longname, 'Delete Project') self.assertEqual(deleted_project.description['en'], 'Project to be deleted') self.assertEqual(deleted_project.description['de'], 'Lösch-Projekt') self.assertEqual(deleted_project.selfjoin, False) self.assertEqual(deleted_project.status, False) self.assertEqual(deleted_project.keywords, {'test', 'project', 'delete'})
def fromJsonObj(cls, con: Connection, json_obj: Any): id = json_obj.get('id') if id is None: raise BaseError('Group "id" is missing') name = json_obj.get('name') if name is None: raise BaseError('Group "name" is missing') descriptions = LangString.fromJsonObj(json_obj.get('descriptions')) tmp = json_obj.get('project') if tmp is None: raise BaseError('Group "project" is missing') project = tmp.get('id') if project is None: raise BaseError('Group "project" has no "id"') selfjoin = json_obj.get('selfjoin') if selfjoin is None: raise BaseError("selfjoin is missing") status = json_obj.get('status') if status is None: raise BaseError("Status is missing") return cls(con=con, name=name, id=id, descriptions=descriptions, project=project, selfjoin=selfjoin, status=status)
def test_Group_update(self) -> None: """ Update an existing group :return: None """ group = Group(con=self.con, name="Group update", descriptions=LangString( {Languages.EN: 'This is group update'}), project=self.test_project, status=True, selfjoin=False).create() group.name = "Group update - modified" group.descriptions = {"en": "This is group update - modified"} group.selfjoin = True group.status = False updated_group = group.update() self.assertEqual(updated_group.name, 'Group update - modified') self.assertCountEqual(updated_group.descriptions.toJsonObj(), [{ 'language': 'en', 'value': 'This is group ' 'update - ' 'modified' }]) self.assertEqual(updated_group.project, self.test_project) self.assertFalse(updated_group.status) self.assertTrue(updated_group.selfjoin)
def create_groups(con: Connection, groups: list[dict[str, str]], project: Project, verbose: bool) -> dict[str, Group]: """ Creates group(s) on a DSP server from a list of group definitions Args: con: connection instance to connect to the DSP server groups: List of definitions of the groups (JSON) to be created project: Project the group(s) should be added to verbose: Prints out more information if set to True Returns: Dict with group names and groups """ new_groups: dict[str, Group] = {} for group in groups: group_name = group["name"] # check if the group already exists, skip if so all_groups: Optional[list[Group]] = Group.getAllGroups(con) group_exists: bool = False if all_groups: for group_item in all_groups: if group_item.project == project.id and group_item.name == group_name: group_exists = True if group_exists: print(f"WARN Group '{group_name}' already exists. Skipping...") continue # check if status is defined, set default value if not group_status: Optional[str] = group.get("status") group_status_bool = True if isinstance(group_status, str): group_status_bool = json.loads(group_status.lower()) # lower() converts string to boolean # check if selfjoin is defined, set default value if not group_selfjoin: Optional[str] = group.get("selfjoin") group_selfjoin_bool = False if isinstance(group_selfjoin, str): group_selfjoin_bool = json.loads(group_selfjoin.lower()) # lower() converts string to boolean # create the group try: new_group: Group = Group(con=con, name=group_name, descriptions=LangString(group["descriptions"]), project=project, status=group_status_bool, selfjoin=group_selfjoin_bool).create() if verbose: print(f"Created group '{group_name}'.") if new_group.name: new_groups[new_group.name] = new_group except BaseError as err: print(f"ERROR while trying to create group '{group_name}'. The error message was: {err.message}") exit(1) except Exception as exception: print(f"ERROR while trying to create group '{group_name}'. The error message was: {exception}") exit(1) return new_groups
def create_project(con: Connection, data_model: dict[str, Any], verbose: bool) -> Project: """ Creates a project on a DSP server with information provided in the data_model Args: con: connection instance to connect to the DSP server data_model: The data model as JSON verbose: Prints out more information if set to True Returns: created project """ project_shortcode = data_model["project"]["shortcode"] project_shortname = data_model["project"]["shortname"] try: project = Project(con=con, shortcode=data_model["project"]["shortcode"], shortname=data_model["project"]["shortname"], longname=data_model["project"]["longname"], description=LangString(data_model["project"].get("descriptions")), keywords=set(data_model["project"].get("keywords")), selfjoin=False, status=True).create() if verbose: print(f"Created project '{project_shortname}' ({project_shortcode}).") return project except BaseError as err: print( f"ERROR while trying to create project '{project_shortname}' ({project_shortcode}). The error message was: {err.message}") exit(1) except Exception as exception: print( f"ERROR while trying to create project '{project_shortname}' ({project_shortcode}). The error message was: {exception}") exit(1)
def test_langstring_instantiation3(self) -> None: """Test a LangString using string and Languages-enums as index.""" ls = LangString({ Languages.DE: self.simple_string_de, Languages.FR: self.simple_string_fr }) self.assertEqual(ls[Languages.DE], self.simple_string_de) self.assertEqual(ls['fr'], self.simple_string_fr)
def __init__(self, con: Connection, id: Optional[str] = None, name: Optional[str] = None, descriptions: LangString = None, project: Optional[Union[str, Project]] = None, selfjoin: Optional[bool] = None, status: Optional[bool] = None): super().__init__(con) self._id = str(id) if id is not None else None self._name = str(name) if name is not None else None self._descriptions = LangString(descriptions) if project is not None and isinstance(project, Project): self._project = project.id else: self._project = str(project) if project is not None else None self._selfjoin = bool(selfjoin) if selfjoin is not None else None self._status = bool(status) if status is not None else None
def test_langstring_change(self) -> None: """test if changing a LangString item works.""" ls = LangString({ Languages.DE: self.simple_string_de, Languages.FR: self.simple_string_fr }) ls['de'] = 'gagaga' self.assertEqual(ls[Languages.DE], 'gagaga') self.assertEqual(ls['fr'], self.simple_string_fr)
def test_ListNode_update(self) -> None: """ Update the data of a node :return: None """ node = ListNode(con=self.con, project=self.project, label=LangString({Languages.EN: "root node 3"}), comments=LangString({Languages.EN: "Third root node"}), name="test_node").create() node.addLabel('de', "Neues Label") node.rmLabel('en') node.addComment('fr', 'un commentaire en français') node.rmComment('en') node.name = 'test_node_update' node.update() self.assertEqual(node.label['de'], "Neues Label") self.assertEqual(node.comments['fr'], 'un commentaire en français') self.assertEqual(node.name, 'test_node_update')
def test_ListNode_hierarchy(self) -> None: """ Create a node and a sub-node :return: None """ node = ListNode(con=self.con, project=self.project, label=LangString({Languages.EN: "root node"}), comments=LangString( {Languages.EN: "This is a root node"}), name="root_node").create() subnode = ListNode( con=self.con, project=self.project, label=LangString({Languages.DE: 'Ein Knoten der Liste'}), comments=LangString({Languages.DE: "Ein Kommentar"}), name="sub_node", parent=node).create() self.assertTrue(node.isRootNode) self.assertFalse(subnode.isRootNode)
def test_langstring_iterator(self) -> None: """Test iterating over a LangString.""" ls = LangString({ Languages.DE: self.simple_string_de, Languages.FR: self.simple_string_fr }) for tmp in ls: if tmp[0] == Languages.DE: self.assertEqual(tmp[1], self.simple_string_de) elif tmp[0] == Languages.FR: self.assertEqual(tmp[1], self.simple_string_fr)
def test_langstring_fromjsonld(self) -> None: """Test reading a LangString from JSON-LD as used in Knora data/ontologies""" test = [{ '@language': 'en', '@value': self.test_string_en }, { '@language': 'de', '@value': self.test_string_de }] ls = LangString.fromJsonLdObj(test) self.assertEqual(ls['de'], self.test_string_de) self.assertEqual(ls[Languages.EN], self.test_string_en)
def test_langstring_fromjson(self) -> None: """Test reading a LangString from JSON as used in Knora Admin.""" test = [{ 'language': 'en', 'value': self.test_string_en }, { 'language': 'de', 'value': self.test_string_de }] ls = LangString.fromJsonObj(test) self.assertEqual(ls['de'], self.test_string_de) self.assertEqual(ls[Languages.EN], self.test_string_en)
def test_group_create(self) -> None: """ Create a group :return: None """ group = Group(con=self.con, name="Group create", descriptions=LangString( {Languages.EN: 'This is group create'}), project=self.test_project, status=True, selfjoin=False) self.assertEqual(group.name, 'Group create') self.assertCountEqual(group.descriptions.toJsonObj(), [{ 'language': 'en', 'value': 'This is group create' }]) self.assertEqual(group.project, self.test_project) self.assertTrue(group.status) self.assertFalse(group.selfjoin)
def test_project_create(self) -> None: project = Project(con=self.con, shortcode='0FF0', shortname="new_project", longname="New test project", description=LangString({ Languages.EN: 'New project', Languages.DE: 'Neues Projekt' }), keywords={'test', 'project', 'new'}, selfjoin=False, status=True, logo=self.logo_file) new_project = project.create() self.assertIsNotNone(new_project) self.assertEqual(new_project.shortcode, '0FF0') self.assertEqual(new_project.shortname, 'new_project') self.assertEqual(new_project.longname, 'New test project') self.assertEqual(new_project.description['en'], 'New project') self.assertEqual(new_project.description['de'], 'Neues Projekt') self.assertEqual(new_project.keywords, {'test', 'project', 'new'}) self.assertEqual(new_project.selfjoin, False) self.assertEqual(new_project.status, True) self.assertEqual(new_project.keywords, {'test', 'project', 'new'})
def test_Group_delete(self) -> None: """ Mark an existing group as deleted (it will not be deleted completely from the triplestore, but status set to False) :return: None """ group = Group(con=self.con, name="Group delete", descriptions=LangString( {Languages.EN: 'This is group delete'}), project=self.test_project, status=True, selfjoin=False).create() deleted_group = group.delete() self.assertEqual(deleted_group.name, 'Group delete') self.assertCountEqual(deleted_group.descriptions.toJsonObj(), [{ 'language': 'en', 'value': 'This is group delete' }]) self.assertEqual(deleted_group.project, self.test_project) self.assertFalse(deleted_group.status) self.assertFalse(deleted_group.selfjoin)
class TestResourceClass(unittest.TestCase): test_project = "http://rdfh.ch/projects/0001" res_name = 'res_class_name' res_label = LangString({Languages.EN: 'Resource Class Label'}) res_comment = LangString( {Languages.EN: 'This is a resource class for testing'}) def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test') def test_ResourceClass_create(self) -> None: onto = Ontology( con=self.con, project=self.test_project, name='test_onto', label='Test Ontology', ).create() last_modification_date_onto = onto.lastModificationDate # create test resource class last_modification_date_res, res_class = ResourceClass( con=self.con, context=onto.context, name=self.res_name, ontology_id=onto.id, label=self.res_label, comment=self.res_comment).create(last_modification_date_onto) self.assertIsNotNone(res_class.id) self.assertEqual(res_class.name, self.res_name) self.assertEqual(res_class.label['en'], self.res_label['en']) self.assertEqual(res_class.comment['en'], self.res_comment['en']) def test_ResourceClass_update(self) -> None: onto = Ontology( con=self.con, project=self.test_project, name='test_onto_2', label='Test Ontology 2', ).create() last_modification_date = onto.lastModificationDate # create test resource class last_modification_date, res_class = ResourceClass( con=self.con, context=onto.context, name=self.res_name, ontology_id=onto.id, label=self.res_label, comment=self.res_comment).create(last_modification_date) onto.lastModificationDate = last_modification_date self.assertIsNotNone(res_class.id) # modify the resource class res_class.addLabel('de', "Dies ist ein Kommentar") res_class.rmLabel('en') res_class.addComment('it', "Commentario italiano") last_modification_date, res_class = res_class.update( last_modification_date) self.assertEqual(res_class.label['de'], "Dies ist ein Kommentar") self.assertEqual(res_class.comment['it'], "Commentario italiano") def tearDown(self) -> None: """ is executed after all tests are run through; performs a log out """ self.con.logout()
def create_ontology(input_file: str, lists_file: str, server: str, user_mail: str, password: str, verbose: bool, dump: bool) -> None: """ Creates the ontology and all its parts from a JSON input file on a DSP server Args: input_file: The input JSON file from which the ontology and its parts should be created lists_file: The file which the list output (list node ID) is written to server: The DSP server which the ontology should be created on user_mail: The user (e-mail) which the ontology should be created with (requesting user) password: The password for the user (requesting user) verbose: Prints more information if set to True dump: Dumps test files (JSON) for DSP API requests if set to True Returns: None """ knora_api_prefix = "knora-api:" # read the ontology from the input file with open(input_file) as f: onto_json_str = f.read() data_model = json.loads(onto_json_str) # expand all lists referenced in the list section of the data model and add them to the ontology data_model["project"]["lists"] = expand_lists_from_excel(data_model) # validate the ontology if not validate_ontology(data_model): exit(1) # make the connection to the server con = login(server=server, user=user_mail, password=password) if dump: con.start_logging() # read the prefixes of external ontologies that may be used context = Context(data_model.get("prefixes") or {}) # check if the project exists project = None try: project = Project(con=con, shortcode=data_model["project"]["shortcode"]).read() except BaseError: pass # if project exists, update it if project: print(f"Project '{data_model['project']['shortcode']}' already exists. Updating it...") updated_project: Project = update_project(project=project, data_model=data_model, verbose=verbose) if verbose: updated_project.print() # if project does not exist, create it else: if verbose: print("Create project...") project = create_project(con=con, data_model=data_model, verbose=verbose) # create the list(s), skip if it already exists list_root_nodes = {} if data_model["project"].get("lists"): if verbose: print("Create lists...") list_root_nodes = create_lists(input_file, lists_file, server, user_mail, password, verbose) # create the group(s), skip if it already exists new_groups = {} if data_model["project"].get("groups"): if verbose: print("Create groups...") new_groups = create_groups(con=con, groups=data_model["project"]["groups"], project=project, verbose=verbose) # create or update the user(s), skip if it already exists if data_model["project"].get("users"): if verbose: print("Create users...") create_users(con=con, users=data_model["project"]["users"], groups=new_groups, project=project, verbose=verbose) # create the ontologies if verbose: print("Create ontologies...") for ontology in data_model.get("project").get("ontologies"): new_ontology = None last_modification_date = None ontology_name = ontology["name"] try: new_ontology = Ontology(con=con, project=project, label=ontology["label"], name=ontology_name).create() last_modification_date = new_ontology.lastModificationDate if verbose: print(f"Created ontology '{ontology_name}'.") except BaseError as err: print( f"ERROR while trying to create ontology '{ontology_name}'. The error message was {err.message}") exit(1) except Exception as exception: print(f"ERROR while trying to create ontology '{ontology_name}'. The error message was {exception}") exit(1) # add the prefixes defined in the json file for prefix, ontology_info in context: if prefix not in new_ontology.context and ontology_info: s = ontology_info.iri + ("#" if ontology_info.hashtag else "") new_ontology.context.add_context(prefix, s) # create the empty resource classes new_res_classes: dict[str, ResourceClass] = {} for res_class in ontology.get("resources"): res_name = res_class.get("name") super_classes = res_class.get("super") if isinstance(super_classes, str): super_classes = [super_classes] res_label = LangString(res_class.get("labels")) res_comment = res_class.get("comments") if res_comment: res_comment = LangString(res_comment) else: res_comment = LangString({"en": "[no comment provided]"}) # if no cardinalities are submitted, don't create the class if not res_class.get("cardinalities"): print(f"ERROR while trying to add cardinalities to class '{res_name}'. No cardinalities submitted. At" f"least one direct cardinality is required to create a class with dsp-tools.") continue new_res_class: Optional[ResourceClass] = None try: last_modification_date, new_res_class = ResourceClass(con=con, context=new_ontology.context, ontology_id=new_ontology.id, name=res_name, superclasses=super_classes, label=res_label, comment=res_comment).create( last_modification_date) except BaseError as err: print( f"ERROR while trying to create resource class {res_name}. The error message was {err.message}") except Exception as exception: print( f"ERROR while trying to create resource class {res_name}. The error message was {exception}") if new_res_class: if isinstance(new_res_class.id, str): new_res_classes[new_res_class.id] = new_res_class new_ontology.lastModificationDate = last_modification_date if verbose: print("Created resource class:") new_res_class.print() # create the property classes for prop_class in ontology.get("properties"): prop_name = prop_class.get("name") prop_label = LangString(prop_class.get("labels")) # get the super-property/ies if defined, valid forms are: # - "prefix:super-property" : fully qualified name of property in another ontology. The prefix has to be # defined in the prefixes part. # - "super-property" : super-property defined in the knora-api ontology # - if omitted, "knora-api:hasValue" is assumed if prop_class.get("super"): super_props = [] for super_class in prop_class.get("super"): if ':' in super_class: super_props.append(super_class) else: super_props.append(knora_api_prefix + super_class) else: super_props = ["knora-api:hasValue"] # get the "object" if defined, valid forms are: # - "prefix:object_name" : fully qualified object. The prefix has to be defined in the prefixes part. # - ":object_name" : The object is defined in the current ontology. # - "object_name" : The object is defined in "knora-api" if prop_class.get("object"): tmp_group_name = prop_class.get("object").split(':') if len(tmp_group_name) > 1: if tmp_group_name[0]: prop_object = prop_class.get("object") # fully qualified name else: prop_object = new_ontology.name + ':' + tmp_group_name[1] # object refers to actual ontology else: prop_object = knora_api_prefix + prop_class.get("object") # object refers to knora-api else: prop_object = None prop_subject = prop_class.get("subject") gui_element = prop_class.get("gui_element") gui_attributes = prop_class.get("gui_attributes") if gui_attributes and gui_attributes.get("hlist"): gui_attributes["hlist"] = "<" + list_root_nodes[gui_attributes["hlist"]]["id"] + ">" prop_comment = prop_class.get("comments") if prop_comment: prop_comment = LangString(prop_comment) else: prop_comment = LangString({"en": "[no comment provided]"}) new_prop_class = None try: last_modification_date, new_prop_class = PropertyClass(con=con, context=new_ontology.context, label=prop_label, name=prop_name, ontology_id=new_ontology.id, superproperties=super_props, object=prop_object, subject=prop_subject, gui_element="salsah-gui:" + gui_element, gui_attributes=gui_attributes, comment=prop_comment).create( last_modification_date) except BaseError as err: print( f"ERROR while trying to create property class {prop_name}. The error message was: {err.message}" ) except Exception as exception: print( f"ERROR while trying to create property class {prop_name}. The error message was: {exception}") if new_prop_class: new_ontology.lastModificationDate = last_modification_date if verbose: print("Created property:") new_prop_class.print() # Add cardinalities to class switcher = { "1": Cardinality.C_1, "0-1": Cardinality.C_0_1, "0-n": Cardinality.C_0_n, "1-n": Cardinality.C_1_n } for res_class in ontology.get("resources"): if res_class.get("cardinalities"): for card_info in res_class.get("cardinalities"): rc = new_res_classes.get(new_ontology.id + "#" + res_class.get("name")) cardinality = switcher[card_info.get("cardinality")] prop_name_for_card = card_info.get("propname") tmp_group_name = prop_name_for_card.split(":") if len(tmp_group_name) > 1: if tmp_group_name[0]: prop_id = prop_name_for_card # fully qualified name else: prop_id = new_ontology.name + ":" + tmp_group_name[1] # prop name refers to actual ontology else: prop_id = knora_api_prefix + prop_name_for_card # prop name refers to knora-api if rc: try: last_modification_date = rc.addProperty( property_id=prop_id, cardinality=cardinality, gui_order=card_info.get("gui_order"), last_modification_date=last_modification_date) except BaseError as err: print( f"ERROR while trying to add cardinality {prop_id} to resource class {res_class.get('name')}." f"The error message was {err.message}") except Exception as exception: print( f"ERROR while trying to add cardinality {prop_id} to resource class {res_class.get('name')}." f"The error message was {exception}") new_ontology.lastModificationDate = last_modification_date
def descriptions(self, value: Optional[LangString]) -> None: self._descriptions = LangString(value) self._changed.add('descriptions')
class Group(Model): """ This class represents a Knora group Attributes ---------- con : Connection A connection instance to a Knora server id : str IRI of the group [get only, cannot be modified after creation of instance] name : str Name of the group descriptions : LangString Group descriptions in a given language (Languages.EN, Languages.DE, Languages.FR, Languages.IT). project : str | project either the IRI of a project [get only, cannot be modified after creation of instance] or an valid Project instance selfjoin : boolean A flag indicating if selfjoin is allowed in this group status : boolean A flag indicating if the group is active (True) or inactive/makred deleted (False) """ PROJECT_MEMBER_GROUP: str = "http://www.knora.org/ontology/knora-admin#ProjectMember" PROJECT_ADMIN_GROUP: str = "http://www.knora.org/ontology/knora-admin#ProjectAdmin" PROJECT_SYSTEMADMIN_GROUP: str = "http://www.knora.org/ontology/knora-admin#SystemAdmin" ROUTE: str = "/admin/groups" ROUTE_SLASH: str = ROUTE + "/" _id: str _name: str _descriptions: LangString _project: str _selfjoin: bool _status: bool def __init__(self, con: Connection, id: Optional[str] = None, name: Optional[str] = None, descriptions: LangString = None, project: Optional[Union[str, Project]] = None, selfjoin: Optional[bool] = None, status: Optional[bool] = None): super().__init__(con) self._id = str(id) if id is not None else None self._name = str(name) if name is not None else None self._descriptions = LangString(descriptions) if project is not None and isinstance(project, Project): self._project = project.id else: self._project = str(project) if project is not None else None self._selfjoin = bool(selfjoin) if selfjoin is not None else None self._status = bool(status) if status is not None else None @property def id(self) -> Optional[str]: return self._id @id.setter def id(self, value: str) -> None: raise BaseError('Group id cannot be modified!') @property def name(self) -> Optional[str]: return self._name @name.setter def name(self, value: str): self._name = value self._changed.add('name') @property def descriptions(self) -> Optional[LangString]: return self._descriptions @descriptions.setter def descriptions(self, value: Optional[LangString]) -> None: self._descriptions = LangString(value) self._changed.add('descriptions') @property def project(self): return self._project @project.setter def project(self, value: str): raise BaseError('project id cannot be modified!') @property def selfjoin(self) -> bool: return self._selfjoin @selfjoin.setter def selfjoin(self, value: bool) -> None: self._selfjoin = value self._changed.add('selfjoin') @property def status(self) -> bool: return self._status @status.setter def status(self, value: bool) -> None: self._status = value self._changed.add('status') def has_changed(self) -> bool: if self._changed: return True else: return False @classmethod def fromJsonObj(cls, con: Connection, json_obj: Any): id = json_obj.get('id') if id is None: raise BaseError('Group "id" is missing') name = json_obj.get('name') if name is None: raise BaseError('Group "name" is missing') descriptions = LangString.fromJsonObj(json_obj.get('descriptions')) tmp = json_obj.get('project') if tmp is None: raise BaseError('Group "project" is missing') project = tmp.get('id') if project is None: raise BaseError('Group "project" has no "id"') selfjoin = json_obj.get('selfjoin') if selfjoin is None: raise BaseError("selfjoin is missing") status = json_obj.get('status') if status is None: raise BaseError("Status is missing") return cls(con=con, name=name, id=id, descriptions=descriptions, project=project, selfjoin=selfjoin, status=status) def toJsonObj(self, action: Actions): tmp = {} if action == Actions.Create: if self._name is None: raise BaseError("There must be a valid name!") tmp['name'] = self._name if not self._descriptions.isEmpty(): tmp['descriptions'] = self._descriptions.toJsonObj() if self._project is None: raise BaseError("There must be a valid project!") tmp['project'] = self._project if self._selfjoin is None: raise BaseError("There must be a valid value for selfjoin!") tmp['selfjoin'] = self._selfjoin if self._status is None: raise BaseError("There must be a valid value for status!") tmp['status'] = self._status else: if self._name is not None and 'name' in self._changed: tmp['name'] = self._name if not self._descriptions.isEmpty( ) and 'descriptions' in self._changed: tmp['descriptions'] = self._descriptions.toJsonObj() if self._selfjoin is not None and 'selfjoin' in self._changed: tmp['selfjoin'] = self._selfjoin return tmp def create(self) -> Group: jsonobj = self.toJsonObj(Actions.Create) jsondata = json.dumps(jsonobj) result = self._con.post(Group.ROUTE, jsondata) return Group.fromJsonObj(self._con, result['group']) def read(self): result = self._con.get(Group.ROUTE_SLASH + quote_plus(self._id)) return Group.fromJsonObj(self._con, result['group']) def update(self): jsonobj = self.toJsonObj(Actions.Update) if jsonobj: jsondata = json.dumps(jsonobj) result = self._con.put(Group.ROUTE_SLASH + quote_plus(self._id), jsondata) updated_group = Group.fromJsonObj(self._con, result['group']) if self._status is not None and 'status' in self._changed: jsondata = json.dumps({'status': self._status}) result = self._con.put( Group.ROUTE_SLASH + quote_plus(self._id) + '/status', jsondata) updated_group = Group.fromJsonObj(self._con, result['group']) return updated_group def delete(self): result = self._con.delete(Group.ROUTE_SLASH + quote_plus(self._id)) return Group.fromJsonObj(self._con, result['group']) @staticmethod def getAllGroups(con: Connection) -> Optional[list[Group]]: try: result = con.get(Group.ROUTE) return [ Group.fromJsonObj(con, group_item) for group_item in result["groups"] ] except BaseError: # return None if no groups are found or an error happened return None @staticmethod def getAllGroupsForProject(con: Connection, proj_shortcode: str) -> list[Group]: result = con.get(Group.ROUTE) if 'groups' not in result: raise BaseError("Request got no groups!") all_groups = result["groups"] project_groups = [] for group in all_groups: if group["project"][ "id"] == "http://rdfh.ch/projects/" + proj_shortcode: project_groups.append(group) return list(map(lambda a: Group.fromJsonObj(con, a), project_groups)) def createDefinitionFileObj(self): group = { "name": self.name, "descriptions": self.descriptions.createDefinitionFileObj(), "selfjoin": self.selfjoin, "status": self.status } return group def print(self) -> None: print('Group Info:') print(' Id: {}'.format(self._id)) print(' Name: {}'.format(self._name)) if self._descriptions is not None: print(' Descriptions:') for descr in self._descriptions.items(): print(' {}: {}'.format(descr[0], descr[1])) else: print(' Descriptions: None') print(' Project: {}'.format(self._project)) print(' Selfjoin: {}'.format(self._selfjoin)) print(' Status: {}'.format(self._status))
def test_langstring_instantiation1(self) -> None: """Test a LangString without language.""" ls = LangString(self.simple_string_de) self.assertEqual(ls[None], self.simple_string_de)
def test_langstring_emptyness(self) -> None: """Test if a LanGstring can be emptied and if the emptyness is detected.""" ls = LangString() self.assertTrue(ls.isEmpty()) ls = LangString(self.simple_string_de) ls.empty() self.assertTrue(ls.isEmpty()) ls = LangString({ Languages.DE: self.simple_string_de, Languages.FR: self.simple_string_fr }) ls.empty() self.assertTrue(ls.isEmpty())
class TestPropertyClass(unittest.TestCase): project = "http://rdfh.ch/projects/0001" onto_name = 'propclass-test-a' onto_label = 'propclass_test_ontology' onto: Ontology last_modification_date: LastModificationDate con: Connection name = 'MyPropClassName' object = 'TextValue' label = LangString({Languages.DE: 'MyPropClassLabel'}) comment = LangString( {Languages.DE: 'This is a property class for testing'}) def setUp(self) -> None: """ is executed before all tests; sets up a connection and logs in as user root; creates a new ontology """ self.con = Connection('http://0.0.0.0:3333') self.con.login('*****@*****.**', 'test') # Create a test ontology self.onto = Ontology( con=self.con, project=self.project, name=self.onto_name, label=self.onto_label, ).create() self.assertIsNotNone(self.onto.id) self.last_modification_date = self.onto.lastModificationDate def tearDown(self) -> None: """ is executed after all tests are run through; removes test ontology """ result = self.onto.delete() self.assertIsNotNone(result) def test_PropertyClass_create(self) -> None: """ create new property class """ self.last_modification_date, property_class = PropertyClass( con=self.con, context=self.onto.context, name=self.name, ontology_id=self.onto.id, object=self.object, label=self.label, comment=self.comment).create(self.last_modification_date) self.onto.lastModificationDate = self.last_modification_date self.assertIsNotNone(property_class.id) self.assertEqual(property_class.name, self.name) self.assertEqual(property_class.label['de'], self.label['de']) self.assertEqual(property_class.comment['de'], self.comment['de']) # get ontology data self.onto = self.onto.read() self.last_modification_date = self.onto.lastModificationDate self.last_modification_date = property_class.delete( self.last_modification_date) # get ontology data self.onto = self.onto.read() def test_PropertyClass_update(self) -> None: self.onto = self.onto.read() # create test resource class self.last_modification_date, property_class = PropertyClass( con=self.con, context=self.onto.context, name=self.name, ontology_id=self.onto.id, object=self.object, label=self.label, comment=self.comment).create(self.last_modification_date) self.onto.lastModificationDate = self.last_modification_date self.assertIsNotNone(property_class.id) # modify the property class property_class.addLabel('en', "This is english comment") property_class.rmLabel('de') property_class.addComment('it', "Commentario italiano") self.last_modification_date, property_class_updated = property_class.update( self.last_modification_date) self.onto.lastModificationDate = self.last_modification_date self.assertEqual(property_class_updated.label['en'], "This is english comment") self.assertEqual(property_class_updated.comment['it'], "Commentario italiano") # delete the resource class to clean up self.last_modification_date = property_class_updated.delete( self.last_modification_date) self.onto.lastModificationDate = self.last_modification_date