diff --git a/package-lock.json b/package-lock.json
index 921140b9451369c9c08daaa1d422c693058a1146..775807cea0d15cd8c7f85a9a3dea51db568d20b5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4398,9 +4398,9 @@
       }
     },
     "caniuse-lite": {
-      "version": "1.0.30001237",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001237.tgz",
-      "integrity": "sha512-pDHgRndit6p1NR2GhzMbQ6CkRrp4VKuSsqbcLeOQppYPKOYkKT/6ZvZDvKJUqcmtyWIAHuZq3SVS2vc1egCZzw=="
+      "version": "1.0.30001242",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001242.tgz",
+      "integrity": "sha512-KvNuZ/duufelMB3w2xtf9gEWCSxJwUgoxOx5b6ScLXC4kPc9xsczUVCPrQU26j5kOsHM4pSUL54tAZt5THQKug=="
     },
     "capture-exit": {
       "version": "2.0.0",
diff --git a/package.json b/package.json
index 45da5415fb864aa887bee48076a1964c8e6be4ee..967f68baa880658fbf7c17e924062c6064d9232f 100644
--- a/package.json
+++ b/package.json
@@ -17,8 +17,8 @@
     "@material-ui/lab": "4.0.0-alpha.57",
     "bootstrap": "4.5",
     "flexlayout-react": "0.5.5",
-    "jszip": "3.2.0",
     "jquery": "3.6.0",
+    "jszip": "3.2.0",
     "react": "^17.0.1",
     "react-bootstrap": "1.4.0",
     "react-dom": "^17.0.1",
diff --git a/src/mocks/mock_dialog.json b/src/mocks/mock_dialog.json
new file mode 100644
index 0000000000000000000000000000000000000000..da3492dddfba4d9f6336ac42b9ed24ad2850572f
--- /dev/null
+++ b/src/mocks/mock_dialog.json
@@ -0,0 +1,4 @@
+{
+  "type" :"Network Error",
+  "message" : "The experiment is loading"
+}
\ No newline at end of file
diff --git a/src/mocks/mock_scan_storage_response.json b/src/mocks/mock_scan_storage_response.json
new file mode 100644
index 0000000000000000000000000000000000000000..afd252ca68505ea50bfbfee034c3c318579ef324
--- /dev/null
+++ b/src/mocks/mock_scan_storage_response.json
@@ -0,0 +1,4 @@
+{
+  "deletedFolders":[0,1],
+  "addedFolders": [2]
+}
\ No newline at end of file
diff --git a/src/mocks/mock_zip_responses.json b/src/mocks/mock_zip_responses.json
new file mode 100644
index 0000000000000000000000000000000000000000..a255a0985dcef21706bbc399693f53d7006be465
--- /dev/null
+++ b/src/mocks/mock_zip_responses.json
@@ -0,0 +1,11 @@
+[
+  {
+    "zipBaseFolderName": "0",
+    "destFolderName": "1"
+
+  },
+  {
+    "zipBaseFolderName": "0",
+    "destFolderName": "2"
+  }
+]
\ No newline at end of file
diff --git a/src/services/__tests__/dialog-service.test.js b/src/services/__tests__/dialog-service.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..5f384e40fc433245f4c830d07aff878a56bdd150
--- /dev/null
+++ b/src/services/__tests__/dialog-service.test.js
@@ -0,0 +1,125 @@
+/**
+ * @jest-environment jsdom
+*/
+import '@testing-library/jest-dom';
+import 'jest-fetch-mock';
+
+import DialogService from '../dialog-service';
+
+import MockDialog from '../../mocks/mock_dialog.json';
+
+test('makes sure that invoking the constructor fails with the right message', () => {
+  expect(() => {
+    new DialogService();
+  }).toThrow(Error);
+  expect(() => {
+    new DialogService();
+  }).toThrowError(Error('Use DialogService.instance'));
+});
+
+test('the experiments service instance always refers to the same object', () => {
+  const instance1 = DialogService.instance;
+  const instance2 = DialogService.instance;
+  expect(instance1).toBe(instance2);
+});
+
+test('should emit an event on network error', () => {
+  jest.spyOn(DialogService.instance, 'networkError').mockImplementation(() => {
+    return Promise.resolve();
+  });
+  let NetworkError = MockDialog;
+
+  let confirmNetworkError = (startingNetwork) => {
+    expect(startingNetwork).toEqual(NetworkError);
+  };
+  DialogService.instance.addListener(
+    DialogService.EVENTS.Error,
+    confirmNetworkError
+  );
+  DialogService.instance.networkError(NetworkError);
+  DialogService.instance.removeListener(
+    DialogService.EVENTS.Error,
+    confirmNetworkError
+  );
+});
+
+test('should emit an event on data error', () => {
+  jest.spyOn(DialogService.instance, 'dataError').mockImplementation(() => {
+    return Promise.resolve();
+  });
+  let DataError = MockDialog;
+
+  let confirmDataError = (startingData) => {
+    expect(startingData).toEqual(DataError);
+  };
+  DialogService.instance.addListener(
+    DialogService.EVENTS.ERROR,
+    confirmDataError
+  );
+  DialogService.instance.dataError(DataError);
+  DialogService.instance.removeListener(
+    DialogService.EVENTS.ERROR,
+    confirmDataError
+  );
+});
+
+test('should emit an event on simulation error', () => {
+  jest.spyOn(DialogService.instance, 'simulationError').mockImplementation(() => {
+    return Promise.resolve();
+  });
+  let SimulationError = MockDialog;
+
+  let confirmSimulationError = (startingSimulation) => {
+    expect(startingSimulation).toEqual(SimulationError);
+  };
+  DialogService.instance.addListener(
+    DialogService.EVENTS.ERROR,
+    confirmSimulationError
+  );
+  DialogService.instance.dataError(SimulationError);
+  DialogService.instance.removeListener(
+    DialogService.EVENTS.ERROR,
+    confirmSimulationError
+  );
+});
+
+test('should emit an event on progress notification', () => {
+  jest.spyOn(DialogService.instance, 'progressNotification').mockImplementation(() => {
+    return Promise.resolve();
+  });
+  let ProgressNotification = MockDialog;
+
+  let confirmProgressNotification = (startingProgress) => {
+    expect(startingProgress).toEqual(ProgressNotification);
+  };
+  DialogService.instance.addListener(
+    DialogService.EVENTS.ERROR,
+    confirmProgressNotification
+  );
+  DialogService.instance.dataError(ProgressNotification);
+  DialogService.instance.removeListener(
+    DialogService.EVENTS.ERROR,
+    confirmProgressNotification
+  );
+});
+
+test('should emit an event on warning notification', () => {
+  jest.spyOn(DialogService.instance, 'warningNotification').mockImplementation(() => {
+    return Promise.resolve();
+  });
+  let WarningNotification = MockDialog;
+
+  let confirmWarningNotification = (startingWarning) => {
+    expect(startingWarning).toEqual(WarningNotification);
+  };
+
+  DialogService.instance.addListener(
+    DialogService.EVENTS.ERROR,
+    confirmWarningNotification
+  );
+  DialogService.instance.dataError(WarningNotification);
+  DialogService.instance.removeListener(
+    DialogService.EVENTS.ERROR,
+    confirmWarningNotification
+  );
+});
diff --git a/src/services/experiments/files/__tests__/import-experiment-service.test.js b/src/services/experiments/files/__tests__/import-experiment-service.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..e48cefb9b8a5810a223767cb932222f0d0c69757
--- /dev/null
+++ b/src/services/experiments/files/__tests__/import-experiment-service.test.js
@@ -0,0 +1,31 @@
+/**
+ * @jest-environment jsdom
+*/
+import '@testing-library/jest-dom';
+import 'jest-fetch-mock';
+
+import ImportExperimentService from '../import-experiment-service';
+
+import MockScanStorageResponse from '../../../../mocks/mock_scan_storage_response.json';
+import MockZipResponses from '../../../../mocks/mock_zip_responses.json';
+
+test('makes sure that invoking the constructor fails with the right message', () => {
+  expect(() => {
+    new ImportExperimentService();
+  }).toThrow(Error);
+  expect(() => {
+    new ImportExperimentService();
+  }).toThrowError(Error('Use ImportExperimentService.instance'));
+});
+
+test('makes sure zip responses are encapsulated in an object', async () => {
+  let importZipResponses = {zipBaseFolderName:['0', '0'], destFolderName:['1', '2'], numberOfZips: 2};
+  expect(await ImportExperimentService.instance.getImportZipResponses(
+    MockZipResponses.map((response) => new Response(JSON.stringify(response))))).toStrictEqual(importZipResponses);
+});
+
+test('makes sure storage response is prepared', async () => {
+  let scanStorageResponse = {deletedFoldersNumber:2, addedFoldersNumber:1, deletedFolders:'0, 1', addedFolders:'2' };
+  expect(await ImportExperimentService.instance.getScanStorageResponse(
+    new Response(JSON.stringify(MockScanStorageResponse)))).toStrictEqual(scanStorageResponse);
+});
\ No newline at end of file
diff --git a/src/services/experiments/files/import-experiment-service.js b/src/services/experiments/files/import-experiment-service.js
index 5ae1b74db8e043de07d94bd2cad534237542ca8a..d7307b9f5a73017969c626e045f03d30b0de4638 100644
--- a/src/services/experiments/files/import-experiment-service.js
+++ b/src/services/experiments/files/import-experiment-service.js
@@ -7,8 +7,19 @@ import DialogService from '../../dialog-service.js';
 const importExperimentURL = `${config.api.proxy.url}${endpoints.proxy.storage.importExperiment.url}`;
 const scanStorageURL = `${config.api.proxy.url}${endpoints.proxy.storage.scanStorage.url}`;
 
+/**
+ * The Import Experiment Service performs the requests (Extract),
+ * processes data such as zip or folder (Transform),
+ * and passes them to the Import Experiment Component (Load).
+ * Errors are handled by communicating with the Error Handler Service.
+ */
+
 let _instance = null;
 const SINGLETON_ENFORCER = Symbol();
+
+/**
+ * Non-default options (content type) for the POST request
+ */
 const options = {
   mode: 'cors', // no-cors, *cors, same-origin
   cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
@@ -42,13 +53,13 @@ export default class ImportExperimentService extends HttpService {
     return _instance;
   }
 
-  getImportZipResponses(responses) {
+  async getImportZipResponses(responses) {
     let importZipResponses = {
       zipBaseFolderName: [],
       destFolderName: []
     };
     importZipResponses.numberOfZips = responses.length;
-    responses.forEach(async response =>{
+    await responses.forEach(async response =>{
       response = await response.json();
       importZipResponses['zipBaseFolderName'].push(response['zipBaseFolderName']);
       importZipResponses['destFolderName'].push(response['destFolderName']);
@@ -129,7 +140,7 @@ export default class ImportExperimentService extends HttpService {
     });
   }
 
-  readZippedExperimentExperiment(event) {
+  readZippedExperiment(event) {
     let files = event.target.files;
     let zipFiles = [];
     Array.from(files).forEach(file => {
@@ -146,7 +157,7 @@ export default class ImportExperimentService extends HttpService {
   }
 
   importZippedExperiment(event) {
-    let promises = this.readZippedExperimentExperiment(event)
+    let promises = this.readZippedExperiment(event)
       .then(zipContents =>
         zipContents.map(zipContent =>
           this.httpRequestPOST(importExperimentURL, zipContent, options)