import { fireEvent, render, waitFor, within } from '@testing-library/react-native' import React from 'react' import * as Keychain from 'react-native-keychain' import { Provider } from 'react-redux' import { navigate } from 'src/navigator/NavigationService' import { Screens } from 'src/navigator/Screens' import { StackParamList } from 'src/navigator/types' import { goToNextOnboardingScreen } from 'src/onboarding/steps' import VerificationStartScreen from 'src/verify/VerificationStartScreen' import MockedNavigator from 'test/MockedNavigator' import { createMockStore } from 'test/utils' import { mockOnboardingProps } from 'test/values' const mockedKeychain = jest.mocked(Keychain) const mockOnboardingPropsSelector = jest.fn(() => mockOnboardingProps) jest.mock('src/onboarding/steps', () => ({ goToNextOnboardingScreen: jest.fn(), getOnboardingStepValues: () => ({ step: 3, totalSteps: 3 }), onboardingPropsSelector: () => mockOnboardingPropsSelector(), })) const renderComponent = ( navParams?: StackParamList[Screens.VerificationStartScreen], restoreAccount = false ) => render( ) describe('VerificationStartScreen', () => { beforeEach(() => { jest.clearAllMocks() }) it('displays the correct components on mount when not onboarding', async () => { mockedKeychain.getGenericPassword.mockResolvedValue({ password: 'some signed message', username: 'username', service: 'service', storage: 'storage', }) const { getByText, getByTestId, queryByTestId, queryByText } = renderComponent() await waitFor(() => expect(getByText('phoneVerificationScreen.startButtonLabel')).toBeTruthy()) expect(getByText('phoneVerificationScreen.title')).toBeTruthy() expect(getByText('phoneVerificationScreen.description')).toBeTruthy() expect(getByTestId('CountrySelectionButton')).toBeTruthy() expect(getByTestId('PhoneNumberField')).toBeTruthy() expect(getByText('phoneVerificationScreen.learnMore.buttonLabel')).toBeTruthy() expect(queryByText('skip')).toBeFalsy() expect(queryByTestId('HeaderSubTitle')).toBeFalsy() }) it('displays the correct components on mount when onboarding and creating new wallet', async () => { mockedKeychain.getGenericPassword.mockResolvedValue({ password: 'some signed message', username: 'username', service: 'service', storage: 'storage', }) const { getByText, getByTestId } = renderComponent({ hasOnboarded: false }) await waitFor(() => expect(getByText('phoneVerificationScreen.startButtonLabel')).toBeTruthy()) expect(getByText('phoneVerificationScreen.title')).toBeTruthy() expect(getByText('phoneVerificationScreen.description')).toBeTruthy() expect(getByTestId('CountrySelectionButton')).toBeTruthy() expect(getByTestId('PhoneNumberField')).toBeTruthy() expect(getByText('phoneVerificationScreen.learnMore.buttonLabel')).toBeTruthy() expect(getByText('skip')).toBeTruthy() expect(getByTestId('HeaderSubTitle')).toHaveTextContent( 'registrationSteps, {"step":3,"totalSteps":3}' ) }) it('displays the correct components on mount when onboarding and restoring wallet', async () => { mockedKeychain.getGenericPassword.mockResolvedValue({ password: 'some signed message', username: 'username', service: 'service', storage: 'storage', }) const { getByText, getByTestId, queryByTestId } = renderComponent({ hasOnboarded: false }, true) await waitFor(() => expect(getByText('phoneVerificationScreen.startButtonLabel')).toBeTruthy()) expect(getByText('phoneVerificationScreen.title')).toBeTruthy() expect(getByText('phoneVerificationScreen.description')).toBeTruthy() expect(getByTestId('CountrySelectionButton')).toBeTruthy() expect(getByTestId('PhoneNumberField')).toBeTruthy() expect(getByText('phoneVerificationScreen.learnMore.buttonLabel')).toBeTruthy() expect(getByText('skip')).toBeTruthy() expect(queryByTestId('HeaderSubTitle')).toBeFalsy() }) it('does not allow starting CPV when signed message is not yet available', async () => { mockedKeychain.getGenericPassword.mockResolvedValue(false) const { queryByText, getByTestId } = renderComponent() fireEvent.changeText(getByTestId('PhoneNumberField'), '619123456') await waitFor(() => expect(getByTestId('PhoneVerificationContinue')).toBeDisabled()) expect(getByTestId('Button/Loading')).toBeTruthy() expect(queryByText('phoneVerificationScreen.startButtonLabel')).toBeFalsy() }) it('shows the learn more dialog', async () => { const { getByTestId, getByText } = renderComponent() fireEvent.press(getByText('phoneVerificationScreen.learnMore.buttonLabel')) await waitFor(() => expect(getByTestId('PhoneVerificationLearnMoreDialog')).toBeTruthy()) const LearnMoreDialog = getByTestId('PhoneVerificationLearnMoreDialog') expect( within(LearnMoreDialog).getByText('phoneVerificationScreen.learnMore.title') ).toBeTruthy() expect(within(LearnMoreDialog).getByText('phoneVerificationScreen.learnMore.body')).toBeTruthy() }) it('skip button works', async () => { const { getByText } = renderComponent({ hasOnboarded: false }) fireEvent.press(getByText('skip')) await waitFor(() => expect(goToNextOnboardingScreen).toHaveBeenCalledWith({ firstScreenInCurrentStep: Screens.VerificationStartScreen, onboardingProps: mockOnboardingProps, }) ) }) it('proceeds to the next verification step during onboarding', async () => { mockedKeychain.getGenericPassword.mockResolvedValue({ password: 'some signed message', username: 'username', service: 'service', storage: 'storage', }) const { getByText, getByTestId } = renderComponent({ hasOnboarded: false }) fireEvent.changeText(getByTestId('PhoneNumberField'), '619123456') await waitFor(() => expect(getByText('phoneVerificationScreen.startButtonLabel')).toBeTruthy()) fireEvent.press(getByText('phoneVerificationScreen.startButtonLabel')) expect(navigate).toHaveBeenCalledTimes(1) expect(navigate).toHaveBeenCalledWith(Screens.VerificationCodeInputScreen, { countryCallingCode: '+31', e164Number: '+31619123456', registrationStep: { step: 3, totalSteps: 3 }, hasOnboarded: false, }) }) it('proceeds to the next verification step without steps if restoring', async () => { mockedKeychain.getGenericPassword.mockResolvedValue({ password: 'some signed message', username: 'username', service: 'service', storage: 'storage', }) const { getByText, getByTestId } = renderComponent({ hasOnboarded: false }, true) fireEvent.changeText(getByTestId('PhoneNumberField'), '619123456') await waitFor(() => expect(getByText('phoneVerificationScreen.startButtonLabel')).toBeTruthy()) fireEvent.press(getByText('phoneVerificationScreen.startButtonLabel')) expect(navigate).toHaveBeenCalledTimes(1) expect(navigate).toHaveBeenCalledWith(Screens.VerificationCodeInputScreen, { countryCallingCode: '+31', e164Number: '+31619123456', registrationStep: undefined, hasOnboarded: false, }) }) it('proceeds to the next verification step with the correct navigation props after onboarding', async () => { mockedKeychain.getGenericPassword.mockResolvedValue({ password: 'some signed message', username: 'username', service: 'service', storage: 'storage', }) const { getByText, getByTestId } = renderComponent({ hasOnboarded: true }, false) fireEvent.changeText(getByTestId('PhoneNumberField'), '619123456') await waitFor(() => expect(getByText('phoneVerificationScreen.startButtonLabel')).toBeTruthy()) fireEvent.press(getByText('phoneVerificationScreen.startButtonLabel')) expect(navigate).toHaveBeenCalledTimes(1) expect(navigate).toHaveBeenCalledWith(Screens.VerificationCodeInputScreen, { countryCallingCode: '+31', e164Number: '+31619123456', registrationStep: undefined, hasOnboarded: true, }) }) })