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}`
)
})
})