From 8e4a21ba4f5eea279d741759134f24ba502cdcaf Mon Sep 17 00:00:00 2001 From: HoangNDM6 Date: Tue, 22 Aug 2023 15:26:32 +0700 Subject: [PATCH 01/11] fix duplicate call api --- src/logic/safe/store/actions/fetchSafe.ts | 12 ++++++------ src/pages/Staking/index.tsx | 11 +++++------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/logic/safe/store/actions/fetchSafe.ts b/src/logic/safe/store/actions/fetchSafe.ts index a7cadd768f..9c92afd9cc 100644 --- a/src/logic/safe/store/actions/fetchSafe.ts +++ b/src/logic/safe/store/actions/fetchSafe.ts @@ -141,16 +141,16 @@ export const fetchMSafe = let safeInfo: Partial = {} let remoteSafeInfo: SafeInfo | null = null let mSafeInfo: IMSafeInfo | null = null + let accountInfo: SequenceResponse | null = null try { - ;[mSafeInfo, remoteSafeInfo] = await _getSafeInfo(safeAddress, safeId) + ;[mSafeInfo, remoteSafeInfo, accountInfo] = await _getSafeInfo(safeAddress, safeId) } catch (err) { console.error(err) } const state = store.getState() const chainId = currentChainId(state) - const currentChainInfo = getChainInfo() as any // If the network has changed while the safe was being loaded, // ignore the result @@ -161,7 +161,7 @@ export const fetchMSafe = // remote (client-gateway) if (remoteSafeInfo) { safeInfo = await extractRemoteSafeInfo(remoteSafeInfo) - const onlineData: SequenceResponse = (await getAccountInfo(safeAddress)).account[0] + const onlineData: SequenceResponse | null = accountInfo safeInfo.nextQueueSeq = mSafeInfo?.nextQueueSeq || onlineData?.sequence?.toString() safeInfo.sequence = mSafeInfo?.sequence || onlineData?.sequence?.toString() @@ -213,11 +213,11 @@ export const fetchMSafe = return dispatch(updateSafe({ address, ...safeInfo, owners, safeId: safeId })) } -async function _getSafeInfo(safeAddress: string, safeId: number): Promise<[IMSafeInfo, SafeInfo]> { - const chainInfo = getChainInfo() as any +async function _getSafeInfo(safeAddress: string, safeId: number): Promise<[IMSafeInfo, SafeInfo, SequenceResponse]> { const getAccountAssetPromise = getAccountAsset(safeAddress) const getMSafeInfoPromise = getMSafeInfo(safeId) const getAccountInfoPromise = getAccountInfo(safeAddress) + return Promise.all([getAccountAssetPromise, getMSafeInfoPromise, getAccountInfoPromise]).then(([accountAssetData, mSafeInfotData, accountInfoData]) => { const formatMSafeInfotData: IMSafeInfo = { ...mSafeInfotData, @@ -302,7 +302,7 @@ async function _getSafeInfo(safeAddress: string, safeId: number): Promise<[IMSaf txHistoryTag: mSafeInfotData.txHistoryTag, } - return [formatMSafeInfotData, safeInfoData] + return [formatMSafeInfotData, safeInfoData, accountInfoData.account[0]] }); diff --git a/src/pages/Staking/index.tsx b/src/pages/Staking/index.tsx index c40f72735a..5c33ab70e4 100644 --- a/src/pages/Staking/index.tsx +++ b/src/pages/Staking/index.tsx @@ -14,7 +14,6 @@ import { simulate, } from 'src/services/index' -import queryString from 'query-string' import { extractPrefixedSafeAddress, extractSafeAddress } from 'src/routes/routes' import { coin } from '@cosmjs/stargate' @@ -24,12 +23,12 @@ import Breadcrumb from 'src/components/Breadcrumb' import { ConnectWalletModal } from 'src/components/ConnectWalletModal' import useConnectWallet from 'src/logic/hooks/useConnectWallet' import { MsgTypeUrl } from 'src/logic/providers/constants/constant' +import { currentSafeWithNames } from 'src/logic/safe/store/selectors' import { loadedSelector } from 'src/logic/wallets/store/selectors' import { convertAmount, formatNumber } from 'src/utils' import { grantedSelector } from 'src/utils/safeUtils/selector' import MyDelegation from './MyDelegation' import TxActionModal from './TxActionModal' -import { currentSafeWithNames } from 'src/logic/safe/store/selectors' export const defValidatorImage = 'https://validator-logos.s3.ap-southeast-1.amazonaws.com/validator-default.svg' function Staking(props): ReactElement { @@ -160,7 +159,7 @@ function Staking(props): ReactElement { useEffect(() => { const dataTemp: any = [] const formatDataDelegations = allDelegations.map((delegation: any) => { - const reward = allRewards.find( + const reward = allRewards?.find( (rw: any) => rw.validator_address === delegation.delegation.validator_address, ) as any return { @@ -212,7 +211,7 @@ function Staking(props): ReactElement { }, }, })) - .find((item) => item.operatorAddress === address) + ?.find((item) => item.operatorAddress === address) const delegation = { claimedReward: { @@ -220,8 +219,8 @@ function Staking(props): ReactElement { denom: rewardAmount[0]?.denom, }, delegatableBalance: { - amount: balances.find((balance) => balance.type === 'native')?.tokenBalance, - denom: balances.find((balance) => balance.type === 'native')?.denom, + amount: balances?.find((balance) => balance.type === 'native')?.tokenBalance, + denom: balances?.find((balance) => balance.type === 'native')?.denom, }, delegationBalance: { amount: allDelegations?.find((item) => item.delegation.validator_address === address)?.balance.amount, From 38f9d5f3de06eb63a71d694d87f97f44f1bbbc3a Mon Sep 17 00:00:00 2001 From: HoangNDM6 Date: Wed, 23 Aug 2023 14:52:20 +0700 Subject: [PATCH 02/11] fix undelegate --- src/pages/Staking/TxActionModal/Delegate.tsx | 2 +- src/pages/Staking/TxActionModal/Redelegate.tsx | 7 ++++--- src/pages/Staking/TxActionModal/Undelegate.tsx | 7 ++++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/pages/Staking/TxActionModal/Delegate.tsx b/src/pages/Staking/TxActionModal/Delegate.tsx index 1c3cfa01dd..0a6bf73815 100644 --- a/src/pages/Staking/TxActionModal/Delegate.tsx +++ b/src/pages/Staking/TxActionModal/Delegate.tsx @@ -29,7 +29,7 @@ export default function Delegate({ validator, amount, onClose, gasUsed }) { const denom = getCoinMinimalDenom() const chainDefaultGasPrice = getChainDefaultGasPrice() const decimal = getCoinDecimal() - const defaultGas = gasUsed || '400000' + const defaultGas = gasUsed !== null && gasUsed !== undefined ? gasUsed : '400000' const gasFee = defaultGas && chainDefaultGasPrice ? calculateGasFee(+defaultGas, +chainDefaultGasPrice, decimal) diff --git a/src/pages/Staking/TxActionModal/Redelegate.tsx b/src/pages/Staking/TxActionModal/Redelegate.tsx index 054573c5a9..ccc30aa810 100644 --- a/src/pages/Staking/TxActionModal/Redelegate.tsx +++ b/src/pages/Staking/TxActionModal/Redelegate.tsx @@ -37,9 +37,10 @@ export default function Redelegate({ validator, amount, onClose, dstValidator, g const chainDefaultGasPrice = getChainDefaultGasPrice() const decimal = getCoinDecimal() const defaultGas = - gasUsed || - chainDefaultGas.find((chain) => chain.typeUrl === MsgTypeUrl.Redelegate)?.gasAmount || - DEFAULT_GAS_LIMIT.toString() + gasUsed !== null && gasUsed !== undefined + ? gasUsed + : chainDefaultGas.find((chain) => chain.typeUrl === MsgTypeUrl.Redelegate)?.gasAmount || + DEFAULT_GAS_LIMIT.toString() const gasFee = defaultGas && chainDefaultGasPrice ? calculateGasFee(+defaultGas, +chainDefaultGasPrice, decimal) diff --git a/src/pages/Staking/TxActionModal/Undelegate.tsx b/src/pages/Staking/TxActionModal/Undelegate.tsx index 1d7457e079..16da97ec4e 100644 --- a/src/pages/Staking/TxActionModal/Undelegate.tsx +++ b/src/pages/Staking/TxActionModal/Undelegate.tsx @@ -39,9 +39,10 @@ export default function Undelegate({ validator, amount, onClose, gasUsed }) { const chainDefaultGasPrice = getChainDefaultGasPrice() const decimal = getCoinDecimal() const defaultGas = - gasUsed || - chainDefaultGas.find((chain) => chain.typeUrl === MsgTypeUrl.Undelegate)?.gasAmount || - DEFAULT_GAS_LIMIT.toString() + gasUsed !== null && gasUsed !== undefined + ? gasUsed + : chainDefaultGas?.find((chain) => chain.typeUrl === MsgTypeUrl.Undelegate)?.gasAmount || + DEFAULT_GAS_LIMIT.toString() const gasFee = defaultGas && chainDefaultGasPrice ? calculateGasFee(+defaultGas, +chainDefaultGasPrice, decimal) From 2626c908a5c8c7c5d31e389d0fed6d2d82b85a60 Mon Sep 17 00:00:00 2001 From: HoangNDM6 Date: Wed, 23 Aug 2023 15:12:57 +0700 Subject: [PATCH 03/11] fix undelegate --- src/pages/Staking/TxActionModal/Delegate.tsx | 3 ++- src/pages/Staking/TxActionModal/Redelegate.tsx | 2 +- src/pages/Staking/TxActionModal/Undelegate.tsx | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/Staking/TxActionModal/Delegate.tsx b/src/pages/Staking/TxActionModal/Delegate.tsx index 1c3cfa01dd..50dcf4beab 100644 --- a/src/pages/Staking/TxActionModal/Delegate.tsx +++ b/src/pages/Staking/TxActionModal/Delegate.tsx @@ -17,6 +17,7 @@ import { extractSafeAddress } from 'src/routes/routes' import { convertAmount, formatNativeCurrency, formatNativeToken } from 'src/utils' import { signAndCreateTransaction } from 'src/utils/signer' import { Wrapper } from './style' +import { DEFAULT_GAS_LIMIT } from 'src/services/constant/common' export default function Delegate({ validator, amount, onClose, gasUsed }) { const safeAddress = extractSafeAddress() @@ -29,7 +30,7 @@ export default function Delegate({ validator, amount, onClose, gasUsed }) { const denom = getCoinMinimalDenom() const chainDefaultGasPrice = getChainDefaultGasPrice() const decimal = getCoinDecimal() - const defaultGas = gasUsed || '400000' + const defaultGas = gasUsed || DEFAULT_GAS_LIMIT.toString() const gasFee = defaultGas && chainDefaultGasPrice ? calculateGasFee(+defaultGas, +chainDefaultGasPrice, decimal) diff --git a/src/pages/Staking/TxActionModal/Redelegate.tsx b/src/pages/Staking/TxActionModal/Redelegate.tsx index 054573c5a9..821c3154b1 100644 --- a/src/pages/Staking/TxActionModal/Redelegate.tsx +++ b/src/pages/Staking/TxActionModal/Redelegate.tsx @@ -38,7 +38,7 @@ export default function Redelegate({ validator, amount, onClose, dstValidator, g const decimal = getCoinDecimal() const defaultGas = gasUsed || - chainDefaultGas.find((chain) => chain.typeUrl === MsgTypeUrl.Redelegate)?.gasAmount || + chainDefaultGas?.find((chain) => chain.typeUrl === MsgTypeUrl.Redelegate)?.gasAmount || DEFAULT_GAS_LIMIT.toString() const gasFee = defaultGas && chainDefaultGasPrice diff --git a/src/pages/Staking/TxActionModal/Undelegate.tsx b/src/pages/Staking/TxActionModal/Undelegate.tsx index 1d7457e079..123df73ef5 100644 --- a/src/pages/Staking/TxActionModal/Undelegate.tsx +++ b/src/pages/Staking/TxActionModal/Undelegate.tsx @@ -40,7 +40,7 @@ export default function Undelegate({ validator, amount, onClose, gasUsed }) { const decimal = getCoinDecimal() const defaultGas = gasUsed || - chainDefaultGas.find((chain) => chain.typeUrl === MsgTypeUrl.Undelegate)?.gasAmount || + chainDefaultGas?.find((chain) => chain.typeUrl === MsgTypeUrl.Undelegate)?.gasAmount || DEFAULT_GAS_LIMIT.toString() const gasFee = defaultGas && chainDefaultGasPrice From 53ec85afce31dc780011eb2a59bf42663eed2e69 Mon Sep 17 00:00:00 2001 From: HoangNDM6 Date: Thu, 24 Aug 2023 16:01:22 +0700 Subject: [PATCH 04/11] fix delegate --- src/pages/Staking/index.tsx | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/pages/Staking/index.tsx b/src/pages/Staking/index.tsx index 5c33ab70e4..8b9d37ac7c 100644 --- a/src/pages/Staking/index.tsx +++ b/src/pages/Staking/index.tsx @@ -198,20 +198,19 @@ function Staking(props): ReactElement { setDataDelegateOfUser(null) const validatorsRes: any = await getAllValidators() - const validator = validatorsRes.validator - .map((val) => ({ - commission: val.commission.commission_rates.rate * 100, - delegators: val.delegators_count, - operatorAddress: val.operator_address, - votingPower: { - percent_voting_power: val.percent_voting_power, - tokens: { - amount: val.tokens, - denom: nativeCurrency.symbol, - }, + const validatorItem = validatorsRes.validator.find((item) => item.operator_address === address) + const validator = { + commission: validatorItem.commission.commission_rates.rate * 100, + delegators: validatorItem.delegators_count, + operatorAddress: validatorItem.operator_address, + votingPower: { + percent_voting_power: validatorItem.percent_voting_power, + tokens: { + amount: validatorItem.tokens, + denom: nativeCurrency.symbol, }, - })) - ?.find((item) => item.operatorAddress === address) + }, + } const delegation = { claimedReward: { From 9ff845f3f45696e9991b63cf00af9a5208c3f8fa Mon Sep 17 00:00:00 2001 From: HoangNDM6 Date: Thu, 31 Aug 2023 14:29:33 +0700 Subject: [PATCH 05/11] remove unused file --- src/App/ReceiveModal.tsx | 4 +- src/App/TermModal.tsx | 17 +- src/App/index.tsx | 4 +- src/components/Button/index.tsx | 2 +- src/components/ButtonSelect/index.tsx | 2 - src/components/ChainIndicator/index.test.tsx | 23 - src/components/CircleDot/CircleDot.tsx | 1 - src/components/CloseButton/index.tsx | 2 +- src/components/ConnectWalletModal/styles.tsx | 12 +- src/components/CustomIconText/index.tsx | 22 - src/components/DecodeTxs/__tests__/index.ts | 23 - src/components/ExecuteCheckbox/index.test.tsx | 24 - src/components/FeeAndSequence/index.tsx | 12 +- .../__tests__/index.test.ts | 71 -- src/components/GlobalErrorBoundary/index.tsx | 11 +- src/components/InfiniteScroll/index.tsx | 60 -- src/components/List/index.tsx | 2 - src/components/List/styles.tsx | 2 - src/components/Modal/index.tsx | 2 +- src/components/NetworkLabel/styles.tsx | 2 +- src/components/NotificationPopup/index.tsx | 2 +- .../Popup/MultiSendPopup/CreateTxPopup.tsx | 2 +- src/components/Popup/MultiSendPopup/index.tsx | 2 +- src/components/Popup/SendingPopup/index.tsx | 1 - .../PrefixedEthHashInfo/index.test.tsx | 39 - .../ReviewInfoText/ReviewInfoText.test.tsx | 57 -- src/components/ReviewInfoText/index.tsx | 5 +- .../SafeListSidebar/SafeList/index.tsx | 2 +- .../ScanQRModal/ScanQRWrapper/index.tsx | 1 - src/components/StatusCard/index.tsx | 2 +- src/components/Stepper/Stepper.test.tsx | 299 ------ .../StepperForm/StepperForm.test.tsx | 344 ------- src/components/StepperForm/StepperForm.tsx | 3 +- .../StoreMigrator/__test__/utils.test.ts | 313 ------- src/components/Table/index.tsx | 3 +- src/components/TransactionsFees/index.tsx | 2 - src/components/forms/AddressInput/index.tsx | 18 +- src/components/forms/validator.test.ts | 275 ------ .../layout/Button/GnoButton.test.tsx | 26 - .../layout/ButtonLink/ButtonLink.test.jsx | 12 - src/components/layout/Heading/index.tsx | 4 +- src/components/layout/Link/index.tsx | 2 +- src/components/layout/Span/Span.test.jsx | 12 - src/components/layout/Span/index.tsx | 2 +- src/config/__tests__/index.test.ts | 16 - src/config/__tests__/utils.test.ts | 24 - src/config/cache/chains.ts | 3 - src/config/index.ts | 3 +- src/layout/Footer/Footer.test.tsx | 125 --- src/layout/Footer/index.tsx | 3 - src/layout/Sidebar/ListIcon.tsx | 3 +- src/layout/Sidebar/index.tsx | 5 - src/layout/Sidebar/useSidebarItems.tsx | 13 +- src/logic/TermContext/index.tsx | 2 +- .../__tests__/addressBookReducer.test.ts | 114 --- .../utils/__tests__/addressBookUtils.test.ts | 52 -- ...getTransferMethodByContractAddress.test.ts | 68 -- .../__tests__/safeContractErrors.test.ts | 19 - src/logic/exceptions/CodedException.test.ts | 110 --- .../useEstimateTransactionGas.test.ts | 191 ---- .../hooks/__tests__/useMnemonicName.test.ts | 35 - .../fetchTokenCurrenciesBalances.test.ts | 32 - src/logic/safe/store/actions/fetchSafe.ts | 2 +- .../models/types/__tests__/gateway.d.test.ts | 265 ------ .../safe/transactions/__tests__/gas.test.ts | 30 - .../transactions/__tests__/txMonitor.test.ts | 125 --- .../transactions/offchainSigner/utils.test.ts | 79 -- .../tokens/store/actions/fetchSafeTokens.ts | 1 - .../utils/__tests__/formatAmount.test.ts | 177 ---- .../wallets/__tests__/ethAddresses.test.ts | 284 ------ src/logic/wallets/__tests__/getWeb3.test.ts | 65 -- src/logic/wallets/__tests__/network.test.ts | 105 --- .../wallets/store/actions/removeProvider.ts | 3 - .../wallets/transactionDataCheck/index.ts | 1 - src/logic/wallets/utils/walletList.ts | 1 - src/pages/AddressBook/__tests__/utils.test.ts | 95 -- src/pages/Staking/ActionModal/index.tsx | 30 +- src/pages/Staking/ActionModal/manage.tsx | 2 +- src/pages/Staking/ActionModal/redelegate.tsx | 14 +- src/pages/Staking/ActionModal/styles.tsx | 31 +- src/pages/Staking/MyDelegation/index.tsx | 1 - src/pages/Staking/MyDelegation/style.ts | 3 - src/pages/Staking/SelectValidator/index.tsx | 7 +- .../Staking/TxActionModal/Redelegate.tsx | 4 - src/pages/Staking/Undelegating/index.tsx | 3 - src/pages/Transactions/History/index.tsx | 2 +- .../components/TxDetail/Action.tsx | 6 +- src/pages/Transactions/index.tsx | 6 - src/pages/Voting/index.tsx | 2 - src/pages/welcome/Welcome.test.tsx | 61 -- src/pages/welcome/Welcome.tsx | 28 +- src/routes/AllowSafePage/AllowSafePage.tsx | 21 +- .../CreateSafePage/CreateSafePage.test.tsx | 863 ------------------ .../steps/NameNewSafeStep/NameNewSafeStep.tsx | 14 +- .../steps/NameNewSafeStep/styles.tsx | 2 +- .../ReviewNewSafeStep/ReviewNewSafeStep.tsx | 21 +- .../steps/ReviewNewSafeStep/styles.tsx | 8 +- src/routes/CreateSafePage/styles.tsx | 4 +- src/routes/LoadSafePage/LoadSafePage.test.tsx | 626 ------------- src/routes/LoadSafePage/LoadSafePage.tsx | 38 +- .../opening/assets/creation-process.gif | Bin 40083 -> 0 bytes src/routes/opening/assets/plus.svg | 4 - src/routes/opening/assets/safe-created.svg | 16 - src/routes/opening/assets/vault-error.svg | 13 - src/routes/opening/assets/vault.svg | 12 - src/routes/opening/assets/wallet.svg | 5 - src/routes/opening/components/Footer.tsx | 107 --- src/routes/opening/container/index.tsx | 7 - src/routes/opening/container/selector.ts | 7 - src/routes/opening/index.tsx | 393 -------- src/routes/opening/steps.ts | 48 - .../opening/utils/getSafeAddressFromLogs.ts | 23 - .../components/Apps/__tests__/utils.test.ts | 40 - .../Apps/components/AppsList.test.tsx | 288 ------ .../ConfirmTxModal/ConfirmTxModal.test.tsx | 307 ------- .../SignMessageModal.test.tsx | 112 --- .../Balances/AssetTableCell/index.tsx | 37 - .../safe/components/Balances/Coins/index.tsx | 125 --- .../safe/components/Balances/Coins/styles.ts | 57 -- .../Balances/Collectibles/components/Item.tsx | 134 --- .../Collectibles/img/cryptokitties.png | Bin 17007 -> 0 bytes .../Balances/Collectibles/img/marblecards.png | Bin 30754 -> 0 bytes .../Balances/Collectibles/index.tsx | 75 -- .../Balances/Collectibles/styles.tsx | 64 -- .../AddressBookInput.test.tsx | 166 ---- .../SendModal/screens/ChooseTxType/index.tsx | 5 - .../MethodsDropdown}/img/check.svg | 0 .../MethodsDropdown/index.tsx | 4 +- .../MethodsDropdown}/style.ts | 0 .../SendModal/screens/ModalHeader/index.tsx | 1 - .../SendModal/screens/SendFunds/index.tsx | 1 - .../safe/components/Balances/dataFetcher.ts | 29 - src/routes/safe/components/Balances/index.tsx | 118 --- .../utils/setCollectibleImageToPlaceholder.ts | 8 - .../CurrencyDropdown.test.tsx | 153 ---- .../components/CurrencyDropdown/index.tsx | 141 --- .../Settings/Advanced/Advanced.test.tsx | 322 ------- .../Settings/ManageOwners/index.tsx | 3 - .../hooks/useTransactionParameters.ts | 9 - src/routes/safe/index.tsx | 1 - src/utils/__tests__/checksumAddress.test.ts | 20 - src/utils/__tests__/history.test.ts | 44 - src/utils/__tests__/isValidAddress.test.ts | 19 - src/utils/__tests__/prefixedAddress.test.ts | 43 - src/utils/__tests__/strings.test.ts | 63 -- src/utils/storage/__tests__/index.test.ts | 13 - src/utils/storage/__tests__/local.test.ts | 41 - src/utils/storage/__tests__/session.test.ts | 35 - .../EditTxParametersForm/index.tsx | 30 +- 149 files changed, 149 insertions(+), 8568 deletions(-) delete mode 100644 src/components/ChainIndicator/index.test.tsx delete mode 100644 src/components/CustomIconText/index.tsx delete mode 100644 src/components/DecodeTxs/__tests__/index.ts delete mode 100644 src/components/ExecuteCheckbox/index.test.tsx delete mode 100644 src/components/GlobalErrorBoundary/__tests__/index.test.ts delete mode 100644 src/components/InfiniteScroll/index.tsx delete mode 100644 src/components/PrefixedEthHashInfo/index.test.tsx delete mode 100644 src/components/ReviewInfoText/ReviewInfoText.test.tsx delete mode 100644 src/components/Stepper/Stepper.test.tsx delete mode 100644 src/components/StepperForm/StepperForm.test.tsx delete mode 100644 src/components/StoreMigrator/__test__/utils.test.ts delete mode 100644 src/components/forms/validator.test.ts delete mode 100644 src/components/layout/Button/GnoButton.test.tsx delete mode 100644 src/components/layout/ButtonLink/ButtonLink.test.jsx delete mode 100644 src/components/layout/Span/Span.test.jsx delete mode 100644 src/config/__tests__/index.test.ts delete mode 100644 src/config/__tests__/utils.test.ts delete mode 100644 src/layout/Footer/Footer.test.tsx delete mode 100644 src/logic/addressBook/store/__tests__/addressBookReducer.test.ts delete mode 100644 src/logic/addressBook/utils/__tests__/addressBookUtils.test.ts delete mode 100644 src/logic/collectibles/utils/__tests__/getTransferMethodByContractAddress.test.ts delete mode 100644 src/logic/contracts/__tests__/safeContractErrors.test.ts delete mode 100644 src/logic/exceptions/CodedException.test.ts delete mode 100644 src/logic/hooks/__tests__/useEstimateTransactionGas.test.ts delete mode 100644 src/logic/hooks/__tests__/useMnemonicName.test.ts delete mode 100644 src/logic/safe/api/__tests__/fetchTokenCurrenciesBalances.test.ts delete mode 100644 src/logic/safe/store/models/types/__tests__/gateway.d.test.ts delete mode 100644 src/logic/safe/transactions/__tests__/gas.test.ts delete mode 100644 src/logic/safe/transactions/__tests__/txMonitor.test.ts delete mode 100644 src/logic/safe/transactions/offchainSigner/utils.test.ts delete mode 100644 src/logic/tokens/utils/__tests__/formatAmount.test.ts delete mode 100644 src/logic/wallets/__tests__/ethAddresses.test.ts delete mode 100644 src/logic/wallets/__tests__/getWeb3.test.ts delete mode 100644 src/logic/wallets/__tests__/network.test.ts delete mode 100644 src/pages/AddressBook/__tests__/utils.test.ts delete mode 100644 src/pages/welcome/Welcome.test.tsx delete mode 100644 src/routes/CreateSafePage/CreateSafePage.test.tsx delete mode 100644 src/routes/LoadSafePage/LoadSafePage.test.tsx delete mode 100644 src/routes/opening/assets/creation-process.gif delete mode 100644 src/routes/opening/assets/plus.svg delete mode 100644 src/routes/opening/assets/safe-created.svg delete mode 100644 src/routes/opening/assets/vault-error.svg delete mode 100644 src/routes/opening/assets/vault.svg delete mode 100644 src/routes/opening/assets/wallet.svg delete mode 100644 src/routes/opening/components/Footer.tsx delete mode 100644 src/routes/opening/container/index.tsx delete mode 100644 src/routes/opening/container/selector.ts delete mode 100644 src/routes/opening/index.tsx delete mode 100644 src/routes/opening/steps.ts delete mode 100644 src/routes/opening/utils/getSafeAddressFromLogs.ts delete mode 100644 src/routes/safe/components/Apps/__tests__/utils.test.ts delete mode 100644 src/routes/safe/components/Apps/components/AppsList.test.tsx delete mode 100644 src/routes/safe/components/Apps/components/ConfirmTxModal/ConfirmTxModal.test.tsx delete mode 100644 src/routes/safe/components/Apps/components/SignMessageModal/SignMessageModal.test.tsx delete mode 100644 src/routes/safe/components/Balances/AssetTableCell/index.tsx delete mode 100644 src/routes/safe/components/Balances/Coins/index.tsx delete mode 100644 src/routes/safe/components/Balances/Coins/styles.ts delete mode 100644 src/routes/safe/components/Balances/Collectibles/components/Item.tsx delete mode 100755 src/routes/safe/components/Balances/Collectibles/img/cryptokitties.png delete mode 100755 src/routes/safe/components/Balances/Collectibles/img/marblecards.png delete mode 100644 src/routes/safe/components/Balances/Collectibles/index.tsx delete mode 100644 src/routes/safe/components/Balances/Collectibles/styles.tsx delete mode 100644 src/routes/safe/components/Balances/SendModal/screens/AddressBookInput/AddressBookInput.test.tsx rename src/routes/safe/components/{CurrencyDropdown => Balances/SendModal/screens/ContractInteraction/MethodsDropdown}/img/check.svg (100%) rename src/routes/safe/components/{CurrencyDropdown => Balances/SendModal/screens/ContractInteraction/MethodsDropdown}/style.ts (100%) delete mode 100644 src/routes/safe/components/Balances/index.tsx delete mode 100644 src/routes/safe/components/Balances/utils/setCollectibleImageToPlaceholder.ts delete mode 100644 src/routes/safe/components/CurrencyDropdown/CurrencyDropdown.test.tsx delete mode 100644 src/routes/safe/components/CurrencyDropdown/index.tsx delete mode 100644 src/routes/safe/components/Settings/Advanced/Advanced.test.tsx delete mode 100644 src/utils/__tests__/checksumAddress.test.ts delete mode 100644 src/utils/__tests__/history.test.ts delete mode 100644 src/utils/__tests__/isValidAddress.test.ts delete mode 100644 src/utils/__tests__/prefixedAddress.test.ts delete mode 100644 src/utils/__tests__/strings.test.ts delete mode 100644 src/utils/storage/__tests__/index.test.ts delete mode 100644 src/utils/storage/__tests__/local.test.ts delete mode 100644 src/utils/storage/__tests__/session.test.ts diff --git a/src/App/ReceiveModal.tsx b/src/App/ReceiveModal.tsx index 5583020b3c..b068a83416 100644 --- a/src/App/ReceiveModal.tsx +++ b/src/App/ReceiveModal.tsx @@ -1,4 +1,3 @@ -import { Button, Text } from '@aura/safe-react-components' import IconButton from '@material-ui/core/IconButton' import { createStyles, makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' @@ -13,9 +12,8 @@ import Hairline from 'src/components/layout/Hairline' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' import { getChainInfo, getExplorerInfo } from 'src/config' -import { fontColor, lg, md, screenSm, secondaryText } from 'src/theme/variables' +import { borderLinear, lg, md, screenSm, secondaryText } from 'src/theme/variables' import PrefixedEthHashInfo from '../components/PrefixedEthHashInfo' -import { borderLinear } from 'src/theme/variables' const useStyles = (chainInfo: ChainInfo) => makeStyles( createStyles({ diff --git a/src/App/TermModal.tsx b/src/App/TermModal.tsx index 5e16ebdd56..e419051b18 100644 --- a/src/App/TermModal.tsx +++ b/src/App/TermModal.tsx @@ -3,24 +3,15 @@ import { createStyles, makeStyles } from '@material-ui/core/styles' import Close from '@material-ui/icons/Close' import { ReactElement } from 'react' -import styled from 'styled-components' -import { useDispatch, useSelector } from 'react-redux' import { ChainInfo } from '@gnosis.pm/safe-react-gateway-sdk' +import Logo from 'src/assets/icons/Logo.svg' import Hairline from 'src/components/layout/Hairline' import Paragraph from 'src/components/layout/Paragraph' import Row from 'src/components/layout/Row' -import { getChainInfo, getExplorerInfo } from 'src/config' -import { fontColor, lg, md, screenSm, secondaryText } from 'src/theme/variables' -import { borderLinear } from 'src/theme/variables' -import Logo from 'src/assets/icons/Logo.svg' -import session from 'src/utils/storage/session' -import { store } from 'src/logic/safe/store' -import { setTerm } from 'src/logic/checkTerm/store/actions/setTerm' +import { getChainInfo } from 'src/config' import { handleConnectWallet } from 'src/logic/providers' - -import enqueueSnackbar from 'src/logic/notifications/store/actions/enqueueSnackbar' -import { enhanceSnackbarForAction, NOTIFICATIONS } from 'src/logic/notifications' -import { TermSelector } from 'src/logic/checkTerm/store/selector' +import { borderLinear, lg, md, secondaryText } from 'src/theme/variables' +import styled from 'styled-components' const useStyles = (chainInfo: ChainInfo) => makeStyles( diff --git a/src/App/index.tsx b/src/App/index.tsx index 61522817c2..8d6684fdb0 100644 --- a/src/App/index.tsx +++ b/src/App/index.tsx @@ -76,7 +76,7 @@ const App: React.FC = ({ children }) => { const { name: safeName, totalFiatBalance: currentSafeBalance } = useSelector(currentSafeWithNames) const safeAddress = extractSafeAddress() const safeId = extractSafeId() - const { safeActionsState, onShow, onHide, showSendFunds, hideSendFunds } = useSafeActions() + const { onShow, showSendFunds } = useSafeActions() const { connectWalletState, onConnectWalletShow, onConnectWalletHide } = useConnectWallet() const currentCurrency = useSelector(currentCurrencySelector) const granted = useSelector(grantedSelector) @@ -86,13 +86,11 @@ const App: React.FC = ({ children }) => { useSafeScheduledUpdates(safeAddress, safeId) // load every X seconds useAddressBookSync() - const sendFunds = safeActionsState.sendFunds const formattedTotalBalance = currentSafeBalance ? formatAmountInUsFormat(currentSafeBalance.toString()) : '' const balance = !!formattedTotalBalance && !!currentCurrency ? `${formattedTotalBalance} ${currentCurrency}` : undefined const onReceiveShow = () => onShow('Receive') - const onReceiveHide = () => onHide('Receive') const onTermHide = () => { termContext?.SetTerm(false) diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx index f81de4e4b5..92ffc4a0a7 100644 --- a/src/components/Button/index.tsx +++ b/src/components/Button/index.tsx @@ -1,6 +1,6 @@ import { Button } from '@aura/safe-react-components' import styled from 'styled-components' -import { borderLinear, colorLinear } from 'src/theme/variables' +import { borderLinear } from 'src/theme/variables' export const OutlinedButton = ({ children, ...rest }) => { return ( diff --git a/src/components/ButtonSelect/index.tsx b/src/components/ButtonSelect/index.tsx index 2afc4d0cf9..d19cea38d1 100644 --- a/src/components/ButtonSelect/index.tsx +++ b/src/components/ButtonSelect/index.tsx @@ -1,8 +1,6 @@ -import React from 'react' import { makeStyles } from '@material-ui/core/styles' import FormControl from '@material-ui/core/FormControl' import Select from '@material-ui/core/Select' -import Input from '@material-ui/core/Input' import { borderLinear } from 'src/theme/variables' import CaretDown from './CaretDown.svg' import { MenuItem } from '@material-ui/core' diff --git a/src/components/ChainIndicator/index.test.tsx b/src/components/ChainIndicator/index.test.tsx deleted file mode 100644 index 6af8a7d2f3..0000000000 --- a/src/components/ChainIndicator/index.test.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { ChainId } from 'src/config/chain.d' -import { render } from 'src/utils/test-utils' -import ChainIndicator from '.' - -describe('', () => { - it('renders Rinkeby indicator', () => { - const { container } = render() - const icon = container.querySelector('svg') - const label = (container.textContent || '').trim() - - expect(icon?.getAttribute('color')).toBe('#00bcd4') - expect(label).toBe('Rinkeby') - }) - - it('renders Polygon indicator', () => { - const { container } = render() - const icon = container.querySelector('svg') - const label = (container.textContent || '').trim() - - expect(icon?.getAttribute('color')).toBe('#8248E5') - expect(label).toBe('Polygon') - }) -}) diff --git a/src/components/CircleDot/CircleDot.tsx b/src/components/CircleDot/CircleDot.tsx index f9af2fffe5..e72ee1d82c 100644 --- a/src/components/CircleDot/CircleDot.tsx +++ b/src/components/CircleDot/CircleDot.tsx @@ -1,5 +1,4 @@ import * as React from 'react' -import Dot from '@material-ui/icons/FiberManualRecord' import { getChainById } from 'src/config' import { ChainId } from 'src/config/chain.d' import styled from 'styled-components' diff --git a/src/components/CloseButton/index.tsx b/src/components/CloseButton/index.tsx index 718c915811..dc3cfd7f62 100644 --- a/src/components/CloseButton/index.tsx +++ b/src/components/CloseButton/index.tsx @@ -1,4 +1,4 @@ -import React, { ReactElement } from 'react' +import { ReactElement } from 'react' import styled from 'styled-components' const CloseButtonStyled = styled.button` diff --git a/src/components/ConnectWalletModal/styles.tsx b/src/components/ConnectWalletModal/styles.tsx index 1fc4966cb9..decf7adfcf 100644 --- a/src/components/ConnectWalletModal/styles.tsx +++ b/src/components/ConnectWalletModal/styles.tsx @@ -1,17 +1,7 @@ -import { createStyles } from '@material-ui/core' import styled from 'styled-components' import { lg } from '../../theme/variables' import Row from '../layout/Row' -const styles = createStyles({ - heading: { - padding: lg, - justifyContent: 'space-between', - maxHeight: '75px', - boxSizing: 'border-box', - }, -}) - const WalletList = styled.div` height: fit-content; padding: ${lg}; @@ -46,4 +36,4 @@ const ImageTitle = styled.span` text-align: left; ` -export { WalletList, ImageContainer, ImageItem, ImageTitle } +export { ImageContainer, ImageItem, ImageTitle, WalletList } diff --git a/src/components/CustomIconText/index.tsx b/src/components/CustomIconText/index.tsx deleted file mode 100644 index 2f527c18ee..0000000000 --- a/src/components/CustomIconText/index.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { ReactElement } from 'react' -import PrefixedEthHashInfo from '../PrefixedEthHashInfo' - -type Props = { - address: string - iconUrl?: string - iconUrlFallback?: string - text?: string -} - -export const CustomIconText = ({ address, iconUrl, text, iconUrlFallback }: Props): ReactElement => ( - -) diff --git a/src/components/DecodeTxs/__tests__/index.ts b/src/components/DecodeTxs/__tests__/index.ts deleted file mode 100644 index f7d67b8d9b..0000000000 --- a/src/components/DecodeTxs/__tests__/index.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { getByteLength } from '..' - -describe('DecodeTxs tests', () => { - it('should calculate the byte length of a single hex string', () => { - expect(getByteLength('0x000000ea')).toBe(4) - }) - - it('should calculate the byte length of multiple hex strings', () => { - expect(getByteLength('0x000000ea,0x48656c6c6f2125')).toBe(11) - }) - - it('should calculate the byte length of an hex array', () => { - expect(getByteLength(['0x000000ea', '0x48656c6c6f2125'])).toBe(11) - }) - - it('should return 0 if passed a non-hex value', () => { - expect(getByteLength('hello')).toBe(0) - }) - - it('should return 0 if passed a non-string', () => { - expect(getByteLength(123 as unknown as string)).toBe(0) - }) -}) diff --git a/src/components/ExecuteCheckbox/index.test.tsx b/src/components/ExecuteCheckbox/index.test.tsx deleted file mode 100644 index 8d5dcebc7c..0000000000 --- a/src/components/ExecuteCheckbox/index.test.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { fireEvent, render, screen, waitFor, act } from 'src/utils/test-utils' -import { history } from 'src/routes/routes' -import ExecuteCheckbox from '.' - -describe('ExecuteCheckbox', () => { - it('should call onChange when checked/unchecked', async () => { - const onChange = jest.fn() - history.push('/rin:0xb3b83bf204C458B461de9B0CD2739DB152b4fa5A/balances') - - await act(async () => { - render() - }) - - await waitFor(() => { - expect(screen.getByTestId('execute-checkbox')).toBeInTheDocument() - }) - - fireEvent.click(screen.getByTestId('execute-checkbox')) - expect(onChange).toHaveBeenCalledWith(false) - - fireEvent.click(screen.getByTestId('execute-checkbox')) - expect(onChange).toHaveBeenCalledWith(true) - }) -}) diff --git a/src/components/FeeAndSequence/index.tsx b/src/components/FeeAndSequence/index.tsx index 5d5e6c3e07..247b980cc3 100644 --- a/src/components/FeeAndSequence/index.tsx +++ b/src/components/FeeAndSequence/index.tsx @@ -1,15 +1,15 @@ -import TextField from 'src/components/Input/TextField' +import { useEffect } from 'react' import { useSelector } from 'react-redux' +import ReloadIcon from 'src/assets/icons/reload.svg' +import TextField from 'src/components/Input/TextField' import { getChainDefaultGasPrice, getCoinDecimal, getNativeCurrency } from 'src/config' +import calculateGasFee from 'src/logic/providers/utils/fee' import { currentSafeWithNames } from 'src/logic/safe/store/selectors' import { formatNativeCurrency } from 'src/utils' +import { usePagedQueuedTransactions } from 'src/utils/hooks/usePagedQueuedTransactions' import { FilledButton, LinkButton } from '../Button' import Gap from '../Gap' -import ReloadIcon from 'src/assets/icons/reload.svg' import { Info, Wrap } from './styles' -import { useState, useEffect } from 'react' -import calculateGasFee from 'src/logic/providers/utils/fee' -import { usePagedQueuedTransactions } from 'src/utils/hooks/usePagedQueuedTransactions' export default function FeeAndSequence({ open, @@ -22,7 +22,7 @@ export default function FeeAndSequence({ setSequence, }) { const { nextQueueSeq, sequence: currentSequence } = useSelector(currentSafeWithNames) - const { count, isLoading, hasMore, next, transactions } = usePagedQueuedTransactions() + const { transactions } = usePagedQueuedTransactions() const nativeCurrency = getNativeCurrency() const chainDefaultGasPrice = getChainDefaultGasPrice() diff --git a/src/components/GlobalErrorBoundary/__tests__/index.test.ts b/src/components/GlobalErrorBoundary/__tests__/index.test.ts deleted file mode 100644 index 9cbc9aa5f7..0000000000 --- a/src/components/GlobalErrorBoundary/__tests__/index.test.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { handleChunkError } from '..' - -const LAST_CHUNK_FAILURE_RELOAD_KEY = 'SAFE__lastChunkFailureReload' -const createTestErrorObject = (message: string) => ({ name: 'Test', message }) - -describe('handleChunkError', () => { - beforeEach(() => { - // Mock window.location.reload - Object.defineProperty(window, 'location', { - writable: true, - value: { reload: jest.fn() }, - }) - - window.sessionStorage.clear() - }) - - it('does not handle non-chunk loading failure errors', () => { - const testErrorObj = createTestErrorObject('Unrelated error') - - const isChunkError = handleChunkError(testErrorObj) - - expect(sessionStorage.getItem(LAST_CHUNK_FAILURE_RELOAD_KEY)).toBeNull() - expect(isChunkError).toBe(false) - expect(window.location.reload).not.toHaveBeenCalled() - }) - - const testChunkErrorObj = createTestErrorObject('Loading chunk 123 failed') - - it('handles no sessionStorage value existence', () => { - const isChunkError = handleChunkError(testChunkErrorObj) - - expect(sessionStorage.getItem(LAST_CHUNK_FAILURE_RELOAD_KEY)).toBeNull() - expect(isChunkError).toBe(false) - expect(window.location.reload).not.toHaveBeenCalled() - }) - - it('handles malformed sessionStorage values', () => { - const sessionStorageValue = 'This is a string' - sessionStorage.setItem(LAST_CHUNK_FAILURE_RELOAD_KEY, sessionStorageValue) - - const isChunkError = handleChunkError(testChunkErrorObj) - - expect(sessionStorage.getItem(LAST_CHUNK_FAILURE_RELOAD_KEY)).not.toBe(sessionStorageValue) - expect(isChunkError).toBe(false) - expect(window.location.reload).not.toHaveBeenCalled() - }) - - it('does not reload if there was a reload within the past 10 seconds', () => { - const time = new Date().getTime() - const timeString = time.toString() - - sessionStorage.setItem(LAST_CHUNK_FAILURE_RELOAD_KEY, timeString) - - const isChunkError = handleChunkError(testChunkErrorObj) - - expect(isChunkError).toBe(false) - expect(window.location.reload).not.toHaveBeenCalled() - }) - - it('reloads if the reload was more than 10 seconds ago', () => { - const expiredTime = new Date().getTime() - 11_000 - const expiredTimeString = expiredTime.toString() - - sessionStorage.setItem(LAST_CHUNK_FAILURE_RELOAD_KEY, expiredTimeString) - - const isChunkError = handleChunkError(testChunkErrorObj) - - expect(isChunkError).toBe(true) - expect(window.location.reload).toHaveBeenCalledTimes(1) - }) -}) diff --git a/src/components/GlobalErrorBoundary/index.tsx b/src/components/GlobalErrorBoundary/index.tsx index a0b42429e7..ffd55b7d60 100644 --- a/src/components/GlobalErrorBoundary/index.tsx +++ b/src/components/GlobalErrorBoundary/index.tsx @@ -1,12 +1,11 @@ -import styled from 'styled-components' -import { Text, Link, Icon, FixedIcon, Title } from '@aura/safe-react-components' -import { IS_PRODUCTION } from 'src/utils/constants' import { FallbackRender } from '@sentry/react/dist/errorboundary' -import { ROOT_ROUTE } from 'src/routes/routes' -import { loadFromSessionStorage, removeFromSessionStorage, saveToSessionStorage } from 'src/utils/storage/session' +import { useState } from 'react' import Astronaut from 'src/assets/images/astronaut.png' import Space from 'src/assets/images/bg-space.png' -import { useState } from 'react' +import { ROOT_ROUTE } from 'src/routes/routes' +import { IS_PRODUCTION } from 'src/utils/constants' +import { loadFromSessionStorage, removeFromSessionStorage, saveToSessionStorage } from 'src/utils/storage/session' +import styled from 'styled-components' import { LinkButton } from '../Button' const Wrapper = styled.div` width: 100vw; diff --git a/src/components/InfiniteScroll/index.tsx b/src/components/InfiniteScroll/index.tsx deleted file mode 100644 index 8ad11453c9..0000000000 --- a/src/components/InfiniteScroll/index.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import { createContext, forwardRef, MutableRefObject, ReactElement, ReactNode, useEffect, useState } from 'react' -import { InViewHookResponse, useInView } from 'react-intersection-observer' - -export const INFINITE_SCROLL_CONTAINER = 'infinite-scroll-container' - -const InfiniteScrollContext = createContext<{ - ref: MutableRefObject | ((instance: HTMLDivElement | null) => void) | null - lastItemId?: string - setLastItemId: (itemId?: string) => void -}>({ setLastItemId: () => {}, ref: null }) - -const InfiniteScrollProvider = forwardRef( - ({ children }, ref): ReactElement => { - const [lastItemId, _setLastItemId] = useState() - - const setLastItemId = (itemId?: string) => { - setTimeout(() => _setLastItemId(itemId), 0) - } - - return ( - - {children} - - ) - }, -) - -InfiniteScrollProvider.displayName = 'InfiniteScrollProvider' - -type InfiniteScrollProps = { - children: ReactNode - hasMore: boolean - next: () => Promise - config?: InViewHookResponse -} - -export const InfiniteScroll = ({ children, hasMore, next, config }: InfiniteScrollProps): ReactElement => { - const { ref, inView } = useInView({ - threshold: 0, - root: document.querySelector(`#${INFINITE_SCROLL_CONTAINER}`), - rootMargin: '0px 0px 200px 0px', - triggerOnce: true, - ...config, - }) - - useEffect(() => { - // Avoid memory leak - queue/history have separate InfiniteScroll wrappers - let isMounted = true - - if (isMounted && inView && hasMore) { - next() - } - - return () => { - isMounted = false - } - }, [inView, hasMore, next]) - - return {children} -} diff --git a/src/components/List/index.tsx b/src/components/List/index.tsx index ca966482d1..c81dbb8b84 100644 --- a/src/components/List/index.tsx +++ b/src/components/List/index.tsx @@ -2,7 +2,6 @@ import { useEffect, useState } from 'react' import { Link, useHistory } from 'react-router-dom' import ListMui from '@material-ui/core/List' import Collapse from '@material-ui/core/Collapse' -import { FixedIcon } from '@aura/safe-react-components' import IconButton from '@material-ui/core/IconButton' import ExpandLess from '@material-ui/icons/ExpandLess' @@ -16,7 +15,6 @@ import { TextAndBadgeWrapper, StyledBadge, StyledSubListMui, - StyledFixedIcon, } from './styles' export type ListItemType = { badge?: boolean diff --git a/src/components/List/styles.tsx b/src/components/List/styles.tsx index f1e1440800..13895df736 100644 --- a/src/components/List/styles.tsx +++ b/src/components/List/styles.tsx @@ -7,8 +7,6 @@ import Badge from '@material-ui/core/Badge' import ListMui, { ListProps } from '@material-ui/core/List' import { FixedIcon } from '@aura/safe-react-components' -import { semiBoldFont, mediumFontSize } from 'src/theme/variables' - const useStyles = makeStyles((theme: Theme) => createStyles({ root: { diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index 08a34c073c..8043c7308d 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -1,4 +1,4 @@ -import { Button, Icon, Loader } from '@aura/safe-react-components' +import { Icon, Loader } from '@aura/safe-react-components' import cn from 'classnames' import { ReactElement } from 'react' diff --git a/src/components/NetworkLabel/styles.tsx b/src/components/NetworkLabel/styles.tsx index 46e3ca9414..dfe608ce0e 100644 --- a/src/components/NetworkLabel/styles.tsx +++ b/src/components/NetworkLabel/styles.tsx @@ -1,4 +1,4 @@ -import { border, extraSmallFontSize, sm, xs, fontColor } from 'src/theme/variables' +import { extraSmallFontSize, sm, xs } from 'src/theme/variables' import styled from 'styled-components' type StyledLabelTypes = { diff --git a/src/components/NotificationPopup/index.tsx b/src/components/NotificationPopup/index.tsx index 8c69639a3f..fa3f359ff4 100644 --- a/src/components/NotificationPopup/index.tsx +++ b/src/components/NotificationPopup/index.tsx @@ -1,4 +1,4 @@ -import React, { ReactElement } from 'react' +import { ReactElement } from 'react' import styled from 'styled-components' import notiIcon from 'src/pages/Staking/assets/notiLinear.svg' diff --git a/src/components/Popup/MultiSendPopup/CreateTxPopup.tsx b/src/components/Popup/MultiSendPopup/CreateTxPopup.tsx index 98ffc83bf4..4141e18557 100644 --- a/src/components/Popup/MultiSendPopup/CreateTxPopup.tsx +++ b/src/components/Popup/MultiSendPopup/CreateTxPopup.tsx @@ -36,7 +36,7 @@ export default function CreateTxPopup({ gasUsed: string }) { const safeAddress = extractSafeAddress() - const { nativeBalance: balance, nextQueueSeq, sequence: currentSequence } = useSelector(currentSafeWithNames) + const { nativeBalance: balance, nextQueueSeq } = useSelector(currentSafeWithNames) const dispatch = useDispatch() const denom = getCoinMinimalDenom() const chainDefaultGasPrice = getChainDefaultGasPrice() diff --git a/src/components/Popup/MultiSendPopup/index.tsx b/src/components/Popup/MultiSendPopup/index.tsx index a96f18931f..af1416b5ae 100644 --- a/src/components/Popup/MultiSendPopup/index.tsx +++ b/src/components/Popup/MultiSendPopup/index.tsx @@ -5,7 +5,7 @@ import { extendedSafeTokensSelector } from 'src/utils/safeUtils/selector' import { AminoMsgMultiSend, coins } from '@cosmjs/stargate' import BigNumber from 'bignumber.js' -import { OutlinedButton, OutlinedNeutralButton, TextButton } from 'src/components/Button' +import { OutlinedButton, OutlinedNeutralButton } from 'src/components/Button' import Gap from 'src/components/Gap' import TextArea from 'src/components/Input/TextArea' import TokenSelect from 'src/components/Input/Token' diff --git a/src/components/Popup/SendingPopup/index.tsx b/src/components/Popup/SendingPopup/index.tsx index fa3181375e..216bad1c05 100644 --- a/src/components/Popup/SendingPopup/index.tsx +++ b/src/components/Popup/SendingPopup/index.tsx @@ -2,7 +2,6 @@ import { ReactElement, useEffect, useState } from 'react' import { useSelector } from 'react-redux' import { getCoinMinimalDenom } from 'src/config' -import { SpendingLimit } from 'src/logic/safe/store/models/safe' import { extendedSafeTokensSelector } from 'src/utils/safeUtils/selector' diff --git a/src/components/PrefixedEthHashInfo/index.test.tsx b/src/components/PrefixedEthHashInfo/index.test.tsx deleted file mode 100644 index 29b3036cb5..0000000000 --- a/src/components/PrefixedEthHashInfo/index.test.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import PrefixedEthHashInfo from '.' -import { render, screen } from 'src/utils/test-utils' - -const hash = '0x69904ff6d6100799344E5C9A2806936318F6ba4f' -jest.mock('src/routes/routes', () => { - const original = jest.requireActual('src/routes/routes') - return { - ...original, - extractShortChainName: () => 'arb', - } -}) - -describe('', () => { - it('Renders PrefixedEthHashInfo without shortName', () => { - const customState = { - appearance: { - showShortName: false, - }, - } - - render(, customState) - - expect(screen.queryByText('arb:')).not.toBeInTheDocument() - expect(screen.getByText(hash)).toBeInTheDocument() - }) - - it('Renders PrefixedEthHashInfo with shortName', () => { - const customState = { - appearance: { - showShortName: true, - }, - } - - render(, customState) - - expect(screen.queryByText('arb:')).toBeInTheDocument() - expect(screen.getByText(hash)).toBeInTheDocument() - }) -}) diff --git a/src/components/ReviewInfoText/ReviewInfoText.test.tsx b/src/components/ReviewInfoText/ReviewInfoText.test.tsx deleted file mode 100644 index a97373aa73..0000000000 --- a/src/components/ReviewInfoText/ReviewInfoText.test.tsx +++ /dev/null @@ -1,57 +0,0 @@ -import { useSelector } from 'react-redux' -import { EstimationStatus } from 'src/logic/hooks/useEstimateTransactionGas' -import { render, screen } from 'src/utils/test-utils' -import { ReviewInfoText } from './index' -import { history } from 'src/routes/routes' - -const safeAddress = '0xC245cb45B044d66fbE8Fb33C26c0b28B4fc367B2' -const url = `/rin:${safeAddress}/settings/advanced` -history.location.pathname = url - -describe('', () => { - const initialData = { - gasCostFormatted: '0', - isExecution: true, - isCreation: false, - isOffChainSignature: false, - txEstimationExecutionStatus: EstimationStatus.SUCCESS, - } - const customState = { - safes: { - safes: { - [safeAddress]: { - address: safeAddress, - nonce: 8, - modules: null, - guard: '', - currentVersion: '1.3.0', - }, - }, - }, - } - const testId = 'reviewInfoText-component' - const warningCommonCopy = - 'will need to be created and executed before this transaction, are you sure you want to do this?' - - it('Renders ReviewInfoText with safeNonce being one lastTxNonce + 1', () => { - const lastTxNonce = 10 - const safeNonce = `${lastTxNonce + 1}` - - render(, customState) - - expect(screen.getByTestId(testId)).toBeInTheDocument() - expect(screen.queryByText(warningCommonCopy)).not.toBeInTheDocument() - }) - - it('Renders ReviewInfoText with safeNonce more than one transaction ahead of lastTxNonce', () => { - const lastTxNonce = 10 - const safeNonce = `${lastTxNonce + 4}` - const expectedCopy = 'transactions ' + warningCommonCopy - - render(, customState) - - expect(screen.getByTestId(testId)).toBeInTheDocument() - expect(screen.getByText('6')).toBeInTheDocument() - expect(screen.queryByText(expectedCopy)).toBeInTheDocument() - }) -}) diff --git a/src/components/ReviewInfoText/index.tsx b/src/components/ReviewInfoText/index.tsx index 3a7a0806b7..fa85dd8aed 100644 --- a/src/components/ReviewInfoText/index.tsx +++ b/src/components/ReviewInfoText/index.tsx @@ -5,11 +5,8 @@ import { useSelector } from 'react-redux' import Paragraph from 'src/components/layout/Paragraph' import { currentSafe } from 'src/logic/safe/store/selectors' import { getLastTxNonce } from 'src/logic/safe/store/selectors/gatewayTransactions' -import { lg, sm } from 'src/theme/variables' import { TransactionFees } from '../TransactionsFees' -import { getRecommendedNonce } from 'src/logic/safe/api/fetchSafeTxGasEstimation' -import { extractSafeAddress } from 'src/routes/routes' -import { useEffect, useState } from 'react' +import { useState } from 'react' import { EstimationStatus } from 'src/logic/hooks/useEstimateTransactionGas' type CustomReviewInfoTextProps = { diff --git a/src/components/SafeListSidebar/SafeList/index.tsx b/src/components/SafeListSidebar/SafeList/index.tsx index ed97df32af..105849e89d 100644 --- a/src/components/SafeListSidebar/SafeList/index.tsx +++ b/src/components/SafeListSidebar/SafeList/index.tsx @@ -2,7 +2,7 @@ import MuiList from '@material-ui/core/List' import ListItem from '@material-ui/core/ListItem' import styled from 'styled-components' import makeStyles from '@material-ui/core/styles/makeStyles' -import { Fragment, ReactElement, useEffect, useState } from 'react' +import { Fragment, ReactElement } from 'react' import { Text } from '@aura/safe-react-components' import { Link } from 'react-router-dom' import uniqBy from 'lodash/uniqBy' diff --git a/src/components/ScanQRModal/ScanQRWrapper/index.tsx b/src/components/ScanQRModal/ScanQRWrapper/index.tsx index 6dab2ec791..6c1f6ab706 100644 --- a/src/components/ScanQRModal/ScanQRWrapper/index.tsx +++ b/src/components/ScanQRModal/ScanQRWrapper/index.tsx @@ -1,7 +1,6 @@ import { makeStyles } from '@material-ui/core/styles' import { ReactElement, useState } from 'react' -import QRIcon from 'src/assets/icons/qrcode.svg' import { ScanQRModal } from 'src/components/ScanQRModal' import Img from 'src/components/layout/Img' import QrCodeIcon from 'src/routes/CreateSafePage/assets/uil_qrcode-scan.svg' diff --git a/src/components/StatusCard/index.tsx b/src/components/StatusCard/index.tsx index 2cc15188d3..5f17a6772f 100644 --- a/src/components/StatusCard/index.tsx +++ b/src/components/StatusCard/index.tsx @@ -1,4 +1,4 @@ -import React, { ReactElement } from 'react' +import { ReactElement } from 'react' import { ProposalStatus } from 'src/types/proposal' import styled from 'styled-components' diff --git a/src/components/Stepper/Stepper.test.tsx b/src/components/Stepper/Stepper.test.tsx deleted file mode 100644 index 2e3d781f86..0000000000 --- a/src/components/Stepper/Stepper.test.tsx +++ /dev/null @@ -1,299 +0,0 @@ -import { history } from 'src/routes/routes' -import { fireEvent, render, screen, waitForElementToBeRemoved } from 'src/utils/test-utils' -import Stepper, { StepElement } from './Stepper' - -describe('', () => { - it('Renders Stepper component', () => { - render( - - -
Step 1 content
-
- -
Step 2 content
-
- -
Final step content
-
-
, - ) - - const stepperNode = screen.getByTestId('stepper-component') - - expect(stepperNode).toBeInTheDocument() - }) - - it('Renders first step by default', () => { - render( - - -
Step 1 content
-
- -
Step 2 content
-
- -
Final step content
-
-
, - ) - - const stepOneNode = screen.getByText('Step 1 content') - expect(stepOneNode).toBeInTheDocument() - expect(screen.queryByText('Step 2 content')).not.toBeInTheDocument() - expect(screen.queryByText('Final step content')).not.toBeInTheDocument() - }) - - it('Renders all step labels', () => { - render( - - -
Step 1 content
-
- -
Step 2 content
-
- -
Final step content
-
-
, - ) - - const stepOneLabelNode = screen.getByText('Step 1 label') - expect(stepOneLabelNode).toBeInTheDocument() - - const stepTwoLabelNode = screen.getByText('Step 2 label') - expect(stepTwoLabelNode).toBeInTheDocument() - - const finalStepLabelNode = screen.getByText('Final step label') - expect(finalStepLabelNode).toBeInTheDocument() - }) - - describe('Navigation', () => { - describe('Next button', () => { - it('Renders next step when clicks on next button', async () => { - render( - - -
Step 1 content
-
- -
Step 2 content
-
- -
Final step content
-
-
, - ) - - // Step 1 - const stepOneNode = screen.getByText('Step 1 content') - expect(stepOneNode).toBeInTheDocument() - expect(screen.queryByText('Step 2 content')).not.toBeInTheDocument() - expect(screen.queryByText('Final step content')).not.toBeInTheDocument() - - // Step 2 - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 1 content')) - const stepTwoNode = screen.getByText('Step 2 content') - expect(stepTwoNode).toBeInTheDocument() - expect(screen.queryByText('Step 1 content')).not.toBeInTheDocument() - expect(screen.queryByText('Final step content')).not.toBeInTheDocument() - - // Final Step - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 2 content')) - const finalStepNode = screen.getByText('Final step content') - expect(finalStepNode).toBeInTheDocument() - expect(screen.queryByText('Step 1 content')).not.toBeInTheDocument() - expect(screen.queryByText('Step 2 content')).not.toBeInTheDocument() - }) - }) - - describe('Back button', () => { - it('Returns to the previous step clicking on back button', async () => { - render( - - -
Step 1 content
-
- -
Step 2 content
-
- -
Final step content
-
-
, - ) - // we start in the Step 2 - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 1 content')) - const stepTwoNode = screen.getByText('Step 2 content') - expect(stepTwoNode).toBeInTheDocument() - expect(screen.queryByText('Step 1 content')).not.toBeInTheDocument() - expect(screen.queryByText('Final step content')).not.toBeInTheDocument() - - // we go back to the step 1 - fireEvent.click(screen.getByText('Back')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 2 content')) - expect(screen.getByText('Step 1 content')).toBeInTheDocument() - expect(screen.queryByText('Step 2 content')).not.toBeInTheDocument() - expect(screen.queryByText('Final step content')).not.toBeInTheDocument() - }) - - it('Returns to the previous screen if we are in the first step and click on Cancel button', () => { - const goBackSpy = jest.spyOn(history, 'goBack') - render( - - -
Step 1 content
-
- -
Step 2 content
-
- -
Final step content
-
-
, - ) - - expect(goBackSpy).not.toHaveBeenCalled() - fireEvent.click(screen.getByText('Cancel')) - expect(goBackSpy).toHaveBeenCalled() - goBackSpy.mockRestore() - }) - }) - - describe('Label navigation', () => { - it('Previous steps labels are clickable', () => { - render( - - -
Step 1 content
-
- -
Step 2 content
-
- -
Final step content
-
-
, - ) - - const stepOneLabelNode = screen.getByText('Step 1 label') - const stepTwoLabelNode = screen.getByText('Step 2 label') - - // we go to step 2 - const nextButtonNode = screen.getByText('Next') - fireEvent.click(nextButtonNode) - - // we can go again to step 1 by clicking on the label - expect(screen.getByText('Step 2 content')) - fireEvent.click(stepOneLabelNode) - expect(screen.getByText('Step 1 content')) - - // we go to final step - fireEvent.click(nextButtonNode) - fireEvent.click(nextButtonNode) - expect(screen.getByText('Final step content')) - - // we can go again to step 2 by clicking on the label - fireEvent.click(stepTwoLabelNode) - expect(screen.getByText('Step 2 content')) - - // we go to final step again - fireEvent.click(nextButtonNode) - expect(screen.getByText('Final step content')) - - // we can go again to step 1 by clicking on the label - fireEvent.click(stepOneLabelNode) - expect(screen.getByText('Step 1 content')) - }) - - it('Next steps labels are NOT clickable', () => { - render( - - -
Step 1 content
-
- -
Step 2 content
-
- -
Final step content
-
-
, - ) - const stepTwoLabelNode = screen.getByText('Step 2 label') - const finalStepLabelNode = screen.getByText('Final step label') - - // we click on the Step 2 label and nothing happens - expect(screen.getByText('Step 1 content')).toBeInTheDocument() - fireEvent.click(stepTwoLabelNode) - expect(screen.getByText('Step 1 content')).toBeInTheDocument() - - // we click on the Final Step label and nothing happens - expect(screen.getByText('Step 1 content')).toBeInTheDocument() - fireEvent.click(finalStepLabelNode) - expect(screen.getByText('Step 1 content')).toBeInTheDocument() - - // we go to step 2 and check the final label is not clickable - const nextButtonNode = screen.getByText('Next') - fireEvent.click(nextButtonNode) - expect(screen.getByText('Step 2 content')).toBeInTheDocument() - fireEvent.click(finalStepLabelNode) - expect(screen.getByText('Step 2 content')).toBeInTheDocument() - }) - }) - }) - - it('Customize next button label', async () => { - const customNextButtonLabel = 'my next button custom label' - - render( - - -
Step 1 content
-
- -
Step 2 content
-
- -
Final step content
-
-
, - ) - - expect(screen.getByText(customNextButtonLabel)).toBeInTheDocument() - expect(screen.queryByText('Next')).not.toBeInTheDocument() - }) - - it('Perform onFinish callback in the last step', async () => { - const onFinishSpy = jest.fn() - - render( - - -
Step 1 content
-
- -
Step 2 content
-
- -
Final step content
-
-
, - ) - - // we go to the final step - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 1 content')) - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 2 content')) - expect(screen.getByText('Final step content')).toBeInTheDocument() - - expect(onFinishSpy).not.toHaveBeenCalled() - fireEvent.click(screen.getByText('Next')) - expect(onFinishSpy).toHaveBeenCalled() - }) -}) diff --git a/src/components/StepperForm/StepperForm.test.tsx b/src/components/StepperForm/StepperForm.test.tsx deleted file mode 100644 index fb94f93cd9..0000000000 --- a/src/components/StepperForm/StepperForm.test.tsx +++ /dev/null @@ -1,344 +0,0 @@ -import { fireEvent, render, screen, waitForElementToBeRemoved } from 'src/utils/test-utils' -import Field from '../forms/Field' -import TextField from '../forms/TextField' -import StepperForm, { StepFormElement } from './StepperForm' - -describe('', () => { - it('Renders StepperForm component', () => { - const onSubmitSpy = jest.fn() - const stepOneValidationsSpy = jest.fn() - const finalStepValidationsSpy = jest.fn() - - const { container } = render( - - -
-
Step 1 content
- -
-
- -
-
Step 2 content
- -
-
- -
Final step content
-
-
, - ) - - const formNode = container.querySelector('form') - - expect(formNode).toBeInTheDocument() - expect(screen.getByTestId('stepper-form-test')).toBeInTheDocument() - }) - - it('Initial values in the form', () => { - const onSubmitSpy = jest.fn() - const stepOneValidationsSpy = jest.fn() - const finalStepValidationsSpy = jest.fn() - - const initialValues = { - stepOneTextfield: 'initial value of stepOneTextfield', - stepTwoTextfield: 'initial value of stepTwoTextfield', - } - - render( - - -
-
Step 1 content
- -
-
- -
-
Step 2 content
- -
-
- -
Final step content
-
-
, - ) - - const stepOneInputNode = screen.getByTestId('stepOneTextfield-field') as HTMLInputElement - - expect(stepOneInputNode).toBeInTheDocument() - expect(stepOneInputNode.value).toBe('initial value of stepOneTextfield') - }) - - it('renders ', () => { - render( - -
Step form content
-
, - ) - - expect(screen.getByText('Step form content')).toBeInTheDocument() - }) - - describe('Form navigation', () => { - it('Renders next form step when clicks on next button', async () => { - const onSubmitSpy = jest.fn() - const stepOneValidationsSpy = jest.fn() - const finalStepValidationsSpy = jest.fn() - - render( - - -
-
Step 1 content
- -
-
- -
-
Step 2 content
- -
-
- -
Final step content
-
-
, - ) - - // Form Step 1 - const formStepOneNode = screen.getByText('Step 1 content') - expect(formStepOneNode).toBeInTheDocument() - const stepOneInputNode = screen.getByTestId('stepOneTextfield-field') - expect(stepOneInputNode).toBeInTheDocument() - - // Form Step 2 - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 1 content')) - const formStepTwoNode = screen.getByText('Step 2 content') - expect(formStepTwoNode).toBeInTheDocument() - const stepTwoInputNode = screen.getByTestId('stepTwoTextfield-field') - expect(stepTwoInputNode).toBeInTheDocument() - - // Final Form Step - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 2 content')) - const finalFormStepNode = screen.getByText('Final step label') - expect(finalFormStepNode).toBeInTheDocument() - }) - }) - - describe('Form validations', () => { - it('Triggers validations when clicks on next button', async () => { - const onSubmitSpy = jest.fn() - const stepOneValidationsSpy = jest.fn() - const finalStepValidationsSpy = jest.fn() - - render( - - -
-
Step 1 content
- -
-
- -
-
Step 2 content
- -
-
- -
Final step content
-
-
, - ) - - fireEvent.click(screen.getByText('Next')) - expect(stepOneValidationsSpy).toHaveBeenCalled() - expect(finalStepValidationsSpy).not.toHaveBeenCalled() - await waitForElementToBeRemoved(() => screen.queryByText('Step 1 content')) - - expect(finalStepValidationsSpy).not.toHaveBeenCalled() - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 2 content')) - expect(finalStepValidationsSpy).toHaveBeenCalled() - }) - - it('If errors are present in the form you can not go to the next step', () => { - const onSubmitSpy = jest.fn() - const stepOneValidationsWithErrorsSpy = jest.fn(() => ({ - stepOneTextfield: 'this field has an error', - })) - const finalStepValidationsSpy = jest.fn() - - render( - - -
-
Step 1 content
- -
-
- -
-
Step 2 content
- -
-
- -
Final step content
-
-
, - ) - - // we try to go next - fireEvent.click(screen.getByText('Next')) - expect(stepOneValidationsWithErrorsSpy).toHaveBeenCalled() - expect(screen.queryByText('Step 2 content')).not.toBeInTheDocument() - }) - - it('Shows the form errors', () => { - const onSubmitSpy = jest.fn() - const stepOneValidationsWithErrorsSpy = jest.fn(() => ({ - stepOneTextfield: 'this field has an error', - })) - const finalStepValidationsSpy = jest.fn() - - render( - - -
-
Step 1 content
- -
-
- -
-
Step 2 content
- -
-
- -
Final step content
-
-
, - ) - - // we try to go next - fireEvent.click(screen.getByText('Next')) - expect(screen.queryByText('this field has an error')).toBeInTheDocument() - }) - }) - - it('Performs onSubmit in the final form step', async () => { - const onSubmitSpy = jest.fn() - const stepOneValidations = jest.fn() - const finalStepValidationsSpy = jest.fn() - - render( - - -
-
Step 1 content
- -
-
- -
-
Step 2 content
- -
-
- -
Final step content
-
-
, - ) - - // we go to the final step - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 1 content')) - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 2 content')) - - expect(onSubmitSpy).not.toHaveBeenCalled() - fireEvent.click(screen.getByText('Next')) - expect(onSubmitSpy).toHaveBeenCalled() - }) - - it('If errors are present, the form is not Submitted', async () => { - const onSubmitSpy = jest.fn() - const stepOneValidationsSpy = jest.fn() - const finalStepValidationsWithErrorsSpy = jest.fn(() => ({ - error: 'this a final step error', - })) - - render( - - -
-
Step 1 content
- -
-
- -
-
Step 2 content
- -
-
- -
Final step content
-
-
, - ) - - // we go to the final step - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 1 content')) - fireEvent.click(screen.getByText('Next')) - await waitForElementToBeRemoved(() => screen.queryByText('Step 2 content')) - - expect(onSubmitSpy).not.toHaveBeenCalled() - fireEvent.click(screen.getByText('Next')) - expect(onSubmitSpy).not.toHaveBeenCalled() - }) - - it('Disables Next step button', () => { - const onSubmitSpy = jest.fn() - const stepOneValidationsSpy = jest.fn() - const finalStepValidationsSpy = jest.fn() - - const { container } = render( - - -
-
Step 1 content
- -
-
- -
-
Step 2 content
- -
-
- -
Final step content
-
-
, - ) - - // Next button disabled - expect(container.querySelector('button[type=submit]')).toBeDisabled() - // Back button NOT disabled - expect(container.querySelector('button[type=button]')).not.toBeDisabled() - - // stay at Step 1 even if we click on the disabled Next button - fireEvent.click(screen.getByText('Next')) - expect(screen.getByText('Step 1 content')).toBeInTheDocument() - expect(screen.queryByText('Step 2 content')).not.toBeInTheDocument() - }) -}) diff --git a/src/components/StepperForm/StepperForm.tsx b/src/components/StepperForm/StepperForm.tsx index 9100fc44b3..1152d926bb 100644 --- a/src/components/StepperForm/StepperForm.tsx +++ b/src/components/StepperForm/StepperForm.tsx @@ -2,7 +2,7 @@ import React, { JSXElementConstructor, ReactElement, useMemo, useState } from 'r import { useEffect } from 'react' import { Form } from 'react-final-form' import { Validator } from '../forms/validator' -import Stepper, { StepElement, StepElementType } from '../Stepper/Stepper' +import Stepper, { StepElement } from '../Stepper/Stepper' import { useStepper } from '../Stepper/stepperContext' type StepperFormProps = { @@ -71,7 +71,6 @@ type StepFormElementProps = { disableNextButton?: boolean } - export function StepFormElement({ children }: StepFormElementProps): ReactElement { return children } diff --git a/src/components/StoreMigrator/__test__/utils.test.ts b/src/components/StoreMigrator/__test__/utils.test.ts deleted file mode 100644 index 721374be9a..0000000000 --- a/src/components/StoreMigrator/__test__/utils.test.ts +++ /dev/null @@ -1,313 +0,0 @@ -import * as migrationUtils from '../utils' - -jest.mock('src/logic/exceptions/CodedException', () => { - // Require the original module to not be mocked... - const originalModule = jest.requireActual('src/logic/exceptions/CodedException') - - return { - __esModule: true, // Use it when dealing with esModules - ...originalModule, - trackError: jest.fn(), - } -}) - -// Only exported functions -describe('getSubdomainUrl', () => { - // production - it('returns the correct production url', () => { - Object.defineProperty(window, 'location', { - writable: true, - value: { hostname: 'gnosis-safe.io' }, - }) - - const subdomain = migrationUtils.getSubdomainUrl('rinkeby') - expect(subdomain).toEqual('https://rinkeby.gnosis-safe.io/app') - }) - - it('returns nothing for incorrect staging url', () => { - Object.defineProperty(window, 'location', { - writable: true, - value: { hostname: 'fake.url' }, - }) - - const subdomain = migrationUtils.getSubdomainUrl('rinkeby') - expect(subdomain).toEqual('') - }) - - // staging - it('returns the correct staging url', () => { - Object.defineProperty(window, 'location', { - writable: true, - value: { hostname: 'safe-team-mainnet.staging.gnosisdev.com' }, - }) - - const subdomain = migrationUtils.getSubdomainUrl('bsc') - expect(subdomain).toEqual('https://safe-team-bsc.staging.gnosisdev.com/app') - }) -}) - -describe('getNetworksToMigrate', () => { - it('returns all networks when no localStorage value exists', () => { - Object.defineProperty(window, 'localStorage', { - writable: true, - value: { getItem: jest.fn(() => null) }, - }) - - const networks = migrationUtils.getNetworksToMigrate() - expect(networks).toEqual(['arbitrum', 'bsc', 'ewc', 'polygon', 'rinkeby', 'volta', 'xdai']) - }) - - it('returns non-migrated networks', () => { - Object.defineProperty(window, 'localStorage', { - writable: true, - value: { getItem: jest.fn(() => JSON.stringify(['bsc', 'rinkeby'])) }, - }) - - const networks = migrationUtils.getNetworksToMigrate() - expect(networks).toEqual(['arbitrum', 'ewc', 'polygon', 'volta', 'xdai']) - }) - - it('returns an empty array when all networks are migrated', () => { - Object.defineProperty(window, 'localStorage', { - writable: true, - value: { - getItem: jest.fn(() => JSON.stringify(['arbitrum', 'bsc', 'polygon', 'rinkeby', 'xdai', 'ewc', 'volta'])), - }, - }) - - const networks = migrationUtils.getNetworksToMigrate() - expect(networks).toEqual([]) - }) -}) - -describe('addMigratedNetwork', () => { - it('should not add already migrated network', () => { - Object.defineProperty(window, 'localStorage', { - writable: true, - value: { getItem: jest.fn(() => JSON.stringify(['rinkeby'])), setItem: jest.fn() }, - }) - - migrationUtils.addMigratedNetwork('rinkeby') - expect(localStorage.setItem).not.toHaveBeenCalled() - }) - - it('should add newly migrated network', () => { - Object.defineProperty(window, 'localStorage', { - writable: true, - value: { getItem: jest.fn(() => JSON.stringify(['xdai'])), setItem: jest.fn() }, - }) - - migrationUtils.addMigratedNetwork('rinkeby') - expect(localStorage.setItem).toHaveBeenCalledWith('SAFE__migratedNetworks', JSON.stringify(['xdai', 'rinkeby'])) - }) -}) - -describe('isNetworkSubdomain', () => { - it('returns true if subdomain', () => { - Object.defineProperty(window, 'location', { - writable: true, - value: { - href: 'https://rinkeby.gnosis-safe.io/app/#/safes/0xb3b83bf204C458B461de9B0CD2739DB152b4fa5A/balances', - hostname: 'rinkeby.gnosis-safe.io', - }, - }) - - expect(migrationUtils.isNetworkSubdomain()).toBe(true) - }) - - it('returns false if not subdomain', () => { - Object.defineProperty(window, 'location', { - writable: true, - value: { href: 'https://gnosis-safe.io/app/welcome', hostname: 'gnosis-safe.io' }, - }) - - expect(migrationUtils.isNetworkSubdomain()).toBe(false) - }) -}) -describe('handleMessage', () => { - let receivedCallback: () => void - let addressBookCallbackMock: () => void - let immortalDataCallbackMock: () => void - - beforeAll(() => { - receivedCallback = jest.fn() - addressBookCallbackMock = jest.fn() - immortalDataCallbackMock = jest.fn() - - Object.defineProperty(window, 'localStorage', { - writable: true, - value: { - getItem: jest.fn(), - setItem: jest.fn(), - }, - }) - }) - - afterEach(() => { - jest.clearAllMocks() - }) - - it('should return if not a valid origin', () => { - Object.defineProperty(window, 'location', { - writable: true, - value: { hostname: 'google.com' }, - }) - - const eventMock = { - data: { - payload: '', - }, - origin: 'gnosis-safe.io', - } as MessageEvent - - migrationUtils.handleMessage(eventMock, receivedCallback, addressBookCallbackMock, immortalDataCallbackMock) - - expect(receivedCallback).not.toHaveBeenCalled() - expect(addressBookCallbackMock).not.toHaveBeenCalled() - expect(immortalDataCallbackMock).not.toHaveBeenCalled() - }) - - it('should return if no payload', () => { - Object.defineProperty(window, 'location', { - writable: true, - value: { hostname: 'gnosis-safe.io' }, - }) - - Object.defineProperty(window, 'origin', { - writable: true, - value: 'https://gnosis-safe.io', - }) - - const eventMock = { - data: { - somethingElse: '', - }, - origin: 'https://rinkeby.gnosis-safe.io', - } as MessageEvent - - migrationUtils.handleMessage(eventMock, receivedCallback, addressBookCallbackMock, immortalDataCallbackMock) - - expect(receivedCallback).not.toHaveBeenCalled() - expect(addressBookCallbackMock).not.toHaveBeenCalled() - expect(immortalDataCallbackMock).not.toHaveBeenCalled() - }) - - it('should return if there is a completely malformed payload', () => { - const exceptions = require('src/logic/exceptions/CodedException') - Object.defineProperty(window, 'location', { - writable: true, - value: { hostname: 'gnosis-safe.io' }, - }) - - Object.defineProperty(window, 'origin', { - writable: true, - value: 'https://gnosis-safe.io', - }) - - const eventMock = { - data: { - payload: 'isdufhgoisdfuhglsdf', - }, - origin: 'https://rinkeby.gnosis-safe.io', - } as MessageEvent - - migrationUtils.handleMessage(eventMock, receivedCallback, addressBookCallbackMock, immortalDataCallbackMock) - - expect(receivedCallback).toHaveBeenCalled() - expect(addressBookCallbackMock).not.toHaveBeenCalled() - expect(immortalDataCallbackMock).not.toHaveBeenCalled() - expect(exceptions.trackError).toHaveBeenCalled() - }) - - it('should not try to merge the address book if the address book payload is malformed', () => { - const exceptions = require('src/logic/exceptions/CodedException') - - Object.defineProperty(window, 'location', { - writable: true, - value: { hostname: 'gnosis-safe.io' }, - }) - - Object.defineProperty(window, 'origin', { - writable: true, - value: 'https://gnosis-safe.io', - }) - - const eventMock = { - data: { - payload: JSON.stringify({ - SAFE__addressBook: 'sdfiguhfdoshgudslf', - ['_immortal|v2_RINKEBY__SAFES']: JSON.stringify({ test: 'aisfdhoilsaf' }), - ['_immortal|v2_MAINNET__SAFES']: JSON.stringify({}), - }), - }, - origin: 'https://rinkeby.gnosis-safe.io', - } as MessageEvent - - migrationUtils.handleMessage(eventMock, receivedCallback, addressBookCallbackMock, immortalDataCallbackMock) - - expect(receivedCallback).toHaveBeenCalled() - expect(addressBookCallbackMock).not.toHaveBeenCalled() - expect(exceptions.trackError).toHaveBeenCalledTimes(1) - expect(immortalDataCallbackMock).toHaveBeenCalledTimes(1) - expect(immortalDataCallbackMock).toHaveBeenCalledWith('v2_RINKEBY__SAFES', { test: 'aisfdhoilsaf' }) - }) - - it('should not save localStorage data if the localStorage payload is malformed', () => { - const exceptions = require('src/logic/exceptions/CodedException') - - Object.defineProperty(window, 'location', { - writable: true, - value: { hostname: 'gnosis-safe.io' }, - }) - - Object.defineProperty(window, 'origin', { - writable: true, - value: 'https://gnosis-safe.io', - }) - - const eventMock = { - data: { - payload: JSON.stringify({ - SAFE__addressBook: JSON.stringify([]), - ['_immortal|v2_RINKEBY__SAFES']: 'sdifughosidfghdfgs', - }), - }, - origin: 'https://rinkeby.gnosis-safe.io', - } as MessageEvent - - migrationUtils.handleMessage(eventMock, receivedCallback, addressBookCallbackMock, immortalDataCallbackMock) - - expect(receivedCallback).toHaveBeenCalled() - expect(addressBookCallbackMock).toHaveBeenCalledWith([]) - expect(immortalDataCallbackMock).not.toHaveBeenCalled() - expect(exceptions.trackError).toHaveBeenCalledTimes(1) - }) - - it('should migrate correctly formed address book/localStorage data', () => { - Object.defineProperty(window, 'location', { - writable: true, - value: { hostname: 'gnosis-safe.io' }, - }) - - Object.defineProperty(window, 'origin', { - writable: true, - value: 'https://gnosis-safe.io', - }) - - const eventMock = { - data: { - payload: JSON.stringify({ - SAFE__addressBook: JSON.stringify([]), - ['_immortal|v2_RINKEBY__SAFES']: JSON.stringify({}), - }), - }, - origin: 'https://rinkeby.gnosis-safe.io', - } as MessageEvent - - migrationUtils.handleMessage(eventMock, receivedCallback, addressBookCallbackMock, immortalDataCallbackMock) - - expect(receivedCallback).toHaveBeenCalled() - expect(addressBookCallbackMock).toHaveBeenCalledWith([]) - expect(immortalDataCallbackMock).toHaveBeenCalledWith('v2_RINKEBY__SAFES', {}) - }) -}) diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx index 38b620c3f2..69423c924c 100644 --- a/src/components/Table/index.tsx +++ b/src/components/Table/index.tsx @@ -1,5 +1,4 @@ import * as React from 'react' -import { Loader } from '@aura/safe-react-components' import Table from '@material-ui/core/Table' import TableBody from '@material-ui/core/TableBody' import TablePagination from '@material-ui/core/TablePagination' @@ -7,7 +6,7 @@ import { withStyles } from '@material-ui/core/styles' import TableHead from 'src/components/Table/TableHead' import { getSorting, stableSort } from 'src/components/Table/sorting' import Row from 'src/components/layout/Row' -import { styles, getEmptyStyle } from './styles' +import { styles } from './styles' const backProps = { 'aria-label': 'Previous Page', } diff --git a/src/components/TransactionsFees/index.tsx b/src/components/TransactionsFees/index.tsx index cf6b0588c7..961599b654 100644 --- a/src/components/TransactionsFees/index.tsx +++ b/src/components/TransactionsFees/index.tsx @@ -1,8 +1,6 @@ import { EstimationStatus } from 'src/logic/hooks/useEstimateTransactionGas' import Paragraph from 'src/components/layout/Paragraph' -import { getNativeCurrency } from 'src/config' import { TransactionFailText } from 'src/components/TransactionFailText' -import { Text } from '@aura/safe-react-components' import styled from 'styled-components' const StyledText = styled.span` diff --git a/src/components/forms/AddressInput/index.tsx b/src/components/forms/AddressInput/index.tsx index 44ceab7f9b..6eefab04fe 100644 --- a/src/components/forms/AddressInput/index.tsx +++ b/src/components/forms/AddressInput/index.tsx @@ -1,23 +1,17 @@ +import CircularProgress from '@material-ui/core/CircularProgress' +import InputAdornment from '@material-ui/core/InputAdornment' import { useCallback, useEffect, useMemo, useState } from 'react' import { Field } from 'react-final-form' import { OnChange } from 'react-final-form-listeners' -import InputAdornment from '@material-ui/core/InputAdornment' -import CircularProgress from '@material-ui/core/CircularProgress' import TextField from 'src/components/forms/TextField' -import { - Validator, - composeValidators, - mustBeEthereumAddress, - required, - mustBeValidAddress, -} from 'src/components/forms/validator' -import { trimSpaces } from 'src/utils/strings' +import { Validator, composeValidators, mustBeValidAddress, required } from 'src/components/forms/validator' +import { Errors, logError } from 'src/logic/exceptions/CodedException' +import { isValidCryptoDomainName, isValidEnsName } from 'src/logic/wallets/ethAddresses' import { getAddressFromDomain } from 'src/logic/wallets/getWeb3' -import { isValidEnsName, isValidCryptoDomainName } from 'src/logic/wallets/ethAddresses' import { checksumAddress } from 'src/utils/checksumAddress' -import { Errors, logError } from 'src/logic/exceptions/CodedException' import { parsePrefixedAddress } from 'src/utils/prefixedAddress' +import { trimSpaces } from 'src/utils/strings' interface AddressInputProps { fieldMutator: (address: string) => void diff --git a/src/components/forms/validator.test.ts b/src/components/forms/validator.test.ts deleted file mode 100644 index a8c47d6690..0000000000 --- a/src/components/forms/validator.test.ts +++ /dev/null @@ -1,275 +0,0 @@ -import { - required, - mustBeInteger, - mustBeFloat, - maxValue, - mustBeUrl, - minValue, - mustBeEthereumAddress, - mustBeAddressHash, - minMaxLength, - uniqueAddress, - differentFrom, - ADDRESS_REPEATED_ERROR, - addressIsNotCurrentSafe, - OWNER_ADDRESS_IS_SAFE_ADDRESS_ERROR, - mustBeHexData, - validAddressBookName, -} from 'src/components/forms/validator' - -describe('Forms > Validators', () => { - describe('Required validator', () => { - const REQUIRED_ERROR_MSG = 'Required' - - it('Returns undefined for a non-empty string', () => { - expect(required('Im not empty')).toBeUndefined() - }) - - it('Returns an error message for an empty string', () => { - expect(required('')).toEqual(REQUIRED_ERROR_MSG) - }) - - it('Returns an error message for a string containing only spaces', () => { - expect(required(' ')).toEqual(REQUIRED_ERROR_MSG) - }) - }) - - describe('mustBeInteger validator', () => { - const MUST_BE_INTEGER_ERROR_MSG = 'Must be an integer' - - it('Returns undefined for an integer number string', () => { - expect(mustBeInteger('10')).toBeUndefined() - }) - - it('Returns an error message for a float number', () => { - expect(mustBeInteger('1.0')).toEqual(MUST_BE_INTEGER_ERROR_MSG) - }) - - it('Returns an error message for a non-number string', () => { - expect(mustBeInteger('iamnotanumber')).toEqual(MUST_BE_INTEGER_ERROR_MSG) - }) - }) - - describe('mustBeFloat validator', () => { - const MUST_BE_FLOAT_ERR_MSG = 'Must be a number' - - it('Returns undefined for a float number string', () => { - expect(mustBeFloat('1.0')).toBeUndefined() - }) - - it('Returns an error message for a non-number string', () => { - expect(mustBeFloat('iamnotanumber')).toEqual(MUST_BE_FLOAT_ERR_MSG) - }) - }) - - describe('minValue validator', () => { - const getMinValueErrMsg = (minValue: number, inclusive = true): string => - `Should be greater than ${inclusive ? 'or equal to ' : ''}${minValue}` - - it('Returns undefined for a number greater than minimum', () => { - const minimum = Math.random() - const number = (minimum + 1).toString() - - expect(minValue(minimum)(number)).toBeUndefined() - }) - - it('Returns an error message for a number less than minimum', () => { - const minimum = Math.random() - const number = (minimum - 1).toString() - - expect(minValue(minimum)(number)).toEqual(getMinValueErrMsg(minimum)) - }) - - it('Returns an error message for a number equal to minimum with false inclusive param', () => { - const minimum = Math.random() - const number = (minimum - 1).toString() - - expect(minValue(minimum, false)(number)).toEqual(getMinValueErrMsg(minimum, false)) - }) - - it('Returns an error message for a non-number string', () => { - expect(minValue(1)('imnotanumber')).toEqual(getMinValueErrMsg(1)) - }) - }) - - describe('mustBeUrl validator', () => { - const MUST_BE_URL_ERR_MSG = 'Please, provide a valid url' - - it('Returns undefined for a valid url', () => { - expect(mustBeUrl('https://gnosis-safe.io')).toBeUndefined() - }) - - it('Returns an error message for an valid url', () => { - expect(mustBeUrl('gnosis-safe')).toEqual(MUST_BE_URL_ERR_MSG) - }) - }) - - describe('maxValue validator', () => { - const getMaxValueErrMsg = (maxValue: number): string => `Maximum value is ${maxValue}` - - it('Returns undefined for a number less than maximum', () => { - const max = Math.random() - const number = (max - 1).toString() - - expect(maxValue(max)(number)).toBeUndefined() - }) - - it('Returns undefined for a number equal to maximum', () => { - const max = Math.random() - - expect(maxValue(max)(max.toString())).toBeUndefined() - }) - - it('Returns an error message for a number greater than maximum', () => { - const max = Math.random() - const number = (max + 1).toString() - - expect(maxValue(max)(number)).toEqual(getMaxValueErrMsg(max)) - }) - - it('Returns an error message for a non-number string', () => { - expect(maxValue(1)('imnotanumber')).toEqual(getMaxValueErrMsg(1)) - }) - }) - - describe('mustBeHexData validator', () => { - const MUST_BE_HEX_DATA_ERROR_MSG = 'Has to be a valid strict hex data (it must start with 0x)' - - it('should return undefined for `0x`', function () { - expect(mustBeHexData('0x')).toBeUndefined() - }) - - it('should return undefined for an address', function () { - expect(mustBeHexData('0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toBeUndefined() - }) - - it('should return undefined for a valid hex string', function () { - expect( - mustBeHexData( - '0x095ea7b30000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d0000000000000000000000000000000000000000000000000000000000000000', - ), - ).toBeUndefined() - }) - - it('should return an error message for an empty string', function () { - expect(mustBeHexData('')).toEqual(MUST_BE_HEX_DATA_ERROR_MSG) - }) - - it('should return the error message for a non-strict hex string', function () { - expect(mustBeHexData('0')).toEqual(MUST_BE_HEX_DATA_ERROR_MSG) - }) - }) - describe('mustBeAddressHash validator', () => { - const MUST_BE_ETH_ADDRESS_ERR_MSG = 'Must be a valid address' - - it('Returns undefined for a valid ethereum address', async () => { - expect(await mustBeAddressHash('0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toBeUndefined() - }) - - it('Returns an error message for an address with an invalid checksum', async () => { - expect(await mustBeAddressHash('0xde0b295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toEqual(MUST_BE_ETH_ADDRESS_ERR_MSG) - }) - - it('Returns an error message for non-address and non-domain string', async () => { - expect(await mustBeAddressHash('notanaddress')).toEqual(MUST_BE_ETH_ADDRESS_ERR_MSG) - }) - }) - - describe('mustBeEthereumAddress validator', () => { - const MUST_BE_ETH_ADDRESS_OR_DOMAIN_ERR_MSG = 'Must be a valid address, ENS or Unstoppable domain' - - it('Returns undefined for a valid ethereum address', async () => { - expect(await mustBeEthereumAddress('0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toBeUndefined() - }) - - it('Returns an error message for an address with an invalid checksum', async () => { - expect(await mustBeEthereumAddress('0xde0b295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toEqual( - MUST_BE_ETH_ADDRESS_OR_DOMAIN_ERR_MSG, - ) - }) - }) - - describe('minMaxLength validator', () => { - const getMinMaxLenErrMsg = (minLen: number, maxLen: number): string => `Should be ${minLen} to ${maxLen} symbols` - - it('Returns undefined for a string between minimum and maximum length', async () => { - expect(minMaxLength(1, 10)('length7')).toBeUndefined() - }) - - it('Returns an error message for a string with length greater than maximum', async () => { - const minMaxLengths: [number, number] = [1, 5] - - expect(minMaxLength(...minMaxLengths)('length7')).toEqual(getMinMaxLenErrMsg(...minMaxLengths)) - }) - - it('Returns an error message for a string with length less than minimum', async () => { - const minMaxLengths: [number, number] = [7, 10] - - expect(minMaxLength(...minMaxLengths)('string')).toEqual(getMinMaxLenErrMsg(...minMaxLengths)) - }) - }) - - describe('uniqueAddress validator', () => { - it('Returns undefined if `addresses` does not contains the provided address', async () => { - const addresses = ['0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'] - - expect(uniqueAddress(addresses)('0x2D6F2B448b0F711Eb81f2929566504117d67E44F')).toBeUndefined() - }) - - it('Returns an error message if address is in the `addresses` list already', async () => { - const addresses = ['0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe', '0x2D6F2B448b0F711Eb81f2929566504117d67E44F'] - - expect(uniqueAddress(addresses)('0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe')).toEqual(ADDRESS_REPEATED_ERROR) - }) - }) - - describe('addressIsNotSafe validator', () => { - it('Returns undefined if the given `address` it not the given `safeAddress`', async () => { - const address = '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe' - const safeAddress = '0x2D6F2B448b0F711Eb81f2929566504117d67E44F' - - expect(addressIsNotCurrentSafe(safeAddress)(address)).toBeUndefined() - }) - - it('Returns an error message if the given `address` is the same as the `safeAddress`', async () => { - const address = '0x2D6F2B448b0F711Eb81f2929566504117d67E44F' - const safeAddress = '0x2D6F2B448b0F711Eb81f2929566504117d67E44F' - - expect(addressIsNotCurrentSafe(safeAddress)(address)).toEqual(OWNER_ADDRESS_IS_SAFE_ADDRESS_ERROR) - }) - }) - - describe('differentFrom validator', () => { - const getDifferentFromErrMsg = (diffValue: string): string => `Value should be different than ${diffValue}` - - it('Returns undefined for different values', async () => { - expect(differentFrom('a')('b')).toBeUndefined() - }) - - it('Returns an error message for equal values', async () => { - expect(differentFrom('a')('a')).toEqual(getDifferentFromErrMsg('a')) - }) - }) - - describe('validAddressBookName validator', () => { - it('Returns error for an empty string', () => { - expect(validAddressBookName('')).toBe('Should be 1 to 50 symbols') - }) - it('Returns error for a name longer than 50 chars', () => { - expect(validAddressBookName('abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabc')).toBe( - 'Should be 1 to 50 symbols', - ) - }) - it('Returns error for a blacklisted name', () => { - const blacklistedErrorMessage = 'Name should not include: UNKNOWN, OWNER #, MY WALLET' - - expect(validAddressBookName('unknown')).toBe(blacklistedErrorMessage) - expect(validAddressBookName('unknown a')).toBe(blacklistedErrorMessage) - expect(validAddressBookName('owner #1')).toBe(blacklistedErrorMessage) - expect(validAddressBookName('My Wallet')).toBe(blacklistedErrorMessage) - }) - it('Returns undefined for a non-blacklisted name', () => { - expect(validAddressBookName('A valid name')).toBeUndefined() - }) - }) -}) diff --git a/src/components/layout/Button/GnoButton.test.tsx b/src/components/layout/Button/GnoButton.test.tsx deleted file mode 100644 index 8cdf257744..0000000000 --- a/src/components/layout/Button/GnoButton.test.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import { render, fireEvent, screen } from 'src/utils/test-utils' -import GnoButton from './index' - -describe('', () => { - it('Should render GnoButton', () => { - render() - - const gnoButtonNode = screen.getByTestId('gno-button-id') - - expect(gnoButtonNode).toBeInTheDocument() - }) - - it('Should trigger onClick event when clicks on the button', () => { - const onClickSpy = jest.fn() - - render() - - const gnoButtonNode = screen.getByTestId('gno-button-id') - - expect(onClickSpy).not.toHaveBeenCalled() - - fireEvent.click(gnoButtonNode) - - expect(onClickSpy).toHaveBeenCalled() - }) -}) diff --git a/src/components/layout/ButtonLink/ButtonLink.test.jsx b/src/components/layout/ButtonLink/ButtonLink.test.jsx deleted file mode 100644 index 229ae908b6..0000000000 --- a/src/components/layout/ButtonLink/ButtonLink.test.jsx +++ /dev/null @@ -1,12 +0,0 @@ -import { render, screen } from 'src/utils/test-utils' -import GnoButtonLink from './index' - -describe('', () => { - it('Should render GnoButtonLink', () => { - render() - - const gnoButtonLinkNode = screen.getByTestId('gno-button-link-id') - - expect(gnoButtonLinkNode).toBeInTheDocument() - }) -}) diff --git a/src/components/layout/Heading/index.tsx b/src/components/layout/Heading/index.tsx index a4eafab734..7306bc45a4 100644 --- a/src/components/layout/Heading/index.tsx +++ b/src/components/layout/Heading/index.tsx @@ -1,8 +1,6 @@ import classNames from 'classnames/bind' -import * as React from 'react' - import styles from './index.module.scss' - +import React from 'react' import { capitalize } from 'src/utils/css' const cx = classNames.bind(styles) diff --git a/src/components/layout/Link/index.tsx b/src/components/layout/Link/index.tsx index 1a648886be..c027cc1986 100644 --- a/src/components/layout/Link/index.tsx +++ b/src/components/layout/Link/index.tsx @@ -1,5 +1,5 @@ import classNames from 'classnames/bind' -import * as React from 'react' +import React from 'react' import { Link } from 'react-router-dom' import styles from './index.module.scss' diff --git a/src/components/layout/Span/Span.test.jsx b/src/components/layout/Span/Span.test.jsx deleted file mode 100644 index 3516b132e3..0000000000 --- a/src/components/layout/Span/Span.test.jsx +++ /dev/null @@ -1,12 +0,0 @@ -import { render, screen } from 'src/utils/test-utils' -import Span from './index' - -describe('', () => { - it('Should render Span and his content', () => { - render({'Test Text placeholder'}) - - const spanNode = screen.getByText('Test Text placeholder') - - expect(spanNode).toBeInTheDocument() - }) -}) diff --git a/src/components/layout/Span/index.tsx b/src/components/layout/Span/index.tsx index 589f4ab6ed..f86ed0c52f 100644 --- a/src/components/layout/Span/index.tsx +++ b/src/components/layout/Span/index.tsx @@ -1,4 +1,4 @@ -import * as React from 'react' +import React from 'react' class Span extends React.PureComponent { render(): React.ReactElement { diff --git a/src/config/__tests__/index.test.ts b/src/config/__tests__/index.test.ts deleted file mode 100644 index 9206e0ab05..0000000000 --- a/src/config/__tests__/index.test.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { setChainId } from 'src/logic/config/utils' -import { CHAIN_ID } from '../chain.d' -import { getPublicRpcUrl } from '..' - -describe('Config getters', () => { - describe('getPublicRpcUrl', () => { - afterEach(() => { - setChainId(CHAIN_ID.RINKEBY) - }) - - it('gets a public RPC from the config', () => { - setChainId(CHAIN_ID.POLYGON) - expect(getPublicRpcUrl()).toBe('https://polygon-rpc.com/') - }) - }) -}) diff --git a/src/config/__tests__/utils.test.ts b/src/config/__tests__/utils.test.ts deleted file mode 100644 index fdd72f21a8..0000000000 --- a/src/config/__tests__/utils.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { evalTemplate } from '../utils' - -describe('replaceTemplateParams', () => { - it('replace a template param', () => { - const str = 'https://rinkeby.etherscan.io/address/{{address}}' - - expect(evalTemplate(str, { address: '0x123' })).toBe('https://rinkeby.etherscan.io/address/0x123') - }) - it('replaces multiple template params', () => { - const str = - 'https://api-rinkeby.etherscan.io/api?module={{module}}&action={{action}}&address={{address}}&apiKey={{apiKey}}' - - const params = { - module: 'contract', - action: 'getAbi', - address: '0x123', - apiKey: 'test', - } - - expect(evalTemplate(str, params)).toBe( - 'https://api-rinkeby.etherscan.io/api?module=contract&action=getAbi&address=0x123&apiKey=test', - ) - }) -}) diff --git a/src/config/cache/chains.ts b/src/config/cache/chains.ts index 35b7a7b698..c8dd5dd3d4 100644 --- a/src/config/cache/chains.ts +++ b/src/config/cache/chains.ts @@ -1,7 +1,4 @@ import { ChainInfo, RPC_AUTHENTICATION } from '@gnosis.pm/safe-react-gateway-sdk' -import _ from 'lodash' -import { _setChainId } from 'src/config' -import { DEFAULT_CHAIN_ID } from 'src/utils/constants' import { getMChainsConfig } from '../../services' // Cache is required as loading Redux store directly is an anit-pattern diff --git a/src/config/index.ts b/src/config/index.ts index aed3335958..1a264bdcb7 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -8,13 +8,12 @@ import { } from '@gnosis.pm/safe-react-gateway-sdk' import { - GATEWAY_URL, DEFAULT_CHAIN_ID, ETHERSCAN_API_KEY, INFURA_TOKEN, SAFE_APPS_RPC_TOKEN, TX_SERVICE_VERSION, -} from 'src/utils/constants' +} from 'src/utils/constants'; import { ChainId, ChainName, ShortName } from './chain.d' import { emptyChainInfo, getChains } from './cache/chains' import { evalTemplate } from './utils' diff --git a/src/layout/Footer/Footer.test.tsx b/src/layout/Footer/Footer.test.tsx deleted file mode 100644 index 8652e14287..0000000000 --- a/src/layout/Footer/Footer.test.tsx +++ /dev/null @@ -1,125 +0,0 @@ -import Footer from './index' -import CookiesBanner from 'src/components/CookiesBanner' -import { render, fireEvent, screen } from 'src/utils/test-utils' - -describe('