diff --git a/__tests__/findUserPdl.spec.js b/__tests__/findUserPdl.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..fbf854b832d6362b409f90c044383236b16fbc85
--- /dev/null
+++ b/__tests__/findUserPdl.spec.js
@@ -0,0 +1,51 @@
+const xml2js = require('xml2js')
+const { errors } = require('cozy-konnector-libs')
+const { findUserPdl } = require('../src/findUserPdl')
+
+const mockSoapRequest = jest.fn()
+jest.mock('easy-soap-request', () => async () => mockSoapRequest())
+
+jest.spyOn(xml2js, 'parseStringPromise').mockResolvedValue('response')
+
+const mockParseUserPdl = jest.fn()
+jest.mock('../src/parsing', () => ({
+  parseUserPdl: () => mockParseUserPdl(),
+}))
+
+const responseMock = {
+  response: {
+    body: 'mockedBody',
+  },
+}
+
+describe('recherchePoint', () => {
+  it('should throw LOGIN_FAILED for too many responses', async () => {
+    mockSoapRequest.mockResolvedValue(responseMock)
+    mockParseUserPdl.mockImplementationOnce(() => {
+      throw new Error('fail')
+    })
+
+    try {
+      await findUserPdl()
+      expect(true).toBe(false)
+    } catch (error) {
+      expect(error).toBe(errors.LOGIN_FAILED)
+    }
+  })
+
+  it('should throw LOGIN_FAIL if soapRequest fails', async () => {
+    mockSoapRequest.mockRejectedValueOnce('reject')
+    try {
+      await findUserPdl()
+      expect(true).toBe(false)
+    } catch (error) {
+      expect(error).toBe(errors.LOGIN_FAILED)
+    }
+  })
+
+  it('should return a correct pdl number', async () => {
+    mockSoapRequest.mockResolvedValue(responseMock)
+    mockParseUserPdl.mockResolvedValue('12345')
+    expect(await findUserPdl()).toBe('12345')
+  })
+})
diff --git a/__tests__/requests/bo.spec.js b/__tests__/requests/bo.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..7e2102956c86c644a604a5de28d3e6aafcbca11b
--- /dev/null
+++ b/__tests__/requests/bo.spec.js
@@ -0,0 +1,93 @@
+const { createBoConsent, getBoConsent } = require('../../src/requests/bo')
+const { default: 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 })
+      const consent = await createBoConsent({
+        pdl: 11111111111111,
+        name: 'POUET',
+        adresse: '20 rue du lac',
+        postalCode: '69003',
+        inseeCode: '69383',
+      })
+      expect(consent).toBe({ id: 1 })
+    })
+    it('should handle unavailable BO', async () => {
+      axios.post.mockImplementationOnce(() =>
+        Promise.reject(errors.MAINTENANCE)
+      )
+      try {
+        await createBoConsent({
+          pdl: 11111111111111,
+          name: 'POUET',
+          adresse: '20 rue du lac',
+          postalCode: '69003',
+          inseeCode: '69383',
+        })
+        expect(true).toBe(false)
+      } catch (e) {
+        expect(e).toBe(errors.MAINTENANCE)
+      }
+    })
+  })
+  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',
+      })
+      const consent = await getBoConsent(1)
+      expect(consent).toBe({
+        pointId: 11111111111111,
+        name: 'POUET',
+        adresse: '20 rue du lac',
+        postalCode: '69003',
+        inseeCode: '69383',
+      })
+    })
+    it('should get consent from BO with service id', async () => {
+      axios.get.mockResolvedValueOnce({
+        id: 1,
+        pointId: 11111111111111,
+        name: 'POUET',
+        adresse: '20 rue du lac',
+        postalCode: '69003',
+        inseeCode: '69383',
+        serviceId: 'abcde',
+      })
+      const consent = await getBoConsent(1)
+      expect(consent.serviceId).toBeTruthy()
+      expect(consent).toBe({
+        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({
+          pointId: 11111111111111,
+          name: 'POUET',
+          adresse: '20 rue du lac',
+          postalCode: '69003',
+          inseeCode: '69383',
+        })
+        expect(true).toBe(false)
+      } catch (e) {
+        expect(e).toBe(errors.MAINTENANCE)
+      }
+    })
+  })
+})
diff --git a/__tests__/requests/insee.spec.js b/__tests__/requests/insee.spec.js
index 2be3245aa5957e09a7f1bc7604e6041aee8b8cdc..c8154a3ac93c639aea0534a603c1aeee3d82b39c 100644
--- a/__tests__/requests/insee.spec.js
+++ b/__tests__/requests/insee.spec.js
@@ -1,15 +1,24 @@
+const { errors } = require('cozy-konnector-libs')
 const { getInseeCode } = require('../../src/requests/insee')
 describe('getInseeCode', () => {
   it('should return a valid insee code for Lyon 7', async () => {
     expect(await getInseeCode(69007)).toEqual('69387')
   })
 
-  it('should return null for a unexisting post code', async () => {
-    expect(await getInseeCode(69069)).toEqual(null)
+  it('should throw USER_ACTION_NEEDED for a unexisting post code', async () => {
+    try {
+      await getInseeCode(69069)
+    } catch (error) {
+      expect(error).toEqual(errors.USER_ACTION_NEEDED)
+    }
   })
 
-  it('should return null for post code 69290 when city is not provided', async () => {
-    expect(await getInseeCode(69290)).toEqual(null)
+  it('should throw USER_ACTION_NEEDED for post code 69290 when city is not provided', async () => {
+    try {
+      await getInseeCode(69290)
+    } catch (error) {
+      expect(error).toEqual(errors.USER_ACTION_NEEDED)
+    }
   })
 
   it('should return Craponne insee code for post code 69290', async () => {
diff --git a/__tests__/requests/sge.spec.js b/__tests__/requests/sge.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..28770b2b649b4aa16a4fc2149a449585baa9de6a
--- /dev/null
+++ b/__tests__/requests/sge.spec.js
@@ -0,0 +1,6 @@
+describe('Sge routes', () => {
+  //TODO: write TU
+  it('should be true', () => {
+    expect(true).toBe(true)
+  })
+})
diff --git a/__tests__/verifyUserIdentity.spec.js b/__tests__/verifyUserIdentity.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..98263253c4a140dee01ec3300581336f4bb762d2
--- /dev/null
+++ b/__tests__/verifyUserIdentity.spec.js
@@ -0,0 +1,55 @@
+const { errors } = require('cozy-konnector-libs')
+const { verifyUserIdentity } = require('../src/verifyUserIdentity')
+
+jest.mock('../src/requests/insee', () => ({
+  getInseeCode: jest.fn().mockResolvedValue(69),
+}))
+
+jest.mock('../src/findUserPdl', () => ({
+  findUserPdl: jest.fn().mockResolvedValue('12345'),
+}))
+
+jest.mock('../src/index', () => ({
+  start: jest.fn(),
+}))
+
+describe('verifyUserIdentity', () => {
+  it('should throw LOGIN_FAILED when pdl give and recieved are NOT matching 🚫', async () => {
+    try {
+      await verifyUserIdentity(
+        {
+          name: 'John',
+          address: '1 street',
+          pointId: 987654321,
+          postalCode: '69069',
+        },
+        'azertyuiop',
+        'apiKey',
+        'login@user.com'
+      )
+      expect(true).toBe(false)
+    } catch (error) {
+      expect(error).toBe(errors.LOGIN_FAILED)
+    }
+  })
+
+  it('should return void when pdl give and recieved are matching ✅', async () => {
+    expect.assertions(1)
+    try {
+      await verifyUserIdentity(
+        {
+          name: 'John',
+          address: '1 street',
+          pointId: '12345',
+          postalCode: '69069',
+        },
+        'azertyuiop',
+        'apiKey',
+        'login@user.com'
+      )
+      expect(true).toBeTruthy()
+    } catch (error) {
+      expect(true).toBe(false)
+    }
+  })
+})
diff --git a/importedData.json b/importedData.json
index 9e26dfeeb6e641a33dae4961196235bdb965b21b..5b3d3e991426163b55da470e84c7a4e80fab9b56 100644
--- a/importedData.json
+++ b/importedData.json
@@ -1 +1,6 @@
-{}
\ No newline at end of file
+{
+  "io.cozy.files": [],
+  "com.grandlyon.enedis.year": [],
+  "com.grandlyon.enedis.month": [],
+  "com.grandlyon.enedis.minute": []
+}
\ No newline at end of file
diff --git a/src/findUserPdl.js b/src/findUserPdl.js
new file mode 100644
index 0000000000000000000000000000000000000000..ba1871244813edb30b3f7ff343ccbe9cdf19e613
--- /dev/null
+++ b/src/findUserPdl.js
@@ -0,0 +1,56 @@
+// @ts-check
+const { log, errors } = require('cozy-konnector-libs')
+const soapRequest = require('easy-soap-request')
+const { parseUserPdl, parseTags, parseValue } = require('./parsing')
+const { rechercherPoint } = require('./requests/sge')
+const xml2js = require('xml2js')
+
+/**
+ * @param {string} url
+ * @param {string} apiAuthKey
+ * @param {string} appLogin
+ * @param {string} name
+ * @param {string} address
+ * @param {string} postalCode
+ * @param {string} inseeCode
+ * @return {Promise<string | null>} User Pdl
+ */
+async function findUserPdl(
+  url,
+  apiAuthKey,
+  appLogin,
+  name,
+  address,
+  postalCode,
+  inseeCode
+) {
+  log('info', 'Fetching user data')
+  const sgeHeaders = {
+    'Content-Type': 'text/xml;charset=UTF-8',
+    apikey: apiAuthKey,
+  }
+
+  const { response } = await soapRequest({
+    url: url,
+    headers: sgeHeaders,
+    xml: rechercherPoint(appLogin, name, postalCode, inseeCode, address),
+  }).catch(err => {
+    log('error', 'rechercherPointResponse')
+    log('error', err)
+    throw errors.LOGIN_FAILED
+  })
+
+  const parsedReply = await xml2js.parseStringPromise(response.body, {
+    tagNameProcessors: [parseTags],
+    valueProcessors: [parseValue],
+    explicitArray: false,
+  })
+
+  try {
+    return parseUserPdl(parsedReply)
+  } catch (error) {
+    throw errors.LOGIN_FAILED
+  }
+}
+
+module.exports = { findUserPdl }
diff --git a/src/index.js b/src/index.js
index 1d51dce19a79931161028e7f05bf51fe02003936..20790eeda46e1e5895a2ce5dcfb0cd9171eecd5b 100644
--- a/src/index.js
+++ b/src/index.js
@@ -17,13 +17,12 @@ const {
   formateDataForDoctype,
   parseTags,
   parseValue,
-  parseUserPdl,
 } = require('./parsing')
 const {
   consulterDonneesTechniquesContractuelles,
   consultationMesuresDetailleesMaxPower,
   consultationMesuresDetaillees,
-  rechercherPoint,
+
   commanderCollectePublicationMesures,
   commanderArretServiceSouscritMesures,
 } = require('./requests/sge')
@@ -33,7 +32,7 @@ const {
   getBoConsent,
   deleteBoConsent,
 } = require('./requests/bo')
-const { getInseeCode } = require('./requests/insee')
+const { verifyUserIdentity } = require('./verifyUserIdentity')
 
 moment.locale('fr') // set the language
 moment.tz.setDefault('Europe/Paris') // set the timezone
@@ -81,11 +80,8 @@ async function start(fields, cozyParameters) {
   log('info', 'User Logging...')
 
   if (await isFirstStart()) {
-    if (
-      !(await verifyUserIdentity(fields, baseUrl, apiAuthKey, loginUtilisateur))
-    ) {
-      throw errors.LOGIN_FAILED
-    }
+    await verifyUserIdentity(fields, baseUrl, apiAuthKey, loginUtilisateur)
+
     await createBoConsent()
     //TODO: remove because useless ? Done later in code
     // const startDate = await getDataStartDate(
@@ -97,6 +93,7 @@ async function start(fields, cozyParameters) {
     await commanderCollectePublicationMesures()
     await updateBoConsent()
   } else {
+    //AlternateStart
     await getBoConsent()
     if (!(await verifyUserIdentity(fields))) {
       await deleteBoConsent()
@@ -109,39 +106,6 @@ async function start(fields, cozyParameters) {
   await gatherData(baseUrl, apiAuthKey, loginUtilisateur, fields.pointId)
 }
 
-/**
- * Verify user identity
- * @param {object} fields
- * @param {string} baseUrl
- * @param {string} apiAuthKey
- * @param {string} loginUtilisateur
- */
-async function verifyUserIdentity(
-  fields,
-  baseUrl,
-  apiAuthKey,
-  loginUtilisateur
-) {
-  const inseeCode = await getInseeCode(fields.postalCode)
-  if (!inseeCode) throw errors.USER_ACTION_NEEDED
-
-  const pdl = await findUserPdl(
-    `${baseUrl}/enedis_SDE_recherche-point/1.0`,
-    apiAuthKey,
-    loginUtilisateur,
-    fields.name,
-    fields.addresse,
-    fields.postalCode,
-    inseeCode
-  )
-
-  if (fields.pointId != pdl) {
-    log('error', 'PointId does not match')
-    return false
-  }
-  return true
-}
-
 /**
  * Main method for gathering data
  * @param {string} baseUrl
@@ -476,41 +440,3 @@ function isFirstStart() {
   //TODO: Implement
   return true
 }
-
-/**
- * @return {Promise<string>} User Pdl
- */
-async function findUserPdl(
-  url,
-  apiAuthKey,
-  appLogin,
-  name,
-  addresse,
-  postalCode,
-  inseeCode
-) {
-  log('info', 'Fetching user data')
-  const sgeHeaders = {
-    'Content-Type': 'text/xml;charset=UTF-8',
-    apikey: apiAuthKey,
-  }
-  const { response } = await soapRequest({
-    url: url,
-    headers: sgeHeaders,
-    xml: rechercherPoint(appLogin, name, postalCode, inseeCode, addresse),
-  }).catch(err => {
-    log('error', 'rechercherPointResponse')
-    log('error', err)
-    throw errors.LOGIN_FAILED
-    //TODO: handling code error SGT4F6 and SGT432 into USER_ACTIon_NEEDED
-  })
-
-  const parsedReply = await xml2js.parseStringPromise(response.body, {
-    tagNameProcessors: [parseTags],
-    valueProcessors: [parseValue],
-    explicitArray: false,
-  })
-
-  //TODO: handle errors
-  return parseUserPdl(parsedReply)
-}
diff --git a/src/requests/insee.js b/src/requests/insee.js
index b32fef4178f98c0ddc5f60f13b746b125a9c9924..a616d9d8d9e48dd03db69aaecf8eafda3558d5b4 100644
--- a/src/requests/insee.js
+++ b/src/requests/insee.js
@@ -1,6 +1,6 @@
 // @ts-check
 const { default: axios } = require('axios')
-const { log } = require('cozy-konnector-libs')
+const { log, errors } = require('cozy-konnector-libs')
 
 const API_URL = 'https://apicarto.ign.fr/api/codes-postaux/communes'
 
@@ -8,7 +8,7 @@ const API_URL = 'https://apicarto.ign.fr/api/codes-postaux/communes'
  * Return inseeCode given a postalCode
  * @param {string} postalCode
  * @param {string} [city]
- * @return {Promise<string | null>} inseeCode
+ * @return {Promise<string>} inseeCode
  */
 async function getInseeCode(postalCode, city) {
   try {
@@ -18,7 +18,7 @@ async function getInseeCode(postalCode, city) {
     if (response.data.length === 1) {
       return response.data[0].codeCommune
     } else {
-      if (!city) return null
+      if (!city) throw errors.USER_ACTION_NEEDED
 
       const filteredResponse = response.data.filter(
         town => town.nomCommune.toLowerCase() === city.toLowerCase()
@@ -30,7 +30,7 @@ async function getInseeCode(postalCode, city) {
       'error',
       `Query getInseeCode failed for postalCode ${postalCode} / ${city}`
     )
-    return null
+    throw errors.USER_ACTION_NEEDED
   }
 }
 
diff --git a/src/types.js b/src/types.js
index b2d1f4016528c80d44ce27bc9b6c461fd1c170c6..b5cff384d39d1698486456f6abbf49fce321ca55 100644
--- a/src/types.js
+++ b/src/types.js
@@ -15,12 +15,24 @@
  * @property {string} d
  */
 
+// /**
+//  * User definition
+//  * @typedef {object} User
+//  * @property {string} name
+//  * @property {string} address
+//  * @property {string} postalCode
+//  * @property {string} pointId
+//  * @property {string} [inseeCode]
+//  */
+
 /**
- * User definition
- * @typedef {object} User
+ * Consent definition
+ * @typedef {object} Consent
+ * @property {number} pointId
  * @property {string} name
- * @property {string} address
+ * @property {string} adresse
  * @property {string} postalCode
- * @property {string} pointId
- * @property {string} [inseeCode]
+ * @property {string} inseeCode
+ * @property {string} [serviceId]
+ * @property {number} [id]
  */
diff --git a/src/verifyUserIdentity.js b/src/verifyUserIdentity.js
new file mode 100644
index 0000000000000000000000000000000000000000..2d46ceda30cdf1ef223cfbef110b6dbaa6b9d2d5
--- /dev/null
+++ b/src/verifyUserIdentity.js
@@ -0,0 +1,38 @@
+// @ts-check
+const { log, errors } = require('cozy-konnector-libs')
+const { findUserPdl } = require('./findUserPdl')
+const { getInseeCode } = require('./requests/insee')
+
+/**
+ * Verify user identity
+ * @param {object} fields
+ * @param {string} baseUrl
+ * @param {string} apiAuthKey
+ * @param {string} loginUtilisateur
+ * @returns {Promise<void>}
+ */
+async function verifyUserIdentity(
+  fields,
+  baseUrl,
+  apiAuthKey,
+  loginUtilisateur
+) {
+  const inseeCode = await getInseeCode(fields.postalCode)
+
+  const pdl = await findUserPdl(
+    `${baseUrl}/enedis_SDE_recherche-point/1.0`,
+    apiAuthKey,
+    loginUtilisateur,
+    fields.name,
+    fields.address,
+    fields.postalCode,
+    inseeCode
+  )
+
+  if (fields.pointId != pdl) {
+    log('error', 'PointId does not match')
+    throw errors.LOGIN_FAILED
+  }
+}
+
+module.exports = { verifyUserIdentity }
diff --git a/yarn.lock b/yarn.lock
index 30265ef2e1efa24124c1ac721c2d478e079a7242..2c0a6a47f2fc138ea1cd9225767cf9cd11146602 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5943,7 +5943,7 @@ mkdirp@^0.5.1:
   dependencies:
     minimist "^1.2.6"
 
-mkdirp@^1.0.4:
+mkdirp@^1.0.3, mkdirp@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
   integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==