diff --git a/src/routes/safe/component/Withdraw/withdraw.test.js b/src/routes/safe/component/Withdraw/withdraw.test.js index 231aed7c..46cd0e08 100644 --- a/src/routes/safe/component/Withdraw/withdraw.test.js +++ b/src/routes/safe/component/Withdraw/withdraw.test.js @@ -1,6 +1,6 @@ // @flow import { aNewStore } from '~/store' -import { addEtherTo } from '~/test/utils/etherMovements' +import { addEtherTo } from '~/test/utils/tokenMovements' import { aDeployedSafe, executeWithdrawOn } from '~/routes/safe/store/test/builder/deployedSafe.builder' import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps' import { safeSelector } from '~/routes/safe/store/selectors/index' diff --git a/src/routes/safe/container/actions.js b/src/routes/safe/container/actions.js index bc5bff23..ff9a91b4 100644 --- a/src/routes/safe/container/actions.js +++ b/src/routes/safe/container/actions.js @@ -1,6 +1,6 @@ // @flow import fetchSafe from '~/routes/safe/store/actions/fetchSafe' -import fetchBalances from '~/routes/safe/store/actions/fetchBalances' +import { fetchBalances } from '~/routes/safe/store/actions/fetchBalances' export type Actions = { fetchSafe: typeof fetchSafe, diff --git a/src/routes/safe/store/actions/fetchBalances.js b/src/routes/safe/store/actions/fetchBalances.js index 5d49d733..70128769 100644 --- a/src/routes/safe/store/actions/fetchBalances.js +++ b/src/routes/safe/store/actions/fetchBalances.js @@ -1,12 +1,24 @@ // @flow import { Map } from 'immutable' +import contract from 'truffle-contract' import type { Dispatch as ReduxDispatch } from 'redux' -import { getBalanceInEtherOf } from '~/wallets/getWeb3' +import ERC20Token from '#/ERC20Token.json' +import { getBalanceInEtherOf, getWeb3 } from '~/wallets/getWeb3' import { type GlobalState } from '~/store/index' -import { makeBalance, type Balance } from '~/routes/safe/store/model/balance' +import { makeBalance, type Balance, type BalanceProps } from '~/routes/safe/store/model/balance' import addBalances from './addBalances' -export default (safeAddress: string) => async (dispatch: ReduxDispatch) => { +export const calculateBalanceOf = async (tokenAddress: string, address: string) => { + const web3 = getWeb3() + const erc20Token = await contract(ERC20Token) + erc20Token.setProvider(web3.currentProvider) + + return erc20Token.at(tokenAddress) + .then(instance => instance.balanceOf(address).then(funds => funds.toString())) + .catch(() => '0') +} + +export const fetchBalances = (safeAddress: string) => async (dispatch: ReduxDispatch) => { const balance = await getBalanceInEtherOf(safeAddress) const ethBalance = makeBalance({ address: '0', @@ -32,8 +44,13 @@ export default (safeAddress: string) => async (dispatch: ReduxDispatch { + const funds = await calculateBalanceOf(item.address, safeAddress) + return makeBalance({ ...item, funds }) + })) + const balances: Map = Map().withMutations((map) => { - json.forEach(item => map.set(item.symbol, makeBalance(item))) + balancesRecords.forEach(record => map.set(record.get('symbol'), record)) map.set('ETH', ethBalance) }) diff --git a/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js b/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js index 017cebe7..1588d719 100644 --- a/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js +++ b/src/routes/safe/test/Safe.multisig.1owners1threshold.test.js @@ -5,7 +5,7 @@ import { Provider } from 'react-redux' import { ConnectedRouter } from 'react-router-redux' import Button from '~/components/layout/Button' import { aNewStore, history } from '~/store' -import { addEtherTo } from '~/test/utils/etherMovements' +import { addEtherTo } from '~/test/utils/tokenMovements' import { aDeployedSafe } from '~/routes/safe/store/test/builder/deployedSafe.builder' import { SAFELIST_ADDRESS } from '~/routes/routes' import SafeView from '~/routes/safe/component/Safe' diff --git a/src/routes/safe/test/Safe.withdraw.test.js b/src/routes/safe/test/Safe.withdraw.test.js index 9eb74372..13f7dd97 100644 --- a/src/routes/safe/test/Safe.withdraw.test.js +++ b/src/routes/safe/test/Safe.withdraw.test.js @@ -6,7 +6,7 @@ import { ConnectedRouter } from 'react-router-redux' import { type Match } from 'react-router-dom' import Button from '~/components/layout/Button' import { aNewStore, history } from '~/store' -import { addEtherTo } from '~/test/utils/etherMovements' +import { addEtherTo } from '~/test/utils/tokenMovements' import { aDeployedSafe, executeWithdrawOn } from '~/routes/safe/store/test/builder/deployedSafe.builder' import { SAFELIST_ADDRESS } from '~/routes/routes' import SafeView from '~/routes/safe/component/Safe' diff --git a/src/routes/safe/test/testMultisig.js b/src/routes/safe/test/testMultisig.js index d8bf4c87..c96af663 100644 --- a/src/routes/safe/test/testMultisig.js +++ b/src/routes/safe/test/testMultisig.js @@ -3,7 +3,7 @@ import TestUtils from 'react-dom/test-utils' import { sleep } from '~/utils/timer' import { getBalanceInEtherOf } from '~/wallets/getWeb3' import { ADD_MULTISIG_BUTTON_TEXT, SEE_MULTISIG_BUTTON_TEXT } from '~/routes/safe/component/Safe/MultisigTx' -import { addEtherTo } from '~/test/utils/etherMovements' +import { addEtherTo } from '~/test/utils/tokenMovements' import SafeView from '~/routes/safe/component/Safe' import TransactionsComponent from '~/routes/safe/component/Transactions' import TransactionComponent from '~/routes/safe/component/Transactions/Transaction' diff --git a/src/test/builder/safe.dom.builder.js b/src/test/builder/safe.dom.builder.js index 7a1faf49..818ac60d 100644 --- a/src/test/builder/safe.dom.builder.js +++ b/src/test/builder/safe.dom.builder.js @@ -15,7 +15,7 @@ import { makeProvider } from '~/wallets/store/model/provider' import AppRoutes from '~/routes' import { SAFELIST_ADDRESS } from '~/routes/routes' import { promisify } from '~/utils/promisify' -import { addEtherTo } from '~/test/utils/etherMovements' +import { addEtherTo } from '~/test/utils/tokenMovements' const fillOpenSafeForm = async (localStore: Store) => { const provider = await getProviderInfo() diff --git a/src/test/safe.dom.test.js b/src/test/safe.dom.test.js index eb1fda3b..735c6484 100644 --- a/src/test/safe.dom.test.js +++ b/src/test/safe.dom.test.js @@ -9,7 +9,7 @@ import { sendRemoveOwnerForm, checkMinedRemoveOwnerTx, checkPendingRemoveOwnerTx import { checkMinedThresholdTx, sendChangeThresholdForm, checkThresholdOf } from '~/test/utils/transactions/threshold.helper' import { sendWithdrawForm, checkMinedWithdrawTx } from '~/test/utils/transactions/withdraw.helper' import { processTransaction } from '~/routes/safe/component/Transactions/processTransactions' -import { checkBalanceOf } from '~/test/utils/etherMovements' +import { checkBalanceOf } from '~/test/utils/tokenMovements' describe('DOM > Feature > SAFE MULTISIG TX 1 Owner 1 Threshold', () => { let domSafe: DomSafe diff --git a/src/test/safe.redux.balance.test.js b/src/test/safe.redux.balance.test.js index 29eadfda..a08c8211 100644 --- a/src/test/safe.redux.balance.test.js +++ b/src/test/safe.redux.balance.test.js @@ -1,15 +1,12 @@ // @flow -import contract from 'truffle-contract' import { Map } from 'immutable' import { BALANCE_REDUCER_ID } from '~/routes/safe/store/reducer/balances' -import fetchBalances from '~/routes/safe/store/actions/fetchBalances' +import * as fetchBalancesAction from '~/routes/safe/store/actions/fetchBalances' import { aNewStore } from '~/store' import { aMinedSafe } from '~/test/builder/safe.redux.builder' -import { type Balance } from '~/routes/safe/store/model/balance' -import { addEtherTo } from '~/test/utils/etherMovements' -import Token from '#/test/Token.json' -import { getWeb3 } from '~/wallets/getWeb3' -import { promisify } from '~/utils/promisify' +import { type Balance, makeBalance } from '~/routes/safe/store/model/balance' +import addBalances from '~/routes/safe/store/actions/addBalances' +import { addEtherTo, addTknTo } from '~/test/utils/tokenMovements' describe('Safe Actions[fetchBalance]', () => { let store @@ -24,7 +21,7 @@ describe('Safe Actions[fetchBalance]', () => { const tokenList = ['WE', '<3', 'GNO', 'OMG', 'RDN'] // WHEN - await store.dispatch(fetchBalances(address)) + await store.dispatch(fetchBalancesAction.fetchBalances(address)) // THEN const balances: Map> | typeof undefined = store.getState()[BALANCE_REDUCER_ID] @@ -44,7 +41,7 @@ describe('Safe Actions[fetchBalance]', () => { it('reducer should return 0.03456 ETH as funds to safe with 0.03456 ETH', async () => { // WHEN await addEtherTo(address, '0.03456') - await store.dispatch(fetchBalances(address)) + await store.dispatch(fetchBalancesAction.fetchBalances(address)) // THEN const balances: Map> | typeof undefined = store.getState()[BALANCE_REDUCER_ID] @@ -59,29 +56,32 @@ describe('Safe Actions[fetchBalance]', () => { expect(ethBalance.get('funds')).toBe('0.03456') }) - it('reducer should return 2 GNO when safe has 2 GNO', async () => { + it('reducer should return 100 TKN when safe has 100 TKN', async () => { // GIVEN - const web3 = getWeb3() - const token = contract(Token) - token.setProvider(web3.currentProvider) - const accounts = await promisify(cb => getWeb3().eth.getAccounts(cb)) - const myToken = await token.new({ from: accounts[0], gas: '5000000' }) - await myToken.transfer(address, 100, { from: accounts[0], gas: '5000000' }) + const numTokens = 100 + const tokenAddress = await addTknTo(address, numTokens) - // console.log(await myToken.totalSupply()) // WHEN - await store.dispatch(fetchBalances(address)) + const fetchBalancesMock = jest.spyOn(fetchBalancesAction, 'fetchBalances') + const funds = await fetchBalancesAction.calculateBalanceOf(tokenAddress, address) + + const balances: Map = Map().set('TKN', makeBalance({ + address: tokenAddress, + name: 'Token', + symbol: 'TKN', + decimals: 18, + logoUrl: 'https://github.com/TrustWallet/tokens/blob/master/images/0x6810e776880c02933d47db1b9fc05908e5386b96.png?raw=true', + funds, + })) + fetchBalancesMock.mockImplementation(() => store.dispatch(addBalances(address, balances))) + await store.dispatch(fetchBalancesAction.fetchBalances(address)) + fetchBalancesMock.mockRestore() // THEN - const balances: Map> | typeof undefined = store.getState()[BALANCE_REDUCER_ID] - if (!balances) throw new Error() + const safeBalances = store.getState()[BALANCE_REDUCER_ID].get(address) + expect(safeBalances.size).toBe(1) - const safeBalances: Map | typeof undefined = balances.get(address) - if (!safeBalances) throw new Error() - expect(safeBalances.size).toBe(6) - - const ethBalance = safeBalances.get('ETH') - if (!ethBalance) throw new Error() - expect(ethBalance.get('funds')).toBe('0.03456') + const tknBalance = safeBalances.get('TKN') + expect(tknBalance.get('funds')).toBe(String(numTokens)) }) }) diff --git a/src/test/utils/etherMovements.js b/src/test/utils/tokenMovements.js similarity index 68% rename from src/test/utils/etherMovements.js rename to src/test/utils/tokenMovements.js index c84c34dc..2f3b2506 100644 --- a/src/test/utils/etherMovements.js +++ b/src/test/utils/tokenMovements.js @@ -1,8 +1,10 @@ // @flow +import contract from 'truffle-contract' import { getProviderInfo, getBalanceInEtherOf, getWeb3 } from '~/wallets/getWeb3' import { promisify } from '~/utils/promisify' import withdraw, { DESTINATION_PARAM, VALUE_PARAM } from '~/routes/safe/component/Withdraw/withdraw' import { type Safe } from '~/routes/safe/store/model/safe' +import Token from '#/test/Token.json' export const addEtherTo = async (address: string, eth: string) => { const web3 = getWeb3() @@ -27,3 +29,14 @@ export const checkBalanceOf = async (addressToTest: string, value: string) => { const safeBalance = await getBalanceInEtherOf(addressToTest) expect(safeBalance).toBe(value) } + +export const addTknTo = async (safe: string, value: number) => { + const web3 = getWeb3() + const token = contract(Token) + token.setProvider(web3.currentProvider) + const accounts = await promisify(cb => getWeb3().eth.getAccounts(cb)) + const myToken = await token.new({ from: accounts[0], gas: '5000000' }) + await myToken.transfer(safe, value, { from: accounts[0], gas: '5000000' }) + + return myToken.address +} diff --git a/src/test/utils/transactions/withdraw.helper.js b/src/test/utils/transactions/withdraw.helper.js index d9081f4b..4d4775a2 100644 --- a/src/test/utils/transactions/withdraw.helper.js +++ b/src/test/utils/transactions/withdraw.helper.js @@ -1,7 +1,7 @@ // @flow import TestUtils from 'react-dom/test-utils' import { sleep } from '~/utils/timer' -import { checkBalanceOf } from '~/test/utils/etherMovements' +import { checkBalanceOf } from '~/test/utils/tokenMovements' import { checkMinedTx } from '~/test/builder/safe.dom.utils' export const sendWithdrawForm = ( diff --git a/yarn.lock b/yarn.lock index f1b9bf72..c90bc244 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2921,14 +2921,14 @@ bignumber.js@^7.2.1: version "7.2.1" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" +"bignumber.js@git+https://github.com/debris/bignumber.js#master": + version "2.0.7" + resolved "git+https://github.com/debris/bignumber.js#c7a38de919ed75e6fb6ba38051986e294b328df9" + "bignumber.js@git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2": version "2.0.7" resolved "git+https://github.com/debris/bignumber.js.git#94d7146671b9719e00a09c29b01a691bc85048c2" -"bignumber.js@git+https://github.com/debris/bignumber.js.git#master": - version "2.0.7" - resolved "git+https://github.com/debris/bignumber.js.git#c7a38de919ed75e6fb6ba38051986e294b328df9" - binary-extensions@^1.0.0: version "1.11.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205"