diff --git a/app/components/Approvals/PermissionApproval/PermissionApproval.test.tsx b/app/components/Approvals/PermissionApproval/PermissionApproval.test.tsx
index e217c36f813..b22b6c8d366 100644
--- a/app/components/Approvals/PermissionApproval/PermissionApproval.test.tsx
+++ b/app/components/Approvals/PermissionApproval/PermissionApproval.test.tsx
@@ -1,6 +1,5 @@
import React from 'react';
import useApprovalRequest from '../../hooks/useApprovalRequest';
-import { shallow } from 'enzyme';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import { ApprovalRequest } from '@metamask/approval-controller';
import PermissionApproval from './PermissionApproval';
@@ -9,6 +8,7 @@ import AnalyticsV2 from '../../../util/analyticsV2';
import { useSelector } from 'react-redux';
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('../../../util/analyticsV2');
@@ -63,7 +63,7 @@ describe('PermissionApproval', () => {
jest.resetAllMocks();
});
- it('navigates', () => {
+ it('navigates', async () => {
const navigationMock = {
navigate: jest.fn(),
};
@@ -75,7 +75,7 @@ describe('PermissionApproval', () => {
mockCreateAccountConnectNavDetails(NAV_DETAILS_MOCK);
- shallow();
+ render();
expect(navigationMock.navigate).toHaveBeenCalledTimes(1);
expect(navigationMock.navigate).toHaveBeenCalledWith(NAV_DETAILS_MOCK[0]);
@@ -87,7 +87,7 @@ describe('PermissionApproval', () => {
});
});
- it('generates analytics', () => {
+ it('generates analytics', async () => {
const navigationMock = {
navigate: jest.fn(),
};
@@ -114,7 +114,7 @@ describe('PermissionApproval', () => {
},
});
- shallow();
+ render();
expect(AnalyticsV2.trackEvent).toHaveBeenCalledTimes(1);
expect(AnalyticsV2.trackEvent).toHaveBeenCalledWith(
@@ -126,19 +126,19 @@ describe('PermissionApproval', () => {
);
});
- it('returns null if no approval request', () => {
+ it('does not navigate if no approval request', async () => {
const navigationMock = {
navigate: jest.fn(),
};
mockApprovalRequest(undefined);
- expect(shallow()).toEqual(
- {},
- );
+ render();
+
+ expect(navigationMock.navigate).toHaveBeenCalledTimes(0);
});
- it('returns null if incorrect approval request type', () => {
+ it('does not navigate if incorrect approval request type', async () => {
const navigationMock = {
navigate: jest.fn(),
};
@@ -148,12 +148,12 @@ describe('PermissionApproval', () => {
requestData: HOST_INFO_MOCK,
} as any);
- expect(shallow()).toEqual(
- {},
- );
+ render();
+
+ expect(navigationMock.navigate).toHaveBeenCalledTimes(0);
});
- it('returns null if no eth_accounts permission', () => {
+ it('does not navigate if no eth_accounts permission', async () => {
const navigationMock = {
navigate: jest.fn(),
};
@@ -163,8 +163,64 @@ describe('PermissionApproval', () => {
requestData: { ...HOST_INFO_MOCK, permissions: { eth_accounts: false } },
} as any);
- expect(shallow()).toEqual(
- {},
+ render();
+
+ expect(navigationMock.navigate).toHaveBeenCalledTimes(0);
+ });
+
+ it('does not navigate if still processing', async () => {
+ const navigationMock = {
+ navigate: jest.fn(),
+ };
+
+ mockCreateAccountConnectNavDetails(NAV_DETAILS_MOCK);
+
+ mockApprovalRequest({
+ type: ApprovalTypes.REQUEST_PERMISSIONS,
+ requestData: HOST_INFO_MOCK,
+ } as any);
+
+ const { rerender } = render(
+ ,
+ );
+
+ mockApprovalRequest({
+ type: ApprovalTypes.REQUEST_PERMISSIONS,
+ requestData: HOST_INFO_MOCK,
+ } as any);
+
+ rerender();
+
+ expect(navigationMock.navigate).toHaveBeenCalledTimes(1);
+ });
+
+ it('navigates if previous processing finished', async () => {
+ const navigationMock = {
+ navigate: jest.fn(),
+ };
+
+ mockCreateAccountConnectNavDetails(NAV_DETAILS_MOCK);
+
+ mockApprovalRequest({
+ type: ApprovalTypes.REQUEST_PERMISSIONS,
+ requestData: HOST_INFO_MOCK,
+ } as any);
+
+ const { rerender } = render(
+ ,
);
+
+ mockApprovalRequest(undefined);
+
+ rerender();
+
+ mockApprovalRequest({
+ type: ApprovalTypes.REQUEST_PERMISSIONS,
+ requestData: HOST_INFO_MOCK,
+ } as any);
+
+ rerender();
+
+ expect(navigationMock.navigate).toHaveBeenCalledTimes(2);
});
});
diff --git a/app/components/Approvals/PermissionApproval/PermissionApproval.tsx b/app/components/Approvals/PermissionApproval/PermissionApproval.tsx
index 87cf447cb87..f70db700caa 100644
--- a/app/components/Approvals/PermissionApproval/PermissionApproval.tsx
+++ b/app/components/Approvals/PermissionApproval/PermissionApproval.tsx
@@ -1,5 +1,5 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
-import React from 'react';
+import { useEffect, useRef } from 'react';
import useApprovalRequest from '../../hooks/useApprovalRequest';
import { ApprovalTypes } from '../../../core/RPCMethods/RPCMethodMiddleware';
import AnalyticsV2 from '../../../util/analyticsV2';
@@ -15,28 +15,38 @@ export interface PermissionApprovalProps {
const PermissionApproval = (props: PermissionApprovalProps) => {
const { approvalRequest } = useApprovalRequest();
const totalAccounts = useSelector(selectAccountsLength);
+ const isProcessing = useRef(false);
- if (approvalRequest?.type !== ApprovalTypes.REQUEST_PERMISSIONS) return null;
+ useEffect(() => {
+ if (approvalRequest?.type !== ApprovalTypes.REQUEST_PERMISSIONS) {
+ isProcessing.current = false;
+ return;
+ }
- const requestData = approvalRequest?.requestData;
+ const requestData = approvalRequest?.requestData;
- if (!requestData?.permissions?.eth_accounts) return null;
+ if (!requestData?.permissions?.eth_accounts) return;
- const {
- metadata: { id },
- } = requestData;
+ const {
+ metadata: { id },
+ } = requestData;
- AnalyticsV2.trackEvent(MetaMetricsEvents.CONNECT_REQUEST_STARTED, {
- number_of_accounts: totalAccounts,
- source: 'PERMISSION SYSTEM',
- });
+ if (isProcessing.current) return;
- props.navigation.navigate(
- ...createAccountConnectNavDetails({
- hostInfo: requestData,
- permissionRequestId: id,
- }),
- );
+ isProcessing.current = true;
+
+ AnalyticsV2.trackEvent(MetaMetricsEvents.CONNECT_REQUEST_STARTED, {
+ number_of_accounts: totalAccounts,
+ source: 'PERMISSION SYSTEM',
+ });
+
+ props.navigation.navigate(
+ ...createAccountConnectNavDetails({
+ hostInfo: requestData,
+ permissionRequestId: id,
+ }),
+ );
+ }, [approvalRequest, totalAccounts, props.navigation]);
return null;
};