diff --git a/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.test.ts index 4489690654d5..f7f9dd25d4b8 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.test.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.test.ts @@ -76,6 +76,7 @@ describe('useTokenValues', () => { decodedTransferValue: '7', displayTransferValue: '7', fiatDisplayValue: '$6.37', + fiatValue: 6.37, pending: false, }); }); @@ -122,6 +123,7 @@ describe('useTokenValues', () => { decodedTransferValue: '7', displayTransferValue: '7', fiatDisplayValue: null, + fiatValue: null, pending: false, }); }); diff --git a/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts b/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts index 53987ffd06e6..b53e2842e5e7 100644 --- a/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts +++ b/ui/pages/confirmations/components/confirm/info/hooks/use-token-values.ts @@ -89,6 +89,7 @@ export const useTokenValues = (transactionMeta: TransactionMeta) => { decodedTransferValue, displayTransferValue, fiatDisplayValue, + fiatValue, pending: pending || isDecodedTransferValuePending, }; }; diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useSendingValueMetric.test.ts b/ui/pages/confirmations/components/confirm/info/hooks/useSendingValueMetric.test.ts new file mode 100644 index 000000000000..c143dc2879cd --- /dev/null +++ b/ui/pages/confirmations/components/confirm/info/hooks/useSendingValueMetric.test.ts @@ -0,0 +1,104 @@ +import { TransactionMeta } from '@metamask/transaction-controller'; +import { renderHook } from '@testing-library/react-hooks'; +import { useEffect, useState } from 'react'; +import { genUnapprovedTokenTransferConfirmation } from '../../../../../../../test/data/confirmations/token-transfer'; +import { useTransactionEventFragment } from '../../../../hooks/useTransactionEventFragment'; +import { useSendingValueMetric } from './useSendingValueMetric'; + +jest.mock('react-redux', () => ({ + ...jest.requireActual('react-redux'), + useSelector: jest.fn(), +})); + +jest.mock('react', () => ({ + ...jest.requireActual('react'), + useEffect: jest.fn(), + useState: jest.fn(), +})); + +jest.mock('../../../../hooks/useTransactionEventFragment'); + +describe('useSimulationMetrics', () => { + const useTransactionEventFragmentMock = jest.mocked( + useTransactionEventFragment, + ); + + const useStateMock = jest.mocked(useState); + const useEffectMock = jest.mocked(useEffect); + + // TODO: Replace `any` with type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let updateTransactionEventFragmentMock: jest.MockedFunction; + + beforeEach(() => { + jest.resetAllMocks(); + + updateTransactionEventFragmentMock = jest.fn(); + + useTransactionEventFragmentMock.mockReturnValue({ + updateTransactionEventFragment: updateTransactionEventFragmentMock, + }); + + // TODO: Replace `any` with type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + useStateMock.mockImplementation(((initialValue: any) => [ + initialValue, + jest.fn(), + // TODO: Replace `any` with type + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ]) as any); + + useEffectMock.mockImplementation((fn) => fn()); + }); + + describe('useSendingValueMetric', () => { + it('Updates the event property', async () => { + const MOCK_FIAT_VALUE = 10; + const transactionMeta = genUnapprovedTokenTransferConfirmation( + {}, + ) as TransactionMeta; + const props = { transactionMeta, fiatValue: MOCK_FIAT_VALUE }; + + renderHook(() => useSendingValueMetric(props)); + + expect(updateTransactionEventFragmentMock).toHaveBeenCalledWith( + expect.objectContaining({ + properties: expect.objectContaining({ + sending_value: MOCK_FIAT_VALUE, + }), + }), + '1d7c08c0-fe54-11ee-9243-91b1e533746a', + ); + + jest.restoreAllMocks(); + }); + + it('Does not updates the event property if fiat value is undefined', async () => { + const MOCK_FIAT_VALUE = undefined; + const transactionMeta = genUnapprovedTokenTransferConfirmation( + {}, + ) as TransactionMeta; + const props = { transactionMeta, fiatValue: MOCK_FIAT_VALUE }; + + renderHook(() => useSendingValueMetric(props)); + + expect(updateTransactionEventFragmentMock).not.toHaveBeenCalled(); + + jest.restoreAllMocks(); + }); + + it('Does not updates the event property if fiat value is empty string', async () => { + const MOCK_FIAT_VALUE = '' as const; + const transactionMeta = genUnapprovedTokenTransferConfirmation( + {}, + ) as TransactionMeta; + const props = { transactionMeta, fiatValue: MOCK_FIAT_VALUE }; + + renderHook(() => useSendingValueMetric(props)); + + expect(updateTransactionEventFragmentMock).not.toHaveBeenCalled(); + + jest.restoreAllMocks(); + }); + }); +}); diff --git a/ui/pages/confirmations/components/confirm/info/hooks/useSendingValueMetric.ts b/ui/pages/confirmations/components/confirm/info/hooks/useSendingValueMetric.ts new file mode 100644 index 000000000000..06d7bff39c03 --- /dev/null +++ b/ui/pages/confirmations/components/confirm/info/hooks/useSendingValueMetric.ts @@ -0,0 +1,26 @@ +import { TransactionMeta } from '@metamask/transaction-controller'; +import { useEffect } from 'react'; +import { useTransactionEventFragment } from '../../../../hooks/useTransactionEventFragment'; + +export type UseSendingValueMetricProps = { + transactionMeta: TransactionMeta; + fiatValue: number | undefined | ''; +}; + +export const useSendingValueMetric = ({ + transactionMeta, + fiatValue, +}: UseSendingValueMetricProps) => { + const { updateTransactionEventFragment } = useTransactionEventFragment(); + + const transactionId = transactionMeta.id; + const properties = { sending_value: fiatValue }; + const sensitiveProperties = {}; + const params = { properties, sensitiveProperties }; + + useEffect(() => { + if (fiatValue !== undefined && fiatValue !== '') { + updateTransactionEventFragment(params, transactionId); + } + }, [updateTransactionEventFragment, transactionId, JSON.stringify(params)]); +}; diff --git a/ui/pages/confirmations/components/confirm/info/shared/native-send-heading/native-send-heading.tsx b/ui/pages/confirmations/components/confirm/info/shared/native-send-heading/native-send-heading.tsx index f3f1f292fa2e..146eb6f169c7 100644 --- a/ui/pages/confirmations/components/confirm/info/shared/native-send-heading/native-send-heading.tsx +++ b/ui/pages/confirmations/components/confirm/info/shared/native-send-heading/native-send-heading.tsx @@ -32,6 +32,7 @@ import { import { getMultichainNetwork } from '../../../../../../../selectors/multichain'; import { useConfirmContext } from '../../../../../context/confirm'; import { formatAmount } from '../../../../simulation-details/formatAmount'; +import { useSendingValueMetric } from '../../hooks/useSendingValueMetric'; const NativeSendHeading = () => { const { currentConfirmation: transactionMeta } = @@ -114,6 +115,8 @@ const NativeSendHeading = () => { ); + useSendingValueMetric({ transactionMeta, fiatValue }); + return ( { decodedTransferValue, displayTransferValue, fiatDisplayValue, + fiatValue, pending, } = useTokenValues(transactionMeta); @@ -85,6 +87,8 @@ const SendHeading = () => { ); + useSendingValueMetric({ transactionMeta, fiatValue }); + if (pending) { return ; }