add a test for adding custom token
This commit is contained in:
parent
4b0cac5eb0
commit
4625ed1aa5
|
@ -29,6 +29,7 @@ class TextField extends React.PureComponent<TextFieldProps> {
|
|||
text,
|
||||
inputAdornment,
|
||||
classes,
|
||||
testId,
|
||||
...rest
|
||||
} = this.props
|
||||
const helperText = value ? text : undefined
|
||||
|
@ -36,7 +37,7 @@ class TextField extends React.PureComponent<TextFieldProps> {
|
|||
const underline = meta.active || (meta.visited && !meta.valid)
|
||||
|
||||
const inputRoot = helperText ? classes.root : undefined
|
||||
const inputProps = { ...restInput, autoComplete: 'off' }
|
||||
const inputProps = { ...restInput, autoComplete: 'off', 'data-testid': testId }
|
||||
const inputRootProps = { ...inputAdornment, disableUnderline: !underline, className: inputRoot }
|
||||
|
||||
return (
|
||||
|
@ -51,6 +52,7 @@ class TextField extends React.PureComponent<TextFieldProps> {
|
|||
inputProps={inputProps}
|
||||
onChange={onChange}
|
||||
value={value}
|
||||
// data-testid={testId}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ const styles = {
|
|||
type Props = {
|
||||
minWidth?: number,
|
||||
minHeight?: number,
|
||||
testId: string,
|
||||
}
|
||||
|
||||
const calculateStyleBased = (minWidth, minHeight) => ({
|
||||
|
@ -19,10 +20,10 @@ const calculateStyleBased = (minWidth, minHeight) => ({
|
|||
minHeight: minHeight && `${minHeight}px`,
|
||||
})
|
||||
|
||||
const GnoButton = ({ minWidth, minHeight, ...props }: Props) => {
|
||||
const GnoButton = ({ minWidth, minHeight, testId = '', ...props }: Props) => {
|
||||
const style = calculateStyleBased(minWidth, minHeight)
|
||||
|
||||
return <Button style={style} {...props} />
|
||||
return <Button style={style} data-testid={testId} {...props} />
|
||||
}
|
||||
|
||||
export default withStyles(styles)(GnoButton)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// @flow
|
||||
/* eslint-disable react/button-has-type */
|
||||
/* eslint-disable react/default-props-match-prop-types */
|
||||
import * as React from 'react'
|
||||
import cn from 'classnames/bind'
|
||||
import styles from './index.scss'
|
||||
|
@ -12,20 +11,16 @@ type Props = {
|
|||
size?: 'sm' | 'md' | 'lg' | 'xl' | 'xxl',
|
||||
weight?: 'light' | 'regular' | 'bolder' | 'bold',
|
||||
color?: 'soft' | 'medium' | 'dark' | 'white' | 'fancy' | 'primary' | 'secondary' | 'warning' | 'disabled',
|
||||
testId?: string,
|
||||
}
|
||||
|
||||
const GnoButtonLink = ({
|
||||
type, size, weight, color, ...props
|
||||
}: Props) => (
|
||||
<button type={type} className={cx(styles.btnLink, size, color, weight)} {...props} />
|
||||
)
|
||||
|
||||
|
||||
GnoButtonLink.defaultProps = {
|
||||
type: 'button',
|
||||
size: 'md',
|
||||
weight: 'regular',
|
||||
color: 'secondary',
|
||||
}
|
||||
type = 'button',
|
||||
size = 'md',
|
||||
weight = 'regular',
|
||||
color = 'secondary',
|
||||
testId = '',
|
||||
...props
|
||||
}: Props) => <button type={type} className={cx(styles.btnLink, size, color, weight)} data-testid={testId} {...props} />
|
||||
|
||||
export default GnoButtonLink
|
||||
|
|
|
@ -23,6 +23,11 @@ import { addressIsTokenContract, doesntExistInTokenList } from './validators'
|
|||
import { styles } from './style'
|
||||
import { getSymbolAndDecimalsFromContract } from './utils'
|
||||
|
||||
export const ADD_CUSTOM_TOKEN_ADDRESS_INPUT_TEST_ID = 'add-custom-token-address-input'
|
||||
export const ADD_CUSTOM_TOKEN_SYMBOLS_INPUT_TEST_ID = 'add-custom-token-symbols-input'
|
||||
export const ADD_CUSTOM_TOKEN_DECIMALS_INPUT_TEST_ID = 'add-custom-token-decimals-input'
|
||||
export const ADD_CUSTOM_TOKEN_FORM = 'add-custom-token-form'
|
||||
|
||||
type Props = {
|
||||
classes: Object,
|
||||
addToken: Function,
|
||||
|
@ -115,7 +120,7 @@ const AddCustomToken = (props: Props) => {
|
|||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<GnoForm onSubmit={handleSubmit} initialValues={formValues}>
|
||||
<GnoForm onSubmit={handleSubmit} initialValues={formValues} testId={ADD_CUSTOM_TOKEN_FORM}>
|
||||
{() => (
|
||||
<React.Fragment>
|
||||
<Block className={classes.formContainer}>
|
||||
|
@ -135,6 +140,7 @@ const AddCustomToken = (props: Props) => {
|
|||
placeholder="Token contract address*"
|
||||
text="Token contract address*"
|
||||
className={classes.addressInput}
|
||||
testId={ADD_CUSTOM_TOKEN_ADDRESS_INPUT_TEST_ID}
|
||||
/>
|
||||
<FormSpy
|
||||
subscription={{
|
||||
|
@ -156,6 +162,7 @@ const AddCustomToken = (props: Props) => {
|
|||
placeholder="Token symbol*"
|
||||
text="Token symbol"
|
||||
className={classes.addressInput}
|
||||
testId={ADD_CUSTOM_TOKEN_SYMBOLS_INPUT_TEST_ID}
|
||||
/>
|
||||
<Field
|
||||
name="decimals"
|
||||
|
@ -165,6 +172,7 @@ const AddCustomToken = (props: Props) => {
|
|||
placeholder="Token decimals*"
|
||||
text="Token decimals*"
|
||||
className={classes.addressInput}
|
||||
testId={ADD_CUSTOM_TOKEN_DECIMALS_INPUT_TEST_ID}
|
||||
/>
|
||||
<Block align="left">
|
||||
<Field name="showForAllSafes" component={Checkbox} type="checkbox" className={classes.checkbox} />
|
||||
|
|
|
@ -24,6 +24,8 @@ import { type Token } from '~/logic/tokens/store/model/token'
|
|||
import { setImageToPlaceholder } from '~/routes/safe/components/Balances/utils'
|
||||
import { styles } from './style'
|
||||
|
||||
export const ADD_CUSTOM_TOKEN_BUTTON_TEST_ID = 'add-custom-token-btn'
|
||||
|
||||
type Props = {
|
||||
classes: Object,
|
||||
tokens: List<Token>,
|
||||
|
@ -141,6 +143,7 @@ class Tokens extends React.Component<Props, State> {
|
|||
color="secondary"
|
||||
className={classes.add}
|
||||
onClick={switchToAddCustomTokenScreen}
|
||||
testId={ADD_CUSTOM_TOKEN_BUTTON_TEST_ID}
|
||||
>
|
||||
+ ADD CUSTOM TOKEN
|
||||
</Button>
|
||||
|
|
|
@ -26,6 +26,9 @@ import SendModal from './SendModal'
|
|||
import Receive from './Receive'
|
||||
import { styles } from './style'
|
||||
|
||||
export const MANAGE_TOKENS_BUTTON_TEST_ID = 'manage-tokens-btn'
|
||||
export const BALANCE_ROW_TEST_ID = 'balance-row'
|
||||
|
||||
type State = {
|
||||
hideZero: boolean,
|
||||
showToken: boolean,
|
||||
|
@ -128,7 +131,7 @@ class Balances extends React.Component<Props, State> {
|
|||
<Paragraph className={classes.zero}>Hide zero balances</Paragraph>
|
||||
</Col>
|
||||
<Col xs={6} end="sm">
|
||||
<ButtonLink onClick={this.onShow('Token')}>Manage Tokens</ButtonLink>
|
||||
<ButtonLink onClick={this.onShow('Token')} testId="manage-tokens-btn">Manage Tokens</ButtonLink>
|
||||
<Modal
|
||||
title="Manage Tokens"
|
||||
description="Enable and disable tokens to be listed"
|
||||
|
@ -153,7 +156,7 @@ class Balances extends React.Component<Props, State> {
|
|||
defaultFixed
|
||||
>
|
||||
{(sortedData: Array<BalanceRow>) => sortedData.map((row: any, index: number) => (
|
||||
<TableRow tabIndex={-1} key={index} className={classes.hide} data-testid="balance-row">
|
||||
<TableRow tabIndex={-1} key={index} className={classes.hide} data-testid={BALANCE_ROW_TEST_ID}>
|
||||
{autoColumns.map((column: Column) => (
|
||||
<TableCell key={column.id} style={cellWidth(column.width)} align={column.align} component="td">
|
||||
{column.id === BALANCE_TABLE_ASSET_ID ? <AssetTableCell asset={row[column.id]} /> : row[column.id]}
|
||||
|
|
|
@ -13,6 +13,7 @@ import { calculateBalanceOf } from '~/routes/safe/store/actions/fetchTokenBalanc
|
|||
import updateActiveTokens from '~/routes/safe/store/actions/updateActiveTokens'
|
||||
import 'jest-dom/extend-expect'
|
||||
import updateSafe from '~/routes/safe/store/actions/updateSafe'
|
||||
import { BALANCE_ROW_TEST_ID } from '~/routes/safe/components/Balances'
|
||||
|
||||
afterEach(cleanup)
|
||||
|
||||
|
@ -37,7 +38,7 @@ describe('DOM > Feature > Funds', () => {
|
|||
await sleep(1300)
|
||||
|
||||
// Open send funds modal
|
||||
const balanceRows = SafeDom.getAllByTestId('balance-row')
|
||||
const balanceRows = SafeDom.getAllByTestId(BALANCE_ROW_TEST_ID)
|
||||
expect(balanceRows[0]).toHaveTextContent(`${ethAmount} ETH`)
|
||||
const sendButton = SafeDom.getByTestId('balance-send-btn')
|
||||
fireEvent.click(sendButton)
|
||||
|
@ -91,7 +92,7 @@ describe('DOM > Feature > Funds', () => {
|
|||
await sleep(1000)
|
||||
|
||||
// Open send funds modal
|
||||
const balanceRows = SafeDom.getAllByTestId('balance-row')
|
||||
const balanceRows = SafeDom.getAllByTestId(BALANCE_ROW_TEST_ID)
|
||||
expect(balanceRows.length).toBe(2)
|
||||
const sendButtons = SafeDom.getAllByTestId('balance-send-btn')
|
||||
expect(sendButtons.length).toBe(2)
|
||||
|
|
|
@ -1,65 +1,83 @@
|
|||
// @flow
|
||||
import { getWeb3 } from '~/logic/wallets/getWeb3'
|
||||
import { type Match } from 'react-router-dom'
|
||||
import { getFirstTokenContract, getSecondTokenContract } from '~/test/utils/tokenMovements'
|
||||
import { fireEvent } from '@testing-library/react'
|
||||
import { getFirstTokenContract } 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 { renderSafeView } from '~/test/builder/safe.dom.utils'
|
||||
import { sleep } from '~/utils/timer'
|
||||
import { buildMatchPropsFrom } from '~/test/utils/buildReactRouterProps'
|
||||
import { tokenListSelector } from '~/logic/tokens/store/selectors'
|
||||
import { testToken } from '~/test/builder/tokens.dom.utils'
|
||||
import { clickOnManageTokens, clickOnAddCustomToken } from '~/test/utils/DOMNavigation'
|
||||
import * as fetchTokensModule from '~/logic/tokens/store/actions/fetchTokens'
|
||||
import * as enhancedFetchModule from '~/utils/fetch'
|
||||
import {
|
||||
ADD_CUSTOM_TOKEN_ADDRESS_INPUT_TEST_ID,
|
||||
ADD_CUSTOM_TOKEN_SYMBOLS_INPUT_TEST_ID,
|
||||
ADD_CUSTOM_TOKEN_DECIMALS_INPUT_TEST_ID,
|
||||
ADD_CUSTOM_TOKEN_FORM,
|
||||
} from '~/routes/safe/components/Balances/Tokens/screens/AddCustomToken'
|
||||
import { BALANCE_ROW_TEST_ID } from '~/routes/safe/components/Balances/'
|
||||
import 'jest-dom/extend-expect'
|
||||
|
||||
describe('DOM > Feature > Add new ERC 20 Tokens', () => {
|
||||
// https://github.com/testing-library/@testing-library/react/issues/281
|
||||
const originalError = console.error
|
||||
beforeAll(() => {
|
||||
console.error = (...args) => {
|
||||
if (/Warning.*not wrapped in act/.test(args[0])) {
|
||||
return
|
||||
}
|
||||
originalError.call(console, ...args)
|
||||
}
|
||||
})
|
||||
|
||||
afterAll(() => {
|
||||
console.error = originalError
|
||||
})
|
||||
|
||||
describe('DOM > Feature > Add custom ERC 20 Tokens', () => {
|
||||
let web3
|
||||
let accounts
|
||||
let firstErc20Token
|
||||
let secondErc20Token
|
||||
let erc20Token
|
||||
|
||||
beforeAll(async () => {
|
||||
web3 = getWeb3()
|
||||
accounts = await web3.eth.getAccounts()
|
||||
firstErc20Token = await getFirstTokenContract(web3, accounts[0])
|
||||
secondErc20Token = await getSecondTokenContract(web3, accounts[0])
|
||||
|
||||
// $FlowFixMe
|
||||
enhancedFetchModule.enhancedFetch = jest.fn()
|
||||
enhancedFetchModule.enhancedFetch.mockImplementation(() => Promise.resolve({
|
||||
results: [
|
||||
{
|
||||
address: firstErc20Token.address,
|
||||
name: 'First Token Example',
|
||||
symbol: 'FTE',
|
||||
decimals: 18,
|
||||
logoUri: 'https://upload.wikimedia.org/wikipedia/commons/c/c0/Earth_simple_icon.png',
|
||||
},
|
||||
],
|
||||
}))
|
||||
erc20Token = await getFirstTokenContract(web3, accounts[0])
|
||||
})
|
||||
|
||||
it('adds a second erc 20 token filling the form', async () => {
|
||||
it('adds and displays an erc 20 token after 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 store.dispatch(fetchTokensModule.fetchTokens())
|
||||
const TokensDom = renderSafeView(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
|
||||
await clickOnAddToken(TokensDom)
|
||||
await fillAddress(TokensDom, secondErc20Token)
|
||||
await fillHumanReadableInfo(TokensDom)
|
||||
// THEN
|
||||
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)
|
||||
clickOnManageTokens(TokensDom)
|
||||
clickOnAddCustomToken(TokensDom)
|
||||
await sleep(200)
|
||||
|
||||
// Fill address
|
||||
const addTokenForm = TokensDom.getByTestId(ADD_CUSTOM_TOKEN_FORM)
|
||||
const addressInput = TokensDom.getByTestId(ADD_CUSTOM_TOKEN_ADDRESS_INPUT_TEST_ID)
|
||||
fireEvent.change(addressInput, { target: { value: erc20Token.address } })
|
||||
await sleep(500)
|
||||
|
||||
// Check if it loaded symbol/decimals correctly
|
||||
const symbolInput = TokensDom.getByTestId(ADD_CUSTOM_TOKEN_SYMBOLS_INPUT_TEST_ID)
|
||||
const decimalsInput = TokensDom.getByTestId(ADD_CUSTOM_TOKEN_DECIMALS_INPUT_TEST_ID)
|
||||
|
||||
const tokenSymbol = await erc20Token.symbol()
|
||||
const tokenDecimals = await erc20Token.decimals()
|
||||
expect(symbolInput.value).toBe(tokenSymbol)
|
||||
expect(decimalsInput.value).toBe(tokenDecimals.toString())
|
||||
|
||||
// Submit form
|
||||
fireEvent.submit(addTokenForm)
|
||||
await sleep(300)
|
||||
|
||||
// check if token is displayed
|
||||
const balanceRows = TokensDom.getAllByTestId(BALANCE_ROW_TEST_ID)
|
||||
expect(balanceRows.length).toBe(2)
|
||||
expect(balanceRows[1]).toHaveTextContent(tokenSymbol)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
// @flow
|
||||
import { fireEvent } from '@testing-library/reactß'
|
||||
import { fireEvent } from '@testing-library/react'
|
||||
import { MANAGE_TOKENS_BUTTON_TEST_ID } from '~/routes/safe/components/Balances'
|
||||
import { ADD_CUSTOM_TOKEN_BUTTON_TEST_ID } from '~/routes/safe/components/Balances/Tokens/screens/TokenList'
|
||||
|
||||
const clickOnManageTokens = (dom) => {
|
||||
const btn = dom.findByTestId()
|
||||
export const clickOnManageTokens = (dom: any): void => {
|
||||
const btn = dom.getByTestId(MANAGE_TOKENS_BUTTON_TEST_ID)
|
||||
|
||||
|
||||
}
|
||||
fireEvent.click(btn)
|
||||
}
|
||||
|
||||
export const clickOnAddCustomToken = (dom: any): void => {
|
||||
const btn = dom.getByTestId(ADD_CUSTOM_TOKEN_BUTTON_TEST_ID)
|
||||
|
||||
fireEvent.click(btn)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue