diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8d9f0f3a554a4810a0523845ef37253d5ac58297..12f05e65b0c19016d3a8bf06cc5a8f12aa39ac9d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -423,7 +423,7 @@ test-dashboard-service:
   script:
     - "pip install pipenv"
     - "pipenv install gunicorn && pipenv install --dev --system --deploy"
-    - cd ./dbrepo-dashboard-service/ && coverage run --rcfile=.coveragerc -m pytest tests/test_app.py && coverage html && coverage xml && coverage report > ./coverage.txt
+    - cd ./dbrepo-dashboard-service/ && coverage run --rcfile=.coveragerc -m pytest tests/test_integration_app.py && coverage html && coverage xml && coverage report > ./coverage.txt
     - "cat ./coverage.txt | grep -o 'TOTAL[^%]*%'"
   artifacts:
     when: always
@@ -435,6 +435,33 @@ test-dashboard-service:
       junit: ./dbrepo-dashboard-service/coverage.xml
   coverage: '/TOTAL.*?([0-9]{1,3})%/'
 
+test-dashboard-service-init:
+  image: docker.io/python:${PYTHON_VERSION}-alpine${ALPINE_VERSION}
+  stage: test
+  only:
+    - merge_requests
+    - master
+  variables:
+    PIPENV_PIPFILE: "./dbrepo-dashboard-service/init/Pipfile"
+  needs:
+    - build-dashboard-service
+  dependencies:
+    - build-dashboard-service
+  script:
+    - "pip install pipenv"
+    - "pipenv install gunicorn && pipenv install --dev --system --deploy"
+    - cd ./dbrepo-dashboard-service/init/ && coverage run --rcfile=.coveragerc -m pytest tests/test_app.py && coverage html && coverage xml && coverage report > ./coverage.txt
+    - "cat ./coverage.txt | grep -o 'TOTAL[^%]*%'"
+  artifacts:
+    when: always
+    paths:
+      - ./dbrepo-dashboard-service/init/coverage.xml
+      - ./dbrepo-dashboard-service/init/coverage.txt
+    expire_in: 1 days
+    reports:
+      junit: ./dbrepo-dashboard-service/init/coverage.xml
+  coverage: '/TOTAL.*?([0-9]{1,3})%/'
+
 test-search-service-init:
   image: docker.io/python:${PYTHON_VERSION}-alpine${ALPINE_VERSION}
   stage: test
diff --git a/dbrepo-dashboard-service/init/.coveragerc b/dbrepo-dashboard-service/init/.coveragerc
new file mode 100644
index 0000000000000000000000000000000000000000..9fd61fc1664fc653df59d3f0be0aebf997c78060
--- /dev/null
+++ b/dbrepo-dashboard-service/init/.coveragerc
@@ -0,0 +1,7 @@
+[report]
+omit =
+    # omit tests
+    ./tests/*
+
+[html]
+directory = htmlcov
\ No newline at end of file
diff --git a/dbrepo-dashboard-service/init/Pipfile b/dbrepo-dashboard-service/init/Pipfile
index c5ff9db0e1a7c67c753123abb5271f1ab136d282..6c446aaefa2b1aa5ea3603f567c4afe6980d29a0 100644
--- a/dbrepo-dashboard-service/init/Pipfile
+++ b/dbrepo-dashboard-service/init/Pipfile
@@ -21,6 +21,7 @@ grafana-client = "*"
 [dev-packages]
 coverage = "*"
 pytest = "*"
+testcontainers = "*"
 requests-mock = "*"
 
 [requires]
diff --git a/dbrepo-dashboard-service/init/Pipfile.lock b/dbrepo-dashboard-service/init/Pipfile.lock
index 2dc8f7356254c4152f3f0a0d04419547aba3866e..217d8c261463432055d92559eb3d9c1891f0aeac 100644
--- a/dbrepo-dashboard-service/init/Pipfile.lock
+++ b/dbrepo-dashboard-service/init/Pipfile.lock
@@ -1,7 +1,7 @@
 {
     "_meta": {
         "hash": {
-            "sha256": "5831946cd8df6a4f94bb53b4b390eebcc0dba5722f65688d41d438b7e19ea5b9"
+            "sha256": "911a375e6d52635530a1278e4186660b395093e16a092a223fd7050c6241bedc"
         },
         "pipfile-spec": 6,
         "requires": {
@@ -221,7 +221,7 @@
                 "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87",
                 "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"
             ],
-            "markers": "python_version >= '3.8'",
+            "markers": "platform_python_implementation != 'PyPy'",
             "version": "==1.17.1"
         },
         "charset-normalizer": {
@@ -375,7 +375,8 @@
             "hashes": [
                 "sha256:5f541bb5f944276d381e9c4509ffac1036bc7488848d8aaee1aef9184766832b"
             ],
-            "path": "./lib/dbrepo-1.8.0.tar.gz"
+            "path": "./lib/dbrepo-1.8.0.tar.gz",
+            "version": "==1.8.0"
         },
         "flasgger": {
             "hashes": [
@@ -390,7 +391,6 @@
                 "sha256:f69fcd559dc907ed196ab9df0e48471709175e696d6e698dd4dbe940f96ce66b"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.8'",
             "version": "==2.3.3"
         },
         "flask-cors": {
@@ -415,7 +415,6 @@
                 "sha256:8085d6757505b6f3291a2638c84d207e8f0ad0de662d1f46aa2f77e658a0c976"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.9' and python_version < '4'",
             "version": "==4.7.1"
         },
         "frozenlist": {
@@ -522,7 +521,6 @@
                 "sha256:8cb61bb2a87ec07bca10974df276b9a1a95bfdb63f3a696f065692ffc9b8c389"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.7'",
             "version": "==4.3.2"
         },
         "gunicorn": {
@@ -531,7 +529,6 @@
                 "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.7'",
             "version": "==23.0.0"
         },
         "h11": {
@@ -552,11 +549,11 @@
         },
         "iniconfig": {
             "hashes": [
-                "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3",
-                "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"
+                "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7",
+                "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"
             ],
-            "markers": "python_version >= '3.7'",
-            "version": "==2.0.0"
+            "markers": "python_version >= '3.8'",
+            "version": "==2.1.0"
         },
         "itsdangerous": {
             "hashes": [
@@ -697,7 +694,6 @@
                 "sha256:61c9170f92e736b530655e75374681d4fcca9cfa8763ab42be57353b2b203494"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.6'",
             "version": "==1.3.1"
         },
         "markupsafe": {
@@ -939,7 +935,7 @@
                 "sha256:f486038e44caa08dbd97275a9a35a283a8f1d2f0ee60ac260a1790e76660833c",
                 "sha256:f7de08cbe5551911886d1ab60de58448c6df0f67d9feb7d1fb21e9875ef95e91"
             ],
-            "markers": "python_version >= '3.10'",
+            "markers": "python_version == '3.11'",
             "version": "==2.2.4"
         },
         "packaging": {
@@ -1148,7 +1144,6 @@
                 "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.8'",
             "version": "==2.10.6"
         },
         "pydantic-core": {
@@ -1271,7 +1266,6 @@
                 "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.8'",
             "version": "==8.3.5"
         },
         "python-dateutil": {
@@ -1279,7 +1273,7 @@
                 "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3",
                 "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"
             ],
-            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
+            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
             "version": "==2.9.0.post0"
         },
         "python-dotenv": {
@@ -1288,7 +1282,6 @@
                 "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.8'",
             "version": "==1.0.1"
         },
         "pytz": {
@@ -1455,7 +1448,7 @@
                 "sha256:fbc4e6452cc48c3e1398fe930349e2ec9ad76a2c00e729f3e797700c2f0646e6",
                 "sha256:fc73fc2889a01a43737c7a7c7fb9ee13aa56065b22abbed0e787cc58a3747808"
             ],
-            "markers": "python_version >= '3.7'",
+            "markers": "python_version < '3.12' and (platform_python_implementation != 'CPython' or python_full_version > '3.7.10') and (platform_system == 'Darwin' or platform_system == 'Windows' or platform_system == 'Linux') and (platform_machine == 'x86_64' or platform_machine == 's390x' or platform_machine == 'aarch64' or platform_machine == 'armv7l' or platform_machine == 'ppc64le' or platform_machine == 'ppc64' or platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'arm64' or platform_machine == 'ARM64' or platform_machine == 'x86' or platform_machine == 'i686') and (platform_python_implementation == 'CPython' or platform_python_implementation == 'PyPy')",
             "version": "==1.4.2"
         },
         "referencing": {
@@ -1588,7 +1581,7 @@
                 "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274",
                 "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"
             ],
-            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
+            "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
             "version": "==1.17.0"
         },
         "tinydb": {
@@ -2014,9 +2007,16 @@
                 "sha256:f81fe93dc1b8e5673f33443c0786c14b77e36f1025973b85e07c70353e46882b"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.9'",
             "version": "==7.7.0"
         },
+        "docker": {
+            "hashes": [
+                "sha256:ad8c70e6e3f8926cb8a92619b832b4ea5299e2831c14284663184e200546fa6c",
+                "sha256:c96b93b7f0a746f9e77d325bcfb87422a3d8bd4f03136ae8a85b37f1898d5fc0"
+            ],
+            "markers": "python_version >= '3.8'",
+            "version": "==7.1.0"
+        },
         "idna": {
             "hashes": [
                 "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9",
@@ -2027,11 +2027,11 @@
         },
         "iniconfig": {
             "hashes": [
-                "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3",
-                "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"
+                "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7",
+                "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"
             ],
-            "markers": "python_version >= '3.7'",
-            "version": "==2.0.0"
+            "markers": "python_version >= '3.8'",
+            "version": "==2.1.0"
         },
         "packaging": {
             "hashes": [
@@ -2055,9 +2055,16 @@
                 "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.8'",
             "version": "==8.3.5"
         },
+        "python-dotenv": {
+            "hashes": [
+                "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca",
+                "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"
+            ],
+            "index": "pypi",
+            "version": "==1.0.1"
+        },
         "requests": {
             "hashes": [
                 "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760",
@@ -2072,9 +2079,24 @@
                 "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401"
             ],
             "index": "pypi",
-            "markers": "python_version >= '3.5'",
             "version": "==1.12.1"
         },
+        "testcontainers": {
+            "hashes": [
+                "sha256:348c72d369d0bd52b57ab4f07a965ae9562837098c28f0522b969b064b779f10",
+                "sha256:36bd2b58d91f2fc7ac4f4a73c6ec00e5e60c259c10f208dbfe3161029889be92"
+            ],
+            "index": "pypi",
+            "version": "==4.9.2"
+        },
+        "typing-extensions": {
+            "hashes": [
+                "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d",
+                "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"
+            ],
+            "markers": "python_version >= '3.8'",
+            "version": "==4.12.2"
+        },
         "urllib3": {
             "hashes": [
                 "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df",
@@ -2082,6 +2104,91 @@
             ],
             "markers": "python_version >= '3.9'",
             "version": "==2.3.0"
+        },
+        "wrapt": {
+            "hashes": [
+                "sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f",
+                "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c",
+                "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a",
+                "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b",
+                "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555",
+                "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c",
+                "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b",
+                "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6",
+                "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8",
+                "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662",
+                "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061",
+                "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998",
+                "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb",
+                "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62",
+                "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984",
+                "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392",
+                "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2",
+                "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306",
+                "sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7",
+                "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3",
+                "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9",
+                "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6",
+                "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192",
+                "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317",
+                "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f",
+                "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda",
+                "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563",
+                "sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a",
+                "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f",
+                "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d",
+                "sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9",
+                "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8",
+                "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82",
+                "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9",
+                "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845",
+                "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82",
+                "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125",
+                "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504",
+                "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b",
+                "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7",
+                "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc",
+                "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6",
+                "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40",
+                "sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a",
+                "sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3",
+                "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a",
+                "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72",
+                "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681",
+                "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438",
+                "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae",
+                "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2",
+                "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb",
+                "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5",
+                "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a",
+                "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3",
+                "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8",
+                "sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2",
+                "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22",
+                "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72",
+                "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061",
+                "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f",
+                "sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9",
+                "sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04",
+                "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98",
+                "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9",
+                "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f",
+                "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b",
+                "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925",
+                "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6",
+                "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0",
+                "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9",
+                "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c",
+                "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991",
+                "sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6",
+                "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000",
+                "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb",
+                "sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119",
+                "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b",
+                "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58"
+            ],
+            "markers": "python_version >= '3.8'",
+            "version": "==1.17.2"
         }
     }
 }
diff --git a/dbrepo-dashboard-service/init/dashboard.py b/dbrepo-dashboard-service/init/dashboard.py
index 1c502fca1d5fc4f5bb93ff75c337bb9185eafe1b..59b8dd5cb0d0e93adf46e24546548fc2ede26621 100644
--- a/dbrepo-dashboard-service/init/dashboard.py
+++ b/dbrepo-dashboard-service/init/dashboard.py
@@ -1,9 +1,9 @@
 import logging
 import os
 
-from clients.grafana_client import GrafanaClient
 from dbrepo.api.dto import Database
 
+from clients.grafana_client import GrafanaClient
 from panel import get_panels
 
 base_url = os.getenv('BASE_URL', 'http://localhost')
@@ -36,7 +36,7 @@ def find(uid: str):
     return grafana.dashboard.get_dashboard(uid)
 
 
-def create(database_name: str, owner_username: str, uid: str = '') -> dict:
+def create(database_name: str, uid: str = '') -> dict:
     grafana = GrafanaClient().connect()
     dashboard = dict(uid=uid,
                      title=f'{database_name} Overview',
@@ -65,7 +65,7 @@ def update(database: Database) -> None:
         find(database.dashboard_uid)
     except Exception:
         logging.warning(f'Failed to find dashboard with uid: {database.dashboard_uid}')
-        create(database.name, database.owner.username, database.dashboard_uid)
+        create(database.name, database.dashboard_uid)
     dashboard = find(database.dashboard_uid)['dashboard']
     # update metadata
     if not database.is_dashboard_enabled and 'managed' in dashboard['tags']:
diff --git a/dbrepo-dashboard-service/init/tests/conftest.py b/dbrepo-dashboard-service/init/tests/conftest.py
index 3653a2e20a11c5fbdfd6ca12abec190f396c17ca..a110a28b14647effb06e3a23ba4de8bc5dac452f 100644
--- a/dbrepo-dashboard-service/init/tests/conftest.py
+++ b/dbrepo-dashboard-service/init/tests/conftest.py
@@ -40,5 +40,6 @@ def cleanup(request, session):
     """
     logging.info("[fixture] clean dashboards")
     grafana = GrafanaClient().connect()
-    dashboards = grafana.folder.get_folder('')
-    print()
+    for dashboard in grafana.search.search_dashboards():
+        grafana.dashboard.delete_dashboard(dashboard['uid'])
+        logging.debug(f"[fixture] deleted dashboard {dashboard['uid']}")
diff --git a/dbrepo-dashboard-service/init/tests/test_app.py b/dbrepo-dashboard-service/init/tests/test_app.py
new file mode 100644
index 0000000000000000000000000000000000000000..60f3ec44cf6f4152b594932a245ec7bf4d8db99c
--- /dev/null
+++ b/dbrepo-dashboard-service/init/tests/test_app.py
@@ -0,0 +1,100 @@
+import unittest
+
+import requests_mock
+from dbrepo.api.dto import Database, Table, Constraints, Column, ColumnType, ConceptBrief, UnitBrief, \
+    UserBrief, ContainerBrief, ImageBrief, DatabaseBrief
+from dbrepo.api.exceptions import NotExistsError
+
+from app import fetch_databases
+
+req = Database(id="209acf92-5c9b-4633-ad99-113c86f6e948",
+               name="Test",
+               internal_name="test_tuw1",
+               owner=UserBrief(id="c6b71ef5-2d2f-48b2-9d79-b8f23a3a0502", username="foo"),
+               contact=UserBrief(id="c6b71ef5-2d2f-48b2-9d79-b8f23a3a0502", username="foo"),
+               exchange_name="dbrepo",
+               is_public=True,
+               is_schema_public=True,
+               is_dashboard_enabled=True,
+               container=ContainerBrief(id="7efe8b27-6cdc-4387-80e3-92ee28f4a7c5",
+                                        name="MariaDB",
+                                        internal_name="mariadb",
+                                        image=ImageBrief(id="f97791b4-baf4-4b18-8f7d-3084818e6549",
+                                                         name="mariadb",
+                                                         version="11.1.3",
+                                                         default=True)),
+               tables=[Table(id="f94a6164-cad4-4873-a9fd-3fe5313b2e95",
+                             database_id="209acf92-5c9b-4633-ad99-113c86f6e948",
+                             name="Data",
+                             internal_name="data",
+                             owner=UserBrief(id="c6b71ef5-2d2f-48b2-9d79-b8f23a3a0502", username="foo"),
+                             constraints=Constraints(uniques=[], foreign_keys=[], checks=[], primary_key=[]),
+                             is_versioned=False,
+                             queue_name="dbrepo",
+                             routing_key="dbrepo.1.1",
+                             is_public=True,
+                             is_schema_public=True,
+                             columns=[Column(id="7bef7e68-88f1-438e-9b94-0a77afd21471",
+                                             database_id="209acf92-5c9b-4633-ad99-113c86f6e948",
+                                             table_id="f94a6164-cad4-4873-a9fd-3fe5313b2e95",
+                                             name="ID",
+                                             ord=0,
+                                             internal_name="id",
+                                             type=ColumnType.BIGINT,
+                                             is_null_allowed=False,
+                                             size=20,
+                                             d=0,
+                                             concept=ConceptBrief(id="fb32ecf6-1f68-49b4-85ee-04e76263cbef",
+                                                                  uri="http://www.wikidata.org/entity/Q2221906"),
+                                             unit=UnitBrief(id="a67d735e-32ef-4917-b412-fe099c6757a1",
+                                                            uri="http://www.ontology-of-units-of-measure.org/resource/om-2/degreeCelsius"),
+                                             val_min=0,
+                                             val_max=10)]
+                             )])
+
+
+class AppUnitTest(unittest.TestCase):
+
+    def test_fetch_databases_succeeds(self):
+        with requests_mock.Mocker() as mock:
+            # mock
+            mock.get('/api/database',
+                     json=[DatabaseBrief(id='209acf92-5c9b-4633-ad99-113c86f6e948',
+                                         name="Test",
+                                         internal_name="test_tuw1",
+                                         owner_id="c6b71ef5-2d2f-48b2-9d79-b8f23a3a0502",
+                                         is_public=True,
+                                         is_schema_public=True,
+                                         contact=UserBrief(id="c6b71ef5-2d2f-48b2-9d79-b8f23a3a0502",
+                                                           username="foo")).model_dump()])
+            mock.get(f'/api/database/{req.id}', json=req.model_dump())
+            # test
+            response = fetch_databases()
+            self.assertEqual(1, len(response))
+
+    def test_fetch_databases_empty_succeeds(self):
+        with requests_mock.Mocker() as mock:
+            # mock
+            mock.get('/api/database', json=[])
+            # test
+            response = fetch_databases()
+            self.assertEqual(0, len(response))
+
+    def test_fetch_databases_not_found_fails(self):
+        with requests_mock.Mocker() as mock:
+            # mock
+            mock.get('/api/database',
+                     json=[DatabaseBrief(id='209acf92-5c9b-4633-ad99-113c86f6e948',
+                                         name="Test",
+                                         internal_name="test_tuw1",
+                                         owner_id="c6b71ef5-2d2f-48b2-9d79-b8f23a3a0502",
+                                         is_public=True,
+                                         is_schema_public=True,
+                                         contact=UserBrief(id="c6b71ef5-2d2f-48b2-9d79-b8f23a3a0502",
+                                                           username="foo")).model_dump()])
+            mock.get(f'/api/database/{req.id}', status_code=404)
+            # test
+            try:
+                fetch_databases()
+            except NotExistsError:
+                pass
\ No newline at end of file
diff --git a/dbrepo-dashboard-service/init/tests/test_integration_dashboard.py b/dbrepo-dashboard-service/init/tests/test_integration_dashboard.py
new file mode 100644
index 0000000000000000000000000000000000000000..9208049f2acf832f355a4133fd5b374ab9a8a161
--- /dev/null
+++ b/dbrepo-dashboard-service/init/tests/test_integration_dashboard.py
@@ -0,0 +1,93 @@
+import unittest
+
+from grafana_client.client import GrafanaClientError
+
+import dashboard
+from clients.grafana_client import GrafanaClient
+
+
+class DashboardIntegrationTest(unittest.TestCase):
+    DASHBOARD_UID = 'covdb1'
+
+    def test_find_succeeds(self):
+        # mock
+        GrafanaClient().connect().dashboard.update_dashboard(dict(folderUid='',
+                                                                  overwrite=False,
+                                                                  dashboard=dict(uid=self.DASHBOARD_UID,
+                                                                                 title=f'Mock',
+                                                                                 tags=['managed'],
+                                                                                 timezone='browser',
+                                                                                 refresh='30m',
+                                                                                 preload=True,
+                                                                                 panels=[])))
+        # test
+        response = dashboard.find(self.DASHBOARD_UID)
+        self.assertEqual(self.DASHBOARD_UID, response['dashboard']['uid'])
+
+    def test_find_not_found_fails(self):
+        # test
+        try:
+            dashboard.find('idonotexist')
+        except GrafanaClientError:
+            pass
+
+    def test_create_succeeds(self):
+        # test
+        dashboard.create('some_database', 'foobar')
+
+    def test_create_with_uid_succeeds(self):
+        # test
+        response = dashboard.create('some_database', self.DASHBOARD_UID)
+        self.assertEqual(self.DASHBOARD_UID, response['uid'])
+
+    def test_create_uid_exists_fails(self):
+        # mock
+        GrafanaClient().connect().dashboard.update_dashboard(dict(folderUid='',
+                                                                  overwrite=False,
+                                                                  dashboard=dict(uid=self.DASHBOARD_UID,
+                                                                                 title=f'Mock',
+                                                                                 tags=['managed'],
+                                                                                 timezone='browser',
+                                                                                 refresh='30m',
+                                                                                 preload=True,
+                                                                                 panels=[])))
+        # test
+        try:
+            dashboard.create('some_database', self.DASHBOARD_UID)
+        except GrafanaClientError:
+            pass
+
+    def test_delete_succeeds(self):
+        # mock
+        GrafanaClient().connect().dashboard.update_dashboard(dict(folderUid='',
+                                                                  overwrite=False,
+                                                                  dashboard=dict(uid=self.DASHBOARD_UID,
+                                                                                 title=f'Mock',
+                                                                                 tags=['managed'],
+                                                                                 timezone='browser',
+                                                                                 refresh='30m',
+                                                                                 preload=True,
+                                                                                 panels=[])))
+        # test
+        dashboard.delete(self.DASHBOARD_UID)
+
+    def test_delete_not_exists_fails(self):
+        # test
+        try:
+            dashboard.delete('idonotexist')
+        except GrafanaClientError:
+            pass
+
+    def test_update_succeeds(self):
+        # mock
+        GrafanaClient().connect().dashboard.update_dashboard(dict(folderUid='',
+                                                                  overwrite=False,
+                                                                  dashboard=dict(uid=self.DASHBOARD_UID,
+                                                                                 title=f'Mock',
+                                                                                 tags=['managed'],
+                                                                                 timezone='browser',
+                                                                                 refresh='30m',
+                                                                                 preload=True,
+                                                                                 panels=[])))
+        # test
+        dashboard.delete(self.DASHBOARD_UID)
diff --git a/dbrepo-dashboard-service/tests/test_integration_app.py b/dbrepo-dashboard-service/tests/test_integration_app.py
index d2886b9411cd84d20f8c197e3f84e52a7541ba10..20da42ff34b73970562bd978a16840685dfd6586 100644
--- a/dbrepo-dashboard-service/tests/test_integration_app.py
+++ b/dbrepo-dashboard-service/tests/test_integration_app.py
@@ -53,7 +53,7 @@ req = Database(id="209acf92-5c9b-4633-ad99-113c86f6e948",
                              )])
 
 
-class JwtTest(unittest.TestCase):
+class AppIntegrationTest(unittest.TestCase):
 
     def token(self, roles: [str], iat: int = int(time.time())):
         claims = {
diff --git a/dbrepo-search-service/init/tests/test_opensearch_client.py b/dbrepo-search-service/init/tests/test_opensearch_client.py
index 54ef2340ab0cf7763122cbf300deb5f8d44d6fa1..1ad70b53f295053fbed962cb0ff6cd7c2e59d815 100644
--- a/dbrepo-search-service/init/tests/test_opensearch_client.py
+++ b/dbrepo-search-service/init/tests/test_opensearch_client.py
@@ -16,6 +16,7 @@ req = Database(id="209acf92-5c9b-4633-ad99-113c86f6e948",
                exchange_name="dbrepo",
                is_public=True,
                is_schema_public=True,
+               is_dashboard_enabled=True,
                container=ContainerBrief(id="7efe8b27-6cdc-4387-80e3-92ee28f4a7c5",
                                         name="MariaDB",
                                         internal_name="mariadb",
diff --git a/lib/python/tests/test_unit_query.py b/lib/python/tests/test_unit_query.py
index 528d6775a7e3b84a3afdceb68344518d234ba21d..719847fbfee49a5ec101d3a1ebca693d5b7585f2 100644
--- a/lib/python/tests/test_unit_query.py
+++ b/lib/python/tests/test_unit_query.py
@@ -23,6 +23,7 @@ class QueryUnitTest(unittest.TestCase):
         internal_name='test_abcd',
         is_public=True,
         is_schema_public=True,
+        is_dashboard_enabled=True,
         tables=[Table(id="029d773f-f98b-40c0-ab22-b8b1635d4fbc",
                       name="Some Table",
                       description="Test Table",
diff --git a/lib/python/tests/test_unit_view.py b/lib/python/tests/test_unit_view.py
index cb26eeaba8584d201202f7b6693f240b36701011..a3319f1fad59c7e2bd2b8a2d5cfb6745fcfd6fcd 100644
--- a/lib/python/tests/test_unit_view.py
+++ b/lib/python/tests/test_unit_view.py
@@ -22,6 +22,7 @@ class ViewUnitTest(unittest.TestCase):
         internal_name='test_abcd',
         is_public=True,
         is_schema_public=True,
+        is_dashboard_enabled=True,
         tables=[Table(id="029d773f-f98b-40c0-ab22-b8b1635d4fbc",
                       name="Some Table",
                       description="Test Table",