diff --git a/test/core/js/modules/ext_prop_display.js.js b/test/core/js/modules/ext_prop_display.js.js
new file mode 100644
index 0000000000000000000000000000000000000000..18d2c54056609bf0cc6aafca2d06705ad7a40b02
--- /dev/null
+++ b/test/core/js/modules/ext_prop_display.js.js
@@ -0,0 +1,263 @@
+/*
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2022 IndiScale GmbH <info@indiscale.com>
+ * Copyright (C) 2022 Florian Spreckelsen <f.spreckelsen@indiscale.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+'use strict';
+
+QUnit.module("ext_prop_display.js", {
+    before: function (assert) {
+        // setup before module
+    },
+    beforeEach: function (assert) {
+        // setup before each test
+        // entity list, one entity with three properties (ids 1,2,3 for
+        // testing), all of them hidden by default.
+        $(document.body).append('<div class="caosdb-f-main-entities prop-display-test-entities"><div id=115 class="caosdb-entity-panel"><div class="caosdb-entity-panel-heading"><span class="caosdb-f-parent-list"><span class="caosdb-parent-item"><a class="caosdb-parent-name" href="https://demo.indiscale.com/Entity/110">Guitar</a></span></span></div><div class="caosdb-entity-panel-body"><ul class="list-group caosdb-properties"><li id=1 class="caosdb-v-property-row caosdb-f-entity-property caosdb-v-hidden-property"><div class="row"><div class="caosdb-v-property-left-col"><span class="caosdb-property-name">first prop</span></div><div class="caosdb-f-property-value"><span class="caosdb-f-property-single-raw-value caosdb-property-text-value caosdb-f-property-text-value caosdb-v-property-text-value">48.0</span><span class="caosdb-unit">€</span></div></div></li><li id=2 class="caosdb-v-property-row caosdb-f-entity-property caosdb-v-hidden-property"><div class="row"><div class="caosdb-v-property-left-col"><span class="caosdb-property-name">second prop</span></div><div class="caosdb-f-property-value"><span class="caosdb-f-property-single-raw-value caosdb-property-text-value caosdb-f-property-text-value caosdb-v-property-text-value">48.0</span><span class="caosdb-unit">€</span></div></div></li><li id=3 class="caosdb-v-property-row caosdb-f-entity-property caosdb-v-hidden-property"><div class="row"><div class="caosdb-v-property-left-col"><span class="caosdb-property-name">third prop</span></div><div class="caosdb-f-property-value"><span class="caosdb-f-property-single-raw-value caosdb-property-text-value caosdb-f-property-text-value caosdb-v-property-text-value">48.0</span><span class="caosdb-unit">€</span></div></div></li></ul></div></div></div>');
+    },
+    afterEach: function (assert) {
+        // teardown after each test
+        $(".prop-display-test-entities").remove();
+    },
+    after: function (assert) {
+        // teardown after module
+    }
+});
+
+QUnit.test("unhide all properties", function (assert) {
+    assert.ok(prop_display.unhideAllProperties, "unhideAllProperties available");
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 3, "all properties hidden initially");
+    prop_display.unhideAllProperties();
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 0, "no hidden properties after unhiding");
+});
+
+QUnit.test("hide properties garbage type", function (assert) {
+    assert.ok(prop_display.getEntitiesInView, "getEntitiesInView available");
+    assert.ok(prop_display.unhideProperties, "unhideProperties available");
+    const conf = {
+        "DoesntExist": {
+            "hide": [{
+                "name": "first prop",
+                "roles": ["some_role"],
+                "users": ["someone"]
+            }]
+        }
+    };
+    // only one garbage type
+    const allTypes = {
+        "typesWithChildren": {
+            "DoesntExist": ["DoesntExist"]
+        },
+        "allTypesOrChildren": ["DoesntExist"]
+    };
+    const userName = "someone";
+    const userRoles = ["some_role", "some_other_role"];
+    const entities = prop_display.getEntitiesInView();
+    assert.equal(entities.length, 1, "only one entity in test data");
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 3, "all properties hidden initially");
+    prop_display.unhideProperties(entities, conf, allTypes, userName, userRoles);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 0, "no garbage-type entity, so no hidden properties");
+    assert.equal($(document).find(".caosdb-v-show-property").length, 3, "all properties are being shown");
+});
+
+QUnit.test("hide properties garbage property", function (assert) {
+    assert.ok(prop_display.getEntitiesInView, "getEntitiesInView available");
+    assert.ok(prop_display.unhideProperties, "unhideProperties available");
+    const conf = {
+        "MusicalInstrument": {
+            "hide": [{
+                "name": "prop does not exist",
+                "roles": ["some_role"],
+                "users": ["someone"]
+            }]
+        }
+    };
+    const allTypes = {
+        "typesWithChildren": {
+            "MusicalInstrument": ["MusicalInstrument", "Guitar"]
+        },
+        "allTypesOrChildren": ["MusicalInstrument", "Guitar"]
+    };
+    const userName = "someone";
+    const userRoles = ["some_role", "some_other_role"];
+    const entities = prop_display.getEntitiesInView();
+    assert.equal(entities.length, 1, "only one entity in test data");
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 3, "all properties hidden initially");
+    prop_display.unhideProperties(entities, conf, allTypes, userName, userRoles);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 0, "no garbage property, so no hidden properties");
+    assert.equal($(document).find(".caosdb-v-show-property").length, 3, "all properties are being shown");
+});
+
+
+QUnit.test("hide properties", function (assert) {
+    assert.ok(prop_display.getEntitiesInView, "getEntitiesInView available");
+    assert.ok(prop_display.unhideProperties, "unhideProperties available");
+    const conf = {
+        "MusicalInstrument": {
+            "hide": [{
+                    "name": "first prop",
+                    "roles": ["some_role"],
+                    "users": ["someone"]
+                },
+                {
+                    "name": "second prop",
+                    "roles": [],
+                    "users": ["someone else"]
+                },
+                {
+                    "name": "third prop",
+                    "roles": ["some_other_role"],
+                    "users": ["someone else"]
+                }
+            ]
+        }
+    };
+    const allTypes = {
+        "typesWithChildren": {
+            "MusicalInstrument": ["MusicalInstrument", "Guitar"]
+        },
+        "allTypesOrChildren": ["MusicalInstrument", "Guitar"]
+    };
+    var userName = "someone";
+    var userRoles = ["some_role"];
+    const entities = prop_display.getEntitiesInView();
+    assert.equal(entities.length, 1, "only one entity in test data");
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 3, "all properties hidden initially");
+    prop_display.unhideProperties(entities, conf, allTypes, userName, userRoles);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 1, "exactly one hidden property");
+    assert.equal($(document).find(".caosdb-v-show-property").length, 2, "the remaining two are shown");
+    assert.equal($("#1").hasClass("caosdb-v-hidden-property"), true, "first prop hidden");
+    assert.equal($("#2").hasClass("caosdb-v-show-property"), true, "second prop shown");
+    assert.equal($("#3").hasClass("caosdb-v-show-property"), true, "third prop shown");
+
+    // reset
+    prop_display.unhideProperties(entities, conf, allTypes, "", []);
+    assert.equal($(document).find(".caosdb-v-show-property").length, 3, "all shown after reset");
+
+    userRoles = ["some_other_role"];
+    prop_display.unhideProperties(entities, conf, allTypes, userName, userRoles);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 2, "two hidden properties");
+    assert.equal($(document).find(".caosdb-v-show-property").length, 1, "the remaining one is shown");
+    assert.equal($("#1").hasClass("caosdb-v-hidden-property"), true, "first prop hidden");
+    assert.equal($("#2").hasClass("caosdb-v-show-property"), true, "second prop shown");
+    assert.equal($("#3").hasClass("caosdb-v-hidden-property"), true, "third prop hidden");
+
+    // reset
+    prop_display.unhideProperties(entities, conf, allTypes, "", []);
+    assert.equal($(document).find(".caosdb-v-show-property").length, 3, "all shown after reset");
+
+    userName = "someone else";
+    prop_display.unhideProperties(entities, conf, allTypes, userName, userRoles);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 2, "two hidden properties");
+    assert.equal($(document).find(".caosdb-v-show-property").length, 1, "the remaining one is shown");
+    assert.equal($("#1").hasClass("caosdb-v-show-property"), true, "first prop shown");
+    assert.equal($("#2").hasClass("caosdb-v-hidden-property"), true, "second prop hidden");
+    assert.equal($("#3").hasClass("caosdb-v-hidden-property"), true, "third prop hidden");
+
+    // reset
+    prop_display.unhideProperties(entities, conf, allTypes, "", []);
+    assert.equal($(document).find(".caosdb-v-show-property").length, 3, "all shown after reset");
+
+    userRoles = ["some_role", "some_other_role"]
+    prop_display.unhideProperties(entities, conf, allTypes, userName, userRoles);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 3, "two hidden properties");
+    assert.equal($(document).find(".caosdb-v-show-property").length, 0, "None is shown");
+    assert.equal($("#1").hasClass("caosdb-v-hidden-property"), true, "first prop hidden");
+    assert.equal($("#2").hasClass("caosdb-v-hidden-property"), true, "second prop hidden");
+    assert.equal($("#3").hasClass("caosdb-v-hidden-property"), true, "third prop hidden");
+
+});
+
+QUnit.test("show properties", function (assert) {
+    assert.ok(prop_display.getEntitiesInView, "getEntitiesInView available");
+    assert.ok(prop_display.unhideProperties, "unhideProperties available");
+    const conf = {
+        "MusicalInstrument": {
+            "show": [{
+                    "name": "first prop",
+                    "roles": ["some_role"],
+                    "users": ["someone"]
+                },
+                {
+                    "name": "second prop",
+                    "roles": [],
+                    "users": ["someone else"]
+                },
+                {
+                    "name": "third prop",
+                    "roles": ["some_other_role"],
+                    "users": ["someone else"]
+                }
+            ]
+        }
+    };
+    const allTypes = {
+        "typesWithChildren": {
+            "MusicalInstrument": ["MusicalInstrument", "Guitar"]
+        },
+        "allTypesOrChildren": ["MusicalInstrument", "Guitar"]
+    };
+    var userName = "someone";
+    var userRoles = ["some_role"];
+    const entities = prop_display.getEntitiesInView();
+    assert.equal(entities.length, 1, "only one entity in test data");
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 3, "all properties hidden initially");
+    prop_display.unhideProperties(entities, conf, allTypes, userName, userRoles);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 2, "two hidden properties");
+    assert.equal($(document).find(".caosdb-v-show-property").length, 1, "the remaining one shown");
+    assert.equal($("#1").hasClass("caosdb-v-show-property"), true, "first prop shown");
+    assert.equal($("#2").hasClass("caosdb-v-hidden-property"), true, "second prop hidden");
+    assert.equal($("#3").hasClass("caosdb-v-hidden-property"), true, "third prop hidden");
+
+    // reset
+    prop_display.unhideProperties(entities, conf, allTypes, "", []);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 3, "all hidden after reset");
+
+    userRoles = ["some_other_role"];
+    prop_display.unhideProperties(entities, conf, allTypes, userName, userRoles);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 1, "one hidden properties");
+    assert.equal($(document).find(".caosdb-v-show-property").length, 2, "the remaining two are shown");
+    assert.equal($("#1").hasClass("caosdb-v-show-property"), true, "first prop shown");
+    assert.equal($("#2").hasClass("caosdb-v-hidden-property"), true, "second prop hidden");
+    assert.equal($("#3").hasClass("caosdb-v-show-property"), true, "third prop shown");
+
+    // reset
+    prop_display.unhideProperties(entities, conf, allTypes, "", []);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 3, "all hidden after reset");
+
+    userName = "someone else";
+    prop_display.unhideProperties(entities, conf, allTypes, userName, userRoles);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 1, "one hidden property");
+    assert.equal($(document).find(".caosdb-v-show-property").length, 2, "the remaining ones are shown");
+    assert.equal($("#1").hasClass("caosdb-v-hidden-property"), true, "first prop hidden");
+    assert.equal($("#2").hasClass("caosdb-v-show-property"), true, "second prop shown");
+    assert.equal($("#3").hasClass("caosdb-v-show-property"), true, "third prop shown");
+
+    // reset
+    prop_display.unhideProperties(entities, conf, allTypes, "", []);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 3, "all hidden after reset");
+
+    userRoles = ["some_role", "some_other_role"]
+    prop_display.unhideProperties(entities, conf, allTypes, userName, userRoles);
+    assert.equal($(document).find(".caosdb-v-hidden-property").length, 0, "no hidden properties");
+    assert.equal($(document).find(".caosdb-v-show-property").length, 3, "All are shown");
+    assert.equal($("#1").hasClass("caosdb-v-show-property"), true, "first prop shown");
+    assert.equal($("#2").hasClass("caosdb-v-show-property"), true, "second prop shown");
+    assert.equal($("#3").hasClass("caosdb-v-show-property"), true, "third prop shown");
+
+});