import { fireEvent, render, waitFor } from '@testing-library/react-native'
import * as React from 'react'
import { Provider } from 'react-redux'
import { KeylessBackupEvents } from 'src/analytics/Events'
import AppAnalytics from 'src/analytics/AppAnalytics'
import KeylessBackupProgress from 'src/keylessBackup/KeylessBackupProgress'
import { keylessBackupAcceptZeroBalance, keylessBackupBail } from 'src/keylessBackup/slice'
import {
KeylessBackupFlow,
KeylessBackupOrigin,
KeylessBackupStatus,
} from 'src/keylessBackup/types'
import { ensurePincode, navigate, navigateHome } from 'src/navigator/NavigationService'
import { Screens } from 'src/navigator/Screens'
import { goToNextOnboardingScreen } from 'src/onboarding/steps'
import Logger from 'src/utils/Logger'
import { createMockStore, getMockStackScreenProps } from 'test/utils'
import { mockOnboardingProps } from 'test/values'
const mockOnboardingPropsSelector = jest.fn(() => mockOnboardingProps)
jest.mock('src/navigator/NavigationService')
jest.mock('src/analytics/AppAnalytics')
jest.mock('src/utils/Logger')
jest.mock('src/onboarding/steps', () => ({
goToNextOnboardingScreen: jest.fn(),
onboardingPropsSelector: () => mockOnboardingPropsSelector(),
getOnboardingStepValues: () => ({ step: 2, totalSteps: 3 }),
}))
function createStore(keylessBackupStatus: KeylessBackupStatus, zeroBalance = false) {
return createMockStore({
keylessBackup: {
backupStatus: keylessBackupStatus,
},
...(zeroBalance && {
tokens: {
tokenBalances: {},
},
positions: {
positions: [],
},
}),
})
}
function getProps(
flow: KeylessBackupFlow = KeylessBackupFlow.Setup,
origin: KeylessBackupOrigin = KeylessBackupOrigin.Settings
) {
return getMockStackScreenProps(Screens.KeylessBackupProgress, {
keylessBackupFlow: flow,
origin,
})
}
describe('KeylessBackupProgress', () => {
beforeEach(() => {
jest.clearAllMocks()
})
describe('setup', () => {
it('Logs error when not started', async () => {
render(
)
expect(Logger.error).toHaveBeenCalledTimes(1)
})
it('shows spinner when in progress', async () => {
const { getByTestId } = render(
)
expect(getByTestId('GreenLoadingSpinner')).toBeTruthy()
})
it('navigates to home on success of the non onboarding flow', async () => {
const { getByTestId } = render(
)
expect(getByTestId('GreenLoadingSpinnerToCheck')).toBeTruthy()
expect(getByTestId('KeylessBackupProgress/Continue')).toBeTruthy()
fireEvent.press(getByTestId('KeylessBackupProgress/Continue'))
expect(navigateHome).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_progress_completed_continue,
{ origin: KeylessBackupOrigin.Settings }
)
})
it('navigates to next onboarding screen on success of the onboarding flow', async () => {
const { getByTestId } = render(
)
expect(getByTestId('GreenLoadingSpinnerToCheck')).toBeTruthy()
expect(getByTestId('KeylessBackupProgress/Continue')).toBeTruthy()
fireEvent.press(getByTestId('KeylessBackupProgress/Continue'))
expect(goToNextOnboardingScreen).toHaveBeenCalledWith({
onboardingProps: mockOnboardingProps,
firstScreenInCurrentStep: Screens.SignInWithEmail,
})
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_progress_completed_continue,
{
origin: KeylessBackupOrigin.Onboarding,
}
)
})
it('navigates to settings on failure', async () => {
const { getByTestId } = render(
)
expect(getByTestId('RedLoadingSpinnerToInfo')).toBeTruthy()
expect(getByTestId('KeylessBackupProgress/Later')).toBeTruthy()
fireEvent.press(getByTestId('KeylessBackupProgress/Later'))
expect(navigate).toHaveBeenCalledTimes(1)
expect(navigate).toHaveBeenCalledWith(Screens.SecuritySubmenu)
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(KeylessBackupEvents.cab_progress_failed_later)
})
it('navigates to manual backup on failure', async () => {
jest.mocked(ensurePincode).mockResolvedValueOnce(true)
const { getByTestId } = render(
)
expect(getByTestId('KeylessBackupProgress/Manual')).toBeTruthy()
fireEvent.press(getByTestId('KeylessBackupProgress/Manual'))
await waitFor(() => expect(navigate).toHaveBeenCalledTimes(1))
expect(navigate).toHaveBeenCalledWith(Screens.BackupIntroduction)
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_progress_failed_manual,
{ origin: KeylessBackupOrigin.Settings }
)
})
it('navigates to recovery phrase on failure when coming from onboarding', async () => {
jest.mocked(ensurePincode).mockResolvedValueOnce(true)
const { getByTestId } = render(
)
expect(getByTestId('KeylessBackupProgress/ManualOnboarding')).toBeTruthy()
fireEvent.press(getByTestId('KeylessBackupProgress/ManualOnboarding'))
expect(navigate).toBeCalledWith(Screens.AccountKeyEducation, { origin: 'cabOnboarding' })
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_progress_failed_manual,
{ origin: KeylessBackupOrigin.Onboarding }
)
})
it('navigates to CYA on failure when coming from onboarding', async () => {
jest.mocked(ensurePincode).mockResolvedValueOnce(true)
const { getByTestId } = render(
)
expect(getByTestId('KeylessBackupProgress/Skip')).toBeTruthy()
fireEvent.press(getByTestId('KeylessBackupProgress/Skip'))
expect(navigate).toBeCalledWith(Screens.ChooseYourAdventure)
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_progress_failed_skip_onboarding
)
})
})
describe('Restore', () => {
it('Logs error when not started', async () => {
render(
)
expect(Logger.error).toHaveBeenCalledTimes(1)
})
it('shows spinner when in progress', async () => {
const { getByTestId } = render(
)
expect(getByTestId('GreenLoadingSpinner')).toBeTruthy()
})
it('shows the confirm dialog when the user is restoring with zero balance', () => {
const store = createStore(KeylessBackupStatus.RestoreZeroBalance)
const { getByTestId } = render(
)
expect(getByTestId('ConfirmUseAccountDialog')).toBeTruthy()
fireEvent.press(getByTestId('ConfirmUseAccountDialog/PrimaryAction'))
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_restore_zero_balance_accept
)
expect(store.getActions()).toEqual([keylessBackupAcceptZeroBalance()])
store.clearActions()
fireEvent.press(getByTestId('ConfirmUseAccountDialog/SecondaryAction'))
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_restore_zero_balance_bail
)
expect(store.getActions()).toEqual([keylessBackupBail()])
})
it('shows the completed screen when cab is completed', () => {
const { getByTestId, getByText } = render(
)
expect(getByTestId('GreenLoadingSpinnerToCheck')).toBeTruthy()
expect(getByText(`₱`, { exact: false })).toBeTruthy()
expect(getByText(`45.22`, { exact: false })).toBeTruthy()
fireEvent.press(getByTestId('KeylessBackupProgress/Continue'))
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_restore_completed_continue
)
expect(goToNextOnboardingScreen).toHaveBeenCalledWith({
onboardingProps: expect.any(Object),
firstScreenInCurrentStep: Screens.ImportSelect,
})
})
it('shows the zero balance text when completed and the user has no balance', () => {
const { getByText, getByTestId } = render(
)
expect(getByTestId('GreenLoadingSpinnerToCheck')).toBeTruthy()
expect(getByTestId('KeylessBackupProgress/Continue')).toBeTruthy()
expect(getByText('keylessBackupStatus.restore.completed.bodyZeroBalance')).toBeTruthy()
})
it('NotFound: navigates to ImportSelect when try again is pressed', async () => {
const store = createStore(KeylessBackupStatus.NotFound)
const { getByTestId } = render(
)
expect(getByTestId('Help')).toBeTruthy()
expect(getByTestId('KeylessBackupProgress/RestoreNotFoundTryAgain')).toBeTruthy()
fireEvent.press(getByTestId('KeylessBackupProgress/RestoreNotFoundTryAgain'))
expect(navigate).toHaveBeenCalledTimes(1)
expect(navigate).toHaveBeenCalledWith(Screens.ImportSelect)
expect(store.getActions()).toEqual([keylessBackupBail()])
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_restore_failed_try_again,
{
keylessBackupStatus: KeylessBackupStatus.NotFound,
}
)
})
it('NotFound: navigates to Welcome screen when create new wallet is pressed', async () => {
const store = createStore(KeylessBackupStatus.NotFound)
const { getByTestId } = render(
)
expect(getByTestId('Help')).toBeTruthy()
expect(getByTestId('KeylessBackupProgress/RestoreNotFoundCreateNewWallet')).toBeTruthy()
fireEvent.press(getByTestId('KeylessBackupProgress/RestoreNotFoundCreateNewWallet'))
expect(navigate).toHaveBeenCalledTimes(1)
expect(navigate).toHaveBeenCalledWith(Screens.Welcome)
expect(store.getActions()).toEqual([keylessBackupBail()])
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_restore_failed_create_new_wallet,
{
keylessBackupStatus: KeylessBackupStatus.NotFound,
}
)
})
it('Failure navigates to ImportSelect on failure', async () => {
const store = createStore(KeylessBackupStatus.Failed)
const { getByTestId } = render(
)
expect(getByTestId('RedLoadingSpinnerToInfo')).toBeTruthy()
expect(getByTestId('KeylessBackupProgress/RestoreFailedTryAgain')).toBeTruthy()
fireEvent.press(getByTestId('KeylessBackupProgress/RestoreFailedTryAgain'))
expect(navigate).toHaveBeenCalledTimes(1)
expect(navigate).toHaveBeenCalledWith(Screens.ImportSelect)
expect(store.getActions()).toEqual([keylessBackupBail()])
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_restore_failed_try_again,
{
keylessBackupStatus: KeylessBackupStatus.Failed,
}
)
})
it('navigates to Welcome screen on failure', async () => {
const store = createStore(KeylessBackupStatus.Failed)
const { getByTestId } = render(
)
expect(getByTestId('RedLoadingSpinnerToInfo')).toBeTruthy()
expect(getByTestId('KeylessBackupProgress/RestoreFailedCreateNewWallet')).toBeTruthy()
fireEvent.press(getByTestId('KeylessBackupProgress/RestoreFailedCreateNewWallet'))
expect(navigate).toHaveBeenCalledTimes(1)
expect(navigate).toHaveBeenCalledWith(Screens.Welcome)
expect(store.getActions()).toEqual([keylessBackupBail()])
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(
KeylessBackupEvents.cab_restore_failed_create_new_wallet,
{
keylessBackupStatus: KeylessBackupStatus.Failed,
}
)
})
it('navigates to SupportContact screen on failure', async () => {
const { getByTestId } = render(
)
expect(getByTestId('Header/KeylessBackupRestoreHelp')).toBeTruthy()
fireEvent.press(getByTestId('Header/KeylessBackupRestoreHelp'))
expect(navigate).toHaveBeenCalledTimes(1)
expect(navigate).toHaveBeenCalledWith(Screens.SupportContact)
expect(AppAnalytics.track).toHaveBeenCalledTimes(1)
expect(AppAnalytics.track).toHaveBeenCalledWith(KeylessBackupEvents.cab_restore_failed_help)
})
})
})