Skip to content

Commit b1ffab1

Browse files
authored
Refactors (Uniswap#772)
* Bunch of refactoring * Add an integration test that gets as far as swapping * Drop the nonce code that isn't doing anything right now * Undo one of the accidental changes to the reducer
1 parent 60582de commit b1ffab1

18 files changed

Lines changed: 212 additions & 274 deletions

File tree

cypress/integration/landing.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ import { TEST_ADDRESS_NEVER_USE } from '../support/commands'
33
describe('Landing Page', () => {
44
beforeEach(() => cy.visit('/'))
55
it('loads exchange page', () => {
6-
cy.get('#exchangePage')
6+
cy.get('#exchange-page')
77
})
88

99
it('redirects to url /swap', () => {
1010
cy.url().should('include', '/swap')
1111
})
1212

1313
it('allows navigation to send', () => {
14-
cy.get('#send-navLink').click()
14+
cy.get('#send-nav-link').click()
1515
cy.url().should('include', '/send')
1616
})
1717

1818
it('allows navigation to pool', () => {
19-
cy.get('#pool-navLink').click()
19+
cy.get('#pool-nav-link').click()
2020
cy.url().should('include', '/pool')
2121
})
2222

cypress/integration/swap.test.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
describe('Swap', () => {
22
beforeEach(() => cy.visit('/swap'))
33
it('can enter an amount into input', () => {
4-
cy.get('#swapInputField').type('0.001')
4+
cy.get('#swap-currency-input .token-amount-input').type('0.001')
55
})
66

77
it('zero swap amount', () => {
8-
cy.get('#swapInputField').type('0.0')
8+
cy.get('#swap-currency-input .token-amount-input').type('0.0')
99
})
1010

1111
it('can enter an amount into output', () => {
12-
cy.get('#swapOutputField').type('0.001')
12+
cy.get('#swap-currency-output .token-amount-input').type('0.001')
1313
})
1414

1515
it('zero output amount', () => {
16-
cy.get('#swapOutputField').type('0.0')
16+
cy.get('#swap-currency-output .token-amount-input').type('0.0')
17+
})
18+
19+
it('can swap ETH for DAI', () => {
20+
cy.get('#swap-currency-output .open-currency-select-button').click()
21+
cy.get('.token-item-0xc7AD46e0b8a400Bb3C915120d284AafbA8fc4735').click()
22+
cy.get('#swap-currency-input .token-amount-input').type('0.001')
23+
cy.get('#swap-currency-output .token-amount-input').should('not.equal', '')
24+
cy.get('#exchange-show-advanced').click()
25+
cy.get('#exchange-swap-button').click()
26+
cy.get('#exchange-page-confirm-swap-or-send').should('contain', 'Confirm Swap')
1727
})
1828
})

src/components/CreatePool/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { TYPE, Link } from '../../theme'
1212
import { AutoColumn, ColumnCenter } from '../Column'
1313
import { ButtonPrimary, ButtonDropwdown, ButtonDropwdownLight } from '../Button'
1414

15-
import { useToken } from '../../contexts/Tokens'
15+
import { useToken } from '../../hooks/Tokens'
1616
import { useWeb3React } from '../../hooks'
1717
import { usePair } from '../../data/Reserves'
1818

@@ -79,7 +79,7 @@ function CreatePool({ history }: RouteComponentProps<{}>) {
7979
{token0?.symbol}{' '}
8080
</Text>
8181
<TYPE.darkGray fontWeight={500} fontSize={16} marginLeft={'8px'}>
82-
{token0?.symbol === 'ETH' && '(default)'}
82+
{token0?.address === 'ETH' && '(default)'}
8383
</TYPE.darkGray>
8484
</Row>
8585
</ButtonDropwdownLight>

src/components/CurrencyInputPanel/index.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ interface CurrencyInputPanelProps {
136136
showSendWithSwap?: boolean
137137
otherSelectedTokenAddress?: string | null
138138
advanced?: boolean
139-
inputId: string
139+
id: string
140140
}
141141

142142
export default function CurrencyInputPanel({
@@ -157,7 +157,7 @@ export default function CurrencyInputPanel({
157157
showSendWithSwap = false,
158158
otherSelectedTokenAddress = null,
159159
advanced = false,
160-
inputId
160+
id
161161
}: CurrencyInputPanelProps) {
162162
const { t } = useTranslation()
163163

@@ -167,7 +167,7 @@ export default function CurrencyInputPanel({
167167
const theme = useContext(ThemeContext)
168168

169169
return (
170-
<InputPanel>
170+
<InputPanel id={id}>
171171
<Container hideInput={hideInput}>
172172
{!hideInput && (
173173
<LabelRow>
@@ -197,8 +197,8 @@ export default function CurrencyInputPanel({
197197
{!hideInput && (
198198
<>
199199
<NumericalInput
200+
className="token-amount-input"
200201
value={value}
201-
id={inputId}
202202
onUserInput={val => {
203203
onUserInput(field, val)
204204
}}
@@ -210,6 +210,7 @@ export default function CurrencyInputPanel({
210210
)}
211211
<CurrencySelect
212212
selected={!!token}
213+
className="open-currency-select-button"
213214
onClick={() => {
214215
if (!disableTokenSelect) {
215216
setModalOpen(true)
@@ -223,7 +224,7 @@ export default function CurrencyInputPanel({
223224
<TokenLogo address={token?.address} size={'24px'} />
224225
) : null}
225226
{isExchange ? (
226-
<StyledTokenName>
227+
<StyledTokenName className="token-name-container">
227228
{pair?.token0.symbol}:{pair?.token1.symbol}
228229
</StyledTokenName>
229230
) : (
@@ -248,7 +249,7 @@ export default function CurrencyInputPanel({
248249
showSendWithSwap={showSendWithSwap}
249250
hiddenToken={token?.address}
250251
otherSelectedTokenAddress={otherSelectedTokenAddress}
251-
otherSelectedText={field === 0 ? ' Selected as output' : 'Selected as input'}
252+
otherSelectedText={field === 0 ? 'Selected as output' : 'Selected as input'}
252253
/>
253254
)}
254255
</InputPanel>

src/components/ExchangePage/index.tsx

Lines changed: 34 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,42 @@
1-
import React, { useState, useCallback, useEffect, useContext } from 'react'
2-
import ReactGA from 'react-ga'
3-
import { ThemeContext } from 'styled-components'
4-
import { parseEther, parseUnits } from '@ethersproject/units'
5-
import { JSBI, Percent, TokenAmount, TradeType, WETH, Fraction } from '@uniswap/sdk'
6-
import { ArrowDown, ChevronDown, ChevronUp, Repeat } from 'react-feather'
7-
import { withRouter, RouteComponentProps } from 'react-router-dom'
81
import { BigNumber } from '@ethersproject/bignumber'
92
import { MaxUint256 } from '@ethersproject/constants'
103
import { Contract } from '@ethersproject/contracts'
11-
import { useUserAdvanced } from '../../state/application/hooks'
12-
import { useTokenBalanceTreatingWETHasETH, useAllTokenBalancesTreatingWETHasETH } from '../../state/wallet/hooks'
13-
import { Field, SwapAction, useSwapStateReducer } from './swap-store'
4+
import { parseEther, parseUnits } from '@ethersproject/units'
5+
import { Fraction, JSBI, Percent, TokenAmount, TradeType, WETH } from '@uniswap/sdk'
6+
import React, { useCallback, useContext, useEffect, useState } from 'react'
7+
import { ArrowDown, ChevronDown, ChevronUp, Repeat } from 'react-feather'
8+
import ReactGA from 'react-ga'
9+
import { RouteComponentProps, withRouter } from 'react-router-dom'
1410
import { Text } from 'rebass'
11+
import { ThemeContext } from 'styled-components'
1512
import Card, { BlueCard, GreyCard, YellowCard } from '../../components/Card'
1613
import { AutoColumn, ColumnCenter } from '../../components/Column'
17-
import { AutoRow, RowBetween, RowFixed } from '../Row'
1814
import { ROUTER_ADDRESS } from '../../constants'
1915
import { useTokenAllowance } from '../../data/Allowances'
20-
import { useAddUserToken, useFetchTokenByAddress } from '../../state/user/hooks'
21-
import { useAllTokens, useToken } from '../../contexts/Tokens'
22-
import { useHasPendingApproval, useTransactionAdder } from '../../state/transactions/hooks'
16+
import { useV1TradeLinkIfBetter } from '../../data/V1'
2317
import { useTokenContract, useWeb3React } from '../../hooks'
18+
import { useTokenByAddressAndAutomaticallyAdd } from '../../hooks/Tokens'
2419
import { useTradeExactIn, useTradeExactOut } from '../../hooks/Trades'
25-
import { useWalletModalToggle } from '../../state/application/hooks'
20+
import { useUserAdvanced, useWalletModalToggle } from '../../state/application/hooks'
21+
import { useHasPendingApproval, useTransactionAdder } from '../../state/transactions/hooks'
22+
import { useAllTokenBalancesTreatingWETHasETH } from '../../state/wallet/hooks'
2623
import { Hover, TYPE } from '../../theme'
2724
import { Link } from '../../theme/components'
2825
import {
26+
basisPointsToPercent,
2927
calculateGasMargin,
3028
getEtherscanLink,
3129
getRouterContract,
32-
basisPointsToPercent,
33-
QueryParams,
34-
getSigner
30+
getSigner,
31+
QueryParams
3532
} from '../../utils'
3633
import Copy from '../AccountDetails/Copy'
3734
import AddressInputPanel from '../AddressInputPanel'
3835
import { ButtonError, ButtonLight, ButtonPrimary, ButtonSecondary } from '../Button'
3936
import ConfirmationModal from '../ConfirmationModal'
4037
import CurrencyInputPanel from '../CurrencyInputPanel'
4138
import QuestionHelper from '../Question'
39+
import { AutoRow, RowBetween, RowFixed } from '../Row'
4240
import SlippageTabs from '../SlippageTabs'
4341
import TokenLogo from '../TokenLogo'
4442
import {
@@ -55,7 +53,7 @@ import {
5553
TruncatedText,
5654
Wrapper
5755
} from './styleds'
58-
import { useV1TradeLinkIfBetter } from '../../data/V1'
56+
import { Field, SwapAction, useSwapStateReducer } from './swap-store'
5957

6058
enum SwapType {
6159
EXACT_TOKENS_FOR_TOKENS,
@@ -108,35 +106,10 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
108106
const [tradeError, setTradeError] = useState<string>('') // error for things like reserve size or route
109107

110108
const tokens = {
111-
[Field.INPUT]: useToken(fieldData[Field.INPUT].address),
112-
[Field.OUTPUT]: useToken(fieldData[Field.OUTPUT].address)
109+
[Field.INPUT]: useTokenByAddressAndAutomaticallyAdd(fieldData[Field.INPUT].address),
110+
[Field.OUTPUT]: useTokenByAddressAndAutomaticallyAdd(fieldData[Field.OUTPUT].address)
113111
}
114112

115-
// ensure input + output tokens are added to localstorage
116-
const fetchTokenByAddress = useFetchTokenByAddress()
117-
const addToken = useAddUserToken()
118-
const allTokens = useAllTokens()
119-
const inputTokenAddress = fieldData[Field.INPUT].address
120-
useEffect(() => {
121-
if (inputTokenAddress && !Object.keys(allTokens).some(tokenAddress => tokenAddress === inputTokenAddress)) {
122-
fetchTokenByAddress(inputTokenAddress).then(token => {
123-
if (token !== null) {
124-
addToken(token)
125-
}
126-
})
127-
}
128-
}, [inputTokenAddress, allTokens, fetchTokenByAddress, addToken])
129-
const outputTokenAddress = fieldData[Field.OUTPUT].address
130-
useEffect(() => {
131-
if (outputTokenAddress && !Object.keys(allTokens).some(tokenAddress => tokenAddress === outputTokenAddress)) {
132-
fetchTokenByAddress(outputTokenAddress).then(token => {
133-
if (token !== null) {
134-
addToken(token)
135-
}
136-
})
137-
}
138-
}, [outputTokenAddress, allTokens, fetchTokenByAddress, addToken])
139-
140113
// token contracts for approvals and direct sends
141114
const tokenContractInput: Contract = useTokenContract(tokens[Field.INPUT]?.address)
142115
const tokenContractOutput: Contract = useTokenContract(tokens[Field.OUTPUT]?.address)
@@ -157,8 +130,8 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
157130

158131
// get user- and token-specific lookup data
159132
const userBalances = {
160-
[Field.INPUT]: useTokenBalanceTreatingWETHasETH(account, tokens[Field.INPUT]),
161-
[Field.OUTPUT]: useTokenBalanceTreatingWETHasETH(account, tokens[Field.OUTPUT])
133+
[Field.INPUT]: allBalances?.[tokens[Field.INPUT]?.address]?.raw,
134+
[Field.OUTPUT]: allBalances?.[tokens[Field.OUTPUT]?.address]?.raw
162135
}
163136

164137
// parse the amount that the user typed
@@ -773,7 +746,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
773746
if (sending && !sendingWithSwap) {
774747
return (
775748
<AutoColumn>
776-
<ButtonPrimary onClick={onSend}>
749+
<ButtonPrimary onClick={onSend} id="exchange-page-confirm-send">
777750
<Text color="white" fontSize={20}>
778751
Confirm send
779752
</Text>
@@ -868,7 +841,12 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
868841
</AutoColumn>
869842

870843
<AutoRow>
871-
<ButtonError onClick={onSwap} error={!!warningHigh} style={{ margin: '10px 0 0 0' }}>
844+
<ButtonError
845+
onClick={onSwap}
846+
error={!!warningHigh}
847+
style={{ margin: '10px 0 0 0' }}
848+
id="exchange-page-confirm-swap-or-send"
849+
>
872850
<Text fontSize={20} fontWeight={500}>
873851
{warningHigh ? (sending ? 'Send Anyway' : 'Swap Anyway') : sending ? 'Confirm Send' : 'Confirm Swap'}
874852
</Text>
@@ -951,7 +929,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
951929
}
952930

953931
return (
954-
<Wrapper id="exchangePage">
932+
<Wrapper id="exchange-page">
955933
<ConfirmationModal
956934
isOpen={showConfirm}
957935
title={sendingWithSwap ? 'Confirm swap and send' : sending ? 'Confirm Send' : 'Confirm Swap'}
@@ -989,7 +967,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
989967
showSendWithSwap={true}
990968
advanced={advanced}
991969
label={''}
992-
inputId="swapInputField"
970+
id="swap-currency-input"
993971
otherSelectedTokenAddress={tokens[Field.OUTPUT]?.address}
994972
/>
995973
</InputGroup>
@@ -1034,7 +1012,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
10341012
}}
10351013
onTokenSelection={address => onTokenSelection(Field.INPUT, address)}
10361014
otherSelectedTokenAddress={tokens[Field.OUTPUT]?.address}
1037-
inputId="swapInputField"
1015+
id="swap-currency-input"
10381016
/>
10391017

10401018
{sendingWithSwap ? (
@@ -1078,7 +1056,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
10781056
onTokenSelection={address => onTokenSelection(Field.OUTPUT, address)}
10791057
advanced={advanced}
10801058
otherSelectedTokenAddress={tokens[Field.INPUT]?.address}
1081-
inputId="swapOutputField"
1059+
id="swap-currency-output"
10821060
/>
10831061
{sendingWithSwap && (
10841062
<RowBetween padding="0 1rem 0 12px">
@@ -1199,6 +1177,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
11991177
onClick={() => {
12001178
setShowConfirm(true)
12011179
}}
1180+
id="exchange-swap-button"
12021181
disabled={!isValid}
12031182
error={!!warningHigh}
12041183
>
@@ -1229,7 +1208,7 @@ function ExchangePage({ sendingInput = false, history, params }: ExchangePagePro
12291208
<AdvancedDropwdown>
12301209
{!showAdvanced && (
12311210
<Hover>
1232-
<RowBetween onClick={() => setShowAdvanced(true)} padding={'8px 20px'}>
1211+
<RowBetween onClick={() => setShowAdvanced(true)} padding={'8px 20px'} id="exchange-show-advanced">
12331212
<Text fontSize={16} fontWeight={500} style={{ userSelect: 'none' }}>
12341213
Show Advanced
12351214
</Text>

src/components/NavigationTabs/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ function NavigationTabs({ location: { pathname }, history }: RouteComponentProps
142142
<Tabs style={{ marginBottom: '20px' }}>
143143
{tabOrder.map(({ path, textKey, regex }) => (
144144
<StyledNavLink
145-
id={`${textKey}-navLink`}
145+
id={`${textKey}-nav-link`}
146146
key={path}
147147
to={path}
148148
isActive={(_, { pathname }) => !!pathname.match(regex)}

src/components/PoolFinder/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { LightCard } from '../Card'
1414
import { AutoColumn, ColumnCenter } from '../Column'
1515
import { ButtonPrimary, ButtonDropwdown, ButtonDropwdownLight } from '../Button'
1616

17-
import { useToken } from '../../contexts/Tokens'
17+
import { useToken } from '../../hooks/Tokens'
1818
import { useWeb3React } from '@web3-react/core'
1919
import { usePairAdder } from '../../state/user/hooks'
2020
import { usePair } from '../../data/Reserves'

0 commit comments

Comments
 (0)