Skip to content

Commit

Permalink
Refactor hooks related to removing accounts
Browse files Browse the repository at this point in the history
  • Loading branch information
asiia-trilitech committed Mar 14, 2024
1 parent 48ac19f commit 61677df
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 80 deletions.
41 changes: 16 additions & 25 deletions src/components/AccountDrawer/RenameRemoveMenuSwitch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,35 @@ import { useNavigate } from "react-router-dom";
import { RenameAccountModal } from "./RenameAccountModal";
import { Account } from "../../types/Account";
import { useImplicitAccounts } from "../../utils/hooks/getAccountDataHooks";
import { useAppDispatch } from "../../utils/redux/hooks";
import { accountsSlice } from "../../utils/redux/slices/accountsSlice";
import { remove as removeSecretKeyAccount } from "../../utils/redux/thunks/secretKeyAccount";
import { useRemoveAccount } from "../../utils/hooks/removeAccountDataHooks";
import { ConfirmationModal } from "../ConfirmationModal";
import { DynamicModalContext } from "../DynamicModal";
import { RenameRemoveMenu } from "../RenameRemoveMenu";

export const RenameRemoveMenuSwitch: React.FC<{ account: Account }> = ({ account }) => {
const { openWith, onClose: closeModal } = useContext(DynamicModalContext);
const dispatch = useAppDispatch();
const navigate = useNavigate();
const isLastImplicitAccount = useImplicitAccounts().length === 1;
const removeAccount = useRemoveAccount();

let removeAccountAction: any = undefined;

let onRemove = undefined;
switch (account.type) {
case "secret_key":
removeAccountAction = removeSecretKeyAccount;
break;
case "ledger":
case "social":
removeAccountAction = () => accountsSlice.actions.removeAccount(account);
onRemove = () =>
openWith(
<ConfirmationModal
buttonLabel={buttonLabel}
description={description}
onSubmit={() => {
removeAccount(account);
closeModal();
navigate("/");
}}
title={title}
/>
);
break;
case "mnemonic":
case "multisig":
Expand All @@ -43,22 +50,6 @@ export const RenameRemoveMenuSwitch: React.FC<{ account: Account }> = ({ account
buttonLabel = "Remove & Off-board";
}

const onRemove = !removeAccountAction
? undefined
: () =>
openWith(
<ConfirmationModal
buttonLabel={buttonLabel}
description={description}
onSubmit={() => {
dispatch(removeAccountAction(account));
closeModal();
navigate("/");
}}
title={title}
/>
);

return (
<RenameRemoveMenu
onRemove={onRemove}
Expand Down
26 changes: 26 additions & 0 deletions src/utils/hooks/removeAccountDataHooks.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useRemoveAccount } from "./removeAccountDataHooks";
import { mockSecretKeyAccount } from "../../mocks/factories";
import { renderHook } from "../../mocks/testUtils";
import { accountsSlice } from "../redux/slices/accountsSlice";
import { store } from "../redux/store";

describe("useRemoveAccount", () => {
test("deletes relevant data from accounts slice", () => {
const account = mockSecretKeyAccount(0);
store.dispatch(accountsSlice.actions.addAccount(account));
store.dispatch(
accountsSlice.actions.addSecretKey({
pkh: account.address.pkh,
encryptedSecretKey: "encryptedSecretKey" as any,
})
);

const {
result: { current: removeAccount },
} = renderHook(() => useRemoveAccount());
removeAccount(account);

expect(store.getState().accounts.items).toEqual([]);
expect(store.getState().accounts.secretKeys).toEqual({});
});
});
46 changes: 46 additions & 0 deletions src/utils/hooks/removeAccountDataHooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { AccountType, LedgerAccount, SecretKeyAccount, SocialAccount } from "../../types/Account";
import { useAppDispatch } from "../redux/hooks";
import { accountsSlice } from "../redux/slices/accountsSlice";

const { removeMnemonicAndAccounts, removeNonMnemonicAccounts } = accountsSlice.actions;

/**
* Hook for removing all accounts from mnemonic group by a given fingerprint.
*/
export const useRemoveMnemonic = () => {
const dispatch = useAppDispatch();
return (fingerPrint: string) => {
dispatch(
removeMnemonicAndAccounts({
fingerPrint,
})
);
};
};

/**
* Hook for removing all accounts of a given type.
*/
export const useRemoveNonMnemonic = () => {
const dispatch = useAppDispatch();
return (accountType: AccountType) => {
dispatch(
removeNonMnemonicAccounts({
accountType,
})
);
};
};

/**
* Hook for removing single account.
*/
export const useRemoveAccount = () => {
const dispatch = useAppDispatch();
return (account: SocialAccount | LedgerAccount | SecretKeyAccount) => {
if (account.type === "secret_key") {
dispatch(accountsSlice.actions.removeSecretKey(account));
}
dispatch(accountsSlice.actions.removeAccount(account));
};
};
26 changes: 2 additions & 24 deletions src/utils/hooks/setAccountDataHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
useSeedPhrases,
} from "./getAccountDataHooks";
import { useSelectedNetwork } from "./networkHooks";
import { AccountType, LedgerAccount, MnemonicAccount, SocialAccount } from "../../types/Account";
import { LedgerAccount, MnemonicAccount, SocialAccount } from "../../types/Account";
import { makeDerivationPath } from "../account/derivationPathUtils";
import { makeMnemonicAccount } from "../account/makeMnemonicAccount";
import { decrypt, encrypt } from "../crypto/AES";
Expand All @@ -16,7 +16,7 @@ import { accountsSlice } from "../redux/slices/accountsSlice";
import { restore as restoreFromSecretKey } from "../redux/thunks/secretKeyAccount";
import { derivePublicKeyPair, getFingerPrint } from "../tezos";

const { addAccount, removeMnemonicAndAccounts, removeNonMnemonicAccounts } = accountsSlice.actions;
const { addAccount } = accountsSlice.actions;

export const useReset = () => () => {
localStorage.clear();
Expand Down Expand Up @@ -173,25 +173,3 @@ export const useRestoreSocial = () => {
dispatch(addAccount(account));
};
};

export const useRemoveMnemonic = () => {
const dispatch = useAppDispatch();
return (fingerPrint: string) => {
dispatch(
removeMnemonicAndAccounts({
fingerPrint,
})
);
};
};

export const useRemoveNonMnemonic = () => {
const dispatch = useAppDispatch();
return (accountType: AccountType) => {
dispatch(
removeNonMnemonicAccounts({
accountType,
})
);
};
};
3 changes: 3 additions & 0 deletions src/utils/redux/slices/accountsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const accountsSlice = createSlice({
},
reducers: {
reset: () => initialState,
// Do not call this directly, use useRemoveMnemonic from removeAccountDataHooks
removeMnemonicAndAccounts: (
state,
{ payload }: { type: string; payload: { fingerPrint: string } }
Expand All @@ -55,6 +56,7 @@ export const accountsSlice = createSlice({
state.items = newAccounts;
delete state.seedPhrases[fingerPrint];
},
// Do not call this directly, use useRemoveNonMnemonic from removeAccountDataHooks
removeNonMnemonicAccounts: (
state,
{ payload }: { type: string; payload: { accountType: AccountType } }
Expand All @@ -64,6 +66,7 @@ export const accountsSlice = createSlice({
account => account.type === "mnemonic" || account.type !== payload.accountType
);
},
// Do not call this directly, use useRemoveAccount from removeAccountDataHooks
removeAccount: (
state,
{ payload }: { type: string; payload: SocialAccount | LedgerAccount | SecretKeyAccount }
Expand Down
22 changes: 2 additions & 20 deletions src/utils/redux/thunks/secretKeyAccount.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getCurve, remove, restore } from "./secretKeyAccount";
import { mockMnemonicAccount, mockSecretKeyAccount } from "../../../mocks/factories";
import { getCurve, restore } from "./secretKeyAccount";
import { mockMnemonicAccount } from "../../../mocks/factories";
import { decrypt } from "../../crypto/AES";
import { EncryptedData } from "../../crypto/types";
import { accountsSlice } from "../slices/accountsSlice";
Expand Down Expand Up @@ -82,24 +82,6 @@ describe("secretKeyAccount", () => {
});
});

describe("remove", () => {
test("deletes relevant data from accounts slice", () => {
const account = mockSecretKeyAccount(0);
store.dispatch(accountsSlice.actions.addAccount(account));
store.dispatch(
accountsSlice.actions.addSecretKey({
pkh: account.address.pkh,
encryptedSecretKey: "encryptedSecretKey" as any,
})
);

store.dispatch(remove(account));

expect(store.getState().accounts.items).toEqual([]);
expect(store.getState().accounts.secretKeys).toEqual({});
});
});

describe("getCurve", () => {
it("returns ed25519 for edsk", () => {
expect(
Expand Down
6 changes: 0 additions & 6 deletions src/utils/redux/thunks/secretKeyAccount.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Curves } from "@taquito/signer";
import { Prefix } from "@taquito/utils";

import { SecretKeyAccount } from "../../../types/Account";
import { parseImplicitPkh } from "../../../types/Address";
import { encrypt } from "../../crypto/AES";
import { getPublicKeyPairFromSk } from "../../tezos";
Expand Down Expand Up @@ -60,8 +59,3 @@ export const restore =
dispatch(accountsSlice.actions.addAccount(account));
dispatch(accountsSlice.actions.addSecretKey({ pkh: account.address.pkh, encryptedSecretKey }));
};

export const remove = (account: SecretKeyAccount) => (dispatch: AppDispatch) => {
dispatch(accountsSlice.actions.removeSecretKey(account));
dispatch(accountsSlice.actions.removeAccount(account));
};
7 changes: 2 additions & 5 deletions src/views/home/AccountsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,8 @@ import { NameMultisigFormPage } from "../../components/SendFlow/MultisigAccount/
import colors from "../../style/colors";
import { Account } from "../../types/Account";
import { useAllAccounts, useImplicitAccounts } from "../../utils/hooks/getAccountDataHooks";
import {
useDeriveMnemonicAccount,
useRemoveMnemonic,
useRemoveNonMnemonic,
} from "../../utils/hooks/setAccountDataHooks";
import { useRemoveMnemonic, useRemoveNonMnemonic } from "../../utils/hooks/removeAccountDataHooks";
import { useDeriveMnemonicAccount } from "../../utils/hooks/setAccountDataHooks";
import { useAsyncActionHandler } from "../../utils/hooks/useAsyncActionHandler";
import { useAppSelector } from "../../utils/redux/hooks";

Expand Down

1 comment on commit 61677df

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage report

St.
Category Percentage Covered / Total
🟢 Statements 84.85% 2947/3473
🟡 Branches 78.07% 993/1272
🟢 Functions 82.63% 899/1088
🟢 Lines 84.64% 2788/3294

Test suite run success

1182 tests passing in 163 suites.

Report generated by 🧪jest coverage report action from 61677df

Please sign in to comment.