Skip to content

Commit

Permalink
fix: exchange rate display on swap review screen when to token is set…
Browse files Browse the repository at this point in the history
… last (#3291)

### Description

Fixes an issue where the exchange rate on the swap review page would
show incorrectly if the To token was set last.

### Test plan

Tested locally on iOS and unit tests added.

### Related issues

N/A

### Backwards compatibility

Yes
  • Loading branch information
MuckT authored Dec 23, 2022
1 parent c00e404 commit 7e8624e
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 17 deletions.
84 changes: 71 additions & 13 deletions src/swap/SwapReviewScreen.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jest.mock('src/analytics/ValoraAnalytics')
const mockBuyAmount = '3000000000000000000'
const mockSellAmount = '1000000000000000000'

const store = createMockStore({
const store = {
localCurrency: {
exchangeRates: {
[Currency.Dollar]: '1',
Expand Down Expand Up @@ -76,7 +76,9 @@ const store = createMockStore({
},
},
},
})
}

const mockStore = createMockStore(store)

const unvalidatedSwapTransaction = {
sellToken: mockCeloAddress,
Expand Down Expand Up @@ -139,8 +141,8 @@ describe('SwapReviewScreen', () => {
})
)

const { getByTestId, getByText } = render(
<Provider store={store}>
const { getByTestId } = render(
<Provider store={mockStore}>
<SwapReviewScreen />
</Provider>
)
Expand All @@ -152,25 +154,81 @@ describe('SwapReviewScreen', () => {
// Swap To
expect(getByTestId('ToSwapAmountToken')).toHaveTextContent('3.10 cUSD')
// Exchange Rate
expect(getByText('1 CELO ≈ 3.10 cUSD')).toBeTruthy()
expect(getByTestId('ExchangeRate')).toHaveTextContent('1 CELO ≈ 3.10 cUSD')
// Estimated Gas
expect(getByTestId('EstimatedGas')).toHaveTextContent('0.00015 CELO')
// Swap Fee
expect(getByTestId('SwapFee')).toHaveTextContent('swapReviewScreen.free')
})
})

it('should display correct exchange rate when buyAmount is used', async () => {
const newStore = {
...store,
swap: {
...store.swap,
swapUserInput: {
...store.swap.swapUserInput,
toToken: mockCeloAddress,
fromToken: mockCusdAddress,
swapAmount: {
FROM: '8200000000000000000',
TO: '200000000000000000',
},
// This updated field set to To indicates the buy amount is used
updatedField: Field.TO,
},
},
}

const newMockStore = createMockStore(newStore)

mockFetch.mockResponse(
JSON.stringify({
unvalidatedSwapTransaction: {
sellToken: mockCusdAddress,
buyToken: mockCeloAddress,
buyAmount: '2000000000000000000',
sellAmount: '8200000000000000000',
price: '4.10',
gas: '300000',
gasPrice: '500000000',
},
})
)

const { getByTestId } = render(
<Provider store={newMockStore}>
<SwapReviewScreen />
</Provider>
)

await waitFor(() => {
// Swap From
expect(getByTestId('FromSwapAmountToken')).toHaveTextContent('8.20 cUSD')
expect(getByTestId('FromSwapAmountTokenLocal')).toHaveTextContent('$8.20')
// Swap To
expect(getByTestId('ToSwapAmountToken')).toHaveTextContent('2.00 CELO')
// Exchange Rate
expect(getByTestId('ExchangeRate')).toHaveTextContent('4.10 cUSD ≈ 1 CELO')
// Estimated Gas
expect(getByTestId('EstimatedGas')).toHaveTextContent('0.00015 cUSD')
// Swap Fee
expect(getByTestId('SwapFee')).toHaveTextContent('swapReviewScreen.free')
})
})

it('should display error banner on fetch error', async () => {
mockFetch.mockReject()

render(
<Provider store={store}>
<Provider store={mockStore}>
<SwapReviewScreen />
</Provider>
)

await waitFor(() => {
expect(store.getActions()).toEqual(
expect(mockStore.getActions()).toEqual(
expect.arrayContaining([showError(ErrorMessages.FETCH_SWAP_QUOTE_FAILED)])
)
})
Expand All @@ -180,7 +238,7 @@ describe('SwapReviewScreen', () => {
mockFetch.mockResponse(JSON.stringify(mock0xResponse))

render(
<Provider store={store}>
<Provider store={mockStore}>
<SwapReviewScreen />
</Provider>
)
Expand All @@ -194,27 +252,27 @@ describe('SwapReviewScreen', () => {
})

it('should correctly dispatch swapStart', async () => {
store.dispatch = jest.fn()
mockStore.dispatch = jest.fn()
mockFetch.mockResponse(JSON.stringify(mock0xResponse))

const { getByText } = render(
<Provider store={store}>
<Provider store={mockStore}>
<SwapReviewScreen />
</Provider>
)

await waitFor(() => expect(getByText('swapReviewScreen.complete')).not.toBeDisabled())

fireEvent.press(getByText('swapReviewScreen.complete'))
expect(store.dispatch).toHaveBeenCalledWith(swapStart(mockSwap as any))
expect(mockStore.dispatch).toHaveBeenCalledWith(swapStart(mockSwap as any))
})

it('should have correct analytics on swap submission', async () => {
store.dispatch = jest.fn()
mockStore.dispatch = jest.fn()
mockFetch.mockResponse(JSON.stringify(mock0xResponse))

const { getByText } = render(
<Provider store={store}>
<Provider store={mockStore}>
<SwapReviewScreen />
</Provider>
)
Expand Down
12 changes: 8 additions & 4 deletions src/swap/SwapReviewScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,14 @@ export function SwapReviewScreen() {
</Text>
<View style={styles.row}>
<Text style={styles.label}>{t('exchangeRate')}</Text>
<Text style={styles.transactionDetailsRightText}>
{`1 ${fromTokenSymbol}${formatValueToDisplay(
new BigNumber(swapResponse.unvalidatedSwapTransaction.price)
)} ${toTokenSymbol}`}
<Text testID="ExchangeRate" style={styles.transactionDetailsRightText}>
{swapAmountParam === 'buyAmount'
? `${formatValueToDisplay(
new BigNumber(swapResponse.unvalidatedSwapTransaction.price)
)} ${fromTokenSymbol} ≈ 1 ${toTokenSymbol}`
: `1 ${fromTokenSymbol}${formatValueToDisplay(
new BigNumber(swapResponse.unvalidatedSwapTransaction.price)
)} ${toTokenSymbol}`}
</Text>
</View>
<View style={styles.row}>
Expand Down
1 change: 1 addition & 0 deletions src/swap/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export interface SwapTransaction {
guaranteedPrice: string
minimumProtocolFee: string
orders: Array<Order>
// be careful -- price means different things when using sellAmount vs buyAmount
price: string
protocolFee: string
sellAmount: string
Expand Down

0 comments on commit 7e8624e

Please sign in to comment.