mirror of
https://github.com/status-im/safe-react.git
synced 2025-02-06 14:53:30 +00:00
WA-232 DOM test for simulating adding a custom ERC20 token
This commit is contained in:
parent
69ef967481
commit
1e57ed5d53
@ -2,11 +2,10 @@
|
|||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import Stepper from '~/components/Stepper'
|
import Stepper from '~/components/Stepper'
|
||||||
import { getHumanFriendlyToken } from '~/routes/tokens/store/actions/fetchTokens'
|
import { getHumanFriendlyToken } from '~/routes/tokens/store/actions/fetchTokens'
|
||||||
import FirstPage, { TOKEN_ADDRESS_PARAM } from '~/routes/tokens/component/AddToken/FirstPage'
|
import FirstPage, { TOKEN_ADRESS_PARAM } from '~/routes/tokens/component/AddToken/FirstPage'
|
||||||
import SecondPage, { TOKEN_SYMBOL_PARAM, TOKEN_DECIMALS_PARAM, TOKEN_LOGO_URL_PARAM, TOKEN_NAME_PARAM } from '~/routes/tokens/component/AddToken/SecondPage'
|
import SecondPage, { TOKEN_SYMBOL_PARAM, TOKEN_DECIMALS_PARAM, TOKEN_LOGO_URL_PARAM, TOKEN_NAME_PARAM } from '~/routes/tokens/component/AddToken/SecondPage'
|
||||||
import { makeToken, type Token } from '~/routes/tokens/store/model/token'
|
import { makeToken, type Token } from '~/routes/tokens/store/model/token'
|
||||||
import addTokenAction from '~/routes/tokens/store/actions/addToken'
|
import addTokenAction from '~/routes/tokens/store/actions/addToken'
|
||||||
import enableTokenAction from '~/routes/tokens/store/actions/enableToken'
|
|
||||||
import Review from './Review'
|
import Review from './Review'
|
||||||
|
|
||||||
export const getSteps = () => [
|
export const getSteps = () => [
|
||||||
@ -17,7 +16,6 @@ type Props = {
|
|||||||
tokens: string[],
|
tokens: string[],
|
||||||
safeAddress: string,
|
safeAddress: string,
|
||||||
addToken: typeof addTokenAction,
|
addToken: typeof addTokenAction,
|
||||||
enableToken: typeof enableTokenAction,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
@ -26,8 +24,8 @@ type State = {
|
|||||||
|
|
||||||
export const ADD_TOKEN_RESET_BUTTON_TEXT = 'RESET'
|
export const ADD_TOKEN_RESET_BUTTON_TEXT = 'RESET'
|
||||||
|
|
||||||
export const addTokenFnc = async (values: Object, addToken, enableToken, safeAddress: string) => {
|
export const addTokenFnc = async (values: Object, addToken, safeAddress: string) => {
|
||||||
const address = values[TOKEN_ADDRESS_PARAM]
|
const address = values[TOKEN_ADRESS_PARAM]
|
||||||
const name = values[TOKEN_NAME_PARAM]
|
const name = values[TOKEN_NAME_PARAM]
|
||||||
const symbol = values[TOKEN_SYMBOL_PARAM]
|
const symbol = values[TOKEN_SYMBOL_PARAM]
|
||||||
const decimals = values[TOKEN_DECIMALS_PARAM]
|
const decimals = values[TOKEN_DECIMALS_PARAM]
|
||||||
@ -43,7 +41,6 @@ export const addTokenFnc = async (values: Object, addToken, enableToken, safeAdd
|
|||||||
removable: true,
|
removable: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
await enableToken(safeAddress, token)
|
|
||||||
return addToken(safeAddress, token)
|
return addToken(safeAddress, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,9 +50,9 @@ class AddToken extends React.Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAddToken = async (values: Object) => {
|
onAddToken = async (values: Object) => {
|
||||||
const { addToken, enableToken, safeAddress } = this.props
|
const { addToken, safeAddress } = this.props
|
||||||
|
|
||||||
return addTokenFnc(values, addToken, enableToken, safeAddress)
|
return addTokenFnc(values, addToken, safeAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
onReset = () => {
|
onReset = () => {
|
||||||
@ -63,7 +60,7 @@ class AddToken extends React.Component<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fetchInitialPropsSecondPage = async (values: Object) => {
|
fetchInitialPropsSecondPage = async (values: Object) => {
|
||||||
const tokenAddress = values[TOKEN_ADDRESS_PARAM]
|
const tokenAddress = values[TOKEN_ADRESS_PARAM]
|
||||||
const erc20Token = await getHumanFriendlyToken()
|
const erc20Token = await getHumanFriendlyToken()
|
||||||
const instance = await erc20Token.at(tokenAddress)
|
const instance = await erc20Token.at(tokenAddress)
|
||||||
|
|
||||||
|
@ -38,14 +38,11 @@ class TokenLayout extends React.PureComponent<TokenProps, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAddToken = () => {
|
onAddToken = () => {
|
||||||
const {
|
const { addresses, safeAddress, addToken } = this.props
|
||||||
addresses, safeAddress, addToken, enableToken,
|
|
||||||
} = this.props
|
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
component: <AddToken
|
component: <AddToken
|
||||||
addToken={addToken}
|
addToken={addToken}
|
||||||
enableToken={enableToken}
|
|
||||||
tokens={addresses.toArray()}
|
tokens={addresses.toArray()}
|
||||||
safeAddress={safeAddress}
|
safeAddress={safeAddress}
|
||||||
/>,
|
/>,
|
||||||
@ -80,12 +77,14 @@ class TokenLayout extends React.PureComponent<TokenProps, State> {
|
|||||||
<Row grow>
|
<Row grow>
|
||||||
<Col sm={12} top="xs" md={5} margin="xl" overflow>
|
<Col sm={12} top="xs" md={5} margin="xl" overflow>
|
||||||
<MuiList style={listStyle}>
|
<MuiList style={listStyle}>
|
||||||
{tokens.map((token: Token) => (<TokenComponent
|
{tokens.map((token: Token) => (
|
||||||
|
<TokenComponent
|
||||||
key={token.get('address')}
|
key={token.get('address')}
|
||||||
token={token}
|
token={token}
|
||||||
onDisableToken={this.onDisableToken}
|
onDisableToken={this.onDisableToken}
|
||||||
onEnableToken={this.onEnableToken}
|
onEnableToken={this.onEnableToken}
|
||||||
/>))}
|
/>
|
||||||
|
))}
|
||||||
</MuiList>
|
</MuiList>
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm={12} center="xs" md={7} margin="xl" layout="column">
|
<Col sm={12} center="xs" md={7} margin="xl" layout="column">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// @flow
|
// @flow
|
||||||
import addToken from '~/routes/tokens/store/actions/addTokens'
|
import addToken from '~/routes/tokens/store/actions/addToken'
|
||||||
import enableToken from '~/routes/tokens/store/actions/enableToken'
|
import enableToken from '~/routes/tokens/store/actions/enableToken'
|
||||||
import disableToken from '~/routes/tokens/store/actions/disableToken'
|
import disableToken from '~/routes/tokens/store/actions/disableToken'
|
||||||
import { fetchTokens } from '~/routes/tokens/store/actions/fetchTokens'
|
import { fetchTokens } from '~/routes/tokens/store/actions/fetchTokens'
|
||||||
|
@ -33,11 +33,12 @@ export default handleActions({
|
|||||||
},
|
},
|
||||||
[ADD_TOKEN]: (state: State, action: ActionType<typeof addToken>): State => {
|
[ADD_TOKEN]: (state: State, action: ActionType<typeof addToken>): State => {
|
||||||
const { safeAddress, token } = action.payload
|
const { safeAddress, token } = action.payload
|
||||||
const activeTokens = getActiveTokenAddresses(safeAddress)
|
|
||||||
activeTokens.push(token.get('address'))
|
|
||||||
setActiveTokenAddresses(activeTokens)
|
|
||||||
|
|
||||||
return state.setIn([safeAddress, token.get('address')], token)
|
const tokenAddress = token.get('address')
|
||||||
|
const activeTokens = getActiveTokenAddresses(safeAddress)
|
||||||
|
setActiveTokenAddresses(safeAddress, activeTokens.push(tokenAddress))
|
||||||
|
|
||||||
|
return state.setIn([safeAddress, tokenAddress], token)
|
||||||
},
|
},
|
||||||
[DISABLE_TOKEN]: (state: State, action: ActionType<typeof disableToken>): State => {
|
[DISABLE_TOKEN]: (state: State, action: ActionType<typeof disableToken>): State => {
|
||||||
const { address, safeAddress } = action.payload
|
const { address, safeAddress } = action.payload
|
||||||
|
94
src/test/tokens.dom.adding.test.js
Normal file
94
src/test/tokens.dom.adding.test.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// @flow
|
||||||
|
import * as TestUtils from 'react-dom/test-utils'
|
||||||
|
import AddToken from '~/routes/tokens/component/AddToken'
|
||||||
|
import { getWeb3 } from '~/wallets/getWeb3'
|
||||||
|
import { type Match } from 'react-router-dom'
|
||||||
|
import { promisify } from '~/utils/promisify'
|
||||||
|
import TokenComponent from '~/routes/tokens/component/Token'
|
||||||
|
import { getFirstTokenContract, getSecondTokenContract } from '~/test/utils/tokenMovements'
|
||||||
|
import { aNewStore } from '~/store'
|
||||||
|
import { aMinedSafe } from '~/test/builder/safe.redux.builder'
|
||||||
|
import { travelToTokens } from '~/test/builder/safe.dom.utils'
|
||||||
|
import { sleep } from '~/utils/timer'
|
||||||
|
import { buildMathPropsFrom } from '~/test/utils/buildReactRouterProps'
|
||||||
|
import { tokenListSelector } from '~/routes/tokens/store/selectors'
|
||||||
|
import { testToken } from '~/test/builder/tokens.dom.utils'
|
||||||
|
import * as fetchTokensModule from '~/routes/tokens/store/actions/fetchTokens'
|
||||||
|
import * as enhancedFetchModule from '~/utils/fetch'
|
||||||
|
|
||||||
|
describe('DOM > Feature > Add new ERC 20 Tokens', () => {
|
||||||
|
let web3
|
||||||
|
let accounts
|
||||||
|
let firstErc20Token
|
||||||
|
let secondErc20Token
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
web3 = getWeb3()
|
||||||
|
accounts = await promisify(cb => web3.eth.getAccounts(cb))
|
||||||
|
firstErc20Token = await getFirstTokenContract(web3, accounts[0])
|
||||||
|
secondErc20Token = await getSecondTokenContract(web3, accounts[0])
|
||||||
|
|
||||||
|
// $FlowFixMe
|
||||||
|
enhancedFetchModule.enhancedFetch = jest.fn()
|
||||||
|
enhancedFetchModule.enhancedFetch.mockImplementation(() => Promise.resolve([
|
||||||
|
{
|
||||||
|
address: firstErc20Token.address,
|
||||||
|
name: 'First Token Example',
|
||||||
|
symbol: 'FTE',
|
||||||
|
decimals: 18,
|
||||||
|
logoUrl: 'https://upload.wikimedia.org/wikipedia/commons/c/c0/Earth_simple_icon.png',
|
||||||
|
},
|
||||||
|
]))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('adds a second erc 20 token filling the form', async () => {
|
||||||
|
// GIVEN
|
||||||
|
const store = aNewStore()
|
||||||
|
const safeAddress = await aMinedSafe(store)
|
||||||
|
await store.dispatch(fetchTokensModule.fetchTokens(safeAddress))
|
||||||
|
const TokensDom = await travelToTokens(store, safeAddress)
|
||||||
|
await sleep(400)
|
||||||
|
const tokens = TestUtils.scryRenderedComponentsWithType(TokensDom, TokenComponent)
|
||||||
|
expect(tokens.length).toBe(2)
|
||||||
|
testToken(tokens[0].props.token, 'FTE', false)
|
||||||
|
testToken(tokens[1].props.token, 'ETH', true)
|
||||||
|
|
||||||
|
// WHEN
|
||||||
|
// $FlowFixMe
|
||||||
|
const buttons = TestUtils.scryRenderedDOMComponentsWithTag(TokensDom, 'button')
|
||||||
|
expect(buttons.length).toBe(1)
|
||||||
|
TestUtils.Simulate.click(buttons[0])
|
||||||
|
await sleep(400)
|
||||||
|
|
||||||
|
// fill the form
|
||||||
|
const AddTokenComponent = TestUtils.findRenderedComponentWithType(TokensDom, AddToken)
|
||||||
|
let inputs = TestUtils.scryRenderedDOMComponentsWithTag(AddTokenComponent, 'input')
|
||||||
|
expect(inputs.length).toBe(1)
|
||||||
|
const tokenAddressInput = inputs[0]
|
||||||
|
TestUtils.Simulate.change(tokenAddressInput, { target: { value: `${secondErc20Token.address}` } })
|
||||||
|
// $FlowFixMe
|
||||||
|
let form = TestUtils.findRenderedDOMComponentWithTag(AddTokenComponent, 'form')
|
||||||
|
// submit it
|
||||||
|
TestUtils.Simulate.submit(form)
|
||||||
|
await sleep(2500)
|
||||||
|
|
||||||
|
inputs = TestUtils.scryRenderedDOMComponentsWithTag(AddTokenComponent, 'input')
|
||||||
|
expect(inputs.length).toBe(4)
|
||||||
|
|
||||||
|
TestUtils.Simulate.change(inputs[3], { target: { value: 'https://my.token.image/foo' } })
|
||||||
|
|
||||||
|
form = TestUtils.findRenderedDOMComponentWithTag(AddTokenComponent, 'form')
|
||||||
|
// submit it
|
||||||
|
TestUtils.Simulate.submit(form)
|
||||||
|
TestUtils.Simulate.submit(form)
|
||||||
|
|
||||||
|
await sleep(1200)
|
||||||
|
const match: Match = buildMathPropsFrom(safeAddress)
|
||||||
|
const tokenList = tokenListSelector(store.getState(), { match })
|
||||||
|
expect(tokenList.count()).toBe(3)
|
||||||
|
|
||||||
|
testToken(tokenList.get(0), 'FTE', false)
|
||||||
|
testToken(tokenList.get(1), 'ETH', true)
|
||||||
|
testToken(tokenList.get(2), 'TKN', true)
|
||||||
|
})
|
||||||
|
})
|
Loading…
x
Reference in New Issue
Block a user