Skip to content

Commit 095fd84

Browse files
refactor(analytics): migrate Batch 3-8: mobile-platform (#26387)
## **Description** Phase 3 analytics migration (Batch 3-8): migrate Account Backup/Recovery components from `useMetrics` to the new analytics system (`useAnalytics`). **Reason**: Deprecate MetaMetrics in favour of the shared analytics utility and AnalyticsController. **Changes**: `SRPListItem`, `SRPList`, `SRPQuiz`, `ManualBackupStep1`, and `ManualBackupStep2` now use `useAnalytics` from `app/components/hooks/useAnalytics/useAnalytics` instead of `useMetrics`; test mocks updated to mock `useAnalytics` instead of `useMetrics`. ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: https://consensyssoftware.atlassian.net/browse/MCWP-301 (Batch 3-8) ## **Manual testing steps** ```gherkin Feature: Account Backup/Recovery analytics Scenario: user triggers an account backup/recovery flow event Given app is open and user is in an account backup/recovery flow When user performs an action that triggers analytics (e.g. SRP picker selection, SRP quiz progression, seed phrase reveal) Then the event is tracked on Mixpanel ``` ## **Screenshots/Recordings** N/A – analytics migration, no UI change. ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Primarily a hook migration from `useMetrics` to `useAnalytics` with no functional flow changes; risk is limited to potential missing/incorrect analytics wiring due to API/mocking differences. > > **Overview** > Migrates SRP backup/recovery UI surfaces (`SRPList`, `SRPListItem`, `ManualBackupStep1`, `ManualBackupStep2`, and `SRPQuiz`) from the deprecated `useMetrics` hook to the new `useAnalytics` hook while keeping existing event names/properties and event-builder usage. > > Updates the associated Jest tests to mock `useAnalytics` instead of `useMetrics`, including adjusting mocked IDs (`getMetaMetricsId` `getAnalyticsId`) and providing a compatible `createEventBuilder` mock shape where needed. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 988af76. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent a14a1f2 commit 095fd84

9 files changed

Lines changed: 36 additions & 36 deletions

File tree

app/components/UI/SRPList/SRPList.test.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@ import { fireEvent } from '@testing-library/react-native';
1616
import ExtendedKeyringTypes from '../../../constants/keyringTypes';
1717
import { MetaMetricsEvents } from '../../../core/Analytics/MetaMetrics.events';
1818
import { MetricsEventBuilder } from '../../../core/Analytics/MetricsEventBuilder';
19-
import useMetrics from '../../hooks/useMetrics/useMetrics';
2019

2120
const mockTrackEvent = jest.fn();
22-
jest.mock('../../hooks/useMetrics/useMetrics', () => ({
23-
__esModule: true,
24-
default: jest.fn(),
21+
jest.mock('../../hooks/useAnalytics/useAnalytics', () => ({
22+
useAnalytics: jest.fn(),
2523
}));
2624

2725
jest.mock('../../../core/Engine', () => {
@@ -78,7 +76,10 @@ const getTestId = (selector: string, keyringId: string) =>
7876
describe('SRPList', () => {
7977
beforeEach(() => {
8078
jest.clearAllMocks();
81-
(useMetrics as jest.Mock).mockReturnValue({
79+
const { useAnalytics } = jest.requireMock(
80+
'../../hooks/useAnalytics/useAnalytics',
81+
);
82+
(useAnalytics as jest.Mock).mockReturnValue({
8283
trackEvent: mockTrackEvent,
8384
createEventBuilder: MetricsEventBuilder.createEventBuilder,
8485
});

app/components/UI/SRPList/SRPList.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import SRPListItem from '../SRPListItem';
99
import { SRPListSelectorsIDs } from './SRPList.testIds';
1010
import { useHdKeyringsWithSnapAccounts } from '../../hooks/useHdKeyringsWithSnapAccounts';
1111
import { MetaMetricsEvents } from '../../../core/Analytics/MetaMetrics.events';
12-
import useMetrics from '../../hooks/useMetrics/useMetrics';
12+
import { useAnalytics } from '../../hooks/useAnalytics/useAnalytics';
1313
import { useSyncSRPs } from '../../hooks/useSyncSRPs';
1414

1515
const SRPList = ({
@@ -24,7 +24,7 @@ const SRPList = ({
2424
const maxHeight = windowHeight * 0.7;
2525
const { styles } = useStyles(styleSheet, { maxHeight });
2626
const hdKeyringsWithSnapAccounts = useHdKeyringsWithSnapAccounts();
27-
const { trackEvent, createEventBuilder } = useMetrics();
27+
const { trackEvent, createEventBuilder } = useAnalytics();
2828

2929
return (
3030
<View

app/components/UI/SRPListItem/SRPListItem.test.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,10 @@ import SRPListItem from './SRPListItem';
1818
import ExtendedKeyringTypes from '../../../constants/keyringTypes';
1919
import { MetaMetricsEvents } from '../../../core/Analytics/MetaMetrics.events';
2020
import { MetricsEventBuilder } from '../../../core/Analytics/MetricsEventBuilder';
21-
import useMetrics from '../../hooks/useMetrics/useMetrics';
2221

2322
const mockTrackEvent = jest.fn();
24-
jest.mock('../../hooks/useMetrics/useMetrics', () => ({
25-
__esModule: true,
26-
default: jest.fn(),
23+
jest.mock('../../hooks/useAnalytics/useAnalytics', () => ({
24+
useAnalytics: jest.fn(),
2725
}));
2826

2927
jest.mock('../../../core/Engine', () => {
@@ -134,7 +132,10 @@ const getTestId = (selector: string, keyringId: string) =>
134132
describe('SRPList', () => {
135133
beforeEach(() => {
136134
jest.clearAllMocks();
137-
(useMetrics as jest.Mock).mockReturnValue({
135+
const { useAnalytics } = jest.requireMock(
136+
'../../hooks/useAnalytics/useAnalytics',
137+
);
138+
(useAnalytics as jest.Mock).mockReturnValue({
138139
trackEvent: mockTrackEvent,
139140
createEventBuilder: MetricsEventBuilder.createEventBuilder,
140141
});

app/components/UI/SRPListItem/SRPListItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Avatar, {
2323
} from '../../../component-library/components/Avatars/Avatar';
2424
import { useSelector } from 'react-redux';
2525
import { MetaMetricsEvents } from '../../../core/Analytics/MetaMetrics.events';
26-
import useMetrics from '../../hooks/useMetrics/useMetrics';
26+
import { useAnalytics } from '../../hooks/useAnalytics/useAnalytics';
2727
import { selectAvatarAccountType } from '../../../selectors/settings';
2828
import { selectAccountGroupsByKeyringId } from '../../../selectors/multisrp';
2929
import { RootState } from '../../../reducers';
@@ -71,7 +71,7 @@ const SRPListItem = ({
7171
showArrowName = '',
7272
}: SRPListItemProps) => {
7373
const { styles } = useStyles(styleSheet, {});
74-
const { trackEvent, createEventBuilder } = useMetrics();
74+
const { trackEvent, createEventBuilder } = useAnalytics();
7575
const [showAccounts, setShowAccounts] = useState(false);
7676
const accountAvatarType = useSelector(selectAvatarAccountType);
7777

app/components/Views/ManualBackupStep1/index.test.tsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,19 @@ jest.mock('../../../util/theme', () => ({
7474
},
7575
}));
7676

77-
// Mock useMetrics hook
77+
// Mock useAnalytics hook
7878
const mockIsMetricsEnabled = jest.fn().mockReturnValue(true);
79-
jest.mock('../../hooks/useMetrics', () => ({
80-
useMetrics: () => ({
79+
jest.mock('../../hooks/useAnalytics/useAnalytics', () => ({
80+
useAnalytics: () => ({
8181
isEnabled: mockIsMetricsEnabled,
8282
enable: jest.fn(),
8383
addTraitsToUser: jest.fn(),
84-
createEventBuilder: jest.fn(),
84+
createEventBuilder: jest.fn(() => ({
85+
addProperties: jest.fn(() => ({ build: jest.fn() })),
86+
build: jest.fn(),
87+
})),
8588
trackEvent: jest.fn(),
86-
trackAnonymousEvent: jest.fn(),
87-
getMetaMetricsId: jest.fn(),
89+
getAnalyticsId: jest.fn(),
8890
}),
8991
}));
9092

app/components/Views/ManualBackupStep1/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ import Label from '../../../component-library/components/Form/Label';
5454
import TextField from '../../../component-library/components/Form/TextField/TextField';
5555
import { saveOnboardingEvent as saveEvent } from '../../../actions/onboarding';
5656
import { AppThemeKey } from '../../../util/theme/models';
57-
import { useMetrics } from '../../hooks/useMetrics';
57+
import { useAnalytics } from '../../hooks/useAnalytics/useAnalytics';
5858
import {
5959
createTrackFunction,
6060
handleSkipBackup,
@@ -92,7 +92,7 @@ const ManualBackupStep1 = () => {
9292
const [hasFunds, setHasFunds] = useState(false);
9393
const { colors, themeAppearance } = useTheme();
9494
const styles = useMemo(() => createStyles(colors), [colors]);
95-
const { isEnabled: isMetricsEnabled } = useMetrics();
95+
const { isEnabled: isMetricsEnabled } = useAnalytics();
9696

9797
const backupFlow = route?.params?.backupFlow || false;
9898
const settingsBackup = route?.params?.settingsBackup || false;

app/components/Views/ManualBackupStep2/index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import Text, {
3232
TextColor,
3333
} from '../../../component-library/components/Texts/Text';
3434
import Routes from '../../../constants/navigation/Routes';
35-
import { useMetrics } from '../../hooks/useMetrics';
35+
import { useAnalytics } from '../../hooks/useAnalytics/useAnalytics';
3636
import { CommonActions } from '@react-navigation/native';
3737
import { ONBOARDING_SUCCESS_FLOW } from '../../../constants/onboarding';
3838
import { TraceName, endTrace } from '../../../util/trace';
@@ -100,7 +100,7 @@ const ManualBackupStep2 = ({
100100
return gridWords.filter((word) => word !== '').length === validWords.length;
101101
}, [route.params?.words, gridWords]);
102102

103-
const { isEnabled: isMetricsEnabled } = useMetrics();
103+
const { isEnabled: isMetricsEnabled } = useAnalytics();
104104
const goNext = () => {
105105
if (validateWords()) {
106106
seedphraseBackedUp();

app/components/Views/ManualBackupStep2/index.test.tsx

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,13 @@ jest
7272
const mockMath = Object.create(global.Math);
7373
mockMath.random = () => 0.5;
7474

75-
// mock useMetrics
75+
// mock useAnalytics
7676
const mockMetricsIsEnabled = jest.fn().mockReturnValue(true);
77-
jest.mock('../../../components/hooks/useMetrics', () => {
78-
const actual = jest.requireActual('../../../components/hooks/useMetrics');
79-
return {
80-
...actual,
81-
useMetrics: () => ({
82-
isEnabled: mockMetricsIsEnabled,
83-
}),
84-
};
85-
});
77+
jest.mock('../../hooks/useAnalytics/useAnalytics', () => ({
78+
useAnalytics: () => ({
79+
isEnabled: mockMetricsIsEnabled,
80+
}),
81+
}));
8682

8783
describe('ManualBackupStep2', () => {
8884
const mockWords = [

app/components/Views/Quiz/SRPQuiz/SRPQuiz.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { SRP_GUIDE_URL } from '../../../../constants/urls';
1919
import { QuizStage } from '../types';
2020
import { QuizContent } from '../QuizContent';
2121
import stylesheet from './styles';
22-
import { useMetrics } from '../../../../components/hooks/useMetrics';
22+
import { useAnalytics } from '../../../../components/hooks/useAnalytics/useAnalytics';
2323

2424
import {
2525
SrpQuizGetStartedSelectorsIDs,
@@ -55,7 +55,7 @@ const SRPQuiz = (props: SRPQuizProps) => {
5555
const { styles, theme } = useStyles(stylesheet, {});
5656
const { colors } = theme;
5757
const navigation = useNavigation();
58-
const { trackEvent, createEventBuilder } = useMetrics();
58+
const { trackEvent, createEventBuilder } = useAnalytics();
5959

6060
const dismissModal = (): void => {
6161
modalRef.current?.onCloseBottomSheet();

0 commit comments

Comments
 (0)