diff --git a/api/jest.config.ts b/api/jest.config.ts
new file mode 100644
index 0000000000000000000000000000000000000000..09e402b93abdd342aa1ba638532a1805527a247d
--- /dev/null
+++ b/api/jest.config.ts
@@ -0,0 +1,31 @@
+import type { Config } from '@jest/types';
+import * as fs from 'fs';
+import * as dotenv from 'dotenv';
+
+['.env.defaults', '.env'].forEach((f) => dotenv.config({ path: f }));
+
+const srcPath = 'src/engine/connectors';
+const engine_type = process.env.ENGINE_TYPE; // if there no engine all tests will run
+
+export default async (): Promise<Config.InitialOptions> => {
+  const dirs = (await fs.promises.readdir(srcPath))
+    .filter((dir) => dir !== engine_type)
+    .map((dir) => `${srcPath}/${dir}`);
+
+  return {
+    moduleFileExtensions: ['js', 'json', 'ts'],
+    testPathIgnorePatterns: dirs,
+    rootDir: 'src',
+    testRegex: '.*\\.spec\\.ts$',
+    transform: {
+      '^.+\\.(t|j)s$': 'ts-jest',
+    },
+    collectCoverageFrom: ['**/*.(t|j)s'],
+    coverageDirectory: '../coverage',
+    testEnvironment: 'node',
+    setupFiles: ['dotenv/config'],
+    moduleNameMapper: {
+      '^src/(.*)$': '<rootDir>/$1',
+    },
+  };
+};
diff --git a/api/package-lock.json b/api/package-lock.json
index f91260c22f0d301c9b44718acff90118bbaedd2d..3cf24e6b82faa64c029d614fdcbcfc1cf4d543f7 100644
--- a/api/package-lock.json
+++ b/api/package-lock.json
@@ -29,7 +29,7 @@
         "@eclass/semantic-release-docker": "^2.0.0",
         "@nestjs/cli": "^8.0.0",
         "@nestjs/schematics": "^8.0.0",
-        "@nestjs/testing": "^8.0.0",
+        "@nestjs/testing": "^8.2.2",
         "@semantic-release/changelog": "^6.0.1",
         "@semantic-release/git": "^10.0.1",
         "@semantic-release/gitlab": "^7.0.4",
@@ -2105,13 +2105,13 @@
       "dev": true
     },
     "node_modules/@nestjs/testing": {
-      "version": "8.0.6",
-      "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-8.0.6.tgz",
-      "integrity": "sha512-HRXGM5RlGa+o+kxWI9DQCALndSvL3Remjg1cZVFp2w2s5eXRPpiFMo9puXtu9DSc4tz78xYcQGmEaeYNTB7gvg==",
+      "version": "8.2.2",
+      "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-8.2.2.tgz",
+      "integrity": "sha512-TeNdmjSMKKCw6Z4duu5h4FuGtBV0SXqM4qxLytFJ6ZobaODjqh85u9fWqJlthH+XuHslVYsmNBkCeNrgzyrL8A==",
       "dev": true,
       "dependencies": {
         "optional": "0.1.4",
-        "tslib": "2.3.0"
+        "tslib": "2.3.1"
       },
       "funding": {
         "type": "opencollective",
@@ -2132,6 +2132,12 @@
         }
       }
     },
+    "node_modules/@nestjs/testing/node_modules/tslib": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+      "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+      "dev": true
+    },
     "node_modules/@nestjs/typeorm": {
       "version": "8.0.2",
       "resolved": "https://registry.npmjs.org/@nestjs/typeorm/-/typeorm-8.0.2.tgz",
@@ -14165,6 +14171,24 @@
         "randombytes": "^2.1.0"
       }
     },
+    "@nestjs/testing": {
+      "version": "8.2.2",
+      "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-8.2.2.tgz",
+      "integrity": "sha512-TeNdmjSMKKCw6Z4duu5h4FuGtBV0SXqM4qxLytFJ6ZobaODjqh85u9fWqJlthH+XuHslVYsmNBkCeNrgzyrL8A==",
+      "dev": true,
+      "requires": {
+        "optional": "0.1.4",
+        "tslib": "2.3.1"
+      },
+      "dependencies": {
+        "tslib": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+          "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+          "dev": true
+        }
+      }
+    },
     "node_modules/serve-static": {
       "version": "1.14.1",
       "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
diff --git a/api/package.json b/api/package.json
index 00f6a57ccb3c5028ae54daed1fcb0237ebe8137a..bd9aef5a817c42537a4ddfb453266f0be3855be9 100644
--- a/api/package.json
+++ b/api/package.json
@@ -18,7 +18,8 @@
     "test:watch": "jest --watch",
     "test:cov": "jest --coverage",
     "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
-    "test:e2e": "jest --config ./test/jest-e2e.json",
+    "test:e2e": "jest --config ./test/jest.e2e-config.ts",
+    "test:we2e": "jest --watch --config ./test/jest.e2e-config.ts",
     "prepare": "cd .. && husky install api/.husky"
   },
   "dependencies": {
@@ -42,7 +43,7 @@
     "@eclass/semantic-release-docker": "^2.0.0",
     "@nestjs/cli": "^8.0.0",
     "@nestjs/schematics": "^8.0.0",
-    "@nestjs/testing": "^8.0.0",
+    "@nestjs/testing": "^8.2.2",
     "@semantic-release/changelog": "^6.0.1",
     "@semantic-release/git": "^10.0.1",
     "@semantic-release/gitlab": "^7.0.4",
diff --git a/api/src/common/interfaces/utilities.interface.ts b/api/src/common/interfaces/utilities.interface.ts
index ddf5dedfa9585bdffa46ef5a90ca643d49eacf7a..efcb1cd621628c288d0f7d6d5b674275add8d4b8 100644
--- a/api/src/common/interfaces/utilities.interface.ts
+++ b/api/src/common/interfaces/utilities.interface.ts
@@ -1 +1,14 @@
 export type Dictionary<T> = { [key: string]: T };
+
+export enum MIME_TYPES {
+  ERROR = 'text/plain+error',
+  WARNING = 'text/plain+warning',
+  USER_WARNING = 'text/plain+user_error',
+  HIGHCHARTS = 'application/vnd.highcharts+json',
+  JSON = 'application/json',
+  JSONBTREE = 'application/binary-tree+json',
+  PFA = 'application/pfa+json',
+  JSONDATA = 'application/vnd.dataresource+json',
+  HTML = 'text/html',
+  TEXT = 'text/plain',
+}
diff --git a/api/src/engine/connectors/csv/main.connector.ts b/api/src/engine/connectors/csv/main.connector.ts
index 05864adb55c7141de3ec49bd6854b5fdcdb793ee..c9c2b6fd71a69082dbfc95d670c0a8d7a9d4ee87 100644
--- a/api/src/engine/connectors/csv/main.connector.ts
+++ b/api/src/engine/connectors/csv/main.connector.ts
@@ -41,18 +41,16 @@ export default class CSVService implements IEngineService {
     throw new Error('Method not implemented.');
   }
 
-  getExperiment(uuid: string): Experiment | Promise<Experiment> {
+  getExperiment(id: string): Experiment | Promise<Experiment> {
     throw new Error('Method not implemented.');
   }
 
-  removeExperiment(
-    uuid: string,
-  ): PartialExperiment | Promise<PartialExperiment> {
+  removeExperiment(id: string): PartialExperiment | Promise<PartialExperiment> {
     throw new Error('Method not implemented.');
   }
 
   editExperient(
-    uuid: string,
+    id: string,
     expriment: ExperimentEditInput,
   ): Experiment | Promise<Experiment> {
     throw new Error('Method not implemented.');
diff --git a/api/src/engine/connectors/datashield/main.connector.ts b/api/src/engine/connectors/datashield/main.connector.ts
index 462b41003fe536e8976563b11b60e52e562361a5..0b884a9061ef1ad789cb6886f4d125670476337b 100644
--- a/api/src/engine/connectors/datashield/main.connector.ts
+++ b/api/src/engine/connectors/datashield/main.connector.ts
@@ -45,18 +45,16 @@ export default class DataShieldService implements IEngineService {
     throw new Error('Method not implemented.');
   }
 
-  getExperiment(uuid: string): Experiment | Promise<Experiment> {
+  getExperiment(id: string): Experiment | Promise<Experiment> {
     throw new Error('Method not implemented.');
   }
 
-  removeExperiment(
-    uuid: string,
-  ): PartialExperiment | Promise<PartialExperiment> {
+  removeExperiment(id: string): PartialExperiment | Promise<PartialExperiment> {
     throw new Error('Method not implemented.');
   }
 
   editExperient(
-    uuid: string,
+    id: string,
     expriment: ExperimentEditInput,
   ): Experiment | Promise<Experiment> {
     throw new Error('Method not implemented.');
diff --git a/api/src/engine/connectors/exareme/converters.ts b/api/src/engine/connectors/exareme/converters.ts
index e9bc1d7c51908d9b833500d70e573774b908a221..5ca4b79db61a06924af99aebb4e0ca44670de630 100644
--- a/api/src/engine/connectors/exareme/converters.ts
+++ b/api/src/engine/connectors/exareme/converters.ts
@@ -1,7 +1,9 @@
+import { MIME_TYPES } from 'src/common/interfaces/utilities.interface';
 import { Category } from 'src/engine/models/category.model';
-import { AlgorithmParameter } from 'src/engine/models/experiment/algorithm-parameter.model';
+import { Dataset } from 'src/engine/models/dataset.model';
 import { Algorithm } from 'src/engine/models/experiment/algorithm.model';
 import { Experiment } from 'src/engine/models/experiment/experiment.model';
+import { AlgorithmParamInput } from 'src/engine/models/experiment/input/algorithm-parameter.input';
 import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
 import { Group } from 'src/engine/models/group.model';
 import { ResultUnion } from 'src/engine/models/result/common/result-union.model';
@@ -9,14 +11,19 @@ import {
   GroupResult,
   GroupsResult,
 } from 'src/engine/models/result/groups-result.model';
+import { HeatMapResult } from 'src/engine/models/result/heat-map-result.model';
+import { LineChartResult } from 'src/engine/models/result/line-chart-result.model';
 import { RawResult } from 'src/engine/models/result/raw-result.model';
 import { Variable } from 'src/engine/models/variable.model';
 import { Entity } from './interfaces/entity.interface';
 import { ExperimentData } from './interfaces/experiment/experiment.interface';
+import { ResultChartExperiment } from './interfaces/experiment/result-chart-experiment.interface';
 import { ResultExperiment } from './interfaces/experiment/result-experiment.interface';
 import { Hierarchy } from './interfaces/hierarchy.interface';
 import { VariableEntity } from './interfaces/variable-entity.interface';
 import {
+  dataROCToLineResult,
+  dataToHeatmap,
   descriptiveModelToTables,
   descriptiveSingleToTables,
   transformToAlgorithms,
@@ -43,6 +50,14 @@ export const dataToCategory = (data: Entity): Category => {
   };
 };
 
+export const dataToDataset = (data: Entity): Dataset => {
+  return {
+    id: data.code,
+    label: data.label,
+    isLongitudinal: !!data.code.toLowerCase().includes('longitudinal'),
+  };
+};
+
 export const dataToVariable = (data: VariableEntity): Variable => {
   return {
     id: data.code,
@@ -56,11 +71,11 @@ export const dataToVariable = (data: VariableEntity): Variable => {
   };
 };
 
-const algoParamInputToData = (param: AlgorithmParameter) => {
+const algoParamInputToData = (param: AlgorithmParamInput) => {
   return {
-    name: param.name,
-    label: param.name,
-    value: param.value.join(','),
+    name: param.id,
+    label: param.id,
+    value: param.value,
   };
 };
 
@@ -69,7 +84,7 @@ export const experimentInputToData = (data: ExperimentCreateInput) => {
     ((data.transformations?.length > 0 || data.interactions?.length > 0) && {
       single:
         data.transformations?.map((t) => ({
-          var_name: t.name,
+          var_name: t.id,
           unary_operation: t.operation,
         })) || [],
       interactions:
@@ -79,7 +94,7 @@ export const experimentInputToData = (data: ExperimentCreateInput) => {
     }) ||
     null;
 
-  return {
+  const params = {
     algorithm: {
       parameters: [
         {
@@ -97,11 +112,6 @@ export const experimentInputToData = (data: ExperimentCreateInput) => {
           label: 'pathology',
           value: data.domain,
         },
-        {
-          name: 'y',
-          label: 'y',
-          value: data.variables.join(','),
-        },
         ...(formula
           ? [
               {
@@ -112,10 +122,59 @@ export const experimentInputToData = (data: ExperimentCreateInput) => {
           : []),
       ].concat(data.algorithm.parameters.map(algoParamInputToData)),
       type: data.algorithm.type ?? 'string',
-      name: data.algorithm.name,
+      name: data.algorithm.id,
     },
     name: data.name,
   };
+
+  if (data.coVariables && data.coVariables.length) {
+    let separator = ',';
+
+    const design = params.algorithm.parameters.find((p) => p.name === 'design');
+    const excludes = [
+      'Multiple Histograms',
+      'CART',
+      'ID3',
+      'Naive Bayes Training',
+    ];
+
+    if (design && !excludes.includes(data.algorithm.id)) {
+      separator = design.value === 'additive' ? '+' : '*';
+    }
+
+    params.algorithm.parameters.push({
+      name: 'x',
+      label: 'x',
+      value: data.coVariables.join(separator),
+    });
+  }
+
+  if (data.variables) {
+    let variables = data.variables.join(',');
+
+    if (data.algorithm.id === 'TTEST_PAIRED') {
+      const varCount = data.variables.length;
+      variables = data.variables
+        ?.reduce(
+          (vectors: string, v, i) =>
+            (i + 1) % 2 === 0
+              ? `${vectors}${v},`
+              : varCount === i + 1
+              ? `${vectors}${v}-${data.variables[0]}`
+              : `${vectors}${v}-`,
+          '',
+        )
+        .replace(/,$/, '');
+    }
+
+    params.algorithm.parameters.push({
+      name: 'y',
+      label: 'y',
+      value: variables,
+    });
+  }
+
+  return params;
 };
 
 export const descriptiveDataToTableResult = (
@@ -143,31 +202,56 @@ export const descriptiveDataToTableResult = (
   return [result];
 };
 
-export const dataToExperiment = (data: ExperimentData): Experiment => {
-  const expTransform = transformToExperiment.evaluate(data);
+export const dataToExperiment = (
+  data: ExperimentData,
+): Experiment | undefined => {
+  try {
+    const expTransform = transformToExperiment.evaluate(data);
 
-  const exp: Experiment = {
-    ...expTransform,
-    results: [],
-  };
+    const exp: Experiment = {
+      ...expTransform,
+      results: [],
+    };
 
-  exp.results = data.result
-    ? data.result
-        .map((result) => dataToResult(result, exp.algorithm.name))
-        .flat()
-    : [];
+    exp.results = data.result
+      ? data.result
+          .map((result) => dataToResult(result, exp.algorithm.id))
+          .flat()
+      : [];
 
-  return exp;
+    return exp;
+  } catch (e) {
+    return {
+      id: data.uuid,
+      name: data.name,
+      status: 'error',
+      variables: [],
+      domain: data['domain'] ?? '',
+      datasets: [],
+      algorithm: {
+        id: 'unknown',
+      },
+    };
+  }
 };
 
 export const dataToAlgorithms = (data: string): Algorithm[] => {
   return transformToAlgorithms.evaluate(data);
 };
 
-export const dataToRaw = (result: ResultExperiment): RawResult[] => {
+export const dataToRaw = (
+  algo: string,
+  result: ResultExperiment,
+): RawResult[] => {
+  let data = result;
+
+  if (algo === 'CART') {
+    data = { ...data, type: MIME_TYPES.JSONBTREE };
+  }
+
   return [
     {
-      rawdata: result.data,
+      rawdata: data,
     },
   ];
 };
@@ -179,8 +263,10 @@ export const dataToResult = (
   switch (result.type.toLowerCase()) {
     case 'application/json':
       return dataJSONtoResult(result, algo);
+    case 'application/vnd.highcharts+json':
+      return dataHighchartToResult(result as ResultChartExperiment, algo);
     default:
-      return dataToRaw(result);
+      return dataToRaw(algo, result);
   }
 };
 
@@ -192,6 +278,20 @@ export const dataJSONtoResult = (
     case 'descriptive_stats':
       return descriptiveDataToTableResult(result);
     default:
-      return [];
+      return dataToRaw(algo, result);
+  }
+};
+
+export const dataHighchartToResult = (
+  result: ResultChartExperiment,
+  algo: string,
+): Array<typeof ResultUnion> => {
+  switch (result.data.chart.type) {
+    case 'heatmap':
+      return [dataToHeatmap.evaluate(result) as HeatMapResult];
+    case 'area':
+      return [dataROCToLineResult.evaluate(result) as LineChartResult];
+    default:
+      return dataToRaw(algo, result);
   }
 };
diff --git a/api/src/engine/connectors/exareme/interfaces/experiment/experiment.interface.ts b/api/src/engine/connectors/exareme/interfaces/experiment/experiment.interface.ts
index 7412cb0560c9eda88fe61dd4ebbf8128c94e2c62..cd5ceb45a4539812ec15cb94755f2302bb99de63 100644
--- a/api/src/engine/connectors/exareme/interfaces/experiment/experiment.interface.ts
+++ b/api/src/engine/connectors/exareme/interfaces/experiment/experiment.interface.ts
@@ -5,6 +5,7 @@ export interface ExperimentData {
   uuid?: string;
   status?: string;
   createdBy?: string;
+  created: string;
   shared?: boolean;
   viewed?: boolean;
   result?: ResultExperiment[];
diff --git a/api/src/engine/connectors/exareme/interfaces/experiment/result-chart-experiment.interface.ts b/api/src/engine/connectors/exareme/interfaces/experiment/result-chart-experiment.interface.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ef0ba339600d418e2ed02a484dfebcfc5ab8b32b
--- /dev/null
+++ b/api/src/engine/connectors/exareme/interfaces/experiment/result-chart-experiment.interface.ts
@@ -0,0 +1,9 @@
+export interface ResultChartExperiment {
+  data: {
+    chart: {
+      type: string;
+    };
+    series: unknown;
+  };
+  type: string;
+}
diff --git a/api/src/engine/connectors/exareme/interfaces/test-utilities.ts b/api/src/engine/connectors/exareme/interfaces/test-utilities.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2ad1c79e8384dfb1a12fe8dbe75511720dfe4e1f
--- /dev/null
+++ b/api/src/engine/connectors/exareme/interfaces/test-utilities.ts
@@ -0,0 +1,81 @@
+import { IEngineService } from 'src/engine/engine.interfaces';
+import { Experiment } from 'src/engine/models/experiment/experiment.model';
+import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
+
+const TIMEOUT_DURATION_SECONDS = 60 * 10;
+
+const TEST_PATHOLOGIES = {
+  dementia: {
+    code: 'dementia',
+    datasets: [
+      {
+        code: 'desd-synthdata',
+      },
+      { code: 'edsd' },
+      { code: 'ppmi' },
+      { code: 'fake_longitudinal' },
+    ],
+  },
+  mentalhealth: {
+    code: 'mentalhealth',
+    datasets: [{ code: 'demo' }],
+  },
+  tbi: {
+    code: 'tbi',
+    datasets: [{ code: 'dummy_tbi' }],
+  },
+};
+
+const createExperiment = async (
+  input: ExperimentCreateInput,
+  service: IEngineService,
+): Promise<Experiment | undefined> => {
+  return await service.createExperiment(input, false);
+};
+
+const waitForResult = (
+  id: string,
+  service: IEngineService,
+): Promise<Experiment> =>
+  new Promise((resolve, reject) => {
+    let elapsed = 0;
+    const timerId = setInterval(async () => {
+      const experiment = await service.getExperiment(id);
+
+      const loading = experiment ? experiment.status === 'pending' : true;
+
+      if (!loading) {
+        clearInterval(timerId);
+        resolve(experiment);
+      }
+
+      if (elapsed > TIMEOUT_DURATION_SECONDS) {
+        clearInterval(timerId);
+        reject(
+          `Query experiment ${experiment.id} timeout after ${TIMEOUT_DURATION_SECONDS} s`,
+        );
+      }
+
+      elapsed = elapsed + 0.3;
+    }, 300);
+  });
+
+const uid = (): string =>
+  'xxxxxxxx'.replace(/[xy]/g, (c) => {
+    const r = (Math.random() * 16) | 0;
+    const v = c === 'x' ? r : (r & 0x3) | 0x8;
+
+    return v.toString(16);
+  });
+
+const generateNumber = (): string => {
+  return Math.round(Math.random() * 10000).toString();
+};
+export {
+  createExperiment,
+  uid,
+  waitForResult,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+};
diff --git a/api/src/engine/connectors/exareme/main.connector.ts b/api/src/engine/connectors/exareme/main.connector.ts
index 146fb4308b44b7a189b1f31cadcd37e0c35cd8c0..5733366f9125337a555ff7f7df7faad52dae6627 100644
--- a/api/src/engine/connectors/exareme/main.connector.ts
+++ b/api/src/engine/connectors/exareme/main.connector.ts
@@ -24,7 +24,7 @@ import { Group } from 'src/engine/models/group.model';
 import { Variable } from 'src/engine/models/variable.model';
 import {
   dataToAlgorithms,
-  dataToCategory,
+  dataToDataset,
   dataToExperiment,
   dataToGroup,
   dataToVariable,
@@ -74,7 +74,7 @@ export default class ExaremeService implements IEngineService {
 
     return {
       ...resultAPI.data,
-      experiments: resultAPI.data.experiments.map(dataToExperiment),
+      experiments: resultAPI.data.experiments?.map(dataToExperiment) ?? [],
     };
   }
 
@@ -86,8 +86,8 @@ export default class ExaremeService implements IEngineService {
     return dataToAlgorithms(resultAPI.data);
   }
 
-  async getExperiment(uuid: string): Promise<Experiment> {
-    const path = this.options.baseurl + `experiments/${uuid}`;
+  async getExperiment(id: string): Promise<Experiment> {
+    const path = this.options.baseurl + `experiments/${id}`;
 
     const resultAPI = await firstValueFrom(
       this.httpService.get<ExperimentData>(path),
@@ -97,10 +97,10 @@ export default class ExaremeService implements IEngineService {
   }
 
   async editExperient(
-    uuid: string,
+    id: string,
     expriment: ExperimentEditInput,
   ): Promise<Experiment> {
-    const path = this.options.baseurl + `experiments/${uuid}`;
+    const path = this.options.baseurl + `experiments/${id}`;
 
     const resultAPI = await firstValueFrom(
       this.httpService.patch<ExperimentData>(path, expriment),
@@ -109,16 +109,16 @@ export default class ExaremeService implements IEngineService {
     return dataToExperiment(resultAPI.data);
   }
 
-  async removeExperiment(uuid: string): Promise<PartialExperiment> {
-    const path = this.options.baseurl + `experiments/${uuid}`;
+  async removeExperiment(id: string): Promise<PartialExperiment> {
+    const path = this.options.baseurl + `experiments/${id}`;
 
     try {
       await firstValueFrom(this.httpService.delete(path));
       return {
-        uuid: uuid,
+        id: id,
       };
     } catch (error) {
-      throw new BadRequestException(`${uuid} does not exists`);
+      throw new BadRequestException(`${id} does not exists`);
     }
   }
 
@@ -141,7 +141,7 @@ export default class ExaremeService implements IEngineService {
               label: data.label,
               groups: groups,
               rootGroup: dataToGroup(data.metadataHierarchy),
-              datasets: data.datasets ? data.datasets.map(dataToCategory) : [],
+              datasets: data.datasets ? data.datasets.map(dataToDataset) : [],
               variables: data.metadataHierarchy
                 ? this.flattenVariables(data.metadataHierarchy, groups)
                 : [],
@@ -172,22 +172,22 @@ export default class ExaremeService implements IEngineService {
       .pipe(map((response) => response.data));
   }
 
-  getExperimentREST(uuid: string): Observable<string> {
-    const path = this.options.baseurl + `experiments/${uuid}`;
+  getExperimentREST(id: string): Observable<string> {
+    const path = this.options.baseurl + `experiments/${id}`;
 
     return this.httpService
       .get<string>(path)
       .pipe(map((response) => response.data));
   }
 
-  deleteExperiment(uuid: string): Observable<string> {
-    const path = this.options.baseurl + `experiments/${uuid}`;
+  deleteExperiment(id: string): Observable<string> {
+    const path = this.options.baseurl + `experiments/${id}`;
 
     return this.httpService.delete(path).pipe(map((response) => response.data));
   }
 
-  editExperimentREST(uuid: string): Observable<string> {
-    const path = this.options.baseurl + `experiments/${uuid}`;
+  editExperimentREST(id: string): Observable<string> {
+    const path = this.options.baseurl + `experiments/${id}`;
 
     return this.httpService
       .patch(path, this.req.body)
diff --git a/api/src/engine/connectors/exareme/tests/e2e/3c.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/3c.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8770e901a69a2cfbb5575f079e2d7c65bcd32b0f
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/3c.e2e-spec.ts
@@ -0,0 +1,74 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+
+  const modelSlug = `3c-${generateNumber()}`;
+  const algorithmId = 'THREE_C';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['lefthippocampus', 'righthippocampus', 'leftcaudate'],
+    coVariables: ['gender', 'agegroup'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code === 'ppmi' || d.code === 'edsd')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        { id: 'dx', value: 'alzheimerbroadcategory' },
+        { id: 'c2_feature_selection_method', value: 'RF' },
+        { id: 'c2_num_clusters_method', value: 'Euclidean' },
+        { id: 'c2_num_clusters', value: '6' },
+        { id: 'c2_clustering_method', value: 'Euclidean' },
+        { id: 'c3_feature_selection_method', value: 'RF' },
+        { id: 'c3_classification_method', value: 'RF' },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/calibration-belt.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/calibration-belt.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..447b8f457dafe655ee12d7d518bcf8b0fc7d37c7
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/calibration-belt.e2e-spec.ts
@@ -0,0 +1,87 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+
+  const modelSlug = `calibration-belt-${generateNumber()}`;
+  const algorithmId = 'CALIBRATION_BELT';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['mortality_gose'],
+    coVariables: ['mortality_core'],
+    datasets: TEST_PATHOLOGIES.tbi.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.tbi.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        {
+          id: 'devel',
+          value: 'external',
+        },
+        {
+          id: 'max_deg',
+          value: '4',
+        },
+        {
+          id: 'confLevels',
+          value: '0.80,0.95',
+        },
+        {
+          id: 'thres',
+          value: '0.95',
+        },
+        {
+          id: 'num_points',
+          value: '200',
+        },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult.status).toStrictEqual('success');
+      expect(experimentResult).toBeTruthy();
+
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/cart.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/cart.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f8b0085449c7a0229044d66cd73b09a727149ce1
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/cart.e2e-spec.ts
@@ -0,0 +1,72 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { RawResult } from 'src/engine/models/result/raw-result.model';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `cart-${generateNumber()}`;
+  const algorithmId = 'CART';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    coVariables: ['lefthippocampus', 'righthippocampus'],
+    variables: ['alzheimerbroadcategory'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        { id: 'max_depth', value: '3' },
+        { id: 'no_split_points', value: '10' },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+      const r0 = experimentResult.results[0] as RawResult;
+
+      expect(r0?.rawdata['data'].gain).toEqual(0.6142216049382716);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/descriptiveStatistics.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/descriptiveStatistics.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5808b159dae93067640e66ade63f82a15ab3debb
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/descriptiveStatistics.e2e-spec.ts
@@ -0,0 +1,76 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { GroupsResult } from 'src/engine/models/result/groups-result.model';
+import { TableResult } from 'src/engine/models/result/table-result.model';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `statistics-${generateNumber()}`;
+  const algorithmId = 'DESCRIPTIVE_STATS';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['lefthippocampus', 'alzheimerbroadcategory'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [],
+    },
+    filter: '',
+    transformations: [
+      {
+        id: 'lefthippocampus',
+        operation: 'standardize',
+      },
+    ],
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+      const r0 = experimentResult.results[0] as GroupsResult;
+      const table = r0.groups[0].results[0] as TableResult;
+
+      expect(table.data[0][2]).toEqual(474);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/id3.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/id3.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4ef963a6ca5ab93cbe07bf0ff422e40a94744413
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/id3.e2e-spec.ts
@@ -0,0 +1,69 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { RawResult } from 'src/engine/models/result/raw-result.model';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `id3-${generateNumber()}`;
+  const algorithmId = 'ID3';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['alzheimerbroadcategory'],
+    coVariables: ['gender', 'agegroup'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [{ id: 'iterations_max_number', value: '20' }],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(2);
+      const data = experimentResult.results[0] as RawResult;
+
+      expect(data.rawdata['data']['data'][0][2]).toEqual('+80y');
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/k-means.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/k-means.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..57054721ff0675b01d5865ca312bcaa5335e143f
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/k-means.e2e-spec.ts
@@ -0,0 +1,84 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { RawResult } from 'src/engine/models/result/raw-result.model';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `kmeans-${generateNumber()}`;
+  const algorithmId = 'KMEANS';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['leftacgganteriorcingulategyrus', 'rightcerebellumexterior'],
+    coVariables: ['alzheimerbroadcategory'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        {
+          id: 'k',
+          value: '4',
+        },
+        {
+          id: 'e',
+          value: '1',
+        },
+        {
+          id: 'iterations_max_number',
+          value: '1000',
+        },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+      const data = experimentResult.results[0] as RawResult;
+
+      expect(
+        data.rawdata['data'][2]['leftacgganteriorcingulategyrus'],
+      ).toBeCloseTo(4.197, 2);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/kaplan-meier.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/kaplan-meier.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b0766164343410b79c98588100c3a43d037b4df1
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/kaplan-meier.e2e-spec.ts
@@ -0,0 +1,82 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `kaplan-meier-${generateNumber()}`;
+  const algorithmId = 'KAPLAN_MEIER';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['alzheimerbroadcategory'],
+    coVariables: ['apoe4'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        {
+          id: 'outcome_pos',
+          value: 'AD',
+        },
+        {
+          id: 'outcome_neg',
+          value: 'MCI',
+        },
+        {
+          id: 'max_age',
+          value: '100',
+        },
+        {
+          id: 'total_duration',
+          value: '1100',
+        },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/linear-regression.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/linear-regression.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4ed7f222182726313aaaafde67af362e4f748cc1
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/linear-regression.e2e-spec.ts
@@ -0,0 +1,91 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { RawResult } from 'src/engine/models/result/raw-result.model';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `linear-${generateNumber()}`;
+  const algorithmId = 'LINEAR_REGRESSION';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['lefthippocampus'],
+    coVariables: ['leftpcuprecuneus'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        {
+          id: 'referencevalues',
+          value: '[{"name":"alzheimerbroadcategory","val":"Other"}]',
+        },
+        {
+          id: 'encodingparameter',
+          value: 'dummycoding',
+        },
+        {
+          id: 'filter',
+          value:
+            '{"condition":"AND","rules":[{"id":"subjectageyears","field":"subjectageyears","type":"integer","input":"number","operator":"greater","value":"65"}],"valid":true}',
+        },
+      ],
+    },
+    filter:
+      '{"condition":"AND","rules":[{"id":"subjectageyears","field":"subjectageyears","type":"integer","input":"number","operator":"greater","value":"65"}],"valid":true}',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+      const data = experimentResult.results[0] as RawResult;
+
+      expect(data.rawdata['data']['coefficients'][0]['estimate']).toBeCloseTo(
+        0.986,
+        3,
+      );
+      expect(data.rawdata['data']['statistics'][0]['value']).toBeCloseTo(
+        -1.478,
+        3,
+      );
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/logistic-regression.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/logistic-regression.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..abc045cd32efb98cd61908c77bd5a122719d7a41
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/logistic-regression.e2e-spec.ts
@@ -0,0 +1,72 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { RawResult } from 'src/engine/models/result/raw-result.model';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `logistic-${generateNumber()}`;
+  const algorithmId = 'LOGISTIC_REGRESSION';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['gender'],
+    coVariables: ['lefthippocampus'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        { id: 'positive_level', value: 'M' },
+        { id: 'negative_level', value: 'F' },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+      const data = experimentResult.results[0] as RawResult;
+
+      expect(data.rawdata['data']['Coefficients'][0]).toBeCloseTo(-7.628, 3);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/multiple-histograms.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/multiple-histograms.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7604dd93bd27b021f0437fd5c87304135b80957d
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/multiple-histograms.e2e-spec.ts
@@ -0,0 +1,65 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `histograms-${generateNumber()}`;
+  const algorithmId = 'MULTIPLE_HISTOGRAMS';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['lefthippocampus'],
+    coVariables: ['gender', 'alzheimerbroadcategory'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [{ id: 'bins', value: '{ "lefthippocampus" : 35 }' }],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(3);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/naive-bayes.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/naive-bayes.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..024e41227e8642e6896882d09213b02b7510ec25
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/naive-bayes.e2e-spec.ts
@@ -0,0 +1,78 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { RawResult } from '../../../../models/result/raw-result.model';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `naivebayes-${generateNumber()}`;
+  const algorithmId = 'NAIVE_BAYES';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['alzheimerbroadcategory'],
+    coVariables: ['righthippocampus', 'lefthippocampus'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        {
+          id: 'alpha',
+          value: '0.1',
+        },
+        {
+          id: 'k',
+          value: '10',
+        },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(5);
+      const data = experimentResult.results[0] as RawResult;
+
+      expect(data.rawdata['data']['precision'][0]).toBeCloseTo(0.517, 3);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/one-way-anova.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/one-way-anova.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e8361797cd5805a1f84e4e8601d110e8ef344a9e
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/one-way-anova.e2e-spec.ts
@@ -0,0 +1,65 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { RawResult } from '../../../../models/result/raw-result.model';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `anova-1way-${generateNumber()}`;
+  const algorithmId = 'ANOVA_ONEWAY';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['lefthippocampus'],
+    coVariables: ['ppmicategory'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code === 'ppmi')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(4);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/pca.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/pca.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..79f65b81638c405455cdcf2288ce4fd46a6b3a59
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/pca.e2e-spec.ts
@@ -0,0 +1,71 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { RawResult } from '../../../../models/result/raw-result.model';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `pca-${generateNumber()}`;
+  const algorithmId = 'PCA';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['lefthippocampus', 'rightthalamusproper', 'leftthalamusproper'],
+    coVariables: ['alzheimerbroadcategory'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        { id: 'standardize', value: 'false' },
+        { id: 'coding', value: 'null' },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(4);
+      const data = experimentResult.results[0] as RawResult;
+
+      expect(data.rawdata['data']['eigenvalues'][1]).toBeCloseTo(0.433, 3);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/pearson-correlation.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/pearson-correlation.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e1617dd43649650676c7eb41f7c3227158a1bec2
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/pearson-correlation.e2e-spec.ts
@@ -0,0 +1,73 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { RawResult } from '../../../../models/result/raw-result.model';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `pearson-${generateNumber()}`;
+  const algorithmId = 'PEARSON_CORRELATION';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['righthippocampus'],
+    coVariables: ['lefthippocampus'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        { id: 'standardize', value: 'false' },
+        { id: 'coding', value: 'null' },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(2);
+      const data = experimentResult.results[0] as RawResult;
+
+      expect(
+        data.rawdata['data']['Pearson correlation coefficient'][0][0],
+      ).toBeCloseTo(0.924, 3);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/t-test-independant.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/t-test-independant.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2dee1858887a161e31f114f0343660847b676215
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/t-test-independant.e2e-spec.ts
@@ -0,0 +1,101 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { RawResult } from '../../../../models/result/raw-result.model';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `ttest-idp-${generateNumber()}`;
+  const algorithmId = 'TTEST_INDEPENDENT';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: [
+      'rightpcggposteriorcingulategyrus',
+      'leftpcggposteriorcingulategyrus',
+      'rightacgganteriorcingulategyrus',
+      'leftacgganteriorcingulategyrus',
+      'rightmcggmiddlecingulategyrus',
+      'leftmcggmiddlecingulategyrus',
+      'rightphgparahippocampalgyrus',
+    ],
+    coVariables: ['gender'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        {
+          id: 'xlevels',
+          value: 'M,F',
+        },
+        {
+          id: 'testvalue',
+          value: '3.0',
+        },
+        {
+          id: 'hypothesis',
+          value: 'greaterthan',
+        },
+        {
+          id: 'effectsize',
+          value: '1',
+        },
+        {
+          id: 'ci',
+          value: '1',
+        },
+        {
+          id: 'meandiff',
+          value: '1',
+        },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+      const data = experimentResult.results[0] as RawResult;
+
+      expect(data.rawdata['data'][0]['t_value']).toBeCloseTo(18.477, 3);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/t-test-one-sample.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/t-test-one-sample.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a08e6fb3c9a4ce8332e09fc0a4b02b7cf89f2df7
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/t-test-one-sample.e2e-spec.ts
@@ -0,0 +1,89 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { RawResult } from '../../../../models/result/raw-result.model';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `ttest-1s-${generateNumber()}`;
+  const algorithmId = 'TTEST_ONESAMPLE';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['righthippocampus', 'lefthippocampus'],
+    coVariables: ['gender', ' alzheimerbroadcategory'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        {
+          id: 'testvalue',
+          value: '3.0',
+        },
+        {
+          id: 'hypothesis',
+          value: 'different',
+        },
+        {
+          id: 'effectsize',
+          value: '1',
+        },
+        {
+          id: 'ci',
+          value: '1',
+        },
+        {
+          id: 'meandiff',
+          value: '1',
+        },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+      const data = experimentResult.results[0] as RawResult;
+
+      expect(data.rawdata['data'][0]['t_value']).toBeCloseTo(8.155, 3);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/t-test-paired.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/t-test-paired.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dd2b971e8dcb5668faa917f1b1886efb1104359b
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/t-test-paired.e2e-spec.ts
@@ -0,0 +1,72 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { RawResult } from '../../../../models/result/raw-result.model';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `ttest-paired-${generateNumber()}`;
+  const algorithmId = 'TTEST_PAIRED';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['lefthippocampus', 'righthippocampus'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        {
+          id: 'hypothesis',
+          value: 'different',
+        },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+      const data = experimentResult.results[0] as RawResult;
+
+      expect(data.rawdata['data'][0]['t_value']).toBeCloseTo(-63.2, 3);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/tests/e2e/two-way-anova.e2e-spec.ts b/api/src/engine/connectors/exareme/tests/e2e/two-way-anova.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7b616e3266ed5ad805c74297c512c22f4c20c734
--- /dev/null
+++ b/api/src/engine/connectors/exareme/tests/e2e/two-way-anova.e2e-spec.ts
@@ -0,0 +1,89 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { AppModule } from '../../../../../main/app.module';
+import { ENGINE_SERVICE } from '../../../../engine.constants';
+import { IEngineService } from '../../../../engine.interfaces';
+import { ExperimentCreateInput } from '../../../../models/experiment/input/experiment-create.input';
+import { RawResult } from '../../../../models/result/raw-result.model';
+import {
+  createExperiment,
+  generateNumber,
+  TEST_PATHOLOGIES,
+  TIMEOUT_DURATION_SECONDS,
+  waitForResult,
+} from '../../interfaces/test-utilities';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('ExaremeService', () => {
+  let exaremeService: IEngineService;
+
+  beforeEach(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    exaremeService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+  });
+  const modelSlug = `anova-2way-${generateNumber()}`;
+  const algorithmId = 'ANOVA';
+
+  const input: ExperimentCreateInput = {
+    name: modelSlug,
+    variables: ['lefthippocampus'],
+    coVariables: ['alzheimerbroadcategory'],
+    datasets: TEST_PATHOLOGIES.dementia.datasets
+      .filter((d) => d.code !== 'fake_longitudinal')
+      .map((d) => d.code),
+    domain: TEST_PATHOLOGIES.dementia.code,
+    algorithm: {
+      id: algorithmId,
+      type: 'string',
+      parameters: [
+        {
+          id: 'bins',
+          value: '40',
+        },
+        {
+          id: 'iterations_max_number',
+          value: '20',
+        },
+        {
+          id: 'sstype',
+          value: '2',
+        },
+        {
+          id: 'outputformat',
+          value: 'pfa',
+        },
+        {
+          id: 'design',
+          value: 'additive',
+        },
+      ],
+    },
+    filter: '',
+  };
+
+  describe('Integration Test for experiment API', () => {
+    it(`create ${algorithmId}`, async () => {
+      const experiment = await createExperiment(input, exaremeService);
+
+      expect(experiment).toBeTruthy();
+      expect(experiment?.status).toStrictEqual('pending');
+
+      expect(experiment?.id).toBeTruthy();
+
+      const experimentResult = await waitForResult(
+        experiment?.id ?? '',
+        exaremeService,
+      );
+
+      expect(experimentResult).toBeTruthy();
+      expect(experimentResult.status).toStrictEqual('success');
+      expect(experimentResult.results.length).toBeGreaterThanOrEqual(1);
+      const data = experimentResult.results[0] as RawResult;
+
+      expect(data.rawdata['data'][0]['sumofsquares']).toBeCloseTo(34.196, 3);
+    });
+  });
+});
diff --git a/api/src/engine/connectors/exareme/transformations.ts b/api/src/engine/connectors/exareme/transformations.ts
index a57e677bf1e341a527f2c98c105376135c6a4339..07e59d977343342a6686f1f71ce936ee350cd7cd 100644
--- a/api/src/engine/connectors/exareme/transformations.ts
+++ b/api/src/engine/connectors/exareme/transformations.ts
@@ -5,16 +5,16 @@ import * as jsonata from 'jsonata'; // old import style needed due to 'export =
 
 export const transformToAlgorithms = jsonata(`
 (
-    $params := ["y", "pathology", "dataset", "filter"];
+    $params := ["y", "pathology", "dataset", "filter", "x"];
 
     $toArray := function($x) { $type($x) = 'array' ? $x : [$x]};
 
     *.{
-    'name': name,
+    'id': name,
     'label': label,
     'description': desc,
     'parameters': $toArray(parameters[$not(name in $params)].{
-        'name': name,
+        'id': name,
         'description': desc,
         'label': label,
         'type': valueType,
@@ -30,30 +30,45 @@ export const transformToAlgorithms = jsonata(`
 
 export const transformToExperiment = jsonata(`
 ( 
-    $params := ["y", "pathology", "dataset", "filter"];
+    $params := ["y", "pathology", "dataset", "filter", "x", "formula"];
+    $toArray := function($x) { $type($x) = 'array' ? $x : [$x]};
+    $convDate := function($v) { $type($v) = 'string' ? $toMillis($v) : $v };
+    $rp := function($v) {$replace($v, /(\\+|\\*|-)/, ',')};
+    $strSafe := function($v) { $type($v) = 'string' ? $v : "" };
+    $formula := $eval(algorithm.parameters[name = "formula"].value);
 
-    {
+    ($ ~> | algorithm.parameters | {"name": name ? name : label } |){
         "name": name,
-        "uuid": uuid,
+        "id": uuid,
         "author": createdBy,
         "viewed": viewed,
         "status": status,
-        "createdAt": created,
-        "finishedAt": finished,
+        "createdAt": $convDate(created),
+        "finishedAt": $convDate(finished),
         "shared": shared,
-        "updateAt": updated,
-        "domains": algorithm.parameters[name = "pathology"].value,
-        "variables": $split(algorithm.parameters[name = "y"].value, ','),
-        "filter": algorithm.parameters[name = "filter"].value,
+        "updateAt": $convDate(updated),
+        "domain": algorithm.parameters[name = "pathology"].value,
         "datasets": $split(algorithm.parameters[name = "dataset"].value, ','),
+        "variables": $split($rp(algorithm.parameters[name = "y"].value), ','),
+        "coVariables": $toArray($split($rp(algorithm.parameters[name = "x"].value), ',')),
+        "filterVariables": (algorithm.parameters[name = "filter"].value ~> $strSafe() ~> $match(/\\"id\\":\\"(\w*)\\"/)).groups,
+        "filter": algorithm.parameters[name = "filter"].value,
+        "formula": {
+            "transformations": $formula.single.{
+                "id": var_name,
+                "operation": unary_operation
+            }[],
+            "interactions" : $formula.interactions.[var1, var2][]
+        },
         "algorithm": {
-            "name": algorithm.name,
-            "parameters" : 
-                algorithm.parameters[$not(name in $params)].({
-                    "name": name,
-                    "label": label,
-                    "value": value
-                })
+            "id": algorithm.name,
+            "parameters" : $toArray(
+                    algorithm.parameters[$not(name in $params)].({
+                        "id": name,
+                        "label": label,
+                        "value": value
+                    })
+                )
         }
     }
 )
@@ -137,3 +152,57 @@ export const descriptiveSingleToTables = jsonata(`
     ]
 )
 `);
+
+export const dataROCToLineResult = jsonata(`
+({
+    "name": data.title.text,
+    "xAxis": {
+        "label": data.xAxis.title.text
+    },
+    "yAxis": {
+        "label": data.yAxis.title.text
+    },
+    "lines": [
+        {
+            "label": "ROC curve",
+            "x": data.series.data.$[0],
+            "y": data.series.data.$[1],
+            "type": 0
+        }
+    ]
+})
+`);
+
+export const dataToHeatmap = jsonata(`
+(
+    {
+        "name": data.title.text,
+        "xAxis": {
+            "categories": data.xAxis.categories,
+            "label": data.xAxis.label
+        },
+        "yAxis": {
+            "categories": data.yAxis.categories,
+            "label": data.yAxis.label
+        },
+        "matrix": $toMat(data.series.data)
+    }
+)
+`);
+
+dataToHeatmap.registerFunction(
+  'toMat',
+  (a) => {
+    const matrix = [];
+
+    a.forEach(
+      (elem: { y: number | number; x: number | number; value: number }) => {
+        matrix[elem.y] = matrix[elem.y] ?? [];
+        matrix[elem.y][elem.x] = elem.value;
+      },
+    );
+
+    return matrix;
+  },
+  '<a<o>:a<a<n>>',
+);
diff --git a/api/src/engine/connectors/local/main.connector.ts b/api/src/engine/connectors/local/main.connector.ts
index cb472d927f571c9553c0115624a9981f2be653c6..003b3c8cc2927a84dda52f8efe97b7d44edb8ab8 100644
--- a/api/src/engine/connectors/local/main.connector.ts
+++ b/api/src/engine/connectors/local/main.connector.ts
@@ -33,18 +33,16 @@ export default class LocalService implements IEngineService {
     throw new Error('Method not implemented.');
   }
 
-  getExperiment(uuid: string): Experiment | Promise<Experiment> {
+  getExperiment(id: string): Experiment | Promise<Experiment> {
     throw new Error('Method not implemented.');
   }
 
-  removeExperiment(
-    uuid: string,
-  ): PartialExperiment | Promise<PartialExperiment> {
+  removeExperiment(id: string): PartialExperiment | Promise<PartialExperiment> {
     throw new Error('Method not implemented.');
   }
 
   editExperient(
-    uuid: string,
+    id: string,
     expriment: ExperimentEditInput,
   ): Experiment | Promise<Experiment> {
     throw new Error('Method not implemented.');
diff --git a/api/src/engine/engine.controller.ts b/api/src/engine/engine.controller.ts
index e56fa8e7ef75d1b50b233fa28f548129126f790f..a750538507388330a0407e4ef7f91700dc0b575b 100644
--- a/api/src/engine/engine.controller.ts
+++ b/api/src/engine/engine.controller.ts
@@ -30,19 +30,19 @@ export class EngineController {
     return this.engineService.getExperiments();
   }
 
-  @Get('/experiments/:uuid')
-  getExperiment(@Param('uuid') uuid: string): Observable<string> | string {
-    return this.engineService.getExperimentREST(uuid);
+  @Get('/experiments/:id')
+  getExperiment(@Param('id') id: string): Observable<string> | string {
+    return this.engineService.getExperimentREST(id);
   }
 
-  @Delete('/experiments/:uuid')
-  deleteExperiment(@Param('uuid') uuid: string): Observable<string> | string {
-    return this.engineService.deleteExperiment(uuid);
+  @Delete('/experiments/:id')
+  deleteExperiment(@Param('id') id: string): Observable<string> | string {
+    return this.engineService.deleteExperiment(id);
   }
 
-  @Patch('/experiments/:uuid')
-  editExperiment(@Param('uuid') uuid: string): Observable<string> | string {
-    return this.engineService.editExperimentREST(uuid);
+  @Patch('/experiments/:id')
+  editExperiment(@Param('id') id: string): Observable<string> | string {
+    return this.engineService.editExperimentREST(id);
   }
 
   @Post('experiments/transient')
diff --git a/api/src/engine/engine.interfaces.ts b/api/src/engine/engine.interfaces.ts
index ec4fbc7fb43c1b163e3c28eb191162b0e0cf8337..a320765819458b30f430d84934b7e992af77459b 100644
--- a/api/src/engine/engine.interfaces.ts
+++ b/api/src/engine/engine.interfaces.ts
@@ -28,14 +28,12 @@ export interface IEngineService {
     name: string,
   ): Promise<ListExperiments> | ListExperiments;
 
-  getExperiment(uuid: string): Promise<Experiment> | Experiment;
+  getExperiment(id: string): Promise<Experiment> | Experiment;
 
-  removeExperiment(
-    uuid: string,
-  ): Promise<PartialExperiment> | PartialExperiment;
+  removeExperiment(id: string): Promise<PartialExperiment> | PartialExperiment;
 
   editExperient(
-    uuid: string,
+    id: string,
     expriment: ExperimentEditInput,
   ): Promise<Experiment> | Experiment;
 
@@ -46,11 +44,11 @@ export interface IEngineService {
 
   getExperiments(): Observable<string> | string;
 
-  getExperimentREST(uuid: string): Observable<string> | string;
+  getExperimentREST(id: string): Observable<string> | string;
 
-  deleteExperiment(uuid: string): Observable<string> | string;
+  deleteExperiment(id: string): Observable<string> | string;
 
-  editExperimentREST(uuid: string): Observable<string> | string;
+  editExperimentREST(id: string): Observable<string> | string;
 
   startExperimentTransient(): Observable<string> | string;
 
diff --git a/api/src/engine/engine.module.ts b/api/src/engine/engine.module.ts
index 48442588a8d1a2c5120e99fa15d60e7da3c29739..6f8d33c6a63b40a9ac2c07a5bf3983ae0e148775 100644
--- a/api/src/engine/engine.module.ts
+++ b/api/src/engine/engine.module.ts
@@ -53,10 +53,11 @@ export class EngineModule {
       const engine = new service.default(options, httpService, req);
 
       return engine;
-    } catch {
+    } catch (e) {
       this.logger.error(
         `There is a problem with the connector '${options.type}'`,
       );
+      this.logger.verbose(e);
       process.exit(); // We can't continue without an engine, shutdown the process...
     }
   }
diff --git a/api/src/engine/engine.resolver.ts b/api/src/engine/engine.resolver.ts
index 6e23ba38ca26d1129e51abb7cbba8d311cad67b9..ffed50e6467832491d03cf51cab35d6cc2292173 100644
--- a/api/src/engine/engine.resolver.ts
+++ b/api/src/engine/engine.resolver.ts
@@ -29,7 +29,7 @@ export class EngineResolver {
   }
 
   @Query(() => ListExperiments)
-  async experiments(
+  async experimentList(
     @Args('page', { nullable: true, defaultValue: 0 }) page: number,
     @Args('name', { nullable: true, defaultValue: '' }) name: string,
   ) {
@@ -37,8 +37,8 @@ export class EngineResolver {
   }
 
   @Query(() => Experiment)
-  async expriment(@Args('uuid') uuid: string) {
-    return this.engineService.getExperiment(uuid);
+  async experiment(@Args('id') id: string) {
+    return this.engineService.getExperiment(id);
   }
 
   @Query(() => [Algorithm])
@@ -60,16 +60,14 @@ export class EngineResolver {
 
   @Mutation(() => Experiment)
   async editExperiment(
-    @Args('uuid') uuid: string,
+    @Args('id') id: string,
     @Args('data') experiment: ExperimentEditInput,
   ) {
-    return this.engineService.editExperient(uuid, experiment);
+    return this.engineService.editExperient(id, experiment);
   }
 
   @Mutation(() => PartialExperiment)
-  async removeExperiment(
-    @Args('uuid') uuid: string,
-  ): Promise<PartialExperiment> {
-    return this.engineService.removeExperiment(uuid);
+  async removeExperiment(@Args('id') id: string): Promise<PartialExperiment> {
+    return this.engineService.removeExperiment(id);
   }
 }
diff --git a/api/src/engine/interceptors/headers.interceptor.ts b/api/src/engine/interceptors/headers.interceptor.ts
index 9b28e4953456de5d9bc66a390c9cf452cf45306f..8dddccb93815c21cb0f92c79bd97d4fb293bfd35 100644
--- a/api/src/engine/interceptors/headers.interceptor.ts
+++ b/api/src/engine/interceptors/headers.interceptor.ts
@@ -1,17 +1,35 @@
 import { HttpService } from '@nestjs/axios';
-import { Injectable, NestInterceptor, CallHandler } from '@nestjs/common';
+import {
+  CallHandler,
+  HttpException,
+  Inject,
+  Injectable,
+  Logger,
+  NestInterceptor,
+} from '@nestjs/common';
 import { GqlExecutionContext } from '@nestjs/graphql';
 import { IncomingMessage } from 'http';
-import { Observable, tap } from 'rxjs';
+import { catchError, Observable, tap } from 'rxjs';
+import { ENGINE_MODULE_OPTIONS } from '../engine.constants';
+import { IEngineOptions } from '../engine.interfaces';
 
 @Injectable()
 export class HeadersInterceptor implements NestInterceptor {
-  constructor(private httpService: HttpService) {}
+  private readonly logger: Logger;
+
+  constructor(
+    private httpService: HttpService,
+    @Inject(ENGINE_MODULE_OPTIONS) private readonly options: IEngineOptions,
+  ) {
+    // Logger name is the engine name
+    // HttpService will be used mostly by the engine (but it's not always true)
+    this.logger = new Logger(options.type);
+  }
 
   intercept(context: GqlExecutionContext, next: CallHandler): Observable<any> {
     // cleaner : add only the auth header (should find the name)
 
-    const keys = ['cookie', 'x-xsrf-token'];
+    const keys = ['cookie', 'x-xsrf-token']; // should be a module parameter
     let headers = {};
 
     switch (context.getType()) {
@@ -29,7 +47,7 @@ export class HeadersInterceptor implements NestInterceptor {
       }
     }
 
-    Object.keys(headers)
+    Object.keys(headers) // copy needed keys
       .filter((key) => keys.includes(key))
       .map((key) => key.toLowerCase())
       .forEach((key) => {
@@ -37,8 +55,17 @@ export class HeadersInterceptor implements NestInterceptor {
       });
 
     return next.handle().pipe(
+      catchError((e) => {
+        if (!e.response.data || !e.response.status) return e;
+
+        this.logger.log(e.message);
+        this.logger.verbose(
+          `[Error ${e.response.status}] ${e.response.data.message}`,
+        );
+        throw new HttpException(e.response.data, e.response.status); // catch errors, maybe make it optional (module parameter)
+      }),
       tap(() => {
-        this.httpService.axiosRef.defaults.headers.common = {}; //cleaning request
+        this.httpService.axiosRef.defaults.headers.common = {}; // cleaning request
       }),
     );
   }
diff --git a/api/src/engine/models/dataset.model.ts b/api/src/engine/models/dataset.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a15340b0281906705dfc12e32a8af5db4165a27f
--- /dev/null
+++ b/api/src/engine/models/dataset.model.ts
@@ -0,0 +1,8 @@
+import { Field, ObjectType } from '@nestjs/graphql';
+import { Entity } from './entity.model';
+
+@ObjectType()
+export class Dataset extends Entity {
+  @Field({ nullable: true, defaultValue: false })
+  isLongitudinal?: boolean;
+}
diff --git a/api/src/engine/models/domain.model.ts b/api/src/engine/models/domain.model.ts
index f5b8def42a318613b348040b2eccb3ea67a7aa29..1cfef22fb86343d0c521ada3e1e7c7ebc5e7e001 100644
--- a/api/src/engine/models/domain.model.ts
+++ b/api/src/engine/models/domain.model.ts
@@ -1,5 +1,5 @@
 import { Field, ObjectType } from '@nestjs/graphql';
-import { Category } from './category.model';
+import { Dataset } from './dataset.model';
 import { Entity } from './entity.model';
 import { Group } from './group.model';
 import { Variable } from './variable.model';
@@ -15,8 +15,8 @@ export class Domain extends Entity {
   @Field(() => [Variable])
   variables: Variable[];
 
-  @Field(() => [Category])
-  datasets: Category[];
+  @Field(() => [Dataset])
+  datasets: Dataset[];
 
   @Field(() => Group)
   rootGroup: Group;
diff --git a/api/src/engine/models/experiment/algorithm-parameter.model.ts b/api/src/engine/models/experiment/algorithm-parameter.model.ts
index d5db6bfc11634ae3ec054c4c6eef9a5441f74931..d934ebd9a19d08ab2a8b2d0ea1d84f4fa2f369eb 100644
--- a/api/src/engine/models/experiment/algorithm-parameter.model.ts
+++ b/api/src/engine/models/experiment/algorithm-parameter.model.ts
@@ -3,10 +3,10 @@ import { Field, ObjectType } from '@nestjs/graphql';
 @ObjectType()
 export class AlgorithmParameter {
   @Field()
-  name: string;
+  id: string;
 
-  @Field(() => [String], { nullable: true })
-  value?: string[];
+  @Field({ nullable: true })
+  value?: string;
 
   @Field({ nullable: true })
   label?: string;
diff --git a/api/src/engine/models/experiment/algorithm.model.ts b/api/src/engine/models/experiment/algorithm.model.ts
index ec26d747fc8019a29822bf673aa82b29162f5757..818b3c9d5c131a58625b3d724185cb6d87bc7827 100644
--- a/api/src/engine/models/experiment/algorithm.model.ts
+++ b/api/src/engine/models/experiment/algorithm.model.ts
@@ -4,7 +4,7 @@ import { AlgorithmParameter } from './algorithm-parameter.model';
 @ObjectType()
 export class Algorithm {
   @Field()
-  name: string;
+  id: string;
 
   @Field(() => [AlgorithmParameter], { nullable: true, defaultValue: [] })
   parameters?: AlgorithmParameter[];
diff --git a/api/src/engine/models/experiment/author.model.ts b/api/src/engine/models/experiment/author.model.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0536a2e5a337e35f623dc9d649e817fa988dc13d
--- /dev/null
+++ b/api/src/engine/models/experiment/author.model.ts
@@ -0,0 +1,10 @@
+import { Field, ObjectType } from '@nestjs/graphql';
+
+@ObjectType()
+export class Author {
+  @Field({ nullable: true, defaultValue: '' })
+  username?: string;
+
+  @Field({ nullable: true, defaultValue: '' })
+  fullname?: string;
+}
diff --git a/api/src/engine/models/experiment/experiment.model.ts b/api/src/engine/models/experiment/experiment.model.ts
index 06e28b4b2e1c93e8dac7c6e7dc828c706f370c8a..eb757d64d9444f4c505705d3d6faa2b7e32c4d72 100644
--- a/api/src/engine/models/experiment/experiment.model.ts
+++ b/api/src/engine/models/experiment/experiment.model.ts
@@ -1,14 +1,36 @@
 import { Field, ObjectType, PartialType } from '@nestjs/graphql';
 import { ResultUnion } from '../result/common/result-union.model';
 import { Algorithm } from './algorithm.model';
+import { Author } from './author.model';
+
+@ObjectType()
+export class Transformation {
+  @Field({ description: "Variable's id on which to apply the transformation" })
+  id: string;
+
+  @Field({ description: 'Transformation to apply' })
+  operation: string;
+}
+
+@ObjectType()
+export class Formula {
+  @Field(() => [Transformation], { nullable: true, defaultValue: [] })
+  transformations: Transformation[];
+
+  @Field(() => [[String]], { nullable: true, defaultValue: [] })
+  interactions: string[][];
+}
 
 @ObjectType()
 export class Experiment {
-  @Field({ nullable: true })
-  uuid?: string;
+  @Field()
+  id: string;
 
-  @Field({ nullable: true, defaultValue: '' })
-  author?: string;
+  @Field()
+  name: string;
+
+  @Field(() => Author, { nullable: true, defaultValue: '' })
+  author?: Author;
 
   @Field({ nullable: true })
   createdAt?: number;
@@ -43,11 +65,17 @@ export class Experiment {
   @Field(() => [String])
   variables: string[];
 
-  @Field()
-  algorithm: Algorithm;
+  @Field(() => [String], { nullable: true, defaultValue: [] })
+  coVariables?: string[];
+
+  @Field(() => [String], { nullable: true, defaultValue: [] })
+  filterVariables?: string[];
+
+  @Field(() => Formula, { nullable: true })
+  formula?: Formula;
 
   @Field()
-  name: string;
+  algorithm: Algorithm;
 }
 
 @ObjectType()
diff --git a/api/src/engine/models/experiment/input/algorithm-parameter.input.ts b/api/src/engine/models/experiment/input/algorithm-parameter.input.ts
index 8eb4cb26b5dade932440b6fef169275988d33b03..8cd3ec29ddfecb22c1574ea339cd96b4a010f79a 100644
--- a/api/src/engine/models/experiment/input/algorithm-parameter.input.ts
+++ b/api/src/engine/models/experiment/input/algorithm-parameter.input.ts
@@ -1,10 +1,25 @@
-import { Field, InputType } from '@nestjs/graphql';
+import { Field, InputType, registerEnumType } from '@nestjs/graphql';
+
+export enum ParamType {
+  STRING,
+  NUMBER,
+}
+
+registerEnumType(ParamType, {
+  name: 'ParamType',
+});
 
 @InputType()
 export class AlgorithmParamInput {
   @Field()
-  name: string;
+  id: string;
+
+  @Field(() => ParamType, {
+    nullable: true,
+    defaultValue: ParamType.STRING,
+  })
+  type?: ParamType;
 
-  @Field(() => [String])
-  value: string[];
+  @Field(() => String)
+  value: string;
 }
diff --git a/api/src/engine/models/experiment/input/algorithm.input.ts b/api/src/engine/models/experiment/input/algorithm.input.ts
index 54d26b7686559c39b311cee5e5496bce530b0cf5..d87abd4561f975dbb9dfc00964f658265a340085 100644
--- a/api/src/engine/models/experiment/input/algorithm.input.ts
+++ b/api/src/engine/models/experiment/input/algorithm.input.ts
@@ -4,7 +4,7 @@ import { AlgorithmParamInput } from './algorithm-parameter.input';
 @InputType()
 export class AlgorithmInput {
   @Field()
-  name: string;
+  id: string;
 
   @Field(() => [AlgorithmParamInput], { nullable: true, defaultValue: [] })
   parameters: AlgorithmParamInput[];
diff --git a/api/src/engine/models/experiment/input/experiment-create.input.ts b/api/src/engine/models/experiment/input/experiment-create.input.ts
index b0b57cea85b17b0b49d4cbdf7b6cc12f21b71688..a34bb4c8a28c2ee456a6e88f44cdc6a87f4cd059 100644
--- a/api/src/engine/models/experiment/input/experiment-create.input.ts
+++ b/api/src/engine/models/experiment/input/experiment-create.input.ts
@@ -4,7 +4,7 @@ import { AlgorithmInput } from './algorithm.input';
 @InputType()
 export class FormulaTransformation {
   @Field()
-  name: string;
+  id: string;
 
   @Field()
   operation: string;
@@ -24,6 +24,9 @@ export class ExperimentCreateInput {
   @Field(() => [String])
   variables: string[];
 
+  @Field(() => [String], { nullable: true, defaultValue: [] })
+  coVariables?: string[];
+
   @Field()
   algorithm: AlgorithmInput;
 
@@ -31,8 +34,8 @@ export class ExperimentCreateInput {
   name: string;
 
   @Field(() => [FormulaTransformation], { nullable: true })
-  transformations: FormulaTransformation[];
+  transformations?: FormulaTransformation[];
 
   @Field(() => [[String]], { nullable: true })
-  interactions: string[][];
+  interactions?: string[][];
 }
diff --git a/api/src/engine/models/experiment/input/experiment-edit.input.ts b/api/src/engine/models/experiment/input/experiment-edit.input.ts
index d37deb1e8d008d746fda7214bb6890142b74a12a..30812416dea4bdb499226d44763790f9578f21a5 100644
--- a/api/src/engine/models/experiment/input/experiment-edit.input.ts
+++ b/api/src/engine/models/experiment/input/experiment-edit.input.ts
@@ -5,6 +5,9 @@ export class ExperimentEditInput {
   @Field({ nullable: true })
   name?: string;
 
+  @Field({ nullable: true })
+  shared?: boolean;
+
   @Field({ nullable: true })
   viewed?: boolean;
 }
diff --git a/api/src/engine/models/result/common/result-union.model.ts b/api/src/engine/models/result/common/result-union.model.ts
index 2f56bb4d1f6ef577e9e836972f45dd59ede7fc28..bc4bb4a1472ea131fd8696da73d5c3d227c44a8f 100644
--- a/api/src/engine/models/result/common/result-union.model.ts
+++ b/api/src/engine/models/result/common/result-union.model.ts
@@ -19,10 +19,6 @@ export const ResultUnion = createUnionType({
       return TableResult;
     }
 
-    if (value.rawdata) {
-      return RawResult;
-    }
-
     if (value.groups) {
       return GroupsResult;
     }
@@ -31,10 +27,10 @@ export const ResultUnion = createUnionType({
       return HeatMapResult;
     }
 
-    if (value.x) {
+    if (value.lines) {
       return LineChartResult;
     }
 
-    return null;
+    return RawResult;
   },
 });
diff --git a/api/src/engine/models/result/heat-map-result.model.ts b/api/src/engine/models/result/heat-map-result.model.ts
index 267dc3c20201236e5d11ee1cbcbb6d6d89af15a7..8dd65ada27662536bffa7aeea6c8b78b0759c2fa 100644
--- a/api/src/engine/models/result/heat-map-result.model.ts
+++ b/api/src/engine/models/result/heat-map-result.model.ts
@@ -7,12 +7,12 @@ export class HeatMapResult extends Result {
   @Field()
   name: string;
 
-  @Field(() => [[Number]])
-  matrix: number[][];
+  @Field(() => ChartAxis, { nullable: true })
+  xAxis?: ChartAxis;
 
-  @Field(() => ChartAxis)
-  xAxis: ChartAxis;
+  @Field(() => ChartAxis, { nullable: true })
+  yAxis?: ChartAxis;
 
-  @Field(() => ChartAxis)
-  yAxis: ChartAxis;
+  @Field(() => [[Number]])
+  matrix: number[][];
 }
diff --git a/api/src/engine/models/result/raw-result.model.ts b/api/src/engine/models/result/raw-result.model.ts
index 853362293bbfe6da230e487f8ea139ba36a16f3b..01528a5fd6dcbffe09d646bf7356ef87f18c200b 100644
--- a/api/src/engine/models/result/raw-result.model.ts
+++ b/api/src/engine/models/result/raw-result.model.ts
@@ -7,6 +7,6 @@ import { Result } from './common/result.model';
 
 @ObjectType()
 export class RawResult extends Result {
-  @Field(() => GraphQLJSON)
-  rawdata: unknown;
+  @Field(() => GraphQLJSON, { nullable: true, defaultValue: '' })
+  rawdata?: unknown;
 }
diff --git a/api/src/engine/test/core.e2e-spec.ts b/api/src/engine/test/core.e2e-spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bb35467dd1911ea2f88c8af9f0268218ddfdb8a5
--- /dev/null
+++ b/api/src/engine/test/core.e2e-spec.ts
@@ -0,0 +1,47 @@
+import { Test, TestingModule } from '@nestjs/testing';
+import { Domain } from 'src/engine/models/domain.model';
+import { AppModule } from '../../main/app.module';
+import { TIMEOUT_DURATION_SECONDS } from '../connectors/exareme/interfaces/test-utilities';
+import { ENGINE_SERVICE } from '../engine.constants';
+import { IEngineService } from '../engine.interfaces';
+
+jest.setTimeout(1000 * TIMEOUT_DURATION_SECONDS);
+
+describe('Engine service', () => {
+  let engineService: IEngineService;
+  let domains: Domain[];
+
+  beforeAll(async () => {
+    const moduleRef: TestingModule = await Test.createTestingModule({
+      imports: [AppModule],
+    }).compile();
+
+    engineService = await moduleRef.resolve<IEngineService>(ENGINE_SERVICE);
+
+    domains = await engineService.getDomains([]);
+  });
+
+  it('Get domains', async () => {
+    expect(domains).toBeTruthy();
+    expect(domains.length).toBeGreaterThanOrEqual(1);
+  });
+
+  it('Get datasets', async () => {
+    domains.forEach((domain) => {
+      expect(domain.datasets).toBeTruthy();
+    });
+  });
+
+  it('Get algorithms', async () => {
+    const algorithms = await engineService.getAlgorithms();
+    expect(algorithms).toBeTruthy();
+    expect(algorithms.length).toBeGreaterThanOrEqual(1);
+  });
+
+  it('Get groups', async () => {
+    domains.forEach((domain) => {
+      expect(domain.groups).toBeTruthy();
+      expect(domain.groups.length).toBeGreaterThanOrEqual(1);
+    });
+  });
+});
diff --git a/api/src/schema.gql b/api/src/schema.gql
index 1d30677261172d7d7fdc830d938d329d9b5f2d5d..854bd5ec152a379d4a5fcb3b94f6f6dbcf925d23 100644
--- a/api/src/schema.gql
+++ b/api/src/schema.gql
@@ -2,9 +2,10 @@
 # THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
 # ------------------------------------------------------
 
-type Category {
+type Dataset {
   id: String!
   label: String
+  isLongitudinal: Boolean
 }
 
 type Group {
@@ -17,6 +18,11 @@ type Group {
   variables: [String!]
 }
 
+type Category {
+  id: String!
+  label: String
+}
+
 type Variable {
   id: String!
   label: String
@@ -32,13 +38,13 @@ type Domain {
   description: String
   groups: [Group!]!
   variables: [Variable!]!
-  datasets: [Category!]!
+  datasets: [Dataset!]!
   rootGroup: Group!
 }
 
 type AlgorithmParameter {
-  name: String!
-  value: [String!]
+  id: String!
+  value: String
   label: String
   description: String
   defaultValue: String
@@ -50,7 +56,7 @@ type AlgorithmParameter {
 }
 
 type Algorithm {
-  name: String!
+  id: String!
   parameters: [AlgorithmParameter!]
   label: String
   type: String
@@ -72,7 +78,7 @@ type TableResult {
 }
 
 type RawResult {
-  rawdata: JSON!
+  rawdata: JSON
 }
 
 """
@@ -86,9 +92,9 @@ type GroupsResult {
 
 type HeatMapResult {
   name: String!
+  xAxis: ChartAxis
+  yAxis: ChartAxis
   matrix: [[Float!]!]!
-  xAxis: ChartAxis!
-  yAxis: ChartAxis!
 }
 
 type LineChartResult {
@@ -126,9 +132,28 @@ type Header {
   type: String!
 }
 
+type Author {
+  username: String
+  fullname: String
+}
+
+type Transformation {
+  """Variable's id on which to apply the transformation"""
+  id: String!
+
+  """Transformation to apply"""
+  operation: String!
+}
+
+type Formula {
+  transformations: [Transformation!]
+  interactions: [[String!]!]
+}
+
 type Experiment {
-  uuid: String
-  author: String
+  id: String!
+  name: String!
+  author: Author
   createdAt: Float
   updateAt: Float
   finishedAt: Float
@@ -140,13 +165,16 @@ type Experiment {
   filter: String
   domain: String!
   variables: [String!]!
+  coVariables: [String!]
+  filterVariables: [String!]
+  formula: Formula
   algorithm: Algorithm!
-  name: String!
 }
 
 type PartialExperiment {
-  uuid: String
-  author: String
+  id: String
+  name: String
+  author: Author
   createdAt: Float
   updateAt: Float
   finishedAt: Float
@@ -158,8 +186,10 @@ type PartialExperiment {
   filter: String
   domain: String
   variables: [String!]
+  coVariables: [String!]
+  filterVariables: [String!]
+  formula: Formula
   algorithm: Algorithm
-  name: String
 }
 
 type ListExperiments {
@@ -171,15 +201,15 @@ type ListExperiments {
 
 type Query {
   domains(ids: [String!] = []): [Domain!]!
-  experiments(name: String = "", page: Float = 0): ListExperiments!
-  expriment(uuid: String!): Experiment!
+  experimentList(name: String = "", page: Float = 0): ListExperiments!
+  experiment(id: String!): Experiment!
   algorithms: [Algorithm!]!
 }
 
 type Mutation {
   createExperiment(isTransient: Boolean = false, data: ExperimentCreateInput!): Experiment!
-  editExperiment(data: ExperimentEditInput!, uuid: String!): Experiment!
-  removeExperiment(uuid: String!): PartialExperiment!
+  editExperiment(data: ExperimentEditInput!, id: String!): Experiment!
+  removeExperiment(id: String!): PartialExperiment!
 }
 
 input ExperimentCreateInput {
@@ -187,6 +217,7 @@ input ExperimentCreateInput {
   filter: String
   domain: String!
   variables: [String!]!
+  coVariables: [String!] = []
   algorithm: AlgorithmInput!
   name: String!
   transformations: [FormulaTransformation!]
@@ -194,22 +225,29 @@ input ExperimentCreateInput {
 }
 
 input AlgorithmInput {
-  name: String!
+  id: String!
   parameters: [AlgorithmParamInput!] = []
   type: String!
 }
 
 input AlgorithmParamInput {
-  name: String!
-  value: [String!]!
+  id: String!
+  type: ParamType = STRING
+  value: String!
+}
+
+enum ParamType {
+  STRING
+  NUMBER
 }
 
 input FormulaTransformation {
-  name: String!
+  id: String!
   operation: String!
 }
 
 input ExperimentEditInput {
   name: String
+  shared: Boolean
   viewed: Boolean
 }
diff --git a/api/test/app.e2e-spec.ts b/api/test/app.e2e-spec.ts
index 50cda62332e9474925e819ff946358a9c40d1bf2..92622c06ac54f7020c4be59cc4f3751feffeef0b 100644
--- a/api/test/app.e2e-spec.ts
+++ b/api/test/app.e2e-spec.ts
@@ -1,7 +1,7 @@
 import { Test, TestingModule } from '@nestjs/testing';
 import { INestApplication } from '@nestjs/common';
 import * as request from 'supertest';
-import { AppModule } from './../src/app.module';
+import { AppModule } from 'src/main/app.module';
 
 describe('AppController (e2e)', () => {
   let app: INestApplication;
diff --git a/api/test/jest-e2e.json b/api/test/jest-e2e.json
deleted file mode 100644
index e9d912f3e3cefc18505d3cd19b3a5a9f567f5de0..0000000000000000000000000000000000000000
--- a/api/test/jest-e2e.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "moduleFileExtensions": ["js", "json", "ts"],
-  "rootDir": ".",
-  "testEnvironment": "node",
-  "testRegex": ".e2e-spec.ts$",
-  "transform": {
-    "^.+\\.(t|j)s$": "ts-jest"
-  }
-}
diff --git a/api/test/jest.e2e-config.ts b/api/test/jest.e2e-config.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cad149913075e7aa049a6a11ea40b7e96b92e476
--- /dev/null
+++ b/api/test/jest.e2e-config.ts
@@ -0,0 +1,31 @@
+import type { Config } from '@jest/types';
+import * as fs from 'fs';
+import * as dotenv from 'dotenv';
+
+['.env.defaults', '.env'].forEach((f) => dotenv.config({ path: f }));
+
+const srcPath = 'src/engine/connectors';
+const engine_type = process.env.ENGINE_TYPE; // if there no engine all tests will run
+
+export default async (): Promise<Config.InitialOptions> => {
+  const dirs = (await fs.promises.readdir(srcPath))
+    .filter((dir) => dir !== engine_type)
+    .map((dir) => `${srcPath}/${dir}`);
+
+  return {
+    moduleFileExtensions: ['js', 'json', 'ts'],
+    testPathIgnorePatterns: dirs,
+    rootDir: '../src',
+    testRegex: '.e2e-spec.ts$',
+    transform: {
+      '^.+\\.(t|j)s$': 'ts-jest',
+    },
+    collectCoverageFrom: ['**/*.(t|j)s'],
+    coverageDirectory: '../coverage',
+    testEnvironment: 'node',
+    setupFiles: ['dotenv/config'],
+    moduleNameMapper: {
+      '^src/(.*)$': '<rootDir>/$1',
+    },
+  };
+};