Skip to content

Commit

Permalink
refactor(earn): check allow X chain swaps gate when showing deposit o…
Browse files Browse the repository at this point in the history
…ptions (#6389)

### Description

Currently, cross chain swaps show up even if the cross chain swaps gate
is off. This updates the before deposit bottom sheet to check for the
gate before showing the cross chain swap option. Also simplified the
booleans a bit to make it more readable and added more thorough tests

### Test plan

Unit tests

### Related issues

- Part of ACT-1507

### Backwards compatibility

Yes

### Network scalability

N/A
  • Loading branch information
satish-ravi authored Dec 23, 2024
1 parent 4058c6e commit 8891d00
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 143 deletions.
222 changes: 92 additions & 130 deletions src/earn/poolInfoScreen/BeforeDepositBottomSheet.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import BeforeDepositBottomSheet from 'src/earn/poolInfoScreen/BeforeDepositBotto
import { CICOFlow } from 'src/fiatExchanges/types'
import { navigate } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { getFeatureGate } from 'src/statsig'
import { StatsigFeatureGates } from 'src/statsig/types'
import { createMockStore } from 'test/utils'
import { mockEarnPositions, mockTokenBalances } from 'test/values'

Expand All @@ -17,139 +19,99 @@ const mockToken = {
lastKnownPriceUsd: new BigNumber(1),
}

describe('BeforeDepositBottomSheet', () => {
it('show bottom sheet correctly when hasDepositToken is true, no other tokens', () => {
const { getByTestId } = render(
<Provider store={createMockStore()}>
<BeforeDepositBottomSheet
forwardedRef={{ current: null }}
token={mockToken}
pool={mockEarnPositions[0]}
hasDepositToken={true}
hasTokensOnSameNetwork={false}
hasTokensOnOtherNetworks={false}
canAdd={true}
exchanges={[]}
/>
</Provider>
)
expect(getByTestId('Earn/ActionCard/Deposit')).toBeTruthy()
expect(getByTestId('Earn/ActionCard/AddMore')).toBeTruthy()
})
it('show bottom sheet correctly when hasDepositToken is true, token(s) on same chain', () => {
const { getByTestId } = render(
<Provider store={createMockStore()}>
<BeforeDepositBottomSheet
forwardedRef={{ current: null }}
token={mockToken}
pool={mockEarnPositions[0]}
hasDepositToken={true}
hasTokensOnSameNetwork={true}
hasTokensOnOtherNetworks={false}
canAdd={true}
exchanges={[]}
/>
</Provider>
)
expect(getByTestId('Earn/ActionCard/Deposit')).toBeTruthy()
expect(getByTestId('Earn/ActionCard/SwapAndDeposit')).toBeTruthy()
expect(getByTestId('Earn/ActionCard/AddMore')).toBeTruthy()
})
it('show bottom sheet correctly when hasDepositToken is true, token(s) on differnet chain', () => {
const { getByTestId } = render(
<Provider store={createMockStore()}>
<BeforeDepositBottomSheet
forwardedRef={{ current: null }}
token={mockToken}
pool={mockEarnPositions[0]}
hasDepositToken={true}
hasTokensOnSameNetwork={false}
hasTokensOnOtherNetworks={true}
canAdd={true}
exchanges={[]}
/>
</Provider>
)
expect(getByTestId('Earn/ActionCard/Deposit')).toBeTruthy()
expect(getByTestId('Earn/ActionCard/Swap')).toBeTruthy()
expect(getByTestId('Earn/ActionCard/AddMore')).toBeTruthy()
})
it('show bottom sheet correctly when hasDepositToken is true, token(s) on same and different chains', () => {
const { getByTestId } = render(
<Provider store={createMockStore()}>
<BeforeDepositBottomSheet
forwardedRef={{ current: null }}
token={mockToken}
pool={mockEarnPositions[0]}
hasDepositToken={true}
hasTokensOnSameNetwork={true}
hasTokensOnOtherNetworks={true}
canAdd={true}
exchanges={[]}
/>
</Provider>
)
expect(getByTestId('Earn/ActionCard/Deposit')).toBeTruthy()
expect(getByTestId('Earn/ActionCard/SwapAndDeposit')).toBeTruthy()
expect(getByTestId('Earn/ActionCard/CrossChainSwap')).toBeTruthy()
})
it('show bottom sheet correctly when hasDepositToken is false, can same and cross chain swap', () => {
const { getByTestId } = render(
<Provider store={createMockStore()}>
<BeforeDepositBottomSheet
forwardedRef={{ current: null }}
token={mockToken}
pool={mockEarnPositions[0]}
hasDepositToken={false}
hasTokensOnSameNetwork={true}
hasTokensOnOtherNetworks={true}
canAdd={true}
exchanges={[]}
/>
</Provider>
)
expect(getByTestId('Earn/ActionCard/SwapAndDeposit')).toBeTruthy()
expect(getByTestId('Earn/ActionCard/CrossChainSwap')).toBeTruthy()
expect(getByTestId('Earn/ActionCard/Add')).toBeTruthy()
})
jest.mock('src/statsig')

it('show bottom sheet correctly when hasDepositToken is false, can cross chain swap', () => {
const { getByTestId } = render(
<Provider store={createMockStore()}>
<BeforeDepositBottomSheet
forwardedRef={{ current: null }}
token={mockToken}
pool={mockEarnPositions[0]}
hasDepositToken={false}
hasTokensOnSameNetwork={false}
hasTokensOnOtherNetworks={true}
canAdd={true}
exchanges={[]}
/>
</Provider>
)
expect(getByTestId('Earn/ActionCard/Swap')).toBeTruthy()
expect(getByTestId('Earn/ActionCard/Add')).toBeTruthy()
describe('BeforeDepositBottomSheet', () => {
beforeEach(() => {
jest.clearAllMocks()
jest
.mocked(getFeatureGate)
.mockImplementation((gate) => gate === StatsigFeatureGates.ALLOW_CROSS_CHAIN_SWAPS)
})

it('show bottom sheet correctly when hasDepositToken is false, no tokens', () => {
const { getByTestId } = render(
<Provider store={createMockStore()}>
<BeforeDepositBottomSheet
forwardedRef={{ current: null }}
token={mockToken}
pool={mockEarnPositions[0]}
hasDepositToken={false}
hasTokensOnSameNetwork={false}
hasTokensOnOtherNetworks={false}
canAdd={true}
exchanges={[]}
/>
</Provider>
)
expect(getByTestId('Earn/ActionCard/Add')).toBeTruthy()
expect(getByTestId('Earn/ActionCard/Transfer')).toBeTruthy()
})
it.each`
scenario | expectedActions | hasDepositToken | hasTokensOnSameNetwork | hasTokensOnOtherNetworks | canAdd | poolCannotSwapAndDeposit | allowCrossChainSwaps
${'does not have any tokens'} | ${['Add', 'Transfer']} | ${false} | ${false} | ${false} | ${true} | ${false} | ${true}
${'does not have any tokens, cannot buy'} | ${['Transfer']} | ${false} | ${false} | ${false} | ${false} | ${false} | ${true}
${'only has deposit token'} | ${['Deposit', 'AddMore']} | ${true} | ${false} | ${false} | ${true} | ${false} | ${true}
${'only has deposit token, cannot buy'} | ${['Deposit', 'Transfer']} | ${true} | ${false} | ${false} | ${false} | ${false} | ${true}
${'only has other tokens on same chain'} | ${['SwapAndDeposit', 'Add']} | ${false} | ${true} | ${false} | ${true} | ${false} | ${true}
${'only has other tokens on same chain, cannot buy'} | ${['SwapAndDeposit', 'Transfer']} | ${false} | ${true} | ${false} | ${false} | ${false} | ${true}
${'only has other tokens on same chain, pool cannot swap and deposit'} | ${['Swap', 'Add']} | ${false} | ${true} | ${false} | ${true} | ${true} | ${true}
${'only has other tokens on same chain, pool cannot swap and deposit, cannot buy'} | ${['Swap', 'Transfer']} | ${false} | ${true} | ${false} | ${false} | ${true} | ${true}
${'only has tokens on different chain'} | ${['Swap', 'Add']} | ${false} | ${false} | ${true} | ${true} | ${false} | ${true}
${'only has tokens on different chain, cannot buy'} | ${['Swap', 'Transfer']} | ${false} | ${false} | ${true} | ${false} | ${false} | ${true}
${'only has tokens on different chain, cross chain swap disabled'} | ${['Add', 'Transfer']} | ${false} | ${false} | ${true} | ${true} | ${false} | ${false}
${'has deposit token and other tokens on same chain'} | ${['Deposit', 'SwapAndDeposit', 'AddMore']} | ${true} | ${true} | ${false} | ${true} | ${false} | ${true}
${'has deposit token and other tokens on same chain, cannot buy'} | ${['Deposit', 'SwapAndDeposit', 'Transfer']} | ${true} | ${true} | ${false} | ${false} | ${false} | ${true}
${'has deposit token and other tokens on same chain, pool cannot swap and deposit'} | ${['Deposit', 'Swap', 'AddMore']} | ${true} | ${true} | ${false} | ${true} | ${true} | ${true}
${'has deposit token and tokens on different chain, cross chain swap disabled'} | ${['Deposit', 'AddMore']} | ${true} | ${false} | ${true} | ${true} | ${false} | ${false}
${'has deposit token and tokens on different chain'} | ${['Deposit', 'Swap', 'AddMore']} | ${true} | ${false} | ${true} | ${true} | ${false} | ${true}
${'has deposit token and tokens on different chain, cannot buy'} | ${['Deposit', 'Swap', 'Transfer']} | ${true} | ${false} | ${true} | ${false} | ${false} | ${true}
${'has other tokens on same and different chain'} | ${['SwapAndDeposit', 'CrossChainSwap', 'Add']} | ${false} | ${true} | ${true} | ${true} | ${false} | ${true}
${'has other tokens on same and different chain, pool cannot swap and deposit'} | ${['Swap', 'Add']} | ${false} | ${true} | ${true} | ${true} | ${true} | ${true}
${'has other tokens on same and different chain, cross chain swap disabled'} | ${['SwapAndDeposit', 'Add']} | ${false} | ${true} | ${true} | ${true} | ${false} | ${false}
${'has all types of tokens'} | ${['Deposit', 'SwapAndDeposit', 'CrossChainSwap']} | ${true} | ${true} | ${true} | ${true} | ${false} | ${true}
${'has all types of tokens, pool cannot swap and deposit'} | ${['Deposit', 'Swap']} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
${'has all types of tokens, cross chain swap disabled'} | ${['Deposit', 'SwapAndDeposit', 'AddMore']} | ${true} | ${true} | ${true} | ${true} | ${false} | ${false}
${'has all types of tokens, cross chain swap disabled, cannot buy'} | ${['Deposit', 'SwapAndDeposit', 'Transfer']} | ${true} | ${true} | ${true} | ${false} | ${false} | ${false}
${'has all types of tokens, cannot buy'} | ${['Deposit', 'SwapAndDeposit', 'CrossChainSwap']} | ${true} | ${true} | ${true} | ${false} | ${false} | ${true}
`(
'shows correct title and actions when user $scenario',
({
hasDepositToken,
hasTokensOnSameNetwork,
hasTokensOnOtherNetworks,
canAdd,
expectedActions,
poolCannotSwapAndDeposit,
allowCrossChainSwaps,
}: {
hasDepositToken: boolean
hasTokensOnSameNetwork: boolean
hasTokensOnOtherNetworks: boolean
canAdd: boolean
expectedActions: string[]
poolCannotSwapAndDeposit: boolean
allowCrossChainSwaps: boolean
}) => {
jest
.mocked(getFeatureGate)
.mockImplementation(
(gate) => gate === StatsigFeatureGates.ALLOW_CROSS_CHAIN_SWAPS && allowCrossChainSwaps
)
const { getAllByTestId, getByText, queryByTestId } = render(
<Provider store={createMockStore()}>
<BeforeDepositBottomSheet
forwardedRef={{ current: null }}
token={mockToken}
pool={{
...mockEarnPositions[0],
availableShortcutIds: poolCannotSwapAndDeposit
? ['deposit', 'withdraw']
: mockEarnPositions[0].availableShortcutIds,
}}
hasDepositToken={hasDepositToken}
hasTokensOnSameNetwork={hasTokensOnSameNetwork}
hasTokensOnOtherNetworks={hasTokensOnOtherNetworks}
canAdd={canAdd}
exchanges={[]}
/>
</Provider>
)
expect(getAllByTestId(/^Earn\/ActionCard/).map((element) => element.props.testID)).toEqual(
expectedActions.map((action) => `Earn/ActionCard/${action}`)
)
expect(
getByText(
`earnFlow.beforeDepositBottomSheet.${expectedActions.includes('Deposit') || expectedActions.includes('SwapAndDeposit') ? 'depositTitle' : 'beforeYouCanDepositTitle'}`
)
).toBeTruthy()
expect(!!queryByTestId('Earn/BeforeDepositBottomSheet/AlternativeDescription')).toBe(
expectedActions.includes('Deposit') || expectedActions.includes('SwapAndDeposit')
)
}
)

it('navigates correctly when deposit action item is tapped', () => {
const { getByTestId } = render(
Expand Down
35 changes: 22 additions & 13 deletions src/earn/poolInfoScreen/BeforeDepositBottomSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { navigate } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { EarnPosition } from 'src/positions/types'
import { NETWORK_NAMES } from 'src/shared/conts'
import { getFeatureGate } from 'src/statsig'
import { StatsigFeatureGates } from 'src/statsig/types'
import Colors from 'src/styles/colors'
import { typeScale } from 'src/styles/fonts'
import { Spacing } from 'src/styles/styles'
Expand Down Expand Up @@ -283,6 +285,9 @@ export default function BeforeDepositBottomSheet({
const { t } = useTranslation()

const { availableShortcutIds } = pool
const allowCrossChainSwaps = getFeatureGate(StatsigFeatureGates.ALLOW_CROSS_CHAIN_SWAPS)
const canCrossChainSwap = allowCrossChainSwaps && hasTokensOnOtherNetworks

const canSwapDeposit = availableShortcutIds.includes('swap-deposit') && hasTokensOnSameNetwork

const title =
Expand All @@ -297,19 +302,20 @@ export default function BeforeDepositBottomSheet({
depositTokenId: pool.dataProps.depositTokenId,
}

const showCrossChainSwap = canSwapDeposit && hasTokensOnOtherNetworks
const showSwap = !canSwapDeposit && (hasTokensOnSameNetwork || hasTokensOnOtherNetworks)
const showCrossChainSwap = canSwapDeposit && canCrossChainSwap
// Show a generic swap option if the pool doesn't support swap and deposit.
const showSwap = !canSwapDeposit && (hasTokensOnSameNetwork || canCrossChainSwap)

const hasAllDepositAndSwapOptions = hasDepositToken && hasTokensOnSameNetwork && canCrossChainSwap
const hasNoDepositOrSwapOptions =
!hasDepositToken && !hasTokensOnSameNetwork && !canCrossChainSwap

const showAdd = canAdd && !hasDepositToken
// Show AddMore if the token is available for cash-in, the user has the deposit token,
// and does not have both tokens on the same and different networks (in which case deposit and both swap and cross-chain swap will show instead)
const showAddMore =
canAdd && hasDepositToken && !(hasTokensOnSameNetwork && hasTokensOnOtherNetworks)
// Show Transfer if the user does not have the deposit token and does not have any tokens available for swapping
// OR if the token is not a cash-in token and the user does not have the deposit token and both tokens on the same and different networks
// (in which case deposit and both swap and cross-chain swap will show instead)
const showTransfer =
(!hasDepositToken && !hasTokensOnSameNetwork && !hasTokensOnOtherNetworks) ||
(!canAdd && !(hasDepositToken && hasTokensOnSameNetwork && hasTokensOnOtherNetworks))
// Don't show add more if the user has all deposit and swap options are available
const showAddMore = canAdd && hasDepositToken && !hasAllDepositAndSwapOptions
// Show Transfer if the user cannot deposit or swap options or if the token
// does not support buy and if not all deposit and swap options are available
const showTransfer = hasNoDepositOrSwapOptions || (!canAdd && !hasAllDepositAndSwapOptions)

return (
<BottomSheet
Expand Down Expand Up @@ -345,7 +351,10 @@ export default function BeforeDepositBottomSheet({
)}
{(canSwapDeposit || hasDepositToken) &&
(showCrossChainSwap || showSwap || showAdd || showAddMore || showTransfer) && (
<Text style={styles.actionDetails}>
<Text
testID={'Earn/BeforeDepositBottomSheet/AlternativeDescription'}
style={styles.actionDetails}
>
{t('earnFlow.beforeDepositBottomSheet.crossChainAlternativeDescription', {
tokenNetwork: NETWORK_NAMES[token.networkId],
})}
Expand Down

0 comments on commit 8891d00

Please sign in to comment.