Skip to content

Commit

Permalink
fix(token-details): update withdraw to navigate to WithdrawSpend scre…
Browse files Browse the repository at this point in the history
…en (#4377)

### Description

Per feedback from Nitya, update withdraw to navigate to the
WithdrawSpend screen to allow either using Spend or Withdraw.

### Test plan

Unit tests & manual



https://github.com/valora-inc/wallet/assets/5062591/03bb80b9-e9d8-4b08-8e34-cdc152ef3162



### Related issues

N/A

### Backwards compatibility

Yes
  • Loading branch information
satish-ravi authored Oct 24, 2023
1 parent 6808b99 commit 0ec9cb9
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 59 deletions.
51 changes: 50 additions & 1 deletion src/tokens/TokenDetails.test.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { fireEvent, render } from '@testing-library/react-native'
import { fireEvent, render, waitFor } from '@testing-library/react-native'
import React from 'react'
import { Provider } from 'react-redux'
import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import { CICOFlow } from 'src/fiatExchanges/utils'
import { navigate } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import TokenDetailsScreen from 'src/tokens/TokenDetails'
import { Network } from 'src/transactions/types'
import { CiCoCurrency } from 'src/utils/currencies'
import { ONE_DAY_IN_MILLIS } from 'src/utils/time'
import MockedNavigator from 'test/MockedNavigator'
import { createMockStore } from 'test/utils'
Expand All @@ -25,6 +29,9 @@ jest.mock('src/statsig', () => ({
}))

describe('TokenDetails', () => {
beforeEach(() => {
jest.clearAllMocks()
})
it('renders title, balance and token balance item', () => {
const store = createMockStore({
tokens: {
Expand Down Expand Up @@ -323,4 +330,46 @@ describe('TokenDetails', () => {
expect(getByTestId('TokenDetails/Action/More')).toBeTruthy()
expect(queryByTestId('TokenDetails/Action/Withdraw')).toBeFalsy()
})

it('actions navigate to appropriate screens', async () => {
const store = createMockStore({
tokens: {
tokenBalances: {
[mockCeloTokenId]: {
...mockTokenBalances[mockCeloTokenId],
balance: '10',
isSwappable: true,
},
},
},
app: {
showSwapMenuInDrawerMenu: true,
},
})

const { getByTestId } = render(
<Provider store={store}>
<MockedNavigator component={TokenDetailsScreen} params={{ tokenId: mockCeloTokenId }} />
</Provider>
)

fireEvent.press(getByTestId('TokenDetails/Action/Send'))
expect(navigate).toHaveBeenCalledWith(Screens.Send, { defaultTokenIdOverride: mockCeloTokenId })
fireEvent.press(getByTestId('TokenDetails/Action/Swap'))
expect(navigate).toHaveBeenCalledWith(Screens.SwapScreenWithBack, {
fromTokenId: mockCeloTokenId,
})
fireEvent.press(getByTestId('TokenDetails/Action/More'))
await waitFor(() => expect(getByTestId('TokenDetailsMoreActions')).toBeTruthy())
fireEvent.press(getByTestId('TokenDetailsMoreActions/Add'))
expect(navigate).toHaveBeenCalledWith(Screens.FiatExchangeAmount, {
currency: CiCoCurrency.CELO,
tokenId: mockCeloTokenId,
flow: CICOFlow.CashIn,
network: Network.Celo,
})
fireEvent.press(getByTestId('TokenDetailsMoreActions/Withdraw'))
expect(navigate).toHaveBeenCalledWith(Screens.WithdrawSpend)
expect(ValoraAnalytics.track).toHaveBeenCalledTimes(5) // 4 actions + 1 more action
})
})
28 changes: 12 additions & 16 deletions src/tokens/TokenDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,20 +150,6 @@ function PriceInfo({ token }: { token: TokenBalance }) {
)
}

export const onPressCicoAction = (token: TokenBalance, flow: CICOFlow) => {
const tokenSymbol = token.symbol
// this should always be true given that we only show Add / Withdraw if a
// token is CiCoCurrency, but adding it here to ensure type safety
if (isCicoToken(tokenSymbol)) {
navigate(Screens.FiatExchangeAmount, {
currency: tokenSymbol,
tokenId: token.tokenId,
flow,
network: Network.Celo, // TODO (ACT-954): use networkId from token
})
}
}

export const useActions = (token: TokenBalance) => {
const { t } = useTranslation()
const sendableTokens = useTokensForSend()
Expand Down Expand Up @@ -203,7 +189,17 @@ export const useActions = (token: TokenBalance) => {
details: t('tokenDetails.actionDescriptions.add'),
iconComponent: QuickActionsAdd,
onPress: () => {
onPressCicoAction(token, CICOFlow.CashIn)
const tokenSymbol = token.symbol
// this should always be true given that we only show Add / Withdraw if a
// token is CiCoCurrency, but adding it here to ensure type safety
if (isCicoToken(tokenSymbol)) {
navigate(Screens.FiatExchangeAmount, {
currency: tokenSymbol,
tokenId: token.tokenId,
flow: CICOFlow.CashIn,
network: Network.Celo, // TODO (ACT-954): use networkId from token
})
}
},
visible: !!cashInTokens.find((tokenInfo) => tokenInfo.tokenId === token.tokenId),
},
Expand All @@ -213,7 +209,7 @@ export const useActions = (token: TokenBalance) => {
details: t('tokenDetails.actionDescriptions.withdraw'),
iconComponent: QuickActionsWithdraw,
onPress: () => {
onPressCicoAction(token, CICOFlow.CashOut)
navigate(Screens.WithdrawSpend)
},
visible: showWithdraw,
},
Expand Down
52 changes: 10 additions & 42 deletions src/tokens/TokenDetailsMoreActions.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,13 @@ import BigNumber from 'bignumber.js'
import React from 'react'
import { AssetsEvents } from 'src/analytics/Events'
import ValoraAnalytics from 'src/analytics/ValoraAnalytics'
import { CICOFlow } from 'src/fiatExchanges/utils'
import QuickActionsAdd from 'src/icons/quick-actions/Add'
import QuickActionsSend from 'src/icons/quick-actions/Send'
import QuickActionsSwap from 'src/icons/quick-actions/Swap'
import { navigate } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { onPressCicoAction } from 'src/tokens/TokenDetails'
import TokenDetailsMoreActions from 'src/tokens/TokenDetailsMoreActions'
import { StoredTokenBalance, TokenBalance } from 'src/tokens/slice'
import { TokenDetailsAction, TokenDetailsActionName } from 'src/tokens/types'
import { Network, NetworkId } from 'src/transactions/types'
import { NetworkId } from 'src/transactions/types'
import { mockCeloAddress, mockCeloTokenId } from 'test/values'

const mockStoredCeloTokenBalance: StoredTokenBalance = {
Expand Down Expand Up @@ -48,39 +44,31 @@ const mockActions: TokenDetailsAction[] = [
title: 'tokenDetails.actions.send',
details: 'tokenDetails.actions.sendDetails',
iconComponent: QuickActionsSend,
onPress: () => {
navigate(Screens.Send, { defaultTokenIdOverride: mockCeloTokenId })
},
onPress: jest.fn(),
visible: true,
},
{
name: TokenDetailsActionName.Swap,
title: 'tokenDetails.actions.swap',
details: 'tokenDetails.actions.swapDetails',
iconComponent: QuickActionsSwap,
onPress: () => {
navigate(Screens.SwapScreenWithBack, { fromTokenId: mockCeloTokenId })
},
onPress: jest.fn(),
visible: true,
},
{
name: TokenDetailsActionName.Add,
title: 'tokenDetails.actions.add',
details: 'tokenDetails.actions.addDetails',
iconComponent: QuickActionsAdd,
onPress: () => {
onPressCicoAction(mockCeloBalance, CICOFlow.CashIn)
},
onPress: jest.fn(),
visible: true,
},
{
name: TokenDetailsActionName.Withdraw,
title: 'tokenDetails.actions.withdraw',
details: 'tokenDetails.actions.withdrawDetails',
iconComponent: QuickActionsSend,
onPress: () => {
onPressCicoAction(mockCeloBalance, CICOFlow.CashOut)
},
onPress: jest.fn(),
visible: true,
},
]
Expand All @@ -101,29 +89,9 @@ describe('TokenDetailsMoreActions', () => {
expect(getByText('tokenDetails.actions.withdraw')).toBeTruthy()
})

const mockAddParams = {
currency: mockCeloBalance.symbol,
tokenId: mockCeloTokenId,
flow: CICOFlow.CashIn,
network: Network.Celo,
}

const mockWithdrawParams = {
currency: mockCeloBalance.symbol,
tokenId: mockCeloTokenId,
flow: CICOFlow.CashOut,
network: Network.Celo,
}

it.each`
action | buttonText | navigatedScreen | navigationParams
${TokenDetailsActionName.Send} | ${'tokenDetails.actions.send'} | ${Screens.Send} | ${{ defaultTokenIdOverride: mockCeloTokenId }}
${TokenDetailsActionName.Swap} | ${'tokenDetails.actions.swap'} | ${Screens.SwapScreenWithBack} | ${{ fromTokenId: mockCeloTokenId }}
${TokenDetailsActionName.Add} | ${'tokenDetails.actions.add'} | ${Screens.FiatExchangeAmount} | ${mockAddParams}
${TokenDetailsActionName.Withdraw} | ${'tokenDetails.actions.withdraw'} | ${Screens.FiatExchangeAmount} | ${mockWithdrawParams}
`(
it.each(mockActions)(
'triggers the correct analytics and navigation for $buttonText',
async ({ action, buttonText, navigatedScreen, navigationParams }) => {
async ({ name, title, onPress }) => {
const { getByText } = render(
<TokenDetailsMoreActions
forwardedRef={{ current: null }}
Expand All @@ -132,11 +100,11 @@ describe('TokenDetailsMoreActions', () => {
/>
)

fireEvent.press(getByText(buttonText))
fireEvent.press(getByText(title))
expect(ValoraAnalytics.track).toHaveBeenCalledWith(
AssetsEvents.tap_token_details_bottom_sheet_action,
{
action,
action: name,
address: mockCeloAddress,
balanceUsd: 5.8,
networkId: mockCeloBalance.networkId,
Expand All @@ -145,7 +113,7 @@ describe('TokenDetailsMoreActions', () => {
}
)

expect(navigate).toHaveBeenCalledWith(navigatedScreen, navigationParams)
expect(onPress).toHaveBeenCalled()
}
)
})
1 change: 1 addition & 0 deletions src/tokens/TokenDetailsMoreActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default function TokenDetailsMoreActions({
})
action.onPress()
}}
testID={`TokenDetailsMoreActions/${action.name}`}
>
<>
<action.iconComponent color={Colors.dark} />
Expand Down

0 comments on commit 0ec9cb9

Please sign in to comment.