diff --git a/unittests/test_tool.py b/unittests/test_tool.py
index fac8b60ac2d8f03322ba331c4d23e8ec69f9e1d4..7bdccbabdce2e71ddc8cf4d6c40ee033acba06b9 100755
--- a/unittests/test_tool.py
+++ b/unittests/test_tool.py
@@ -541,75 +541,132 @@ def test_replace_entities_with_ids(crawler):
     assert a.get_property("C").value == [12345, 233324]
 
 
-@patch("caoscrawler.crawl.db.Container.insert")
-@patch("caoscrawler.crawl.db.Container.update")
-@patch("caoscrawler.crawl.UpdateCache.insert")
-def test_security_mode_trivial(updateCacheMock, insmock, upmock, ident):
-    crawler = Crawler(debug=True, securityMode=SecurityMode.RETRIEVE)
+def mock_get_entity_by_name(name):
+    candidates = [el for el in full_data.values() if el.name.lower() == name.lower()]
+    if len(candidates) > 0:
+        return candidates[0]
+    else:
+        return None
+
+
+def prepare_crawler_with_sec_mode(mode, ident):
+    crawler = Crawler(debug=True, securityMode=mode)
     crawler.crawl_directory(rfp("test_directories", "examples_article"),
                             rfp("scifolder_cfood.yml"))
     crawler.identifiableAdapter = ident
 
-    def mock_get_entity_by_name(name):
-        candidates = [el for el in full_data.values() if el.name.lower() == name.lower()]
-        if len(candidates) > 0:
-            return candidates[0]
-        else:
-            return None
-    Crawler._get_entity_by_name = mock_get_entity_by_name
-    #Crawler._get_entity_by_name = lambda x: db.RecordType(id=1111, name="A")
-    insl, updl = crawler.synchronize(commit_changes=True)
-    assert crawler.run_id is not None
-    insmock.assert_not_called()
-    upmock.update.assert_not_called()
-    updateCacheMock.assert_not_called()
+    return crawler
+
 
+def reset_mocks(mocks):
+    for mock in mocks:
+        mock.reset_mock()
 
+
+def change_identifiable_prop(ident):
+    # the checks in here are only to make sure we change the record as we intend to
+    meas = ident._records[-2]
+    assert meas.parents[0].name == "Measurement"
+    resps = meas.properties[0]
+    assert resps.name == "date"
+    # change one element; This changes the date which is part of the identifiable
+    resps.value = "2022-01-04"
+
+
+def change_non_identifiable_prop(ident):
+    # the checks in here are only to make sure we change the record as we intend to
+    meas = ident._records[-1]
+    assert meas.parents[0].name == "Measurement"
+    resps = meas.properties[-1]
+    assert resps.name == "responsible"
+    assert len(resps.value) == 2
+    # change one element; This removes a responsible which is not part of the identifiable
+    del resps.value[-1]
+
+
+@patch("caoscrawler.crawl.Crawler._get_entity_by_name",
+       new=Mock(side_effect=mock_get_entity_by_name))
 @patch("caoscrawler.crawl.db.Container.insert")
 @patch("caoscrawler.crawl.db.Container.update")
 @patch("caoscrawler.crawl.UpdateCache.insert")
-def test_security_mode_forbidden(updateCacheMock, insmock, upmock, ident):
-    crawler = Crawler(debug=True, securityMode=SecurityMode.RETRIEVE)
-    crawler.crawl_directory(rfp("test_directories", "examples_article"),
-                            rfp("scifolder_cfood.yml"))
-    crawler.identifiableAdapter = ident
+def test_security_mode(updateCacheMock, upmock, insmock, ident):
+    records_backup = deepcopy(ident._records)
 
-    def mock_get_entity_by_name(name):
-        candidates = [el for el in full_data.values() if el.name.lower() == name.lower()]
-        if len(candidates) > 0:
-            return candidates[0]
-        else:
-            return None
-    Crawler._get_entity_by_name = mock_get_entity_by_name
+    # trivial case: nothing to do
+    crawler = prepare_crawler_with_sec_mode(SecurityMode.RETRIEVE, ident)
+    insl, updl = crawler.synchronize(commit_changes=True)
+    assert crawler.run_id is not None
+    insmock.assert_not_called()
+    upmock.assert_not_called()
+    updateCacheMock.assert_not_called()
+
+    # RETRIEVE: insert only
+    crawler = prepare_crawler_with_sec_mode(SecurityMode.RETRIEVE, ident)
+    # remove one element
     del ident._records[-1]
     insl, updl = crawler.synchronize(commit_changes=True)
     assert crawler.run_id is not None
     insmock.assert_not_called()
-    upmock.update.assert_not_called()
+    upmock.assert_not_called()
     assert updateCacheMock.call_count == 1
-
-
-@patch("caoscrawler.crawl.db.Container.update")
-@patch("caoscrawler.crawl.db.Container.insert")
-@patch("caoscrawler.crawl.UpdateCache.insert")
-def test_security_mode_forbidden_up(updateCacheMock, insmock, upmock, ident):
-    crawler = Crawler(debug=True, securityMode=SecurityMode.INSERT)
-    crawler.crawl_directory(rfp("test_directories", "examples_article"),
-                            rfp("scifolder_cfood.yml"))
-    crawler.identifiableAdapter = ident
-    state = full_data
-
-    def mock_get_entity_by_name(name):
-        candidates = [el for el in full_data.values() if el.name.lower() == name.lower()]
-        if len(candidates) > 0:
-            return candidates[0]
-        else:
-            return None
-    Crawler._get_entity_by_name = mock_get_entity_by_name
-
-    del ident._registered_identifiables["Person"]
+    # reset counts
+    reset_mocks([updateCacheMock, insmock, upmock])
+    # restore original ident
+    ident._records = deepcopy(records_backup)
+
+    # RETRIEVE: update only
+    crawler = prepare_crawler_with_sec_mode(SecurityMode.RETRIEVE, ident)
+    # change one element
+    change_non_identifiable_prop(ident)
     insl, updl = crawler.synchronize(commit_changes=True)
     assert crawler.run_id is not None
-    insmock.assert_called_once()
-    upmock.update.assert_not_called()
+    insmock.assert_not_called()
+    upmock.assert_not_called()
     assert updateCacheMock.call_count == 1
+    # reset counts
+    reset_mocks([updateCacheMock, insmock, upmock])
+    # restore original ident
+    ident._records = deepcopy(records_backup)
+
+    # INSERT: insert only
+    crawler = prepare_crawler_with_sec_mode(SecurityMode.INSERT, ident)
+    # remove one element
+    del ident._records[-1]
+    insl, updl = crawler.synchronize(commit_changes=True)
+    assert crawler.run_id is not None
+    insmock.assert_called_once()
+    upmock.assert_not_called()
+    updateCacheMock.assert_not_called()
+    # reset counts
+    reset_mocks([updateCacheMock, insmock, upmock])
+    # restore original ident
+    ident._records = deepcopy(records_backup)
+
+    # INSERT: update only
+    crawler = prepare_crawler_with_sec_mode(SecurityMode.INSERT, ident)
+    # change one element
+    change_non_identifiable_prop(ident)
+    insl, updl = crawler.synchronize(commit_changes=True)
+    assert crawler.run_id is not None
+    insmock.assert_not_called()
+    upmock.assert_not_called()
+    updateCacheMock.assert_called_once()
+    # reset counts
+    reset_mocks([updateCacheMock, insmock, upmock])
+    # restore original ident
+    ident._records = deepcopy(records_backup)
+
+    # INSERT: insert and update
+    crawler = prepare_crawler_with_sec_mode(SecurityMode.INSERT, ident)
+    # change two elements
+    change_non_identifiable_prop(ident)
+    change_identifiable_prop(ident)
+    insl, updl = crawler.synchronize(commit_changes=True)
+    assert crawler.run_id is not None
+    insmock.asser_called_once()
+    upmock.assert_not_called()
+    updateCacheMock.assert_called_once()
+    # reset counts
+    reset_mocks([updateCacheMock, insmock, upmock])
+    # restore original ident
+    ident._records = deepcopy(records_backup)