diff --git a/src/earn/poolInfoScreen/BeforeDepositBottomSheet.test.tsx b/src/earn/poolInfoScreen/BeforeDepositBottomSheet.test.tsx index c2cb12a8692..d13a8e567f8 100644 --- a/src/earn/poolInfoScreen/BeforeDepositBottomSheet.test.tsx +++ b/src/earn/poolInfoScreen/BeforeDepositBottomSheet.test.tsx @@ -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' @@ -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( - - - - ) - 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( - - - - ) - 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( - - - - ) - 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( - - - - ) - 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( - - - - ) - 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( - - - - ) - 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( - - - - ) - 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( + + + + ) + 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( diff --git a/src/earn/poolInfoScreen/BeforeDepositBottomSheet.tsx b/src/earn/poolInfoScreen/BeforeDepositBottomSheet.tsx index 42cabb5d6f1..67765cc25e5 100644 --- a/src/earn/poolInfoScreen/BeforeDepositBottomSheet.tsx +++ b/src/earn/poolInfoScreen/BeforeDepositBottomSheet.tsx @@ -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' @@ -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 = @@ -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 ( + {t('earnFlow.beforeDepositBottomSheet.crossChainAlternativeDescription', { tokenNetwork: NETWORK_NAMES[token.networkId], })}