diff --git a/src/composables/LayoutMainChain.ts b/src/composables/LayoutMainChain.ts
index b979bb54fcbe87e4280113037be324ab4389e2c7..491995d0200354655a6c96a4fd470e1c47b3675f 100644
--- a/src/composables/LayoutMainChain.ts
+++ b/src/composables/LayoutMainChain.ts
@@ -9,7 +9,8 @@ import { DFSWithSources, DFSsourceDAG } from "./AlgorithmDFS";
 import { networkToGDSGraph } from "./ConvertFromNetwork";
 import { getStartNodes } from "./CalculateStartNodes";
 import { BFS } from "./AlgorithmBFS";
-import { addSubgraphToNetwork, createSubgraph, updateNodeMetadataSubgraph } from './SubgraphForSubgraphNetwork';
+import { addSubgraphToNetwork, createSubgraph } from './SubgraphForSubgraphNetwork';
+import { path } from "d3";
 
 /**
  * This file contains functions find and add main chains and mini-branch (form main chain) in a subgraphNetwork.
@@ -93,11 +94,7 @@ export async function addMainChainFromSources(subgraphNetwork:SubgraphNetwork, s
             // create subgraph and add it
             const newMainChainId="mainChain__"+mainChainID;
             const newMainChain= createSubgraph(newMainChainId, mainChain.nodes,[],TypeSubgraph.MAIN_CHAIN);
-            mainChains[newMainChainId]=newMainChain;
-            // add metadata for node in cluster
-            mainChain.nodes.forEach(nodeID=>{
-                updateNodeMetadataSubgraph(network, nodeID, newMainChainId, TypeSubgraph.MAIN_CHAIN);
-            });
+            subgraphNetwork=addSubgraphToNetwork(subgraphNetwork,newMainChain,TypeSubgraph.MAIN_CHAIN);
         }
     });
 
@@ -163,35 +160,37 @@ export async function addMiniBranchToMainChain(subgraphNetwork:SubgraphNetwork):
  */
 export async function getPathSourcesToTargetNode(network:Network, sources:string[],merge:boolean=true,pathType:PathType=PathType.ALL_LONGEST):Promise<{[key:string]:{nodes:Array<string>, height:number}}>{
 
-    //console.log('DAG_Dijkstra');
-
     let pathsFromSources:{[key:string]:{nodes:Array<string>, height:number}}={};
 
     // for each source : do an independant dfs
-    sources.forEach(async source=>{
+    for (const source of sources){
         // DFS to get a DAG from this source, and get topological sort
         const {dfs,graph}=await DFSsourceDAG(network,[source]);
         // get max distance from source node for all nodes, and by which parent nodes the node had been accessed
         const {distances, parents}=await DistanceFromSourceDAG(graph,dfs,pathType);
+        console.log('distances',distances);
         // get the farthest node from source (node with max distance)
         const targetNodes=findMaxKeys(distances);
         // for each target node : (if several path wanted)
         if (pathType==PathType.ALL_LONGEST || pathType==PathType.ALL){
-            targetNodes.key.forEach(async target => {
+            for (const target of targetNodes.key){
                 // get the parents that goes from source to target node 
+                console.log('parents',parents);
+                console.log('target',target);
                 const nodesBetweenSourceTarget=BFS(parents,target);
                 // merge with an existing path if node in common
                 // height is the max distance +1 
                 pathsFromSources=await mergeNewPath(source,{nodes:nodesBetweenSourceTarget, height:targetNodes.max+1},pathsFromSources,merge);
-            });
+                console.log('pathsFromSources',pathsFromSources);
+            };
         } else  if(pathType==PathType.LONGEST){ // if only one path wanted : take the first
             // get the parents that goes from source to target node 
             const nodesBetweenSourceTarget=BFS(parents,targetNodes.key[0]);
             // merge with an existing path if node in common
-            pathsFromSources= await mergeNewPath(source,{nodes:nodesBetweenSourceTarget, height:targetNodes.max},pathsFromSources,merge);
+            pathsFromSources= await mergeNewPath(source,{nodes:nodesBetweenSourceTarget, height:targetNodes.max+1},pathsFromSources,merge);
         }
             
-    });      
+    }    
     return pathsFromSources;
 }
 
@@ -245,7 +244,6 @@ async function DistanceFromSourceDAG(graph:{[key:string]:Function}, topologicalO
             }
         })
     });
-
     return {distances:distanceFromSource, parents:parentsFromSource};
 }
 
@@ -282,30 +280,53 @@ function findMaxKeys(obj: { [key: string]: number }): {key:string[],max:number}
  */
 async function mergeNewPath(source:string,newPath:{nodes:Array<string>, height:number},pathsFromSources:{[key:string]:{nodes:Array<string>, height:number}}, merge:boolean=true):Promise<{[key:string]:{nodes:Array<string>, height:number}}>{
     const keys=Object.keys(pathsFromSources).sort();
-    let hasmerged=false;
-    if (merge) {
-        keys.forEach(key=>{
-            const pathNodes = pathsFromSources[key].nodes;
-            // Check for common nodes, but target nodes
-            const commonNodes = pathNodes.find(node => newPath.nodes.includes(node));
-            if (commonNodes) {
+
+    // if no path in the object : add the new path
+    if (keys.length===0){
+        pathsFromSources[source]=newPath;
+        return pathsFromSources;
+    }
+
+    // for each path in the object
+    keys.forEach(key=>{
+        const pathNodes = pathsFromSources[key].nodes;
+        console.log('pathNodes',pathNodes);
+        // Check for common nodes
+        const commonNodes = pathNodes.find(node => newPath.nodes.includes(node));
+        console.log('commonNodes',commonNodes);
+        if (commonNodes && commonNodes.length>0){
+            console.log('commonNodes',commonNodes);
+            if(merge){
                 // Merge paths
                 const mergedPath = Array.from(new Set(pathNodes.concat(newPath.nodes)));
-                // Create new key
-                const newKey = `${key}__${source}`;
+                console.log('mergedPath',mergedPath);
+                // Create new key if necessary
+                let newKey:string = key;
+                const sourceAlreadyInKey=key.split('__').includes(source);
+                if(!sourceAlreadyInKey){ 
+                    newKey= `${key}__${source}`;
+                }
                 // Update pathsFromSources object
                 const newheight=newPath.height>pathsFromSources[key].height?newPath.height:pathsFromSources[key].height;
                 pathsFromSources[newKey] = {nodes:mergedPath,height:newheight};
-                // Remove old key
-                delete pathsFromSources[key];
-                hasmerged=true;
+                
+                // Remove old key if the name has changed
+                if(!sourceAlreadyInKey){
+                    delete pathsFromSources[key];
+                }
+            }else{
+                // Highest path is kept
+                if(newPath.height>pathsFromSources[key].height){
+                    delete pathsFromSources[key];
+                    pathsFromSources[source]=newPath;
+                }
             }
-        });
-    }
-    // if no merge : added on it's own
-    if (!hasmerged){
-        pathsFromSources[source]=newPath;
-    }
+        }else{
+            // If no common nodes : path added on it's own
+            if(pathsFromSources[source]) throw new Error('source already in pathsFromSources, but supposed to have no common nodes');
+            pathsFromSources[source]=newPath;
+        }
+    });
     return pathsFromSources;
 }
 
diff --git a/src/composables/LayoutManageSideCompounds.ts b/src/composables/LayoutManageSideCompounds.ts
index 0c580efee35956ed338881bee081874d2f0c16f5..5b51fde891450e47d478cbb5554dbe8a61722ba2 100644
--- a/src/composables/LayoutManageSideCompounds.ts
+++ b/src/composables/LayoutManageSideCompounds.ts
@@ -10,11 +10,6 @@ import { removeAllSelectedNodes , duplicateAllNodesByAttribut} from "./VizCoreFu
 import { getMeanNodesSizePixel, inchesToPixels, minEdgeLength, pixelsToInches } from "./CalculateSize";
 import { sideCompoundAttribute,isDuplicate, isSideCompound, setAsSideCompound } from "./GetSetAttributsNodes";
 
-// General imports
-//import { e, S } from "vitest/dist/reporters-1evA5lom";
-import { c } from "vite/dist/node/types.d-aGj9QkWt";
-import { resolve } from "path";
-import { error } from "console";
 
 
 
diff --git a/src/composables/LayoutSugiyama.ts b/src/composables/LayoutSugiyama.ts
index b5e730ede497eaaf08e41699a0f7f5b7b2bad54d..117ff68305d1f7247f11602eece3fada55daa481 100644
--- a/src/composables/LayoutSugiyama.ts
+++ b/src/composables/LayoutSugiyama.ts
@@ -8,13 +8,7 @@ import {  networkToDOT } from './ConvertFromNetwork';
 import {  changeNetworkFromViz } from './ConvertToNetwork';
 
 // General imports
-//import * as d3 from 'd3';
-import { reactive } from "vue";
-// import cytoscape from 'cytoscape';
-// import fcose from 'cytoscape-fcose';
-// import cosebilkent from 'cytoscape-cose-bilkent';
-import dagre from 'dagrejs';
-import { Graph, instance } from "@viz-js/viz";
+import { instance } from "@viz-js/viz";
 
 
 /**
diff --git a/src/composables/__tests__/LayoutMainChain.test.ts b/src/composables/__tests__/LayoutMainChain.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d18827b615941c4e467cfca0d4273e78053754a3
--- /dev/null
+++ b/src/composables/__tests__/LayoutMainChain.test.ts
@@ -0,0 +1,690 @@
+// Type imports
+import { PathType, StartNodesType } from "../../types/EnumArgs";
+import { SubgraphNetwork } from "../../types/SubgraphNetwork";
+import {TypeSubgraph, type Subgraph} from "../../types/Subgraph";
+import { Network } from  "../../types/TypeVizCore";
+
+// Composable imports
+import * as LayoutMainChain from "../LayoutMainChain";
+import * as AlgorithmDFS from "../AlgorithmDFS";
+import * as ConvertFromNetwork from "../ConvertFromNetwork";
+import * as CalculateStartNodes from "../CalculateStartNodes";
+import * as AlgorithmBFS from "../AlgorithmBFS";
+import * as SubgraphForSubgraphNetwork from '../SubgraphForSubgraphNetwork';
+import { before } from "node:test";
+
+
+describe('LayoutMainChain', () => {
+
+    const createSubgraphMock = jest.spyOn(SubgraphForSubgraphNetwork, 'createSubgraph');
+    const networkToGDSGraphMock = jest.spyOn(ConvertFromNetwork, 'networkToGDSGraph');
+
+    const addSubgraphToNetworkMock=jest.spyOn(SubgraphForSubgraphNetwork, 'addSubgraphToNetwork');
+    addSubgraphToNetworkMock.mockImplementation((subgraphNetwork:SubgraphNetwork,subgraph:Subgraph,type:TypeSubgraph) => {
+        if (!subgraphNetwork[type]) subgraphNetwork[type]={};
+        if(!(subgraph.name in subgraphNetwork[type])){
+            subgraphNetwork[type][subgraph.name]=subgraph;
+        }
+        return subgraphNetwork;
+    });
+
+    let network: Network;
+    let subgraphNetwork: SubgraphNetwork;
+
+    beforeEach(() => {
+        network = {
+            id:"network",
+            nodes:{},
+            links:[]
+        };
+
+        subgraphNetwork={
+            network: network,
+            networkStyle: {},
+        };
+    });
+
+    afterEach(() => {
+        jest.clearAllMocks();
+    });
+
+    describe('addMainChainFromSources', () => {
+
+        const getStartNodesMock= jest.spyOn(CalculateStartNodes, 'getStartNodes');
+        getStartNodesMock.mockReturnValue(Promise.resolve(["A", "B"]));
+ 
+        beforeEach(() => {
+
+            createSubgraphMock.mockImplementation((name:string,nodes:string[])=>{
+                return {
+                    name: name,
+                    nodes: nodes,
+                    type: TypeSubgraph.MAIN_CHAIN,
+                }
+    
+            });
+
+        });
+
+        
+        it('shouldn t use getStartNodes because already list of sources', async () => {
+            // DATA
+            const sources=["A", "B"];
+            const getMainChains= async function(){
+                return {};
+            }
+            
+            // TEST
+            await LayoutMainChain.addMainChainFromSources(subgraphNetwork, sources,getMainChains);
+
+            // EXPECT
+            expect(getStartNodesMock).not.toHaveBeenCalled();
+        });
+
+        it('should use getStartNodes because already list of sources', async () => {
+            // DATA
+            const sources=StartNodesType.RANK_ONLY;
+            const getMainChains= async function(){
+                return {};
+            }
+            
+             // TEST
+             await LayoutMainChain.addMainChainFromSources(subgraphNetwork, sources,getMainChains);
+ 
+             // EXPECT
+             expect(getStartNodesMock).toHaveBeenCalledTimes(1);
+        });
+
+        it('should add 2 mainChain', async () => {
+            // DATA
+            const getMainChains= async function(network: Network, sources: Array<string>):
+            Promise<{[key:string]:{nodes:Array<string>, height:number}}>{
+                return {mainChain1:{nodes:["A", "B"],height:8}, mainChain2:{nodes:["C", "D"],height:8}};
+            }
+            const mainChainExpected : {[key:string]:Subgraph}={
+                mainChain__mainChain1: {
+                  name: 'mainChain__mainChain1',
+                  nodes: [ 'A', 'B' ],
+                  type: TypeSubgraph.MAIN_CHAIN
+                },
+                mainChain__mainChain2: {
+                  name: 'mainChain__mainChain2',
+                  nodes: [ 'C', 'D' ],
+                  type: TypeSubgraph.MAIN_CHAIN
+                }
+              };
+
+            // TEST
+            await LayoutMainChain.addMainChainFromSources(subgraphNetwork, StartNodesType.RANK_ONLY,getMainChains);
+
+            // EXPECT
+            expect(createSubgraphMock).toHaveBeenCalledTimes(2);
+            expect(addSubgraphToNetworkMock).toHaveBeenCalledTimes(2);
+            expect(subgraphNetwork[TypeSubgraph.MAIN_CHAIN]).toBeDefined();
+            expect(subgraphNetwork[TypeSubgraph.MAIN_CHAIN]).toEqual(mainChainExpected);
+
+        });
+
+        it('should only add 1 mainChain bacause one is to small', async () => {
+            // DATA
+            const minHeight=8;
+            const getMainChains= async function(network: Network, sources: Array<string>):
+            Promise<{[key:string]:{nodes:Array<string>, height:number}}>{
+                return {mainChain1:{nodes:["A", "B"],height:3}, mainChain2:{nodes:["C", "D"],height:8}};
+            }
+            const mainChainExpected : {[key:string]:Subgraph}={
+                mainChain__mainChain2: {
+                  name: 'mainChain__mainChain2',
+                  nodes: [ 'C', 'D' ],
+                  type: TypeSubgraph.MAIN_CHAIN
+                }
+              };
+
+            // TEST
+            await LayoutMainChain.addMainChainFromSources(subgraphNetwork, StartNodesType.RANK_ONLY,getMainChains,true,PathType.ALL,minHeight);
+
+            // EXPECT
+            expect(createSubgraphMock).toHaveBeenCalledTimes(1);
+            expect(addSubgraphToNetworkMock).toHaveBeenCalledTimes(1);
+            expect(subgraphNetwork[TypeSubgraph.MAIN_CHAIN]).toBeDefined();
+            expect(subgraphNetwork[TypeSubgraph.MAIN_CHAIN]).toEqual(mainChainExpected);
+
+        });
+
+
+    });
+
+    describe('addMiniBranchToMainChain', () => {
+
+        beforeEach(() => {
+
+            createSubgraphMock.mockImplementation((name:string,nodes:string[],classes: Array<string>, type: TypeSubgraph, parentSubgraph?: {name:string,type:TypeSubgraph})=>{
+                return {
+                    name: name,
+                    nodes: nodes,
+                    type: TypeSubgraph.SECONDARY_CHAIN,
+                    parentSubgraph: parentSubgraph
+                }
+    
+            });
+
+            networkToGDSGraphMock.mockImplementation(async (network)=>{
+                return {
+                    outdegree: jest.fn((id: string) => {
+                        if (id === 'F'|| id === 'E') return 0;
+                        return 1;
+                    }),
+                    adjacent:jest.fn((id: string) => {
+                        switch (id) {
+                            case 'A':
+                                return ['B', 'D'];
+                            case 'B':
+                                return ['C'];
+                            case 'C':
+                                return ['F'];
+                            case 'D':
+                                return ['E'];
+                            default:
+                                return [];
+                        }
+    
+                    })
+                }
+            });
+
+        });
+
+        it('shouldn t add miniBranch because no mainChain', async () => {
+
+            // TEST
+            await LayoutMainChain.addMiniBranchToMainChain(subgraphNetwork);
+
+            // EXPECT
+            expect(networkToGDSGraphMock).not.toHaveBeenCalled();
+
+        });
+
+        it('shouldn t add miniBranch because no product of main chain has outdegree of 0', async () => {
+            // DATA
+            subgraphNetwork[TypeSubgraph.MAIN_CHAIN]={
+                mainChain1: {
+                    name: 'mainChain1',
+                    nodes: [ 'A' ,'B'],
+                    type: TypeSubgraph.MAIN_CHAIN
+                  }
+            };
+
+            // TEST
+            await LayoutMainChain.addMiniBranchToMainChain(subgraphNetwork);
+
+            // EXPECT
+            expect(networkToGDSGraphMock).toHaveBeenCalledTimes(1);
+            if(subgraphNetwork[TypeSubgraph.SECONDARY_CHAIN]){
+                expect(subgraphNetwork[TypeSubgraph.SECONDARY_CHAIN]).toEqual({});
+            }
+
+        });
+
+
+        it('should add miniBranch', async () => {
+            // DATA
+            subgraphNetwork[TypeSubgraph.MAIN_CHAIN]={
+                mainChain1: {
+                    name: 'mainChain1',
+                    nodes: [ 'A' ,'C'],
+                    type: TypeSubgraph.MAIN_CHAIN
+                  },
+                  mainChain2: {
+                    name: 'mainChain2',
+                    nodes: [ 'D' ],
+                    type: TypeSubgraph.MAIN_CHAIN
+                  }
+            };
+
+            const secondaryChainExpected : {[key:string]:Subgraph}={
+                minibranch_mainChain1: {
+                  name: 'minibranch_mainChain1',
+                  nodes: [ 'F' ],
+                  type: TypeSubgraph.SECONDARY_CHAIN,
+                  parentSubgraph: { name: 'mainChain1', type: TypeSubgraph.MAIN_CHAIN }
+                },
+                minibranch_mainChain2: {
+                  name: 'minibranch_mainChain2',
+                  nodes: [ 'E' ],
+                  type: TypeSubgraph.SECONDARY_CHAIN,
+                  parentSubgraph: { name: 'mainChain2', type: TypeSubgraph.MAIN_CHAIN }
+                }
+              }
+
+            // TEST
+            await LayoutMainChain.addMiniBranchToMainChain(subgraphNetwork);
+
+            // EXPECT
+            expect(networkToGDSGraphMock).toHaveBeenCalledTimes(1);
+            expect(createSubgraphMock).toHaveBeenCalledTimes(2);
+            expect(subgraphNetwork[TypeSubgraph.SECONDARY_CHAIN]).toBeDefined();
+            expect(subgraphNetwork[TypeSubgraph.SECONDARY_CHAIN]).toEqual(secondaryChainExpected);
+            
+        });
+
+
+    });
+
+    describe('getPathSourcesToTargetNode', () => {
+
+        let DFSsourceDAGMock = jest.spyOn(AlgorithmDFS, 'DFSsourceDAG');
+        let BFSMock = jest.spyOn(AlgorithmBFS, 'BFS');
+
+        let sources: Array<string>;
+        let graphGDS:{[key:string]:Function};
+
+        
+        describe('case one source with one target', () => {
+
+            beforeEach(() => {
+                // DATA
+                sources=["A"];
+
+                // MOCK
+                graphGDS={
+                    adjacent:jest.fn((id: string) => {
+                        switch (id) {
+                            case 'A':
+                                return ['B', 'F','E'];
+                            case 'B':
+                                return ['C'];
+                            case 'C':
+                                return ['D'];
+                            case 'E':
+                                return ['D'];
+                            case 'F':
+                                return ['G'];
+                            case 'G':
+                                return ['D'];
+                            default:
+                                return [];
+                        }
+
+                    }),
+                    getEdgeWeight:jest.fn(() => (1)),
+                    nodes: jest.fn(() => (['A', 'B', 'C', 'D', 'E', 'F', 'G']))
+                }
+
+                networkToGDSGraphMock.mockImplementation(async ()=>{
+                    return graphGDS;
+                });
+
+                DFSsourceDAGMock.mockReturnValue(Promise.resolve(
+                    {dfs:[
+                            'A', 'F', 'G',
+                            'E', 'B', 'C',
+                            'D'
+                        ], 
+                        graph:graphGDS}
+                ));
+            });
+
+
+            test ('all longest path', async () => {
+    
+                BFSMock.mockReturnValue([ 'D', 'G', 'C', 'F', 'B', 'A' ]);
+    
+                // DATA
+                const pathExpected = { A: { nodes: [ 'D', 'G', 'C', 'F', 'B', 'A' ], height: 4 } };
+    
+    
+                // TEST
+                const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, true ,PathType.ALL_LONGEST);
+    
+                // EXPECT
+                expect(DFSsourceDAGMock).toHaveBeenCalledTimes(1);
+                expect(BFSMock).toHaveBeenCalledTimes(1);
+                expect(BFSMock).toHaveBeenCalledWith({
+                    A: [],
+                    F: [ 'A' ],
+                    G: [ 'F' ],
+                    E: [ 'A' ],
+                    B: [ 'A' ],
+                    C: [ 'B' ],
+                    D: [ 'G', 'C' ]
+                  }, 'D');
+                expect(result).toEqual(pathExpected);
+
+    
+            });
+        
+
+
+            test ('longest path', async () => {
+
+                BFSMock.mockReturnValue([ 'D', 'G', 'F','A' ]);
+
+                // DATA
+                const pathExpected = { A: { nodes: [ 'D', 'G', 'F','A' ], height: 4 } };
+
+                // TEST
+                const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, true ,PathType.LONGEST);
+
+                // EXPECT
+                expect(DFSsourceDAGMock).toHaveBeenCalledTimes(1);
+                expect(BFSMock).toHaveBeenCalledTimes(1);
+                expect(BFSMock).toHaveBeenCalledWith({
+                    A: [],
+                    F: [ 'A' ],
+                    G: [ 'F' ],
+                    E: [ 'A' ],
+                    B: [ 'A' ],
+                    C: [ 'B' ],
+                    D: [ 'G' ]
+                }, 'D');
+                expect(result).toEqual(pathExpected);
+
+
+            });
+
+            test ('all path', async () => {
+
+                BFSMock.mockReturnValue([ 'D','G','E', 'C', 'F','A','B' ]);
+
+                // DATA
+                const pathExpected = {
+                    A: { nodes: [ 'D','G','E', 'C', 'F','A','B' ], height: 4 }
+                };
+
+                // TEST
+                const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, true ,PathType.ALL);
+
+                // EXPECT
+                expect(DFSsourceDAGMock).toHaveBeenCalledTimes(1);
+                expect(BFSMock).toHaveBeenCalledTimes(1);
+                expect(BFSMock).toHaveBeenCalledWith({
+                    A: [],
+                    F: [ 'A' ],
+                    G: [ 'F' ],
+                    E: [ 'A' ],
+                    B: [ 'A' ],
+                    C: [ 'B' ],
+                    D: [ 'G', 'E', 'C' ]
+                }, 'D');
+                expect(result).toEqual(pathExpected);
+
+
+            });
+
+        });
+
+        describe('case one source with several targets', () => {
+
+
+            beforeEach(() => {
+                // DATA
+                sources=["A"];
+
+                // MOCK
+                graphGDS={
+                    adjacent:jest.fn((id: string) => {
+                        switch (id) {
+                            case 'A':
+                                return ['B','D'];
+                            case 'B':
+                                return ['C'];
+                            case 'D':
+                                return ['E'];
+                            default:
+                                return [];
+                        }
+
+                    }),
+                    getEdgeWeight:jest.fn(() => (1)),
+                    nodes: jest.fn(() => (['A', 'B', 'C', 'D', 'E']))
+                }
+
+                networkToGDSGraphMock.mockImplementation(async ()=>{
+                    return graphGDS;
+                });
+
+                DFSsourceDAGMock.mockReturnValue(Promise.resolve(
+                    {dfs:[
+                            'A','D','E', 'B', 'C',
+                        ], 
+                        graph:graphGDS}
+                ));
+
+                
+            });
+
+            test('case of merge', async () => {
+                // MOCK
+                BFSMock.mockReturnValueOnce([ 'C','B','A']);
+                BFSMock.mockReturnValueOnce([ 'E','D','A']);
+               
+                // DATA
+                const pathExpected = {
+                    A: { nodes: [  'C','B','A','E','D'  ], height: 3 }
+                };
+
+                // TEST
+                const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, true ,PathType.ALL_LONGEST);
+
+                // EXPECT
+                expect(DFSsourceDAGMock).toHaveBeenCalledTimes(1);
+                expect(BFSMock).toHaveBeenCalledTimes(2);
+                expect(BFSMock).toHaveBeenCalledWith({ A: [], D: [ 'A' ], E: [ 'D' ], B: [ 'A' ], C: [ 'B' ] }, 'C');
+                expect(BFSMock).toHaveBeenLastCalledWith({ A: [], D: [ 'A' ], E: [ 'D' ], B: [ 'A' ], C: [ 'B' ] }, 'E');
+                expect(result).toEqual(pathExpected);
+
+            });
+
+            test('case of no merge', async () => {
+                // MOCK
+                BFSMock.mockReturnValueOnce([ 'C','B','A']);
+                BFSMock.mockReturnValueOnce([ 'E','D','A']);
+               
+                // DATA
+                const pathExpected = {
+                    A: { nodes: [  'C','B','A' ], height: 3 }
+                };
+
+                // TEST
+                const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, false ,PathType.ALL_LONGEST);
+                
+                // EXPECT
+                expect(DFSsourceDAGMock).toHaveBeenCalledTimes(1);
+                expect(BFSMock).toHaveBeenCalledTimes(2);
+                expect(BFSMock).toHaveBeenCalledWith({ A: [], D: [ 'A' ], E: [ 'D' ], B: [ 'A' ], C: [ 'B' ] }, 'C');
+                expect(BFSMock).toHaveBeenLastCalledWith({ A: [], D: [ 'A' ], E: [ 'D' ], B: [ 'A' ], C: [ 'B' ] }, 'E');
+                expect(result).toEqual(pathExpected);
+
+            });
+
+         });
+
+        describe('case multiple sources with one target for each', () => {
+
+            beforeEach(() => {
+                 // DATA
+                 sources=["A","D"];
+
+                // MOCK 
+                graphGDS={
+                adjacent:jest.fn((id: string) => {
+                    switch (id) {
+                        case 'A':
+                            return ['B'];
+                        case 'B':
+                            return ['C','F'];
+                        case 'D':
+                            return ['G'];
+                        case 'E':
+                            return ['F'];
+                        case 'G':
+                            return ['E'];
+                        case 'F':
+                            return ['H'];
+                        default:
+                            return [];
+                    }
+
+                }),
+                getEdgeWeight:jest.fn(() => (1)),
+                nodes: jest.fn(() => (['A', 'B', 'C', 'D', 'E', 'F','G','H']))
+            }
+
+            networkToGDSGraphMock.mockImplementation(async ()=>{
+                return graphGDS;
+            });
+
+            });
+
+            test ('independant case', async () => {
+                // MOCK 
+                graphGDS={
+                    adjacent:jest.fn((id: string) => {
+                        switch (id) {
+                            case 'A':
+                                return ['B'];
+                            case 'B':
+                                return ['C'];
+                            case 'D':
+                                return ['E'];
+                            case 'E':
+                                return ['F'];
+                            default:
+                                return [];
+                        }
+
+                    }),
+                    getEdgeWeight:jest.fn(() => (1)),
+                    nodes: jest.fn(() => (['A', 'B', 'C', 'D', 'E', 'F']))
+                }
+
+                networkToGDSGraphMock.mockImplementation(async ()=>{
+                    return graphGDS;
+                });
+
+                // DFS start : A
+                DFSsourceDAGMock.mockReturnValueOnce(Promise.resolve(
+                    {dfs:[
+                            'A', 'B', 'C',
+                        ], 
+                        graph:graphGDS}
+                ));
+                // DFS start : D
+                DFSsourceDAGMock.mockReturnValueOnce(Promise.resolve(
+                    {dfs:[
+                            'D', 'E', 'F',
+                        ], 
+                        graph:graphGDS}
+                ));
+
+                // BFS start : C
+                BFSMock.mockReturnValueOnce([ 'C','B','A' ]);
+                // BFS start : F
+                BFSMock.mockReturnValueOnce([  'F','E','D' ]);
+
+                // DATA
+                const pathExpected = {
+                    A: { nodes: [ 'C','B','A' ], height: 3 },
+                    D: { nodes: [ 'F','E','D' ], height: 3 }
+                };
+
+                // TEST
+                const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, true ,PathType.ALL);
+
+                // EXPECT
+                expect(DFSsourceDAGMock).toHaveBeenCalledTimes(2);
+                expect(DFSsourceDAGMock).toHaveBeenCalledWith(expect.anything(),['A']);
+                expect(DFSsourceDAGMock).toHaveBeenLastCalledWith(expect.anything(),['D']);
+                expect(BFSMock).toHaveBeenCalledTimes(2);
+                expect(BFSMock).toHaveBeenCalledWith({ A: [], B: [ 'A' ], C: [ 'B' ] }, 'C');
+                expect(BFSMock).toHaveBeenLastCalledWith({ D: [], E: [ 'D' ], F: [ 'E' ]}, 'F');
+                expect(result).toEqual(pathExpected);
+            });
+
+            test ('dependant case (same unique target), merge = true', async () => {
+                // MOCK
+
+                // DFS start : A
+                DFSsourceDAGMock.mockReturnValueOnce(Promise.resolve(
+                    {dfs:[
+                            'A', 'B','F','H', 'C',
+                        ], 
+                        graph:graphGDS}
+                ));
+
+                // DFS start : D
+                DFSsourceDAGMock.mockReturnValueOnce(Promise.resolve(
+                    {dfs:[
+                            'D', 'G','E', 'F','H',
+                        ], 
+                        graph:graphGDS}
+                ));
+
+                // BFS start : H (DFS with A)
+                BFSMock.mockReturnValueOnce(['H','F','B','A' ]);
+                // BFS start : H (DFS with D)
+                BFSMock.mockReturnValueOnce([ 'H','F','E','G','D' ]);
+
+                const pathExpected = { A__D: { nodes: [ 'H','F','B','A','E','G','D' ], height: 5 } };
+
+                // TEST
+                const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, true ,PathType.ALL);
+
+                // EXPECT
+                expect(DFSsourceDAGMock).toHaveBeenCalledTimes(2);
+                expect(DFSsourceDAGMock).toHaveBeenCalledWith(expect.anything(),['A']);
+                expect(DFSsourceDAGMock).toHaveBeenLastCalledWith(expect.anything(),['D']);
+                expect(BFSMock).toHaveBeenCalledTimes(2);
+                expect(BFSMock).toHaveBeenCalledWith({ A: [], B: [ 'A' ], F: [ 'B' ], H: [ 'F' ], C: [ 'B' ] }, 'H');
+                expect(BFSMock).toHaveBeenLastCalledWith({ D: [], G: [ 'D' ], E: [ 'G' ], F: [ 'E' ], H: [ 'F' ] }, 'H');
+                expect(result).toEqual(pathExpected);
+
+            });
+
+            test ('dependant case, merge = false', async () => {
+
+                // MOCK
+
+                // DFS start : A
+                DFSsourceDAGMock.mockReturnValueOnce(Promise.resolve(
+                    {dfs:[
+                            'A', 'B','F','H', 'C',
+                        ], 
+                        graph:graphGDS}
+                ));
+
+                // DFS start : D
+                DFSsourceDAGMock.mockReturnValueOnce(Promise.resolve(
+                    {dfs:[
+                            'D', 'G','E', 'F','H',
+                        ], 
+                        graph:graphGDS}
+                ));
+
+                // BFS start : H (DFS with A)
+                BFSMock.mockReturnValueOnce(['H','F','B','A' ]);
+                // BFS start : H (DFS with D)
+                BFSMock.mockReturnValueOnce([ 'H','F','E','G','D' ]);
+
+                const pathExpected = { D: { nodes: ['H','F','E','G','D' ], height: 5 } };
+
+                // TEST
+                const result = await LayoutMainChain.getPathSourcesToTargetNode(network, sources, false ,PathType.ALL);
+
+                // EXPECT
+                expect(DFSsourceDAGMock).toHaveBeenCalledTimes(2);
+                expect(DFSsourceDAGMock).toHaveBeenCalledWith(expect.anything(),['A']);
+                expect(DFSsourceDAGMock).toHaveBeenLastCalledWith(expect.anything(),['D']);
+                expect(BFSMock).toHaveBeenCalledTimes(2);
+                expect(BFSMock).toHaveBeenCalledWith({ A: [], B: [ 'A' ], F: [ 'B' ], H: [ 'F' ], C: [ 'B' ] }, 'H');
+                expect(BFSMock).toHaveBeenLastCalledWith({ D: [], G: [ 'D' ], E: [ 'G' ], F: [ 'E' ], H: [ 'F' ] }, 'H');
+                expect(result).toEqual(pathExpected);
+            });
+
+
+        });
+
+
+    });
+
+});
\ No newline at end of file