diff --git a/.vscode/settings.json b/.vscode/settings.json
index a5d64f0c9516fc743f84bdf8fb6a0676d241b962..4fb24b46c15da71ac3f3620c74cf91fd46830e3c 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,22 +1,3 @@
 {
-    "workbench.colorCustomizations": {
-        "activityBar.activeBackground": "#65c89b",
-        "activityBar.activeBorder": "#945bc4",
-        "activityBar.background": "#65c89b",
-        "activityBar.foreground": "#15202b",
-        "activityBar.inactiveForeground": "#15202b99",
-        "activityBarBadge.background": "#945bc4",
-        "activityBarBadge.foreground": "#e7e7e7",
-        "sash.hoverBorder": "#65c89b",
-        "statusBar.background": "#42b883",
-        "statusBar.foreground": "#15202b",
-        "statusBarItem.hoverBackground": "#359268",
-        "statusBarItem.remoteBackground": "#42b883",
-        "statusBarItem.remoteForeground": "#15202b",
-        "titleBar.activeBackground": "#42b883",
-        "titleBar.activeForeground": "#15202b",
-        "titleBar.inactiveBackground": "#42b88399",
-        "titleBar.inactiveForeground": "#15202b99"
-    },
-    "peacock.color": "#42b883"
+  "peacock.color": "#42b883"
 }
diff --git a/__tests__/core/contractActivation.spec.js b/__tests__/core/contractActivation.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..e294d21255e7ad83711315e14301e06624d1887b
--- /dev/null
+++ b/__tests__/core/contractActivation.spec.js
@@ -0,0 +1,95 @@
+const xml2js = require('xml2js')
+const { errors } = require('cozy-konnector-libs')
+const { activateContract } = require('../../src/core/contractActivation')
+
+const mockSoapRequest = jest.fn()
+jest.mock('easy-soap-request', () => async () => mockSoapRequest())
+
+const mockParseServiceId = jest.fn()
+jest.mock('../../src/helpers/parsing', () => ({
+  parseServiceId: () => mockParseServiceId(),
+}))
+
+const responseMock = {
+  response: {
+    body: 'mockedBody',
+  },
+}
+
+describe('activateContract', () => {
+  it('should return last contract if there is multiple contract ✅', async () => {
+    mockSoapRequest.mockResolvedValue(responseMock)
+    mockParseServiceId.mockReturnValue(78232791)
+
+    jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({})
+
+    try {
+      const serviceId = await activateContract(
+        'http://test.com',
+        '111',
+        'login@log.com',
+        '1234567',
+        'POUET',
+        '1111111111111',
+        '01/01/2022',
+        '01/01/2023'
+      )
+      expect(serviceId).toBe(78232791)
+    } catch (error) {
+      expect(error).toBe(errors.LOGIN_FAILED)
+    }
+
+    mockParseServiceId.mockRestore()
+  })
+  it('should throw LOGIN_FAILED when request fail 🚫', async () => {
+    mockSoapRequest.mockRejectedValueOnce('reject')
+    try {
+      await activateContract(
+        'http://test.com',
+        '111',
+        'login@log.com',
+        '1234567',
+        'POUET',
+        '1111111111111',
+        '01/01/2022',
+        '01/01/2023'
+      )
+      expect(true).toBe(false)
+    } catch (error) {
+      expect(error).toBe(errors.LOGIN_FAILED)
+    }
+
+    mockParseServiceId.mockRestore()
+  })
+  it('should throw LOGIN_FAILED when failing parsing 🚫', async () => {
+    mockSoapRequest.mockResolvedValueOnce(responseMock)
+    jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({
+      Envelope: {
+        Body: {
+          Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
+          faultstring: 'Mock error',
+        },
+      },
+    })
+    mockParseServiceId.mockImplementationOnce(() => {
+      throw new Error('error')
+    })
+    try {
+      await activateContract(
+        'http://test.com',
+        '111',
+        'login@log.com',
+        '1234567',
+        'POUET',
+        '1111111111111',
+        '01/01/2022',
+        '01/01/2023'
+      )
+      expect(true).toBe(false)
+    } catch (error) {
+      expect(error).toBe(errors.LOGIN_FAILED)
+    }
+
+    mockParseServiceId.mockRestore()
+  })
+})
diff --git a/__tests__/getContractStartDate.spec.js b/__tests__/core/contractStartDate.spec.js
similarity index 89%
rename from __tests__/getContractStartDate.spec.js
rename to __tests__/core/contractStartDate.spec.js
index 5671973e1551ec34ddbd00ee0d0603bd83842e40..ef78e9770ab03923712470ed72d22373c56514d1 100644
--- a/__tests__/getContractStartDate.spec.js
+++ b/__tests__/core/contractStartDate.spec.js
@@ -1,5 +1,6 @@
 const { errors } = require('cozy-konnector-libs')
-const { getContractStartDate } = require('../src/core/contractStartDate')
+const { getContractStartDate } = require('../../src/core/contractStartDate')
+const xml2js = require('xml2js')
 
 const mockSoapRequest = jest.fn()
 jest.mock('easy-soap-request', () => async () => mockSoapRequest())
@@ -71,6 +72,14 @@ describe('getContractStartDate', () => {
 
   it('should throw NOT_EXISTING_DIRECTORY when failing parsing 🚫', async () => {
     mockSoapRequest.mockResolvedValueOnce(responseIssueMock)
+    jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({
+      Envelope: {
+        Body: {
+          Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
+          faultstring: 'Mock error',
+        },
+      },
+    })
     try {
       await getContractStartDate(
         'http://pouet.com',
diff --git a/__tests__/core/contractTermination.spec.js b/__tests__/core/contractTermination.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..db71c233aef34168e62b1462c11e38511f60b608
--- /dev/null
+++ b/__tests__/core/contractTermination.spec.js
@@ -0,0 +1,86 @@
+const xml2js = require('xml2js')
+const { errors } = require('cozy-konnector-libs')
+const { terminateContract } = require('../../src/core/contractTermination')
+
+const mockSoapRequest = jest.fn()
+jest.mock('easy-soap-request', () => async () => mockSoapRequest())
+
+const responseMock = {
+  response: {
+    body: 'mockedBody',
+  },
+}
+
+describe('terminateContract', () => {
+  it('should terminate contract ✅', async () => {
+    mockSoapRequest.mockResolvedValue(responseMock)
+
+    jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({
+      Envelope: {
+        Body: {
+          Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
+          faultstring: 'Mock error',
+        },
+      },
+    })
+    try {
+      const serviceId = await terminateContract(
+        'http://test.com',
+        '111',
+        'login@log.com',
+        '1111111111111',
+        '1234567'
+      )
+      expect(serviceId).toEqual({
+        Envelope: {
+          Body: {
+            Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
+            faultstring: 'Mock error',
+          },
+        },
+      })
+    } catch (error) {
+      expect(error).toBe(errors.VENDOR_DOWN)
+    }
+  })
+  it('should throw VENDOR_DOWN on bad request🚫', async () => {
+    mockSoapRequest.mockRejectedValueOnce('reject')
+
+    try {
+      await terminateContract(
+        'http://test.com',
+        '111',
+        'login@log.com',
+        '1111111111111',
+        '1234567'
+      )
+      expect(true).toBe(false)
+    } catch (error) {
+      expect(error).toBe(errors.VENDOR_DOWN)
+    }
+  })
+  it('should throw VENDOR_DOWN 🚫', async () => {
+    mockSoapRequest.mockResolvedValue(responseMock)
+
+    jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({
+      Envelope: {
+        Body: {
+          Fault: {},
+        },
+      },
+    })
+
+    try {
+      await terminateContract(
+        'http://test.com',
+        '111',
+        'login@log.com',
+        '1111111111111',
+        '1234567'
+      )
+      expect(true).toBe(false)
+    } catch (error) {
+      expect(error).toBe(errors.VENDOR_DOWN)
+    }
+  })
+})
diff --git a/__tests__/core/contractVerification.spec.js b/__tests__/core/contractVerification.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..12eddf0f97b82756aa96b042deb7764ee9a185cd
--- /dev/null
+++ b/__tests__/core/contractVerification.spec.js
@@ -0,0 +1,229 @@
+const xml2js = require('xml2js')
+const { errors } = require('cozy-konnector-libs')
+const { verifyContract } = require('../../src/core/contractVerification')
+
+const mockSoapRequest = jest.fn()
+jest.mock('easy-soap-request', () => async () => mockSoapRequest())
+
+const mockParseContracts = jest.fn()
+jest.mock('../../src/helpers/parsing', () => ({
+  parseContracts: () => mockParseContracts(),
+}))
+
+const responseMock = {
+  response: {
+    body: 'mockedBody',
+  },
+}
+
+describe('verifyContract', () => {
+  it('should return last contract if there is multiple contract ✅', async () => {
+    mockSoapRequest.mockResolvedValue(responseMock)
+    mockParseContracts.mockReturnValue([
+      {
+        serviceSouscritId: 78232791,
+        etatCode: 'ACTIF',
+        serviceSouscritLibelle:
+          'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+      },
+      {
+        serviceSouscritId: 78232793,
+        etatCode: 'TERMINE',
+        serviceSouscritLibelle:
+          'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+      },
+    ])
+
+    jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValue(
+      {
+        Envelope: {
+          Body: {
+            rechercherServicesSouscritsMesuresResponse: {
+              servicesSouscritsMesures: {
+                serviceSouscritMesures: [
+                  {
+                    serviceSouscritId: 78232791,
+                    etatCode: 'ACTIF',
+                    serviceSouscritLibelle:
+                      'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+                  },
+                  {
+                    serviceSouscritId: 78232793,
+                    etatCode: 'TERMINE',
+                    serviceSouscritLibelle:
+                      'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+                  },
+                ],
+              },
+            },
+          },
+        },
+      }.toString()
+    )
+
+    try {
+      const serviceId = await verifyContract(
+        'http://test.com',
+        '111',
+        'login@log.com',
+        '1234567',
+        '1111111111111'
+      )
+      expect(serviceId).toBe(78232791)
+    } catch (error) {
+      expect(error).toBe(errors.LOGIN_FAILED)
+    }
+
+    mockParseContracts.mockRestore()
+  })
+  it('should return last contract if there is one contract ✅', async () => {
+    mockSoapRequest.mockResolvedValue(responseMock)
+    mockParseContracts.mockReturnValue({
+      serviceSouscritId: 78232791,
+      etatCode: 'ACTIF',
+      serviceSouscritLibelle:
+        'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+    })
+
+    jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValue(
+      {
+        Envelope: {
+          Body: {
+            rechercherServicesSouscritsMesuresResponse: {
+              servicesSouscritsMesures: {
+                serviceSouscritMesures: [
+                  {
+                    serviceSouscritId: 78232791,
+                    etatCode: 'ACTIF',
+                    serviceSouscritLibelle:
+                      'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+                  },
+                  {
+                    serviceSouscritId: 78232793,
+                    etatCode: 'TERMINE',
+                    serviceSouscritLibelle:
+                      'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+                  },
+                ],
+              },
+            },
+          },
+        },
+      }.toString()
+    )
+
+    try {
+      const serviceId = await verifyContract(
+        'http://test.com',
+        '111',
+        'login@log.com',
+        '1234567',
+        '1111111111111'
+      )
+      expect(serviceId).toBe(78232791)
+    } catch (error) {
+      expect(error).toBe(errors.LOGIN_FAILED)
+    }
+
+    mockParseContracts.mockRestore()
+  })
+  it('should return null if last contract is TERMINE 🚫', async () => {
+    mockSoapRequest.mockResolvedValue(responseMock)
+    mockParseContracts.mockReturnValue([
+      {
+        serviceSouscritId: 78232791,
+        etatCode: 'TERMINE',
+        serviceSouscritLibelle:
+          'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+      },
+      {
+        serviceSouscritId: 78232793,
+        etatCode: 'TERMINE',
+        serviceSouscritLibelle:
+          'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+      },
+    ])
+
+    jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValue(
+      {
+        Envelope: {
+          Body: {
+            rechercherServicesSouscritsMesuresResponse: {
+              servicesSouscritsMesures: {
+                serviceSouscritMesures: [
+                  {
+                    serviceSouscritId: 78232791,
+                    etatCode: 'TERMINE',
+                    serviceSouscritLibelle:
+                      'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+                  },
+                  {
+                    serviceSouscritId: 78232793,
+                    etatCode: 'TERMINE',
+                    serviceSouscritLibelle:
+                      'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+                  },
+                ],
+              },
+            },
+          },
+        },
+      }.toString()
+    )
+
+    try {
+      const serviceId = await verifyContract(
+        'http://test.com',
+        '111',
+        'login@log.com',
+        '1234567',
+        '1111111111111'
+      )
+      expect(serviceId).toBe(null)
+    } catch (error) {
+      expect(error).toBe(errors.LOGIN_FAILED)
+    }
+
+    mockParseContracts.mockRestore()
+  })
+  it('should return LOGIN_FAILED if issue in request 🚫', async () => {
+    mockSoapRequest.mockRejectedValueOnce('reject')
+
+    try {
+      await verifyContract(
+        'http://test.com',
+        '111',
+        'login@log.com',
+        '1234567',
+        '1111111111111'
+      )
+      expect(true).toBe(false)
+    } catch (error) {
+      expect(error).toBe(errors.LOGIN_FAILED)
+    }
+  })
+  it('should return LOGIN_FAILED if issue in parsing 🚫', async () => {
+    mockSoapRequest.mockResolvedValue(responseMock)
+    jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValueOnce({
+      Envelope: {
+        Body: {
+          Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
+          faultstring: 'Mock error',
+        },
+      },
+    })
+
+    try {
+      await verifyContract(
+        'http://test.com',
+        '111',
+        'login@log.com',
+        '1234567',
+        '1111111111111'
+      )
+      expect(true).toBe(false)
+    } catch (error) {
+      expect(error).toBe(errors.LOGIN_FAILED)
+    }
+  })
+})
diff --git a/__tests__/findUserPdl.spec.js b/__tests__/core/findUserPdl.spec.js
similarity index 77%
rename from __tests__/findUserPdl.spec.js
rename to __tests__/core/findUserPdl.spec.js
index 6ec8f44f1726a872d76f8da2994cdbf5abba1f47..140201b691964a0dc8a1ae75f79b92589e5d9697 100644
--- a/__tests__/findUserPdl.spec.js
+++ b/__tests__/core/findUserPdl.spec.js
@@ -1,14 +1,21 @@
 const xml2js = require('xml2js')
 const { errors } = require('cozy-konnector-libs')
-const { findUserPdl } = require('../src/core/findUserPdl')
+const { findUserPdl } = require('../../src/core/findUserPdl')
 
 const mockSoapRequest = jest.fn()
 jest.mock('easy-soap-request', () => async () => mockSoapRequest())
 
-jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValue('response')
+jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValue({
+  Envelope: {
+    Body: {
+      Fault: { detail: { erreur: { resultat: { $: { code: 401 } } } } },
+      faultstring: 'Mock error',
+    },
+  },
+})
 
 const mockParseUserPdl = jest.fn()
-jest.mock('../src/helpers/parsing', () => ({
+jest.mock('../../src/helpers/parsing', () => ({
   parseUserPdl: () => mockParseUserPdl(),
 }))
 
@@ -22,7 +29,7 @@ describe('recherchePoint', () => {
   it('should throw LOGIN_FAILED for too many responses', async () => {
     mockSoapRequest.mockResolvedValue(responseMock)
     mockParseUserPdl.mockImplementationOnce(() => {
-      throw new Error('fail')
+      throw new Error('Error')
     })
 
     try {
diff --git a/__tests__/verifyUserIdentity.spec.js b/__tests__/core/verifyUserIdentity.spec.js
similarity index 61%
rename from __tests__/verifyUserIdentity.spec.js
rename to __tests__/core/verifyUserIdentity.spec.js
index 288b9396755d88a15a1c5b3ad18340c060f9d6dc..dac2ccef3edf398c3f579b37efe0b9e795a29d89 100644
--- a/__tests__/verifyUserIdentity.spec.js
+++ b/__tests__/core/verifyUserIdentity.spec.js
@@ -1,15 +1,15 @@
 const { errors } = require('cozy-konnector-libs')
-const { verifyUserIdentity } = require('../src/core/verifyUserIdentity')
+const { verifyUserIdentity } = require('../../src/core/verifyUserIdentity')
 
-jest.mock('../src/requests/insee', () => ({
+jest.mock('../../src/requests/insee', () => ({
   getInseeCode: jest.fn().mockResolvedValue(69),
 }))
 
-jest.mock('../src/core/findUserPdl', () => ({
+jest.mock('../../src/core/findUserPdl', () => ({
   findUserPdl: jest.fn().mockResolvedValue('12345'),
 }))
 
-jest.mock('../src/index', () => ({
+jest.mock('../../src/index', () => ({
   start: jest.fn(),
 }))
 
@@ -32,6 +32,25 @@ describe('verifyUserIdentity', () => {
       expect(error).toBe(errors.LOGIN_FAILED)
     }
   })
+  it('should throw TERMS_VERSION_MISMATCH when pdl give and recieved are NOT matching on alternate start 🚫', async () => {
+    try {
+      await verifyUserIdentity(
+        {
+          name: 'John',
+          address: '1 street',
+          pointId: 987654321,
+          postalCode: '69069',
+        },
+        'azertyuiop',
+        'apiKey',
+        'login@user.com',
+        true
+      )
+      expect(true).toBe(false)
+    } catch (error) {
+      expect(error).toBe(errors.TERMS_VERSION_MISMATCH)
+    }
+  })
 
   it('should return void when pdl give and recieved are matching ✅', async () => {
     expect.assertions(1)
diff --git a/__tests__/aggregate.spec.js b/__tests__/helpers/aggregate.spec.js
similarity index 96%
rename from __tests__/aggregate.spec.js
rename to __tests__/helpers/aggregate.spec.js
index e5a31d1da298ef9a9d344f7863ba1caca8d214bf..f5b64cb00bdcd829a884269fb73ab50d2d28e008 100644
--- a/__tests__/aggregate.spec.js
+++ b/__tests__/helpers/aggregate.spec.js
@@ -1,4 +1,4 @@
-const { buildAgregatedData } = require('../src/helpers/aggregate')
+const { buildAgregatedData } = require('../../src/helpers/aggregate')
 const { cozyClient } = require('cozy-konnector-libs')
 
 describe('buildAgregatedData', () => {
diff --git a/__tests__/helpers/parsing.spec.js b/__tests__/helpers/parsing.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..37fefc0fb31fc6b01f85d632690beba73fe40d7c
--- /dev/null
+++ b/__tests__/helpers/parsing.spec.js
@@ -0,0 +1,152 @@
+const {
+  parseUserPdl,
+  parseContractStartDate,
+  parseContracts,
+  parseServiceId,
+  parseSgeXmlData,
+  formateDataForDoctype,
+  parseTags,
+  parseValue,
+} = require('../../src/helpers/parsing')
+describe('parsing', () => {
+  it('should parse userPdl', () => {
+    const result = {
+      Envelope: {
+        Body: {
+          rechercherPointResponse: { points: { point: { $: { id: 1 } } } },
+        },
+      },
+    }
+    const reply = parseUserPdl(result)
+    expect(reply).toEqual(1)
+  })
+  it('should parse contract start date', () => {
+    const result = {
+      Envelope: {
+        Body: {
+          consulterDonneesTechniquesContractuellesResponse: {
+            point: {
+              donneesGenerales: {
+                dateDerniereModificationFormuleTarifaireAcheminement:
+                  '01/01/2022',
+              },
+            },
+          },
+        },
+      },
+    }
+    const reply = parseContractStartDate(result)
+    expect(reply).toEqual('01/01/2022')
+  })
+  it('should parse contract', () => {
+    const result = {
+      Envelope: {
+        Body: {
+          rechercherServicesSouscritsMesuresResponse: {
+            servicesSouscritsMesures: {
+              serviceSouscritMesures: [
+                {
+                  serviceSouscritId: 78232791,
+                  etatCode: 'TERMINE',
+                  serviceSouscritLibelle:
+                    'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+                },
+                {
+                  serviceSouscritId: 78232793,
+                  etatCode: 'TERMINE',
+                  serviceSouscritLibelle:
+                    'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+                },
+              ],
+            },
+          },
+        },
+      },
+    }
+    const reply = parseContracts(result)
+    expect(reply).toEqual([
+      {
+        serviceSouscritId: 78232791,
+        etatCode: 'TERMINE',
+        serviceSouscritLibelle:
+          'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+      },
+      {
+        serviceSouscritId: 78232793,
+        etatCode: 'TERMINE',
+        serviceSouscritLibelle:
+          'Collecte de la courbe de charge au pas 30 min avec transmission quotidienne des données brutes en soutirage',
+      },
+    ])
+  })
+
+  it('should parse service id', () => {
+    const result = {
+      Envelope: {
+        Body: {
+          commanderCollectePublicationMesuresResponse: {
+            serviceSouscritId: 12,
+          },
+        },
+      },
+    }
+    const reply = parseServiceId(result)
+    expect(reply).toEqual(12)
+  })
+  it('should parse consumption data', () => {
+    const result = {
+      Envelope: {
+        Body: {
+          consulterMesuresDetailleesResponse: {
+            grandeur: {
+              mesure: {
+                v: 14361,
+                d: '2021-08-01T00:00:00.000+02:00',
+              },
+            },
+          },
+        },
+      },
+    }
+    const reply = parseSgeXmlData(result)
+    expect(reply).toEqual({
+      v: 14361,
+      d: '2021-08-01T00:00:00.000+02:00',
+    })
+  })
+  it('should format data for doctype', async () => {
+    const data = [
+      {
+        v: 14361,
+        d: '2021-08-01T00:00:00.000+02:00',
+      },
+      {
+        v: 11,
+        d: '2021-08-02T00:00:00.000+02:00',
+      },
+    ]
+    const reply = await formateDataForDoctype(data)
+    expect(reply).toEqual([
+      { day: 1, hour: 0, load: 14361, minute: 0, month: 8, year: 2021 },
+      { day: 2, hour: 0, load: 11, minute: 0, month: 8, year: 2021 },
+    ])
+  })
+
+  it('should parseTag with :', () => {
+    const reply = parseTags('test:tag')
+    expect(reply).toBe('tag')
+  })
+  it('should parseTag', () => {
+    const reply = parseTags('testtag')
+    expect(reply).toBe('testtag')
+  })
+
+  it('should parse value from Wh to KWh', () => {
+    const reply = parseValue(14361, 'v')
+    expect(reply).toBe(14.36)
+  })
+  it('should not parse value', () => {
+    const reply = parseValue(14361, 'w')
+    expect(reply).toBe(14361)
+  })
+})
diff --git a/__tests__/requests/bo.spec.js b/__tests__/requests/bo.spec.js
index 2a61f80c4f36ab3108d18c22dd79ccce7cbdae6e..9aa0fd6f882e84bdf2d4a366767b7ad3b43f6b12 100644
--- a/__tests__/requests/bo.spec.js
+++ b/__tests__/requests/bo.spec.js
@@ -1,13 +1,32 @@
-const { createBoConsent, getBoConsent } = require('../../src/requests/bo')
-const { default: axios } = require('axios')
+const {
+  createBoConsent,
+  getBoConsent,
+  updateBoConsent,
+  deleteBoConsent,
+} = require('../../src/requests/bo')
+const axios = require('axios')
 const { errors } = require('cozy-konnector-libs')
 
 jest.mock('axios')
 describe('Backoffice routes', () => {
   describe('createBoConsent', () => {
     it('should send consent to BO', async () => {
-      axios.post.mockResolvedValueOnce({ id: 1 })
+      axios.post.mockImplementationOnce(() => {
+        return {
+          data: {
+            ID: 1,
+            firstname: 'mr',
+            lastname: 'POUET',
+            pointId: 11111111111111,
+            postalCode: '69003',
+            address: '20 rue du lac',
+            inseeCode: '69383',
+          },
+        }
+      })
       const consent = await createBoConsent(
+        'http://test.com',
+        'token',
         11111111111111,
         'POUET',
         'mr',
@@ -16,7 +35,7 @@ describe('Backoffice routes', () => {
         '69383'
       )
       expect(consent).toEqual({
-        id: 1,
+        ID: 1,
         firstname: 'mr',
         lastname: 'POUET',
         pointId: 11111111111111,
@@ -31,6 +50,8 @@ describe('Backoffice routes', () => {
       )
       try {
         await createBoConsent(
+          'http://test.com',
+          'token',
           11111111111111,
           'POUET',
           'mr',
@@ -44,50 +65,138 @@ describe('Backoffice routes', () => {
       }
     })
   })
-  describe('getBoConsent', () => {
-    it('should get consent from BO', async () => {
-      axios.get.mockResolvedValueOnce({
-        id: 1,
-        pointId: 11111111111111,
-        name: 'POUET',
-        adresse: '20 rue du lac',
-        postalCode: '69003',
-        inseeCode: '69383',
+  describe('updateBoConsent', () => {
+    it('should update consent to BO', async () => {
+      axios.put.mockImplementationOnce(() => {
+        return {
+          data: {
+            ID: 1,
+            firstname: 'mr',
+            lastname: 'POUET',
+            pointId: 11111111111111,
+            postalCode: '69003',
+            address: '20 rue du lac',
+            inseeCode: '69383',
+            serviceId: '123456',
+          },
+        }
       })
-      const consent = await getBoConsent(1)
-      expect(consent).toBe({
+      const consent = await updateBoConsent(
+        'http://test.com',
+        'token',
+        {
+          ID: 1,
+          firstname: 'mr',
+          lastname: 'POUET',
+          pointId: 11111111111111,
+          postalCode: '69003',
+          address: '20 rue du lac',
+          inseeCode: '69383',
+        },
+        '123456'
+      )
+      expect(consent).toEqual({
+        ID: 1,
+        firstname: 'mr',
+        lastname: 'POUET',
         pointId: 11111111111111,
-        name: 'POUET',
-        adresse: '20 rue du lac',
         postalCode: '69003',
+        address: '20 rue du lac',
         inseeCode: '69383',
+        serviceId: '123456',
       })
     })
-    it('should get consent from BO with service id', async () => {
-      axios.get.mockResolvedValueOnce({
-        id: 1,
+    it('should handle unavailable BO', async () => {
+      axios.put.mockImplementationOnce(() => Promise.reject(errors.MAINTENANCE))
+      try {
+        await updateBoConsent(
+          'http://test.com',
+          'token',
+          {
+            ID: 1,
+            firstname: 'mr',
+            lastname: 'POUET',
+            pointId: 11111111111111,
+            postalCode: '69003',
+            address: '20 rue du lac',
+            inseeCode: '69383',
+          },
+          '123456'
+        )
+        expect(true).toBe(false)
+      } catch (e) {
+        expect(e).toBe(errors.MAINTENANCE)
+      }
+    })
+  })
+
+  describe('deleteBoConsent', () => {
+    it('should delete consent to BO', async () => {
+      axios.delete.mockImplementationOnce(() => {
+        return {
+          data: {
+            ID: 1,
+            firstname: 'mr',
+            lastname: 'POUET',
+            pointId: 11111111111111,
+            postalCode: '69003',
+            address: '20 rue du lac',
+            inseeCode: '69383',
+            serviceId: '123456',
+          },
+        }
+      })
+      const consent = await deleteBoConsent('http://test.com', 'token', 1)
+      expect(consent).toEqual({
+        ID: 1,
+        firstname: 'mr',
+        lastname: 'POUET',
         pointId: 11111111111111,
-        name: 'POUET',
-        adresse: '20 rue du lac',
         postalCode: '69003',
+        address: '20 rue du lac',
         inseeCode: '69383',
-        serviceId: 'abcde',
+        serviceId: '123456',
+      })
+    })
+    it('should handle unavailable BO', async () => {
+      axios.put.mockImplementationOnce(() => Promise.reject(errors.MAINTENANCE))
+      try {
+        await deleteBoConsent('http://test.com', 'token', 1)
+        expect(true).toBe(false)
+      } catch (e) {
+        expect(e).toBe(errors.MAINTENANCE)
+      }
+    })
+  })
+  describe('getBoConsent', () => {
+    it('should get consent from BO', async () => {
+      axios.get.mockImplementationOnce(() => {
+        return {
+          data: {
+            ID: 1,
+            pointId: 11111111111111,
+            name: 'POUET',
+            adresse: '20 rue du lac',
+            postalCode: '69003',
+            inseeCode: '69383',
+          },
+        }
       })
-      const consent = await getBoConsent(1)
-      expect(consent.serviceId).toBeTruthy()
-      expect(consent).toBe({
+      const consent = await getBoConsent('http://test.com', 'token', 1)
+      expect(consent).toEqual({
+        ID: 1,
         pointId: 11111111111111,
         name: 'POUET',
         adresse: '20 rue du lac',
         postalCode: '69003',
         inseeCode: '69383',
-        serviceId: 'abcde',
       })
     })
+
     it('should handle unavailable BO', async () => {
       axios.get.mockImplementationOnce(() => Promise.reject(errors.MAINTENANCE))
       try {
-        await createBoConsent({
+        await getBoConsent({
           pointId: 11111111111111,
           name: 'POUET',
           adresse: '20 rue du lac',
diff --git a/__tests__/requests/cozy.spec.js b/__tests__/requests/cozy.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..ab0b4aa303cbe7bdd973508cc49b19b5a5b9be82
--- /dev/null
+++ b/__tests__/requests/cozy.spec.js
@@ -0,0 +1,70 @@
+const { cozyClient } = require('cozy-konnector-libs')
+const { getAccount, saveAccountData } = require('../../src/requests/cozy')
+
+const mockUpdateOrCreate = jest.fn()
+
+describe('getAccount', () => {
+  it('should find account with provided ID', async () => {
+    const spy = jest.spyOn(cozyClient.data, 'findAll')
+    spy.mockResolvedValueOnce([
+      {
+        _id: '123456',
+        account_type: '123456',
+        auth: {
+          address: '12 rue du pouet',
+          city: 'Lyon',
+          firstname: 'Jean',
+          lastname: 'POUET',
+          pointId: '1234567891234567',
+          postalCode: '69007',
+        },
+      },
+      { _id: '1111111', account_type: '1111111' },
+    ])
+    const account = await getAccount('123456')
+    expect(account).toEqual({
+      _id: '123456',
+      account_type: '123456',
+      auth: {
+        address: '12 rue du pouet',
+        city: 'Lyon',
+        firstname: 'Jean',
+        lastname: 'POUET',
+        pointId: '1234567891234567',
+        postalCode: '69007',
+      },
+    })
+  })
+})
+
+describe('saveAccountData', () => {
+  jest.mock('cozy-konnector-libs', () => ({
+    updateOrCreate: () => mockUpdateOrCreate(),
+  }))
+
+  it('should save data to account', async () => {
+    const spy = jest.spyOn(cozyClient.data, 'findAll')
+    spy.mockResolvedValueOnce([
+      {
+        _id: '123456',
+        account_type: '123456',
+        auth: {
+          address: '12 rue du pouet',
+          city: 'Lyon',
+          firstname: 'Jean',
+          lastname: 'POUET',
+          pointId: '1234567891234567',
+          postalCode: '69007',
+        },
+      },
+      { _id: '1111111', account_type: '1111111' },
+    ])
+    mockUpdateOrCreate.mockResolvedValueOnce({
+      _id: '1111111',
+      account_type: '1111111',
+      data: { name: 'pouet' },
+    })
+    const account = await saveAccountData('1111111', { name: 'pouet' })
+    expect(account[0].data).toEqual({ name: 'pouet' })
+  })
+})
diff --git a/importedData.json b/importedData.json
new file mode 100644
index 0000000000000000000000000000000000000000..5b3d3e991426163b55da470e84c7a4e80fab9b56
--- /dev/null
+++ b/importedData.json
@@ -0,0 +1,6 @@
+{
+  "io.cozy.files": [],
+  "com.grandlyon.enedis.year": [],
+  "com.grandlyon.enedis.month": [],
+  "com.grandlyon.enedis.minute": []
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 3d76bd2734418c82bf344741e0cf2f35b37238cf..54f2e5454affb2a7a7bd9f34645041b1d3eb6cb9 100644
--- a/package.json
+++ b/package.json
@@ -24,6 +24,9 @@
       "pre-commit": "yarn lint"
     }
   },
+  "jest": {
+    "setupFiles": ["./setupTests.js"]
+  },
   "scripts": {
     "start": "node ./src/index.js",
     "dev": "cozy-konnector-dev",
diff --git a/setupTests.js b/setupTests.js
new file mode 100644
index 0000000000000000000000000000000000000000..fa753e451a24ce4b047c84a8d6b32e33d754e310
--- /dev/null
+++ b/setupTests.js
@@ -0,0 +1,3 @@
+// Disable cozy logger
+const cozyKonnectorsLib = require('cozy-konnector-libs')
+jest.spyOn(cozyKonnectorsLib, 'log').mockImplementation(() => {})
diff --git a/src/core/contractTermination.js b/src/core/contractTermination.js
index b558c76be29d4e27ecff4f42b8a0682cb2ae77d2..4348e119ee0e3e743d1cee46dcaadcba2eecef17 100644
--- a/src/core/contractTermination.js
+++ b/src/core/contractTermination.js
@@ -59,10 +59,7 @@ async function terminateContract(
     return parsedReply
   } catch (error) {
     log('error', 'Error while parsing user contract termination: ' + error)
-    log(
-      'error',
-      `Enedis issue ${parsedReply.Envelope.Body.Fault.detail.erreur.resultat.$.code}: ${parsedReply.Envelope.Body.Fault.faultstring}`
-    )
+    log('error', `Enedis issue ${JSON.stringify(parsedReply.Envelope.Body)}`)
     throw errors.VENDOR_DOWN
   }
 }