diff --git a/tests/test_issues_server.py b/tests/test_issues_server.py
index 2de8ece365cb3c6eab2ae2fe9a51c40174b0d236..df1e57f3ddf5fc39e96ee986d7a51ae6180a905c 100644
--- a/tests/test_issues_server.py
+++ b/tests/test_issues_server.py
@@ -943,3 +943,61 @@ def test_147():
     rec3 = db.Record("TestRec3").add_parent("TestRT").add_property("TestPropInt", 1).insert()
     assert db.execute_query("FIND TestRT WITH TestPropInt < 2", unique=True).id == rec3.id
     assert db.execute_query("FIND TestRT WITH TestPropInt < 2.5", unique=True).id == rec3.id
+
+
+def test_140():
+    """https://gitlab.com/caosdb/caosdb-server/-/issues/140"""
+    admin._insert_role(name=CURATOR_ROLE, description="Desc")
+
+    perms = admin._get_permissions(CURATOR_ROLE)
+    g = admin.PermissionRule(action="Grant", permission="TRANSACTION:*")
+    perms.add(g)
+    admin._set_permissions(CURATOR_ROLE, permission_rules=perms)
+    admin._insert_user(name="TestUser", password="Password1!", status="ACTIVE")
+    admin._set_roles(username="TestUser", roles=[CURATOR_ROLE])
+
+    core_model_deny_permissions = [
+        "DELETE",
+        "UPDATE:*",
+        "EDIT:ACL"
+    ]
+    core_model_grant_permissions = [
+        "RETRIEVE:*",
+        "USE:*",
+        "UPDATE:PROPERTY:ADD"
+    ]
+
+    prop = db.Property(name="TestProp", datatype=db.TEXT).insert()
+    rt = db.RecordType(name="TestRT").insert(flags={"ACL": None})
+
+    for d in core_model_deny_permissions:
+        # First deny s.th. later the "UPDATE:PROPERTY:ADD" permission can be granted explicitely
+        rt.deny(role=CURATOR_ROLE, permission=d)
+    rt.update_acl()
+
+    # retrieve again to be sure
+    rt.retrieve(flags={"ACL": None})
+    for g in core_model_grant_permissions:
+        rt.grant(role=CURATOR_ROLE, permission=g)
+    rt.update_acl()
+
+    print(rt.acl)
+
+    db.configure_connection(username="TestUser", password_method="plain",
+                            password="Password1!")
+    assert db.Info().user_info.name == "TestUser"
+    assert db.Info().user_info.roles == [CURATOR_ROLE]
+
+    rt.add_property(prop)
+    rt.get_property("TestProp").value = "some value"
+
+    # this should succeed because the curator has UPDATE:PROPERTY:ADD
+    rt.update()
+
+    assert rt.get_property("TestProp").value == "some value"
+    rt.get_property("TestProp").value = "some other value"
+    with pytest.raises(TransactionError) as cm:
+        # this should fail because the curator doesn't have
+        # UPDATE:PROPERTY:REMOVE
+        rt.update()
+    assert cm.value.errors[0].msg == "You are not allowed to do this."