From b9ee004dd69701eaf969a27469b858713058e7be Mon Sep 17 00:00:00 2001
From: Timm Fitschen <t.fitschen@indiscale.com>
Date: Fri, 2 Jul 2021 15:54:03 +0200
Subject: [PATCH] BUG: Entity.role behavior

---
 src/caosdb/common/models.py | 23 ++++++++++++++++++++++-
 unittests/test_entity.py    | 19 +++++++++++++++++--
 2 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/src/caosdb/common/models.py b/src/caosdb/common/models.py
index 6ec49df2..ed4815ff 100644
--- a/src/caosdb/common/models.py
+++ b/src/caosdb/common/models.py
@@ -128,7 +128,24 @@ class Entity(object):
 
     @property
     def role(self):
-        return self.__role
+        """Return the role of this entity.
+
+        Particularly, this means
+          1. return the explicitly set role, if present.
+          2. or, if this is a direct instance of the Entity class (and not of
+            any subclass of Entity) which hence has no "natural" role, return
+            None.
+          3. Otherwise, return the class name of this entity, because this the
+            natural role of this object.
+        Returns
+        -------
+        str
+            The entities role or `None`
+        """
+        if self.__role:
+            return self.__role
+        if type(self) is not Entity:
+            return type(self).__name__
 
     @role.setter
     def role(self, role):
@@ -832,6 +849,9 @@ class Entity(object):
 
         if xml is None:
             xml = etree.Element("Entity")
+            # use role as xml tag name, fall-back to "Entity"
+            elem_tag = "Entity" if self.role is None else self.role
+            xml = etree.Element(elem_tag)
         assert isinstance(xml, etree._Element)
 
         # unwrap wrapped entity
@@ -2277,6 +2297,7 @@ class _Messages(dict):
 def _basic_sync(e_local, e_remote):
     if e_local is None or e_remote is None:
         return None
+    e_local.role = e_remote.role
     e_local.id = e_remote.id
     e_local.name = e_remote.name
     e_local.description = e_remote.description
diff --git a/unittests/test_entity.py b/unittests/test_entity.py
index e98dfbef..24ebb919 100644
--- a/unittests/test_entity.py
+++ b/unittests/test_entity.py
@@ -41,18 +41,33 @@ class TestEntity(unittest.TestCase):
 
     def test_instance_variables(self):
         entity = Entity()
-        self.assertTrue(hasattr(entity, "role"))
         self.assertTrue(hasattr(entity, "id"))
         self.assertTrue(hasattr(entity, "name"))
         self.assertTrue(hasattr(entity, "description"))
         self.assertTrue(hasattr(entity, "parents"))
         self.assertTrue(hasattr(entity, "properties"))
 
-    def test_role(self):
+    def test_entity_role_1(self):
         entity = Entity(role="TestRole")
         self.assertEqual(entity.role, "TestRole")
         entity.role = "TestRole2"
         self.assertEqual(entity.role, "TestRole2")
 
+    def test_entity_role_2(self):
+        entity = Entity()
+
+        self.assertIsNone(entity.role)
+        self.assertEqual(entity.to_xml().tag, "Entity")
+
+        entity.role = "Record"
+        self.assertEqual(entity.role, "Record")
+        self.assertEqual(entity.to_xml().tag, "Record")
+
+    def test_recordtype_role(self):
+        entity = RecordType()
+
+        self.assertEqual(entity.role, "RecordType")
+        self.assertEqual(entity.to_xml().tag, "RecordType")
+
     def test_instanciation(self):
         self.assertRaises(Exception, Entity())
-- 
GitLab