Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ import { FIAT_ORDER_STATES } from '../../../../../../constants/on-ramp';
import { processFiatOrder } from '../../../index';
import { useTheme } from '../../../../../../util/theme';
import { RootState } from '../../../../../../reducers';
import { hasDepositOrderField } from '../../utils';
import {
getCryptoCurrencyFromTransakId,
hasDepositOrderField,
} from '../../utils';
import { useDepositSDK } from '../../sdk';
import Button, {
ButtonSize,
Expand All @@ -44,6 +47,7 @@ import Button, {
import { SUPPORTED_PAYMENT_METHODS } from '../../constants';
import { DepositOrder } from '@consensys/native-ramps-sdk';
import PrivacySection from '../../components/PrivacySection';
import useAnalytics from '../../../hooks/useAnalytics';

export interface BankDetailsParams {
orderId: string;
Expand All @@ -59,7 +63,8 @@ const BankDetails = () => {
const { colors } = useTheme();
const dispatch = useDispatch();
const dispatchThunk = useThunkDispatch();
const { sdk } = useDepositSDK();
const { sdk, selectedWalletAddress, selectedRegion } = useDepositSDK();
const trackEvent = useAnalytics();

const { orderId, shouldUpdate = true } = useParams<BankDetailsParams>();
const order = useSelector((state: RootState) => getOrderById(state, orderId));
Expand Down Expand Up @@ -210,6 +215,25 @@ const BankDetails = () => {
return;
}

const cryptoCurrency = getCryptoCurrencyFromTransakId(
order.data.cryptoCurrency,
);

trackEvent('RAMPS_TRANSACTION_CONFIRMED', {
ramp_type: 'DEPOSIT',
amount_source: Number(order.data.fiatAmount),
amount_destination: Number(order.cryptoAmount),
exchange_rate: Number(order.data.exchangeRate),
gas_fee: 0, //Number(order.data.gasFee),
processing_fee: 0, //Number(order.data.processingFee),
total_fee: Number(order.data.totalFeesFiat),
payment_method_id: order.data.paymentMethod,
country: selectedRegion?.isoCode || '',
chain_id: cryptoCurrency?.chainId || '',
currency_destination: selectedWalletAddress || order.data.walletAddress,
currency_source: order.data.fiatCurrency,
});

await confirmPayment(order.id, paymentOptionId);

await handleOnRefresh();
Expand All @@ -222,7 +246,15 @@ const BankDetails = () => {
} catch (fetchError) {
console.error(fetchError);
}
}, [navigation, confirmPayment, handleOnRefresh, order]);
}, [
navigation,
confirmPayment,
handleOnRefresh,
order,
selectedRegion?.isoCode,
selectedWalletAddress,
trackEvent,
]);

const handleCancelOrder = useCallback(async () => {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const mockSetOptions = jest.fn();
const mockLinkingOpenURL = jest.fn();
const mockUseDepositSDK = jest.fn();
const mockCancelOrder = jest.fn();
const mockTrackEvent = jest.fn();

jest.mock('@react-navigation/native', () => {
const actualNav = jest.requireActual('@react-navigation/native');
Expand Down Expand Up @@ -58,6 +59,8 @@ jest.mock('../../hooks/useDepositSdkMethod', () => ({
}),
}));

jest.mock('../../../hooks/useAnalytics', () => () => mockTrackEvent);

describe('OrderProcessing Component', () => {
const mockOrder = {
id: 'test-order-id',
Expand All @@ -71,15 +74,37 @@ describe('OrderProcessing Component', () => {
data: {
cryptoCurrency: 'USDC',
providerOrderLink: 'https://transak.com/order/123',
fiatAmount: '100',
exchangeRate: '2000',
totalFeesFiat: '2.50',
networkFees: '2.50',
partnerFees: '2.50',
paymentMethod: 'credit_debit_card',
walletAddress: '0x1234567890123456789012345678901234567890',
fiatCurrency: 'USD',
},
};

const mockSelectedRegion = {
isoCode: 'US',
flag: '🇺🇸',
name: 'United States',
currency: 'USD',
supported: true,
};

const mockSelectedWalletAddress =
'0x1234567890123456789012345678901234567890';

beforeEach(() => {
jest.clearAllMocks();
(getOrderById as jest.Mock).mockReturnValue(mockOrder);
mockUseDepositSDK.mockReturnValue({
isAuthenticated: false,
selectedRegion: mockSelectedRegion,
selectedWalletAddress: mockSelectedWalletAddress,
});
mockTrackEvent.mockClear();
});

it('renders success state correctly', () => {
Expand Down Expand Up @@ -180,4 +205,210 @@ describe('OrderProcessing Component', () => {

expect(mockNavigate).toHaveBeenCalledWith(Routes.DEPOSIT.BUILD_QUOTE);
});

describe('Analytics Event Tracking', () => {
describe('RAMPS_TRANSACTION_COMPLETED tracking', () => {
it('tracks RAMPS_TRANSACTION_COMPLETED event when order state is COMPLETED', () => {
renderWithProvider(<OrderProcessing />, {
state: {
engine: {
backgroundState,
},
},
});

expect(mockTrackEvent).toHaveBeenCalledWith(
'RAMPS_TRANSACTION_COMPLETED',
{
ramp_type: 'DEPOSIT',
amount_source: 100,
amount_destination: 0.05,
exchange_rate: 2000,
gas_fee: 2.5,
processing_fee: 2.5,
total_fee: 2.5,
payment_method_id: 'credit_debit_card',
country: 'US',
chain_id: 'eip155:1',
currency_destination: mockSelectedWalletAddress,
currency_source: 'USD',
},
);
});

it('tracks RAMPS_TRANSACTION_COMPLETED with order wallet address when selectedWalletAddress is not available', () => {
mockUseDepositSDK.mockReturnValueOnce({
isAuthenticated: false,
selectedRegion: mockSelectedRegion,
selectedWalletAddress: null,
});

renderWithProvider(<OrderProcessing />, {
state: {
engine: {
backgroundState,
},
},
});

expect(mockTrackEvent).toHaveBeenCalledWith(
'RAMPS_TRANSACTION_COMPLETED',
{
ramp_type: 'DEPOSIT',
amount_source: 100,
amount_destination: 0.05,
exchange_rate: 2000,
gas_fee: 2.5,
processing_fee: 2.5,
total_fee: 2.5,
payment_method_id: 'credit_debit_card',
country: 'US',
chain_id: 'eip155:1',
currency_destination: '0x1234567890123456789012345678901234567890',
currency_source: 'USD',
},
);
});

it('tracks RAMPS_TRANSACTION_COMPLETED with correct number conversions for all numeric fields', () => {
const orderWithStringNumbers = {
...mockOrder,
data: {
...mockOrder.data,
fiatAmount: '250.75',
exchangeRate: '1850.25',
totalFeesFiat: '5.99',
networkFees: '5.99',
partnerFees: '5.99',
},
cryptoAmount: '0.135',
};
(getOrderById as jest.Mock).mockReturnValue(orderWithStringNumbers);

renderWithProvider(<OrderProcessing />, {
state: {
engine: {
backgroundState,
},
},
});

expect(mockTrackEvent).toHaveBeenCalledWith(
'RAMPS_TRANSACTION_COMPLETED',
{
ramp_type: 'DEPOSIT',
amount_source: 250.75,
amount_destination: 0.135,
exchange_rate: 1850.25,
gas_fee: 5.99,
processing_fee: 5.99,
total_fee: 5.99,
payment_method_id: 'credit_debit_card',
country: 'US',
chain_id: 'eip155:1',
currency_destination: mockSelectedWalletAddress,
currency_source: 'USD',
},
);
});
});

describe('RAMPS_TRANSACTION_FAILED tracking', () => {
it('tracks RAMPS_TRANSACTION_FAILED event when order state is FAILED', () => {
const failedOrder = { ...mockOrder, state: FIAT_ORDER_STATES.FAILED };
(getOrderById as jest.Mock).mockReturnValue(failedOrder);

renderWithProvider(<OrderProcessing />, {
state: {
engine: {
backgroundState,
},
},
});

expect(mockTrackEvent).toHaveBeenCalledWith(
'RAMPS_TRANSACTION_FAILED',
{
ramp_type: 'DEPOSIT',
amount_source: 100,
amount_destination: 0.05,
exchange_rate: 2000,
gas_fee: 2.5,
processing_fee: 2.5,
total_fee: 2.5,
payment_method_id: 'credit_debit_card',
country: 'US',
chain_id: 'eip155:1',
currency_destination: mockSelectedWalletAddress,
currency_source: 'USD',
error_message: 'transaction_failed',
},
);
});
});

describe('No analytics tracking scenarios', () => {
it('does not track analytics events for PENDING state', () => {
const pendingOrder = { ...mockOrder, state: FIAT_ORDER_STATES.PENDING };
(getOrderById as jest.Mock).mockReturnValue(pendingOrder);

renderWithProvider(<OrderProcessing />, {
state: {
engine: {
backgroundState,
},
},
});

expect(mockTrackEvent).not.toHaveBeenCalled();
});

it('does not track analytics events for CREATED state', () => {
const createdOrder = { ...mockOrder, state: FIAT_ORDER_STATES.CREATED };
(getOrderById as jest.Mock).mockReturnValue(createdOrder);

renderWithProvider(<OrderProcessing />, {
state: {
engine: {
backgroundState,
},
},
});

expect(mockTrackEvent).not.toHaveBeenCalled();
});

it('does not track analytics events for CANCELLED state', () => {
const cancelledOrder = {
...mockOrder,
state: FIAT_ORDER_STATES.CANCELLED,
};
(getOrderById as jest.Mock).mockReturnValue(cancelledOrder);

renderWithProvider(<OrderProcessing />, {
state: {
engine: {
backgroundState,
},
},
});

expect(mockTrackEvent).not.toHaveBeenCalled();
});

it('does not track analytics events when order is null', () => {
(getOrderById as jest.Mock).mockReturnValue(null);

renderWithProvider(<OrderProcessing />, {
state: {
engine: {
backgroundState,
},
},
});

expect(mockTrackEvent).not.toHaveBeenCalled();
});
});
});
});
Loading
Loading