import { fireEvent, render, waitFor } from '@testing-library/react-native' import * as React from 'react' import { Provider } from 'react-redux' import { FiatConnectQuoteSuccess } from 'src/fiatconnect' import { PaymentMethodSection, PaymentMethodSectionProps, } from 'src/fiatExchanges/PaymentMethodSection' import { normalizeQuotes } from 'src/fiatExchanges/quotes/normalizeQuotes' import { CICOFlow, PaymentMethod } from 'src/fiatExchanges/types' import { LocalCurrencyCode } from 'src/localCurrency/consts' import { getFeatureGate } from 'src/statsig' import { NetworkId } from 'src/transactions/types' import { createMockStore } from 'test/utils' import { mockCicoQuotes, mockCusdAddress, mockCusdTokenId, mockFiatConnectQuotes, mockProviderSelectionAnalyticsData, } from 'test/values' const mockStore = createMockStore({ localCurrency: { preferredCurrencyCode: LocalCurrencyCode.USD, }, tokens: { tokenBalances: { [mockCusdTokenId]: { address: mockCusdAddress, tokenId: mockCusdTokenId, networkId: NetworkId['celo-alfajores'], symbol: 'cUSD', priceUsd: '1', balance: '10', priceFetchedAt: Date.now(), isFeeCurrency: true, }, }, }, }) jest.mock('src/web3/networkConfig', () => { const originalModule = jest.requireActual('src/web3/networkConfig') return { ...originalModule, __esModule: true, default: { ...originalModule.default, defaultNetworkId: 'celo-alfajores', }, } }) jest.mock('src/statsig', () => ({ getFeatureGate: jest.fn(), })) describe('PaymentMethodSection', () => { let props: PaymentMethodSectionProps beforeEach(() => { props = { paymentMethod: PaymentMethod.Card, normalizedQuotes: normalizeQuotes({ flow: CICOFlow.CashIn, fiatConnectQuotes: [], cicoQuotes: mockCicoQuotes, tokenId: mockCusdTokenId, }), flow: CICOFlow.CashIn, tokenId: mockCusdTokenId, analyticsData: mockProviderSelectionAnalyticsData, } jest.mocked(getFeatureGate).mockReturnValue(false) }) it('shows nothing if there are no available providers', async () => { props.normalizedQuotes = [] const { queryByText, queryByTestId } = render( ) expect(queryByText('selectProviderScreen.bank')).toBeFalsy() expect(queryByText('selectProviderScreen.card')).toBeFalsy() expect(queryByTestId('newDialog')).toBeFalsy() }) it('shows a non-expandable view with receive amount if there is one provider available', async () => { jest.mocked(getFeatureGate).mockReturnValue(true) props.normalizedQuotes = normalizeQuotes({ flow: CICOFlow.CashIn, fiatConnectQuotes: [], cicoQuotes: [mockCicoQuotes[3]], tokenId: mockCusdTokenId, }) const { queryByText, queryByTestId } = render( ) expect(queryByText('selectProviderScreen.card')).toBeTruthy() expect(queryByTestId('image-Ramp')).toBeTruthy() expect(queryByTestId('newLabel-Ramp')).toBeFalsy() expect(queryByTestId('Card/provider-0')).toHaveTextContent( 'selectProviderScreen.receiveAmount100.00 cUSD' ) }) it('shows new info dialog in non expandable section', async () => { props.normalizedQuotes = normalizeQuotes({ flow: CICOFlow.CashIn, fiatConnectQuotes: [], cicoQuotes: [mockCicoQuotes[3]], tokenId: mockCusdTokenId, }) jest.spyOn(props.normalizedQuotes[0], 'isProviderNew').mockReturnValue(true) const { getByText, getByTestId, queryByTestId } = render( ) expect(getByText('selectProviderScreen.card')).toBeTruthy() expect(getByTestId('image-Ramp')).toBeTruthy() expect(getByTestId('newLabel-Ramp')).toBeTruthy() expect(queryByTestId('newDialog')).toBeFalsy() fireEvent.press(getByTestId('newLabel-Ramp')) expect(getByTestId('newDialog')).toBeVisible() fireEvent.press(getByTestId('newDialog/PrimaryAction')) await waitFor(() => expect(queryByTestId('newDialog')).not.toBeOnTheScreen()) }) it('shows new label for multiple providers in expanded view', async () => { // make simplex and moonpay card quotes new jest.spyOn(props.normalizedQuotes[3], 'isProviderNew').mockReturnValue(true) jest.spyOn(props.normalizedQuotes[4], 'isProviderNew').mockReturnValue(true) const { queryByText, queryByTestId, getByText, getByTestId } = render( ) expect(queryByText('selectProviderScreen.card')).toBeTruthy() expect(queryByText('selectProviderScreen.numProviders, {"count":3}')).toBeTruthy() expect(queryByTestId('image-Ramp')).toBeTruthy() expect(queryByTestId('image-Simplex')).toBeTruthy() expect(queryByTestId('image-Moonpay')).toBeTruthy() expect(queryByTestId('newLabel-Ramp')).toBeFalsy() expect(queryByTestId('newLabel-Simplex')).toBeTruthy() expect(queryByTestId('newLabel-Moonpay')).toBeTruthy() expect(queryByTestId('newDialog')).toBeFalsy() fireEvent.press(getByTestId('newLabel-Simplex')) expect(getByTestId('newDialog')).toBeVisible() fireEvent.press(getByTestId('newDialog/PrimaryAction')) await waitFor(() => expect(queryByTestId('newDialog')).not.toBeOnTheScreen()) fireEvent.press(getByTestId('newLabel-Moonpay')) expect(getByTestId('newDialog')).toBeVisible() // Collapse works fireEvent.press(getByText('selectProviderScreen.numProviders, {"count":3}')) expect(queryByTestId('image-Ramp')).toBeFalsy() expect(queryByTestId('image-Simplex')).toBeFalsy() expect(queryByTestId('image-Moonpay')).toBeFalsy() }) it('shows "ID required" when KYC is required', async () => { props.normalizedQuotes = normalizeQuotes({ flow: CICOFlow.CashIn, fiatConnectQuotes: [mockFiatConnectQuotes[3]] as FiatConnectQuoteSuccess[], cicoQuotes: [], tokenId: mockCusdTokenId, }) props.paymentMethod = PaymentMethod.Bank const { queryByTestId } = render( ) const infoElement = queryByTestId('Bank/provider-0/info') expect(infoElement).toBeTruthy() expect(infoElement).toHaveTextContent( 'selectProviderScreen.idRequired | selectProviderScreen.xToYDays, {"lowerBound":1,"upperBound":3}' ) }) it('shows no ID requirement when KYC not required', async () => { props.normalizedQuotes = normalizeQuotes({ flow: CICOFlow.CashIn, fiatConnectQuotes: [mockFiatConnectQuotes[1]] as FiatConnectQuoteSuccess[], cicoQuotes: [], tokenId: mockCusdTokenId, }) props.paymentMethod = PaymentMethod.Bank const { queryByTestId } = render( ) const infoElement = queryByTestId('Bank/provider-0/info') expect(infoElement).toBeTruthy() expect(infoElement).toHaveTextContent( 'selectProviderScreen.xToYHours, {"lowerBound":1,"upperBound":2}' ) expect(infoElement).not.toHaveTextContent('selectProviderScreen.idRequired') }) it.each([ [ PaymentMethod.Card as const, normalizeQuotes({ flow: CICOFlow.CashIn, fiatConnectQuotes: [], cicoQuotes: [mockCicoQuotes[3]], tokenId: mockCusdTokenId, }), 'card', 'oneHour', ], [ PaymentMethod.Bank as const, normalizeQuotes({ flow: CICOFlow.CashIn, fiatConnectQuotes: [mockFiatConnectQuotes[1]] as FiatConnectQuoteSuccess[], cicoQuotes: [], tokenId: mockCusdTokenId, }), 'bank', 'xToYHours', ], [ PaymentMethod.FiatConnectMobileMoney as const, normalizeQuotes({ flow: CICOFlow.CashIn, fiatConnectQuotes: [mockFiatConnectQuotes[4]] as FiatConnectQuoteSuccess[], cicoQuotes: [], tokenId: mockCusdTokenId, }), 'mobileMoney', 'xHours', ], ])('shows appropriate title and settlement time for %s', (paymentMethod, quotes, title, info) => { props.normalizedQuotes = quotes props.paymentMethod = paymentMethod const { getByText, getByTestId } = render( ) expect(getByText(`selectProviderScreen.${title}`)).toBeTruthy() expect(getByTestId(`${paymentMethod}/provider-0/info`)).toHaveTextContent( `selectProviderScreen.${info}` ) }) })