Skip to content

Commit

Permalink
Merge branch 'main' into chore/tldr-readme
Browse files Browse the repository at this point in the history
  • Loading branch information
jpcloureiro authored Feb 16, 2024
2 parents 00c70ee + 215a969 commit 2f7f001
Show file tree
Hide file tree
Showing 266 changed files with 1,598 additions and 1,102 deletions.
20 changes: 20 additions & 0 deletions app/actions/browser/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
/**
* Browser actions for Redux
*/
export const BrowserActionTypes = {
ADD_TO_VISITED_DAPP: 'ADD_TO_VISITED_DAPP',
};

/**
* Adds a new entry to visited dapps
*
* @param {string} hostname - Dapp hostname
* @returns
*/
export function addToVisitedDapp(hostname) {
return {
type: BrowserActionTypes.ADD_TO_VISITED_DAPP,
hostname,
};
}

/**
* Adds a new entry to the browser history
*
Expand Down
2 changes: 1 addition & 1 deletion app/actions/signatureRequest/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SecurityAlertResponse } from '../../components/UI/BlockaidBanner/BlockaidBanner.types';
import { SecurityAlertResponse } from '../../components/Views/confirmations/components/BlockaidBanner/BlockaidBanner.types';

/**
* Clears transaction object completely
Expand Down
167 changes: 167 additions & 0 deletions app/analytics/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { trackDappVisitedEvent } from './index';
import { MetaMetricsEvents } from '../core/Analytics';
import AnalyticsV2 from '../util/analyticsV2';

// Mock AnalyticsV2
jest.mock('../util/analyticsV2', () => ({
trackEvent: jest.fn(),
}));

// Mock store.getState
let mockGetState: jest.Mock;
jest.mock('../store', () => {
mockGetState = jest.fn();
mockGetState.mockImplementation(() => ({
browser: {
visitedDappsByHostname: {},
},
engine: {
backgroundState: {
PreferencesController: {
identities: { '0x1': true, '0x2': true },
},
},
},
}));

return {
store: {
getState: mockGetState,
dispatch: jest.fn(),
},
};
});

describe('trackDappVisitedEvent', () => {
afterEach(() => {
jest.resetAllMocks();
});

it('should track with isFirstVisit = true', () => {
mockGetState.mockImplementation(() => ({
browser: {
visitedDappsByHostname: {},
},
engine: {
backgroundState: {
PreferencesController: {
identities: { '0x1': true, '0x2': true },
},
},
},
}));

const expectedMetrics = {
is_first_visit: true,
number_of_accounts: 2,
number_of_accounts_connected: 1,
source: 'in-app browser',
};

trackDappVisitedEvent({
hostname: 'uniswap.org',
numberOfConnectedAccounts: 1,
});

expect(AnalyticsV2.trackEvent).toBeCalledWith(
MetaMetricsEvents.DAPP_VISITED,
expectedMetrics,
);
});

it('should track with isFirstVisit = false', () => {
mockGetState.mockImplementation(() => ({
browser: {
visitedDappsByHostname: { 'uniswap.org': true },
},
engine: {
backgroundState: {
PreferencesController: {
identities: { '0x1': true, '0x2': true },
},
},
},
}));

const expectedMetrics = {
is_first_visit: false,
number_of_accounts: 2,
number_of_accounts_connected: 1,
source: 'in-app browser',
};

trackDappVisitedEvent({
hostname: 'uniswap.org',
numberOfConnectedAccounts: 1,
});

expect(AnalyticsV2.trackEvent).toBeCalledWith(
MetaMetricsEvents.DAPP_VISITED,
expectedMetrics,
);
});

it('should track with the correct number of connected accounts', () => {
mockGetState.mockImplementation(() => ({
browser: {
visitedDappsByHostname: { 'uniswap.org': true },
},
engine: {
backgroundState: {
PreferencesController: {
identities: { '0x1': true, '0x2': true },
},
},
},
}));

const expectedMetrics = {
is_first_visit: false,
number_of_accounts: 2,
number_of_accounts_connected: 1,
source: 'in-app browser',
};

trackDappVisitedEvent({
hostname: 'uniswap.org',
numberOfConnectedAccounts: 1,
});

expect(AnalyticsV2.trackEvent).toBeCalledWith(
MetaMetricsEvents.DAPP_VISITED,
expectedMetrics,
);
});

it('should track with the correct number of wallet accounts', () => {
mockGetState.mockImplementation(() => ({
browser: {
visitedDappsByHostname: { 'uniswap.org': true },
},
engine: {
backgroundState: {
PreferencesController: {
identities: { '0x1': true },
},
},
},
}));

const expectedMetrics = {
is_first_visit: false,
number_of_accounts: 1,
number_of_accounts_connected: 1,
source: 'in-app browser',
};

trackDappVisitedEvent({
hostname: 'uniswap.org',
numberOfConnectedAccounts: 1,
});

expect(AnalyticsV2.trackEvent).toBeCalledWith(
MetaMetricsEvents.DAPP_VISITED,
expectedMetrics,
);
});
});
38 changes: 38 additions & 0 deletions app/analytics/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { selectIdentities } from '../selectors/preferencesController';
import { store } from '../store';
import { MetaMetricsEvents } from '../core/Analytics';
import AnalyticsV2 from '../util/analyticsV2';
import { addToVisitedDapp } from '../actions/browser';

/**
* Tracks Dapp visited event
*
* @param hostname - Hostname of the Dapp
* @param numberOfConnectedAccounts - Number of connected accounts that are connected to the Dapp
*/
// This file will export more events in the future.
// eslint-disable-next-line import/prefer-default-export
export const trackDappVisitedEvent = ({
hostname,
numberOfConnectedAccounts,
}: {
hostname: string;
numberOfConnectedAccounts: number;
}) => {
const visitedDappsByHostname =
store.getState().browser.visitedDappsByHostname;
const isFirstVisit = !visitedDappsByHostname[hostname];
const accountByAddress = selectIdentities(store.getState());
const numberOfWalletAccounts = Object.keys(accountByAddress).length;

// Add Dapp hostname to visited dapps
store.dispatch(addToVisitedDapp(hostname));

// Track DAPP_VISITED event
AnalyticsV2.trackEvent(MetaMetricsEvents.DAPP_VISITED, {
is_first_visit: isFirstVisit,
number_of_accounts: numberOfWalletAccounts,
number_of_accounts_connected: numberOfConnectedAccounts,
source: 'in-app browser',
});
};
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import AddChainApproval from './AddChainApproval';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import useApprovalRequest from '../../Views/confirmations/hooks/useApprovalRequest';
import { shallow } from 'enzyme';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import { ApprovalRequest } from '@metamask/approval-controller';

jest.mock('../../hooks/useApprovalRequest');
jest.mock('../../Views/confirmations/hooks/useApprovalRequest');

const mockApprovalRequest = (approvalRequest?: ApprovalRequest<any>) => {
(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import useApprovalRequest from '../../Views/confirmations/hooks/useApprovalRequest';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import NetworkVerificationInfo from '../../UI/NetworkVerificationInfo';
import BottomSheet from '../../../component-library/components/BottomSheets/BottomSheet';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import useApprovalRequest from '../../Views/confirmations/hooks/useApprovalRequest';
import { shallow } from 'enzyme';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import { ApprovalRequest } from '@metamask/approval-controller';
import ConnectApproval from './ConnectApproval';

jest.mock('../../hooks/useApprovalRequest');
jest.mock('../../Views/confirmations/hooks/useApprovalRequest');

const mockApprovalRequest = (approvalRequest?: ApprovalRequest<any>) => {
(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import useApprovalRequest from '../../Views/confirmations/hooks/useApprovalRequest';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import ApprovalModal from '../ApprovalModal';
import AccountApproval from '../../UI/AccountApproval';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React from 'react';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import useApprovalRequest from '../../Views/confirmations/hooks/useApprovalRequest';
import { shallow } from 'enzyme';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import {
ApprovalFlowState,
ApprovalRequest,
} from '@metamask/approval-controller';
import FlowLoaderModal from './FlowLoaderModal';
import useApprovalFlow from '../../hooks/useApprovalFlow';
import useApprovalFlow from '../../Views/confirmations/hooks/useApprovalFlow';

jest.mock('../../hooks/useApprovalRequest');
jest.mock('../../hooks/useApprovalFlow');
jest.mock('../../Views/confirmations/hooks/useApprovalRequest');
jest.mock('../../Views/confirmations/hooks/useApprovalFlow');

const APPROVAL_FLOW_MOCK: ApprovalFlowState = {
id: 'testId1',
Expand Down
6 changes: 3 additions & 3 deletions app/components/Approvals/FlowLoaderModal/FlowLoaderModal.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useCallback } from 'react';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import useApprovalRequest from '../../Views/confirmations/hooks/useApprovalRequest';
import ApprovalModal from '../ApprovalModal';
import useApprovalFlow from '../../hooks/useApprovalFlow';
import ApprovalFlowLoader from '../../UI/Approval/ApprovalFlowLoader';
import useApprovalFlow from '../../Views/confirmations/hooks/useApprovalFlow';
import ApprovalFlowLoader from '../../Views/confirmations/components/Approval/ApprovalFlowLoader';

const FlowLoaderModal = () => {
const { approvalRequest } = useApprovalRequest();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
///: BEGIN:ONLY_INCLUDE_IF(snaps)
import React, { useEffect, useState } from 'react';
import ApprovalModal from '../ApprovalModal';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import useApprovalRequest from '../../Views/confirmations/hooks/useApprovalRequest';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import Logger from '../../../util/Logger';
import { SnapInstallState } from './InstallSnapApproval.types';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from 'react';
import { render, fireEvent, waitFor } from '@testing-library/react-native';
import InstallSnapApproval from '../InstallSnapApproval';
import { ApprovalRequest } from '@metamask/approval-controller';
import useApprovalRequest from '../../../hooks/useApprovalRequest';
import useApprovalRequest from '../../../Views/confirmations/hooks/useApprovalRequest';
import {
SNAP_INSTALL_CANCEL,
SNAP_INSTALL_CONNECTION_REQUEST,
Expand All @@ -15,7 +15,7 @@ import {
import SNAP_INSTALL_SUCCESS from '../components/InstallSnapSuccess/InstallSnapSuccess.constants';
import SNAP_INSTALL_ERROR from '../components/InstallSnapError/InstallSnapError.constants';

jest.mock('../../../hooks/useApprovalRequest');
jest.mock('../../../Views/confirmations/hooks/useApprovalRequest');

const onConfirm = jest.fn();
const onReject = jest.fn();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import useApprovalRequest from '../../Views/confirmations/hooks/useApprovalRequest';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import { ApprovalRequest } from '@metamask/approval-controller';
import PermissionApproval from './PermissionApproval';
Expand All @@ -10,7 +10,7 @@ import { MetaMetricsEvents } from '../../../core/Analytics';
import initialBackgroundState from '../../../util/test/initial-background-state.json';
import { render } from '@testing-library/react-native';

jest.mock('../../hooks/useApprovalRequest');
jest.mock('../../Views/confirmations/hooks/useApprovalRequest');
jest.mock('../../../util/analyticsV2');

jest.mock('../../Views/AccountConnect', () => ({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { useEffect, useRef } from 'react';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import useApprovalRequest from '../../Views/confirmations/hooks/useApprovalRequest';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import AnalyticsV2 from '../../../util/analyticsV2';
import { MetaMetricsEvents } from '../../../core/Analytics';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import useApprovalRequest from '../../Views/confirmations/hooks/useApprovalRequest';
import { shallow } from 'enzyme';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import { ApprovalRequest } from '@metamask/approval-controller';
import SignatureApproval from './SignatureApproval';

jest.mock('../../hooks/useApprovalRequest');
jest.mock('../../Views/confirmations/hooks/useApprovalRequest');

const mockApprovalRequest = (approvalRequest?: ApprovalRequest<any>) => {
(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useCallback } from 'react';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import useApprovalRequest from '../../Views/confirmations/hooks/useApprovalRequest';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import SignatureRequestRoot from '../../UI/SignatureRequest/Root';
import SignatureRequestRoot from '../../Views/confirmations/components/SignatureRequest/Root';

const SignatureApproval = () => {
const { approvalRequest, onReject, onConfirm } = useApprovalRequest();
Expand Down
Loading

0 comments on commit 2f7f001

Please sign in to comment.