From 4f2fdf313f37c76835f3ecea51b00ae8ecd4ff18 Mon Sep 17 00:00:00 2001
From: Nawfel Senoussi <nawfelsen@mbp-de-nawfel.home>
Date: Thu, 28 Mar 2024 22:59:13 +0100
Subject: [PATCH] add features function + improve error handling

---
 index.ts                                      |  2 +-
 src/features/burnToken.ts                     | 13 +++
 src/features/createAssociation.ts             | 13 +++
 src/features/createProposal.ts                | 13 +++
 src/features/createToken.ts                   | 13 +++
 src/features/joinAssociation.ts               | 19 ++++
 src/features/showAssociationDetails.ts        | 20 ++++
 src/features/showAssociations.ts              | 14 +++
 src/features/showBalance.ts                   | 13 +++
 .../association/associationHandlers.ts        |  9 +-
 src/handlers/balance/balanceHandlers.ts       |  3 +-
 src/handlers/proposal/proposalHandlers.ts     |  3 +-
 src/handlers/roleHandlers.ts                  | 69 +++++--------
 src/handlers/token/tokenHandlers.ts           |  5 +-
 src/services/association.service.ts           | 26 +++--
 src/services/proposal.service.ts              | 45 ++++-----
 src/services/token.service.ts                 | 12 +--
 .../association/associationHandlers.spec.ts   | 39 ++------
 test/handlers/balance/balanceHandlers.spec.ts | 21 +---
 .../proposal/proposalHandlers.spec.ts         | 11 +--
 test/handlers/roleHandlers.spec.ts            | 96 ++++++++++---------
 test/handlers/token/tokenHandlers.spec.ts     | 17 +---
 22 files changed, 260 insertions(+), 216 deletions(-)
 create mode 100644 src/features/burnToken.ts
 create mode 100644 src/features/createAssociation.ts
 create mode 100644 src/features/createProposal.ts
 create mode 100644 src/features/createToken.ts
 create mode 100644 src/features/joinAssociation.ts
 create mode 100644 src/features/showAssociationDetails.ts
 create mode 100644 src/features/showAssociations.ts
 create mode 100644 src/features/showBalance.ts

diff --git a/index.ts b/index.ts
index ffae560..b20070b 100644
--- a/index.ts
+++ b/index.ts
@@ -16,7 +16,7 @@ import { type WalletData } from './src/types/WalletData.js'
 // IMPORT HANDLERS
 import { handleAdminAssociationChoice, handleAdherentChoice, handleConnectedChoice, handleAdminFATokenChoice } from './src/handlers/roleHandlers.js'
 
-const tezos = new TezosToolkit('https://ghostnet.tezos.marigold.dev/')
+const tezos = new TezosToolkit('https://ghostnet.tezos.marigold.dev')
 const program = new Command()
 
 program.name('my-asso')
diff --git a/src/features/burnToken.ts b/src/features/burnToken.ts
new file mode 100644
index 0000000..5ebd2b4
--- /dev/null
+++ b/src/features/burnToken.ts
@@ -0,0 +1,13 @@
+import { type TezosToolkit } from '@taquito/taquito'
+import chalk from 'chalk'
+import { handleBurnToken } from '../handlers/token/tokenHandlers.js'
+
+async function burnToken (tezos: TezosToolkit): Promise<void> {
+  await handleBurnToken(tezos).then(() => {
+    console.log(chalk.bgGreenBright('\nVous avez bruler vos tokens !!\n'))
+  }).catch((error) => {
+    console.log(chalk.bgRed(`\n${error.message}\n`))
+  })
+}
+
+export { burnToken }
diff --git a/src/features/createAssociation.ts b/src/features/createAssociation.ts
new file mode 100644
index 0000000..d97720b
--- /dev/null
+++ b/src/features/createAssociation.ts
@@ -0,0 +1,13 @@
+import { type TezosToolkit } from '@taquito/taquito'
+import chalk from 'chalk'
+import { handleCreateAssociation } from '../handlers/association/associationHandlers.js'
+
+async function createAssociation (tezos: TezosToolkit): Promise<void> {
+  await handleCreateAssociation(tezos).then(() => {
+    console.log(chalk.bgGreenBright('\nVotre association a été créée !!\n'))
+  }).catch((error) => {
+    console.log(chalk.bgRed(`\n${error.message}\n`))
+  })
+}
+
+export { createAssociation }
diff --git a/src/features/createProposal.ts b/src/features/createProposal.ts
new file mode 100644
index 0000000..99e4e5c
--- /dev/null
+++ b/src/features/createProposal.ts
@@ -0,0 +1,13 @@
+import { type TezosToolkit } from '@taquito/taquito'
+import chalk from 'chalk'
+import { handleCreateProposal } from '../handlers/proposal/proposalHandlers.js'
+
+async function createProposal (tezos: TezosToolkit): Promise<void> {
+  await handleCreateProposal(tezos).then(() => {
+    console.log(chalk.bgGreenBright('\nVous avez soumis une proposition !!\n'))
+  }).catch((error) => {
+    console.log(chalk.bgRed(`\n${error.message}\n`))
+  })
+}
+
+export { createProposal }
diff --git a/src/features/createToken.ts b/src/features/createToken.ts
new file mode 100644
index 0000000..0f3a033
--- /dev/null
+++ b/src/features/createToken.ts
@@ -0,0 +1,13 @@
+import { type TezosToolkit } from '@taquito/taquito'
+import chalk from 'chalk'
+import { handleCreateToken } from '../handlers/token/tokenHandlers.js'
+
+async function createToken (tezos: TezosToolkit): Promise<void> {
+  await handleCreateToken(tezos).then(() => {
+    console.log(chalk.bgGreenBright('\nVotre token a été créé !!\n'))
+  }).catch((error) => {
+    console.log(chalk.bgRed(`\n${error.message}\n`))
+  })
+}
+
+export { createToken }
diff --git a/src/features/joinAssociation.ts b/src/features/joinAssociation.ts
new file mode 100644
index 0000000..d1637f9
--- /dev/null
+++ b/src/features/joinAssociation.ts
@@ -0,0 +1,19 @@
+import { type TezosToolkit } from '@taquito/taquito'
+import chalk from 'chalk'
+import { handleGetAssociations, handleJoinAssociation } from '../handlers/association/associationHandlers.js'
+
+async function joinAssociation (tezos: TezosToolkit): Promise<void> {
+  await handleGetAssociations(tezos).then(async (response) => {
+    const associationsByName: string[] = response
+
+    await handleJoinAssociation(associationsByName, tezos).then(() => {
+      console.log(chalk.bgGreenBright("\nVous avez rejoint l'association !!\n"))
+    }).catch((error) => {
+      console.log(chalk.bgRed(`\n${error.message}\n`))
+    })
+  }).catch((error) => {
+    console.log(chalk.bgRed(`\n${error.message}\n`))
+  })
+}
+
+export { joinAssociation }
diff --git a/src/features/showAssociationDetails.ts b/src/features/showAssociationDetails.ts
new file mode 100644
index 0000000..bc7d1f4
--- /dev/null
+++ b/src/features/showAssociationDetails.ts
@@ -0,0 +1,20 @@
+import { type TezosToolkit } from '@taquito/taquito'
+import chalk from 'chalk'
+import { handleGetAssociationDetails, handleGetAssociations } from '../handlers/association/associationHandlers.js'
+
+async function showAssociationDetails (tezos: TezosToolkit): Promise<void> {
+  await handleGetAssociations(tezos).then(async (response) => {
+    const associationsByName = response
+    await handleGetAssociationDetails(associationsByName, tezos).then((details) => {
+      const associationDetails = details
+      console.log(`Nom de l'association: ${chalk.yellow(associationDetails.name)}`)
+      console.log(`Description de l'association: ${chalk.yellow(associationDetails.description)}`)
+    }).catch((error) => {
+      console.log(chalk.bgRed(`\n${error.message}\n`))
+    })
+  }).catch((error) => {
+    console.log(chalk.bgRed(`\n${error.message}\n`))
+  })
+}
+
+export { showAssociationDetails }
diff --git a/src/features/showAssociations.ts b/src/features/showAssociations.ts
new file mode 100644
index 0000000..9a0409d
--- /dev/null
+++ b/src/features/showAssociations.ts
@@ -0,0 +1,14 @@
+import { type TezosToolkit } from '@taquito/taquito'
+import chalk from 'chalk'
+import { handleGetAssociations } from '../handlers/association/associationHandlers.js'
+
+async function showAssociations (tezos: TezosToolkit): Promise<void> {
+  await handleGetAssociations(tezos).then((response) => {
+    const associationsByName = response
+    associationsByName.forEach(name => { console.log(chalk.yellow(name)) })
+  }).catch((error) => {
+    console.log(chalk.bgRed(`\n${error.message}\n`))
+  })
+}
+
+export { showAssociations }
diff --git a/src/features/showBalance.ts b/src/features/showBalance.ts
new file mode 100644
index 0000000..d45be36
--- /dev/null
+++ b/src/features/showBalance.ts
@@ -0,0 +1,13 @@
+import { type TezosToolkit } from '@taquito/taquito'
+import chalk from 'chalk'
+import { handleGetBalance } from '../handlers/balance/balanceHandlers.js'
+
+async function showBalance (tezos: TezosToolkit): Promise<void> {
+  await handleGetBalance(tezos).then((response) => {
+    console.log(`\nSolde du portefeuille: ${response} ꜩ\n`)
+  }).catch((error) => {
+    console.log(chalk.bgRed(`\n${error.message}\n`))
+  })
+}
+
+export { showBalance }
diff --git a/src/handlers/association/associationHandlers.ts b/src/handlers/association/associationHandlers.ts
index 159c9ac..9a3aae9 100644
--- a/src/handlers/association/associationHandlers.ts
+++ b/src/handlers/association/associationHandlers.ts
@@ -1,5 +1,4 @@
 // IMPORT EXTERNAL LIBS
-import chalk from 'chalk'
 import { type TezosToolkit } from '@taquito/taquito'
 
 // IMPORT TYPES
@@ -58,7 +57,7 @@ async function handleCreateAssociation (tezos: TezosToolkit): Promise<void> {
   try {
     await createAssociation(association, tezos)
   } catch (error) {
-    console.log(chalk.bgRed(`\n${error.lastError.with.string}\n`))
+    throw new Error(`${error.lastError.with.string}`)
   }
 }
 
@@ -87,7 +86,7 @@ async function handleJoinAssociation (associations: string[], tezos: TezosToolki
   try {
     await joinAssociation(associationName, tezos)
   } catch (error) {
-    console.log(chalk.bgRed(`\n${error.lastError.with.string}\n`))
+    throw new Error(`${error.lastError.with.string}`)
   }
 }
 
@@ -100,7 +99,7 @@ async function handleGetAssociations (tezos: TezosToolkit): Promise<string[]> {
   try {
     return await getAssociations(tezos)
   } catch (error) {
-    console.log(chalk.bgRed(`\n${error.lastError.with.string}\n`))
+    throw new Error(`${error.lastError.with.string}`)
   }
 }
 
@@ -129,7 +128,7 @@ async function handleGetAssociationDetails (associations: string[], tezos: Tezos
   try {
     return await getAssociationDetails(associationName, tezos)
   } catch (error) {
-    console.log(chalk.bgRed(`\n${error.lastError.with.string}\n`))
+    throw new Error(`${error.lastError.with.string}`)
   }
 }
 
diff --git a/src/handlers/balance/balanceHandlers.ts b/src/handlers/balance/balanceHandlers.ts
index bef5dd1..6b83fcc 100644
--- a/src/handlers/balance/balanceHandlers.ts
+++ b/src/handlers/balance/balanceHandlers.ts
@@ -1,5 +1,4 @@
 // IMPORT EXTERNAL LIBS
-import chalk from 'chalk'
 import { type TezosToolkit } from '@taquito/taquito'
 
 // IMPORT SERVICES
@@ -14,7 +13,7 @@ async function handleGetBalance (tezos: TezosToolkit): Promise<number> {
   try {
     return await getBalance(tezos)
   } catch (error) {
-    console.log(chalk.bgRed(`\n${error.lastError.with.string}\n`))
+    throw new Error('An error occurred')
   }
 }
 
diff --git a/src/handlers/proposal/proposalHandlers.ts b/src/handlers/proposal/proposalHandlers.ts
index feccb85..edf78e0 100644
--- a/src/handlers/proposal/proposalHandlers.ts
+++ b/src/handlers/proposal/proposalHandlers.ts
@@ -1,5 +1,4 @@
 // IMPORT EXTERNAL LIBS
-import chalk from 'chalk'
 import { type TezosToolkit } from '@taquito/taquito'
 
 // IMPORT TYPES
@@ -58,7 +57,7 @@ async function handleCreateProposal (tezos: TezosToolkit): Promise<void> {
   try {
     await createProposal(proposal, tezos)
   } catch (error) {
-    console.log(chalk.bgRed(`\n${error.lastError.with.string}\n`))
+    throw new Error(`${error.lastError.with.string}`)
   }
 }
 
diff --git a/src/handlers/roleHandlers.ts b/src/handlers/roleHandlers.ts
index 8576476..4aa5fa0 100644
--- a/src/handlers/roleHandlers.ts
+++ b/src/handlers/roleHandlers.ts
@@ -1,10 +1,13 @@
 import { type TezosToolkit } from '@taquito/taquito'
 import chalk from 'chalk'
-import { handleCreateAssociation, handleGetAssociationDetails, handleGetAssociations, handleJoinAssociation } from './association/associationHandlers.js'
-import { handleBurnToken, handleCreateToken } from './token/tokenHandlers.js'
-import { handleGetBalance } from './balance/balanceHandlers.js'
-import { handleCreateProposal } from './proposal/proposalHandlers.js'
-import { type Association } from '../types/Association.js'
+import { showAssociations } from '../features/showAssociations.js'
+import { showAssociationDetails } from '../features/showAssociationDetails.js'
+import { showBalance } from '../features/showBalance.js'
+import { joinAssociation } from '../features/joinAssociation.js'
+import { createAssociation } from '../features/createAssociation.js'
+import { burnToken } from '../features/burnToken.js'
+import { createToken } from '../features/createToken.js'
+import { createProposal } from '../features/createProposal.js'
 
 /**
  * Handles fa token administrator actions based on the specified choice.
@@ -13,23 +16,18 @@ import { type Association } from '../types/Association.js'
  * @returns {Promise<void>} A promise resolved once the processing is complete.
  */
 async function handleAdminFATokenChoice (choice: string, tezos: TezosToolkit): Promise<void> {
-  let balance: number
   switch (choice) {
     case 'Créer une association':
-      await handleCreateAssociation(tezos)
-      console.log(chalk.bgGreenBright('\nVotre association a été créée !!\n'))
+      await createAssociation(tezos)
       break
     case 'Créer un token':
-      await handleCreateToken(tezos)
-      console.log(chalk.bgGreenBright('\nVotre token a été créé !!\n'))
+      await createToken(tezos)
       break
     case 'Bruler des tokens':
-      await handleBurnToken(tezos)
-      console.log(chalk.bgGreenBright('\nVous avez bruler vos tokens !!\n'))
+      await burnToken(tezos)
       break
     case 'Voir mon portefeuille':
-      balance = await handleGetBalance(tezos)
-      console.log(`\nSolde du portefeuille: ${balance} ꜩ\n`)
+      await showBalance(tezos)
       break
     default:
       console.log(chalk.bgRedBright('\nChoix invalide\n'))
@@ -44,19 +42,15 @@ async function handleAdminFATokenChoice (choice: string, tezos: TezosToolkit): P
    * @returns {Promise<void>} A promise resolved once the processing is complete.
    */
 async function handleAdminAssociationChoice (choice: string, tezos: TezosToolkit): Promise<void> {
-  let balance: number
   switch (choice) {
     case 'Créer un token':
-      await handleCreateToken(tezos)
-      console.log(chalk.bgGreenBright('\nVotre token a été créé !!\n'))
+      await createToken(tezos)
       break
     case 'Bruler des tokens':
-      await handleBurnToken(tezos)
-      console.log(chalk.bgGreenBright('\nVous avez bruler vos tokens !!\n'))
+      await burnToken(tezos)
       break
     case 'Voir mon portefeuille':
-      balance = await handleGetBalance(tezos)
-      console.log(`\nSolde du portefeuille: ${balance} ꜩ\n`)
+      await showBalance(tezos)
       break
     default:
       console.log(chalk.bgRedBright('\nChoix invalide\n'))
@@ -71,19 +65,15 @@ async function handleAdminAssociationChoice (choice: string, tezos: TezosToolkit
    * @returns {Promise<void>} A promise resolved once the processing is complete.
    */
 async function handleAdherentChoice (choice: string, tezos: TezosToolkit): Promise<void> {
-  let balance: number
   switch (choice) {
     case 'Faire une proposition':
-      await handleCreateProposal(tezos)
-      console.log(chalk.bgGreenBright('\nVous avez soumis une proposition !!\n'))
+      await createProposal(tezos)
       break
     case 'Créer un token':
-      await handleCreateToken(tezos)
-      console.log(chalk.bgGreenBright('\nVotre token a été créé !!\n'))
+      await createToken(tezos)
       break
     case 'Voir mon portefeuille':
-      balance = await handleGetBalance(tezos)
-      console.log(`\nSolde du portefeuille: ${balance} ꜩ\n`)
+      await showBalance(tezos)
       break
     default:
       console.log(chalk.bgRedBright('\nChoix invalide\n'))
@@ -98,34 +88,21 @@ async function handleAdherentChoice (choice: string, tezos: TezosToolkit): Promi
    * @returns {Promise<void>} A promise resolved once the processing is complete.
    */
 async function handleConnectedChoice (choice: string, tezos: TezosToolkit): Promise<void> {
-  let associationsByName: string[]
-  let associationDetails: Association
-  let balance: number
   switch (choice) {
     case 'Rejoindre une association':
-      associationsByName = await handleGetAssociations(tezos)
-      await handleJoinAssociation(associationsByName, tezos)
-
-      console.log(chalk.bgGreenBright("\nVous avez rejoint l'association !!\n"))
+      await joinAssociation(tezos)
       break
     case 'Créer un token':
-      await handleCreateToken(tezos)
-      console.log(chalk.bgGreenBright('\nVotre token a été créé !!\n'))
+      await createToken(tezos)
       break
     case 'Voir les associations':
-      associationsByName = await handleGetAssociations(tezos)
-      associationsByName.forEach(name => { console.log(chalk.yellow(name)) })
+      await showAssociations(tezos)
       break
     case "Voir les détails d'une association":
-      associationsByName = await handleGetAssociations(tezos)
-      associationDetails = await handleGetAssociationDetails(associationsByName, tezos)
-
-      console.log(`Nom de l'association: ${chalk.yellow(associationDetails.name)}`)
-      console.log(`Description de l'association: ${chalk.yellow(associationDetails.description)}`)
+      await showAssociationDetails(tezos)
       break
     case 'Voir mon portefeuille':
-      balance = await handleGetBalance(tezos)
-      console.log(`\nSolde du portefeuille: ${balance} ꜩ\n`)
+      await showBalance(tezos)
       break
     default:
       console.log(chalk.bgRedBright('\nChoix invalide\n'))
diff --git a/src/handlers/token/tokenHandlers.ts b/src/handlers/token/tokenHandlers.ts
index 94d51e4..8d1df95 100644
--- a/src/handlers/token/tokenHandlers.ts
+++ b/src/handlers/token/tokenHandlers.ts
@@ -1,5 +1,4 @@
 // IMPORT EXTERNAL LIBS
-import chalk from 'chalk'
 import { type TezosToolkit } from '@taquito/taquito'
 
 // IMPORT SERVICE
@@ -39,7 +38,7 @@ async function handleCreateToken (tezos: TezosToolkit): Promise<void> {
   try {
     await createFAToken(nbTokenFungible, tezos)
   } catch (error) {
-    console.log(chalk.bgRed(`\n${error.lastError.with.string}\n`))
+    throw new Error(`${error.lastError.with.string}`)
   }
 }
 
@@ -76,7 +75,7 @@ async function handleBurnToken (tezos: TezosToolkit): Promise<void> {
   try {
     await burnToken(nbTokenToBurn, tezos)
   } catch (error) {
-    console.log(chalk.bgRed(`\n${error.lastError.with.string}\n`))
+    throw new Error(`${error.lastError.with.string}`)
   }
 }
 
diff --git a/src/services/association.service.ts b/src/services/association.service.ts
index 21ce166..9e0dc40 100644
--- a/src/services/association.service.ts
+++ b/src/services/association.service.ts
@@ -2,11 +2,11 @@ import { type Operation, type TezosToolkit } from '@taquito/taquito'
 import { type Association } from '../types/Association'
 
 // NEED UPDATE ADDRESS !! (SMART CONTRACT 1: Registre des associations)
-const address = 'KT1NMZvpAEQmezU8kHKzgi9PjysoH4VTcB3P'
+const address = 'KT1P9oYuywTFUNQvFiWhcWN329R2AgpQv2CV'
 
 const mockAssociations: Association[] = [
   {
-    name: 'Association 1',
+    name: 'Test',
     description: "Ceci est l'association 1"
   },
   {
@@ -15,7 +15,6 @@ const mockAssociations: Association[] = [
   }
 ]
 
-// NEED UPDATE ENTRYPOINT !!
 async function createAssociation (association: Association, tezos: TezosToolkit): Promise<void> {
   const contract = await tezos.contract.at(address)
 
@@ -24,12 +23,11 @@ async function createAssociation (association: Association, tezos: TezosToolkit)
 }
 
 // NEED UPDATE ENTRYPOINT !!
-async function joinAssociation (associationName: string, tezos: TezosToolkit): Promise<Operation> {
-  const contract = await tezos.contract.at(address)
-  const op: Operation = await contract.methodsObject.joinAssociation(associationName).send()
+async function joinAssociation (associationName: string, tezos: TezosToolkit): Promise<void> {
+  // const contract = await tezos.contract.at(address)
+  // const op: Operation = await contract.methodsObject.joinAssociation(associationName).send()
 
-  await op.confirmation()
-  return op
+  // await op.confirmation()
 }
 
 // NEED UPDATE ENTRYPOINT !!
@@ -44,16 +42,16 @@ async function getAssociations (tezos: TezosToolkit): Promise<string[]> {
   return mockAssociations.map(association => association.name)
 }
 
-// NEED UPDATE ENTRYPOINT !!
 async function getAssociationDetails (associationName: string, tezos: TezosToolkit): Promise<Association> {
+  // const executionContextParams = {
+  //   viewCaller: ''
+  // }
   // const contract = await tezos.contract.at(address)
-  // const op: Operation = await contract.methodsObject.getAssociationsDetails(associationName).send()
-
-  // await op.confirmation()
-  // return op
+  // const associationDetails: Association = await contract.contractViews.listDetailsAssociations(associationName).executeView(executionContextParams)
+  // return associationDetails
 
   // MOCK
-  return mockAssociations.find(association => association.name === associationName)
+  return mockAssociations.find((association) => association.name === associationName)
 }
 
 export { createAssociation, joinAssociation, getAssociations, getAssociationDetails }
diff --git a/src/services/proposal.service.ts b/src/services/proposal.service.ts
index 740b2e0..ca105ce 100644
--- a/src/services/proposal.service.ts
+++ b/src/services/proposal.service.ts
@@ -5,53 +5,48 @@ import { type Proposal } from '../types/Proposal'
 const address = 'KT1QZJzhSPQ89K4eC59tmQYCt44qph7wXoJu'
 
 // NEED UPDATE ENTRYPOINT !!
-async function createProposal (proposal: Proposal, tezos: TezosToolkit): Promise<Operation> {
-  const contract = await tezos.contract.at(address)
-  const op: Operation = await contract.methodsObject.createProposal(proposal).send()
+async function createProposal (proposal: Proposal, tezos: TezosToolkit): Promise<void> {
+  // const contract = await tezos.contract.at(address)
+  // const op: Operation = await contract.methodsObject.createProposal(proposal).send()
 
-  await op.confirmation()
-  return op
+  // await op.confirmation()
 }
 
 // NEED UPDATE ENTRYPOINT !!
-async function voteForProposal (proposalName: string, vote: boolean, tezos: TezosToolkit): Promise<Operation> {
+async function voteForProposal (proposalName: string, vote: boolean, tezos: TezosToolkit): Promise<void> {
   const proposalVote = {
     proposalName,
     proposalVote: vote
   }
 
-  const contract = await tezos.contract.at(address)
-  const op: Operation = await contract.methodsObject.voteForProposal(proposalVote).send()
+  // const contract = await tezos.contract.at(address)
+  // const op: Operation = await contract.methodsObject.voteForProposal(proposalVote).send()
 
-  await op.confirmation()
-  return op
+  // await op.confirmation()
 }
 
 // NEED UPDATE ENTRYPOINT !!
-async function closeProposal (proposalName: string, tezos: TezosToolkit): Promise<Operation> {
-  const contract = await tezos.contract.at(address)
-  const op: Operation = await contract.methodsObject.closeProposal(proposalName).send()
+async function closeProposal (proposalName: string, tezos: TezosToolkit): Promise<void> {
+  // const contract = await tezos.contract.at(address)
+  // const op: Operation = await contract.methodsObject.closeProposal(proposalName).send()
 
-  await op.confirmation()
-  return op
+  // await op.confirmation()
 }
 
 // NEED UPDATE ENTRYPOINT !!
-async function resolveProposal (proposalName: string, tezos: TezosToolkit): Promise<Operation> {
-  const contract = await tezos.contract.at(address)
-  const op: Operation = await contract.methodsObject.resolveProposal(proposalName).send()
+async function resolveProposal (proposalName: string, tezos: TezosToolkit): Promise<void> {
+  // const contract = await tezos.contract.at(address)
+  // const op: Operation = await contract.methodsObject.resolveProposal(proposalName).send()
 
-  await op.confirmation()
-  return op
+  // await op.confirmation()
 }
 
 // NEED UPDATE ENTRYPOINT !!
-async function viewVoteInProgressProposal (proposalName: string, tezos: TezosToolkit): Promise<Operation> {
-  const contract = await tezos.contract.at(address)
-  const op: Operation = await contract.methodsObject.viewVoteInProgressProposal(proposalName).send()
+async function viewVoteInProgressProposal (proposalName: string, tezos: TezosToolkit): Promise<void> {
+  // const contract = await tezos.contract.at(address)
+  // const op: Operation = await contract.methodsObject.viewVoteInProgressProposal(proposalName).send()
 
-  await op.confirmation()
-  return op
+  // await op.confirmation()
 }
 
 export { createProposal, voteForProposal, viewVoteInProgressProposal, closeProposal, resolveProposal }
diff --git a/src/services/token.service.ts b/src/services/token.service.ts
index c4e2424..59bc223 100644
--- a/src/services/token.service.ts
+++ b/src/services/token.service.ts
@@ -5,18 +5,18 @@ const address = 'KT1QZJzhSPQ89K4eC59tmQYCt44qph7wXoJu'
 
 // NEED UPDATE ENTRYPOINT !!
 async function createFAToken (nbTokenFongible: number, tezos: TezosToolkit): Promise<void> {
-  const contract = await tezos.contract.at(address)
-  const op: Operation = await contract.methodsObject.createFAToken(nbTokenFongible).send()
+  // const contract = await tezos.contract.at(address)
+  // const op: Operation = await contract.methodsObject.createFAToken(nbTokenFongible).send()
 
-  await op.confirmation()
+  // await op.confirmation()
 }
 
 // NEED UPDATE ENTRYPOINT !!
 async function burnToken (amount: number, tezos: TezosToolkit): Promise<void> {
-  const contract = await tezos.contract.at(address)
-  const op: Operation = await contract.methodsObject.burnToken(amount).send()
+  // const contract = await tezos.contract.at(address)
+  // const op: Operation = await contract.methodsObject.burnToken(amount).send()
 
-  await op.confirmation()
+  // await op.confirmation()
 }
 
 export { createFAToken, burnToken }
diff --git a/test/handlers/association/associationHandlers.spec.ts b/test/handlers/association/associationHandlers.spec.ts
index 40cf299..f5a9c10 100644
--- a/test/handlers/association/associationHandlers.spec.ts
+++ b/test/handlers/association/associationHandlers.spec.ts
@@ -1,6 +1,5 @@
 import { handleCreateAssociation, handleJoinAssociation, handleGetAssociations, handleGetAssociationDetails } from '../../../src/handlers/association/associationHandlers'
 import { type TezosToolkit } from '@taquito/taquito'
-import chalk from 'chalk'
 import { vi, describe, it, expect, beforeEach } from 'vitest'
 
 const { createAssociationSpy, promptSpy, joinAssociationSpy, getAssociationsSpy, getAssociationDetailsSpy } =
@@ -61,7 +60,7 @@ describe('associationHandlers', () => {
     })
 
     describe('when createAssociation is called with error', () => {
-      it('should log error message', async () => {
+      it('should throw error with correct message', async () => {
         const error = {
           lastError: {
             with: {
@@ -74,17 +73,9 @@ describe('associationHandlers', () => {
         const name = 'Association Name'
         const description = 'Association Description'
 
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
         promptSpy.mockResolvedValueOnce({ name, description })
 
-        await handleCreateAssociation(mockedTezosToolkit)
-
-        expect(createAssociationSpy).toBeCalledWith(
-          { name: 'Association Name', description: 'Association Description' },
-          mockedTezosToolkit
-        )
-        expect(consoleSpy).toBeCalledWith(chalk.bgRed('\nCustom Error\n'))
+        await expect(handleCreateAssociation(mockedTezosToolkit)).rejects.toThrow('Custom Error')
       })
     })
   })
@@ -103,7 +94,7 @@ describe('associationHandlers', () => {
     })
 
     describe('when joinAssociation is called with error', () => {
-      it('should log error message', async () => {
+      it('should throw error with correct message', async () => {
         const error = {
           lastError: {
             with: {
@@ -115,13 +106,9 @@ describe('associationHandlers', () => {
         const associationsByName = ['Association 1', 'Association 2']
         const associationChoose = 'Association 1'
 
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
         promptSpy.mockResolvedValueOnce({ choice: associationChoose })
-        await handleJoinAssociation(associationsByName, mockedTezosToolkit)
 
-        expect(joinAssociationSpy).toBeCalled()
-        expect(consoleSpy).toBeCalledWith(chalk.bgRed('\nCustom Error\n'))
+        await expect(handleJoinAssociation(associationsByName, mockedTezosToolkit)).rejects.toThrow('Custom Error')
       })
     })
   })
@@ -156,7 +143,7 @@ describe('associationHandlers', () => {
     })
 
     describe('when getAssociations is called with error', () => {
-      it('should log error message', async () => {
+      it('should throw error with correct message', async () => {
         const error = {
           lastError: {
             with: {
@@ -166,13 +153,7 @@ describe('associationHandlers', () => {
         }
         getAssociationsSpy.mockRejectedValueOnce(error)
 
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
-        const associations = await handleGetAssociations(mockedTezosToolkit)
-
-        expect(getAssociationsSpy).toBeCalled()
-        expect(associations).toBeUndefined()
-        expect(consoleSpy).toBeCalledWith(chalk.bgRed('\nCustom Error\n'))
+        await expect(handleGetAssociations(mockedTezosToolkit)).rejects.toThrow('Custom Error')
       })
     })
   })
@@ -201,7 +182,7 @@ describe('associationHandlers', () => {
     })
 
     describe('when getAssociationDetails is called with error', () => {
-      it('should log error message', async () => {
+      it('should throw error with correct message', async () => {
         const error = {
           lastError: {
             with: {
@@ -213,14 +194,10 @@ describe('associationHandlers', () => {
 
         const associationsByName = ['Association 1', 'Association 2']
         const associationChoose = 'Association 1'
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
 
         promptSpy.mockResolvedValueOnce({ choice: associationChoose })
-        const association = await handleGetAssociationDetails(associationsByName, mockedTezosToolkit)
 
-        expect(getAssociationDetailsSpy).toBeCalled()
-        expect(association).toBeUndefined()
-        expect(consoleSpy).toBeCalledWith(chalk.bgRed('\nCustom Error\n'))
+        await expect(handleGetAssociationDetails(associationsByName, mockedTezosToolkit)).rejects.toThrow('Custom Error')
       })
     })
   })
diff --git a/test/handlers/balance/balanceHandlers.spec.ts b/test/handlers/balance/balanceHandlers.spec.ts
index 66d21f9..9286ea7 100644
--- a/test/handlers/balance/balanceHandlers.spec.ts
+++ b/test/handlers/balance/balanceHandlers.spec.ts
@@ -1,6 +1,5 @@
 import { handleGetBalance } from '../../../src/handlers/balance/balanceHandlers'
 import { type TezosToolkit } from '@taquito/taquito'
-import chalk from 'chalk'
 import { vi, describe, it, expect, beforeEach } from 'vitest'
 
 const { getBalanceSpy } =
@@ -17,7 +16,7 @@ vi.mock('../../../src/services/balance.service', () => ({
 
 const mockedTezosToolkit = {} as unknown as TezosToolkit
 
-describe('handlers', () => {
+describe('balanceHandlers', () => {
   beforeEach(() => {
     vi.clearAllMocks()
   })
@@ -32,22 +31,10 @@ describe('handlers', () => {
     })
 
     describe('when getBalance is called with error', () => {
-      it('should log error message', async () => {
-        const error = {
-          lastError: {
-            with: {
-              string: 'Custom Error'
-            }
-          }
-        }
-        getBalanceSpy.mockRejectedValueOnce(error)
-
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
+      it('should throw error with correct message', async () => {
+        getBalanceSpy.mockRejectedValueOnce({})
 
-        await handleGetBalance(mockedTezosToolkit)
-
-        expect(getBalanceSpy).toBeCalled()
-        expect(consoleSpy).toBeCalledWith(chalk.bgRed('\nCustom Error\n'))
+        await expect(handleGetBalance(mockedTezosToolkit)).rejects.toThrow('An error occurred')
       })
     })
   })
diff --git a/test/handlers/proposal/proposalHandlers.spec.ts b/test/handlers/proposal/proposalHandlers.spec.ts
index 2cd18a4..eae0f45 100644
--- a/test/handlers/proposal/proposalHandlers.spec.ts
+++ b/test/handlers/proposal/proposalHandlers.spec.ts
@@ -1,6 +1,5 @@
 import { handleCreateProposal } from '../../../src/handlers/proposal/proposalHandlers'
 import { type TezosToolkit } from '@taquito/taquito'
-import chalk from 'chalk'
 import { vi, describe, it, expect, beforeEach } from 'vitest'
 
 const { promptSpy, createProposalSpy } =
@@ -32,7 +31,7 @@ vi.mock('../../../src/services/proposal.service', () => ({
 
 const mockedTezosToolkit = {} as unknown as TezosToolkit
 
-describe('handlers', () => {
+describe('proposalHandlers', () => {
   beforeEach(() => {
     vi.clearAllMocks()
   })
@@ -51,7 +50,7 @@ describe('handlers', () => {
     })
 
     describe('when createProposal is called with error', () => {
-      it('should log error message', async () => {
+      it('should throw error with correct message', async () => {
         const error = {
           lastError: {
             with: {
@@ -63,13 +62,9 @@ describe('handlers', () => {
         const title = 'Proposal Title'
         const description = 'Proposal Description'
 
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
         promptSpy.mockResolvedValueOnce({ title, description })
-        await handleCreateProposal(mockedTezosToolkit)
 
-        expect(createProposalSpy).toBeCalled()
-        expect(consoleSpy).toBeCalledWith(chalk.bgRed('\nCustom Error\n'))
+        await expect(handleCreateProposal(mockedTezosToolkit)).rejects.toThrow('Custom Error')
       })
     })
   })
diff --git a/test/handlers/roleHandlers.spec.ts b/test/handlers/roleHandlers.spec.ts
index 747b7ae..9a63f9d 100644
--- a/test/handlers/roleHandlers.spec.ts
+++ b/test/handlers/roleHandlers.spec.ts
@@ -1,12 +1,46 @@
 import { type TezosToolkit } from '@taquito/taquito'
 import { handleAdminFATokenChoice, handleAdminAssociationChoice, handleAdherentChoice, handleConnectedChoice } from '../../src/handlers/roleHandlers'
-import { handleCreateProposal } from '../../src/handlers/proposal/proposalHandlers'
-import { handleCreateAssociation, handleGetAssociations, handleJoinAssociation } from '../../src/handlers/association/associationHandlers'
-import { handleCreateToken, handleBurnToken } from '../../src/handlers/token/tokenHandlers'
-import { handleGetBalance } from '../../src/handlers/balance/balanceHandlers'
-
 import { vi, describe, it, expect, beforeEach } from 'vitest'
 import chalk from 'chalk'
+import { createAssociation } from '../../src/features/createAssociation'
+import { burnToken } from '../../src/features/burnToken'
+import { createToken } from '../../src/features/createToken'
+import { showBalance } from '../../src/features/showBalance'
+import { createProposal } from '../../src/features/createProposal'
+import { joinAssociation } from '../../src/features/joinAssociation'
+import { showAssociations } from '../../src/features/showAssociations'
+
+vi.mock('../../src/features/createAssociation', () => ({
+  createAssociation: vi.fn()
+}))
+
+vi.mock('../../src/features/burnToken', () => ({
+  burnToken: vi.fn()
+}))
+
+vi.mock('../../src/features/createProposal', () => ({
+  createProposal: vi.fn()
+}))
+
+vi.mock('../../src/features/createToken', () => ({
+  createToken: vi.fn()
+}))
+
+vi.mock('../../src/features/joinAssociation', () => ({
+  joinAssociation: vi.fn()
+}))
+
+vi.mock('../../src/features/showAssociationDetails', () => ({
+  showAssociationDetails: vi.fn()
+}))
+
+vi.mock('../../src/features/showAssociations', () => ({
+  showAssociations: vi.fn()
+}))
+
+vi.mock('../../src/features/showBalance', () => ({
+  showBalance: vi.fn()
+}))
 
 vi.mock('../../src/handlers/proposal/proposalHandlers', () => ({
   handleCreateProposal: vi.fn()
@@ -38,34 +72,25 @@ describe('roleHandlers', () => {
   describe('handleAdminFATokenChoice', () => {
     describe('when choice is "Créer une association"', () => {
       it('should call handleCreateAssociation', async () => {
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
         await handleAdminFATokenChoice('Créer une association', mockedTezosToolkit)
 
-        expect(handleCreateAssociation).toBeCalled()
-        expect(consoleSpy).toBeCalledWith(chalk.bgGreenBright('\nVotre association a été créée !!\n'))
+        expect(createAssociation).toBeCalled()
       })
     })
 
     describe('when choice is "Créer un token"', () => {
       it('should call handleCreateToken', async () => {
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
         await handleAdminFATokenChoice('Créer un token', mockedTezosToolkit)
 
-        expect(handleCreateToken).toBeCalled()
-        expect(consoleSpy).toBeCalledWith(chalk.bgGreenBright('\nVotre token a été créé !!\n'))
+        expect(createToken).toBeCalled()
       })
     })
 
     describe('when choice is "Bruler des tokens"', () => {
       it('should call handleBurnToken', async () => {
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
         await handleAdminFATokenChoice('Bruler des tokens', mockedTezosToolkit)
 
-        expect(handleBurnToken).toBeCalled()
-        expect(consoleSpy).toBeCalledWith(chalk.bgGreenBright('\nVous avez bruler vos tokens !!\n'))
+        expect(burnToken).toBeCalled()
       })
     })
 
@@ -73,7 +98,7 @@ describe('roleHandlers', () => {
       it('should call handleGetBalance', async () => {
         await handleAdminFATokenChoice('Voir mon portefeuille', mockedTezosToolkit)
 
-        expect(handleGetBalance).toBeCalled()
+        expect(showBalance).toBeCalled()
       })
     })
 
@@ -90,23 +115,17 @@ describe('roleHandlers', () => {
   describe('handleAdminAssociationChoice', () => {
     describe('when choice is "Créer un token"', () => {
       it('should call handleCreateToken', async () => {
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
         await handleAdminAssociationChoice('Créer un token', mockedTezosToolkit)
 
-        expect(handleCreateToken).toBeCalled()
-        expect(consoleSpy).toBeCalledWith(chalk.bgGreenBright('\nVotre token a été créé !!\n'))
+        expect(createToken).toBeCalled()
       })
     })
 
     describe('when choice is "Bruler des tokens"', () => {
       it('should call handleBurnToken', async () => {
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
         await handleAdminAssociationChoice('Bruler des tokens', mockedTezosToolkit)
 
-        expect(handleBurnToken).toBeCalled()
-        expect(consoleSpy).toBeCalledWith(chalk.bgGreenBright('\nVous avez bruler vos tokens !!\n'))
+        expect(burnToken).toBeCalled()
       })
     })
 
@@ -114,7 +133,7 @@ describe('roleHandlers', () => {
       it('should call handleGetBalance', async () => {
         await handleAdminAssociationChoice('Voir mon portefeuille', mockedTezosToolkit)
 
-        expect(handleGetBalance).toBeCalled()
+        expect(showBalance).toBeCalled()
       })
     })
 
@@ -132,23 +151,17 @@ describe('roleHandlers', () => {
   describe('handleAdherentChoice', () => {
     describe('when choice is "Faire une proposition"', () => {
       it('should call handleCreateProposal', async () => {
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
         await handleAdherentChoice('Faire une proposition', mockedTezosToolkit)
 
-        expect(handleCreateProposal).toBeCalled()
-        expect(consoleSpy).toHaveBeenCalledWith(chalk.bgGreenBright('\nVous avez soumis une proposition !!\n'))
+        expect(createProposal).toBeCalled()
       })
     })
 
     describe('when choice is "Créer un token"', () => {
       it('should call handleCreateToken', async () => {
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
         await handleAdherentChoice('Créer un token', mockedTezosToolkit)
 
-        expect(handleCreateToken).toBeCalled()
-        expect(consoleSpy).toBeCalledWith(chalk.bgGreenBright('\nVotre token a été créé !!\n'))
+        expect(createToken).toBeCalled()
       })
     })
 
@@ -156,7 +169,7 @@ describe('roleHandlers', () => {
       it('should call handleGetBalance', async () => {
         await handleAdherentChoice('Voir mon portefeuille', mockedTezosToolkit)
 
-        expect(handleGetBalance).toBeCalled()
+        expect(showBalance).toBeCalled()
       })
     })
 
@@ -175,18 +188,15 @@ describe('roleHandlers', () => {
       it('should call handleJoinAssociation', async () => {
         await handleConnectedChoice('Rejoindre une association', mockedTezosToolkit)
 
-        expect(handleJoinAssociation).toBeCalled()
+        expect(joinAssociation).toBeCalled()
       })
     })
 
     describe('when choice is "Créer un token"', () => {
       it('should call handleCreateToken', async () => {
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
-
         await handleConnectedChoice('Créer un token', mockedTezosToolkit)
 
-        expect(handleCreateToken).toBeCalled()
-        expect(consoleSpy).toBeCalledWith(chalk.bgGreenBright('\nVotre token a été créé !!\n'))
+        expect(createToken).toBeCalled()
       })
     })
 
@@ -194,7 +204,7 @@ describe('roleHandlers', () => {
       it('should call handleGetAssociations', async () => {
         await handleConnectedChoice('Voir les associations', mockedTezosToolkit)
 
-        expect(handleGetAssociations).toBeCalled()
+        expect(showAssociations).toBeCalled()
       })
     })
 
@@ -202,7 +212,7 @@ describe('roleHandlers', () => {
       it('should call handleGetBalance', async () => {
         await handleConnectedChoice('Voir mon portefeuille', mockedTezosToolkit)
 
-        expect(handleGetBalance).toBeCalled()
+        expect(showBalance).toBeCalled()
       })
     })
 
diff --git a/test/handlers/token/tokenHandlers.spec.ts b/test/handlers/token/tokenHandlers.spec.ts
index 39e9999..bffd0e3 100644
--- a/test/handlers/token/tokenHandlers.spec.ts
+++ b/test/handlers/token/tokenHandlers.spec.ts
@@ -1,6 +1,5 @@
 import { handleCreateToken, handleBurnToken } from '../../../src/handlers/token/tokenHandlers'
 import { type TezosToolkit } from '@taquito/taquito'
-import chalk from 'chalk'
 import { vi, describe, it, expect, beforeEach } from 'vitest'
 
 const { promptSpy, createFATokenSpy, burnTokenSpy } =
@@ -53,7 +52,7 @@ describe('tokenHandlers', () => {
     })
 
     describe('when createFAToken is called with error', () => {
-      it('should log error message', async () => {
+      it('should throw error with correct message', async () => {
         const error = {
           lastError: {
             with: {
@@ -63,14 +62,10 @@ describe('tokenHandlers', () => {
         }
         createFATokenSpy.mockRejectedValueOnce(error)
         const nbTokenFungible = 5
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
 
         promptSpy.mockResolvedValueOnce({ nbTokenFungible })
 
-        await handleCreateToken(mockedTezosToolkit)
-
-        expect(createFATokenSpy).toBeCalledWith(nbTokenFungible, mockedTezosToolkit)
-        expect(consoleSpy).toBeCalledWith(chalk.bgRed('\nCustom Error\n'))
+        await expect(handleCreateToken(mockedTezosToolkit)).rejects.toThrow('Custom Error')
       })
     })
   })
@@ -89,7 +84,7 @@ describe('tokenHandlers', () => {
     })
 
     describe('when burnToken is called with error', () => {
-      it('should log error message', async () => {
+      it('should throw error with correct message', async () => {
         const error = {
           lastError: {
             with: {
@@ -99,14 +94,10 @@ describe('tokenHandlers', () => {
         }
         burnTokenSpy.mockRejectedValueOnce(error)
         const nbTokenToBurn = 5
-        const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
 
         promptSpy.mockResolvedValueOnce({ nbTokenToBurn })
 
-        await handleBurnToken(mockedTezosToolkit)
-
-        expect(burnTokenSpy).toBeCalledWith(nbTokenToBurn, mockedTezosToolkit)
-        expect(consoleSpy).toBeCalledWith(chalk.bgRed('\nCustom Error\n'))
+        await expect(handleBurnToken(mockedTezosToolkit)).rejects.toThrow('Custom Error')
       })
     })
   })
-- 
GitLab