More tests for add/remove liquidity and fix the automatic loading of tokens in those pages

This commit is contained in:
Moody Salem 2020-05-20 22:45:49 -05:00
parent 384c3cada4
commit ccab6f01cf
No known key found for this signature in database
GPG Key ID: 8CB5CD10385138DB
6 changed files with 65 additions and 35 deletions

@ -1,10 +1,19 @@
describe('Add Liquidity', () => {
beforeEach(() =>
cy.visit('/add/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85-0xc778417E063141139Fce010982780140Aa0cD5Ab')
)
it('loads the two correct tokens', () => {
cy.get('#add-liquidity-input-token0 .token-symbol-container').should('contain', 'MKR')
cy.get('#add-liquidity-input-token1 .token-symbol-container').should('contain', 'ETH')
cy.visit('/add/0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85-0xc778417E063141139Fce010982780140Aa0cD5Ab')
cy.get('#add-liquidity-input-token0 .token-symbol-container').should('contain.text', 'MKR')
cy.get('#add-liquidity-input-token1 .token-symbol-container').should('contain.text', 'ETH')
})
it('does not crash if ETH is duplicated', () => {
cy.visit('/add/0xc778417E063141139Fce010982780140Aa0cD5Ab-0xc778417E063141139Fce010982780140Aa0cD5Ab')
cy.get('#add-liquidity-input-token0 .token-symbol-container').should('contain.text', 'ETH')
cy.get('#add-liquidity-input-token1 .token-symbol-container').should('not.contain.text', 'ETH')
})
it('token not in storage is loaded', () => {
cy.visit('/add/0xb290b2f9f8f108d03ff2af3ac5c8de6de31cdf6d-0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85')
cy.get('#add-liquidity-input-token0 .token-symbol-container').should('contain.text', 'SKL')
cy.get('#add-liquidity-input-token1 .token-symbol-container').should('contain.text', 'MKR')
})
})

@ -0,0 +1,19 @@
describe('Remove Liquidity', () => {
it('loads the two correct tokens', () => {
cy.visit('/remove/0xc778417E063141139Fce010982780140Aa0cD5Ab-0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85')
cy.get('#remove-liquidity-token0-symbol').should('contain.text', 'ETH')
cy.get('#remove-liquidity-token1-symbol').should('contain.text', 'MKR')
})
it('does not crash if ETH is duplicated', () => {
cy.visit('/remove/0xc778417E063141139Fce010982780140Aa0cD5Ab-0xc778417E063141139Fce010982780140Aa0cD5Ab')
cy.get('#remove-liquidity-token0-symbol').should('contain.text', 'ETH')
cy.get('#remove-liquidity-token1-symbol').should('not.contain.text', 'ETH')
})
it('token not in storage is loaded', () => {
cy.visit('/remove/0xb290b2f9f8f108d03ff2af3ac5c8de6de31cdf6d-0xF9bA5210F91D0474bd1e1DcDAeC4C58E359AaD85')
cy.get('#remove-liquidity-token0-symbol').should('contain.text', 'SKL')
cy.get('#remove-liquidity-token1-symbol').should('contain.text', 'MKR')
})
})

@ -35,10 +35,13 @@ export function useAllTokens(): { [address: string]: Token } {
}, [userAddedTokens, chainId])
}
export function useToken(tokenAddress: string): Token {
export function useToken(tokenAddress?: string): Token | undefined {
const tokens = useAllTokens()
return tokens?.[tokenAddress]
return useMemo(() => {
const validatedAddress = isAddress(tokenAddress)
if (!validatedAddress) return
return tokens[validatedAddress]
}, [tokens, tokenAddress])
}
// gets token information by address (typically user input) and
@ -46,22 +49,22 @@ export function useToken(tokenAddress: string): Token {
export function useTokenByAddressAndAutomaticallyAdd(tokenAddress?: string): Token | undefined {
const fetchTokenByAddress = useFetchTokenByAddress()
const addToken = useAddUserToken()
const allTokens = useAllTokens()
const token = useToken(tokenAddress)
const { chainId } = useActiveWeb3React()
useEffect(() => {
if (!chainId) return
if (!chainId || !isAddress(tokenAddress)) return
const weth = WETH[chainId as ChainId]
if (weth && weth.address === isAddress(tokenAddress)) return
if (tokenAddress && !allTokens?.[tokenAddress]) {
if (tokenAddress && !token) {
fetchTokenByAddress(tokenAddress).then(token => {
if (token !== null) {
addToken(token)
}
})
}
}, [tokenAddress, allTokens, fetchTokenByAddress, addToken, chainId])
}, [tokenAddress, token, fetchTokenByAddress, addToken, chainId])
return tokenAddress ? allTokens?.[tokenAddress] : undefined
return token
}

@ -27,11 +27,11 @@ import { usePair } from '../../data/Reserves'
import { useTotalSupply } from '../../data/TotalSupply'
import { useTokenContract, useActiveWeb3React } from '../../hooks'
import { useToken } from '../../hooks/Tokens'
import { useTokenByAddressAndAutomaticallyAdd } from '../../hooks/Tokens'
import { useHasPendingApproval, useTransactionAdder } from '../../state/transactions/hooks'
import { useTokenBalanceTreatingWETHasETH } from '../../state/wallet/hooks'
import { TYPE } from '../../theme'
import { calculateGasMargin, calculateSlippageAmount, getRouterContract } from '../../utils'
import { calculateGasMargin, calculateSlippageAmount, getRouterContract, isAddress } from '../../utils'
import AppBody from '../AppBody'
import { Dots, Wrapper } from '../Pool/styleds'
@ -64,14 +64,16 @@ interface AddState {
}
function initializeAddState(inputAddress?: string, outputAddress?: string): AddState {
const validatedInput = isAddress(inputAddress)
const validatedOutput = isAddress(outputAddress)
return {
independentField: Field.INPUT,
typedValue: '',
[Field.INPUT]: {
address: inputAddress
address: validatedInput || ''
},
[Field.OUTPUT]: {
address: outputAddress
address: validatedOutput && validatedOutput !== validatedInput ? validatedOutput : ''
}
}
}
@ -152,10 +154,13 @@ export default function AddLiquidity({ match: { params } }: RouteComponentProps<
const { independentField, typedValue, ...fieldData } = state
const dependentField: Field = independentField === Field.INPUT ? Field.OUTPUT : Field.INPUT
const inputToken = useTokenByAddressAndAutomaticallyAdd(fieldData[Field.INPUT].address)
const outputToken = useTokenByAddressAndAutomaticallyAdd(fieldData[Field.OUTPUT].address)
// get basic SDK entities
const tokens: { [field in Field]: Token } = {
[Field.INPUT]: useToken(fieldData[Field.INPUT].address),
[Field.OUTPUT]: useToken(fieldData[Field.OUTPUT].address)
[Field.INPUT]: inputToken,
[Field.OUTPUT]: outputToken
}
// token contracts for approvals and direct sends

@ -106,14 +106,6 @@ function reducer(
}
}
function useTokenByAddressOrETHAndAutomaticallyAdd(tokenId?: string, chainId?: number): Token | undefined {
const isWETH = tokenId?.toUpperCase() === 'ETH' || tokenId?.toUpperCase() === 'WETH'
const tokenByAddress = useTokenByAddressAndAutomaticallyAdd(isWETH ? null : tokenId)
return isWETH ? WETH[chainId] : tokenByAddress
}
export default function RemoveLiquidity({ match: { params } }: RouteComponentProps<{ tokens: string }>) {
const [token0, token1] = params.tokens.split('-')
@ -123,13 +115,13 @@ export default function RemoveLiquidity({ match: { params } }: RouteComponentPro
const [showConfirm, setShowConfirm] = useState<boolean>(false)
const [showAdvanced, setShowAdvanced] = useState<boolean>(false)
const inputToken: Token = useTokenByAddressOrETHAndAutomaticallyAdd(token0, chainId)
const outputToken: Token = useTokenByAddressOrETHAndAutomaticallyAdd(token1, chainId)
const inputToken: Token = useTokenByAddressAndAutomaticallyAdd(token0)
const outputToken: Token = useTokenByAddressAndAutomaticallyAdd(token1)
// get basic SDK entities
const tokens: { [field in Field]?: Token } = {
[Field.TOKEN0]: inputToken,
[Field.TOKEN1]: outputToken
[Field.TOKEN1]: outputToken && inputToken && outputToken.equals(inputToken) ? undefined : outputToken
}
const pair = usePair(inputToken, outputToken)
@ -726,7 +718,7 @@ export default function RemoveLiquidity({ match: { params } }: RouteComponentPro
</Text>
<RowFixed>
<TokenLogo address={tokens[Field.TOKEN0]?.address} style={{ marginRight: '12px' }} />
<Text fontSize={24} fontWeight={500}>
<Text fontSize={24} fontWeight={500} id="remove-liquidity-token0-symbol">
{tokens[Field.TOKEN0]?.symbol}
</Text>
</RowFixed>
@ -737,7 +729,7 @@ export default function RemoveLiquidity({ match: { params } }: RouteComponentPro
</Text>
<RowFixed>
<TokenLogo address={tokens[Field.TOKEN1]?.address} style={{ marginRight: '12px' }} />
<Text fontSize={24} fontWeight={500}>
<Text fontSize={24} fontWeight={500} id="remove-liquidity-token1-symbol">
{tokens[Field.TOKEN1]?.symbol}
</Text>
</RowFixed>

@ -3,7 +3,7 @@ import { useActiveWeb3React } from '../../hooks'
import { useCallback, useMemo } from 'react'
import { shallowEqual, useDispatch, useSelector } from 'react-redux'
import { useAllTokens } from '../../hooks/Tokens'
import { getTokenDecimals, getTokenName, getTokenSymbol } from '../../utils'
import { getTokenDecimals, getTokenName, getTokenSymbol, isAddress } from '../../utils'
import { AppDispatch, AppState } from '../index'
import {
addSerializedPair,
@ -67,6 +67,8 @@ export function useFetchTokenByAddress(): (address: string) => Promise<Token | n
return useCallback(
async (address: string): Promise<Token | null> => {
if (!library || !chainId) return null
const validatedAddress = isAddress(address)
if (!validatedAddress) return null
const [decimals, symbol, name] = await Promise.all([
getTokenDecimals(address, library).catch(() => null),
getTokenSymbol(address, library).catch(() => 'UNKNOWN'),
@ -76,7 +78,7 @@ export function useFetchTokenByAddress(): (address: string) => Promise<Token | n
if (decimals === null) {
return null
} else {
return new Token(chainId, address, decimals, symbol, name)
return new Token(chainId, validatedAddress, decimals, symbol, name)
}
},
[library, chainId]