Skip to content

Commit 17772c5

Browse files
committed
fix: compliance modal appear once on asset page
1 parent 9355fcc commit 17772c5

3 files changed

Lines changed: 58 additions & 3 deletions

File tree

app/components/UI/Compliance/AccessRestrictedModal/AccessRestrictedModal.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import {
77
FontWeight,
88
ButtonBase,
99
ButtonBaseSize,
10+
BottomSheet,
1011
BottomSheetHeader,
1112
} from '@metamask/design-system-react-native';
12-
import BottomSheet from '../../../../component-library/components/BottomSheets/BottomSheet';
1313
import { strings } from '../../../../../locales/i18n';
1414
import { AccessRestrictedModalProps } from './AccessRestrictedModal.types';
1515
import { AccessRestrictedModalSelectorsIDs } from './AccessRestrictedModal.testIds';
@@ -23,7 +23,6 @@ const AccessRestrictedModal: React.FC<AccessRestrictedModalProps> = ({
2323

2424
return (
2525
<BottomSheet
26-
shouldNavigateBack={false}
2726
onClose={onClose}
2827
testID={AccessRestrictedModalSelectorsIDs.BOTTOM_SHEET}
2928
>

app/components/UI/TokenDetails/components/AssetOverviewContent.test.tsx

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,12 @@ jest.mock('@react-navigation/native', () => {
131131
};
132132
});
133133

134+
const mockGate = jest.fn(
135+
async (action: () => Promise<unknown>) => await action(),
136+
);
134137
jest.mock('../../Compliance', () => ({
135138
useComplianceGate: () => ({
136-
gate: (action: () => Promise<unknown>) => action(),
139+
gate: (action: () => Promise<unknown>) => mockGate(action),
137140
isBlocked: false,
138141
isComplianceEnabled: false,
139142
checkCompliance: jest.fn(),
@@ -325,6 +328,51 @@ describe('AssetOverviewContent', () => {
325328
expect(mockTrack).not.toHaveBeenCalled();
326329
});
327330

331+
it('releases the navigation lock when gate() settles without navigating so Long can be pressed again', async () => {
332+
// Simulate a blocked wallet: gate() shows the compliance modal and
333+
// returns without invoking the action. Without releasing the nav lock
334+
// in the finally(), the second press would be silently ignored.
335+
mockGate.mockImplementationOnce(async () => undefined);
336+
mockGate.mockImplementationOnce(async () => undefined);
337+
338+
const { getByTestId } = renderWithProvider(
339+
<AssetOverviewContent {...defaultProps} />,
340+
{ state: createState(true) },
341+
);
342+
343+
await act(async () => {
344+
fireEvent.press(getByTestId(TokenOverviewSelectorsIDs.LONG_BUTTON));
345+
});
346+
expect(mockGate).toHaveBeenCalledTimes(1);
347+
348+
await act(async () => {
349+
fireEvent.press(getByTestId(TokenOverviewSelectorsIDs.LONG_BUTTON));
350+
});
351+
expect(mockGate).toHaveBeenCalledTimes(2);
352+
expect(mockHandlePerpsAction).not.toHaveBeenCalled();
353+
});
354+
355+
it('releases the navigation lock when gate() settles without navigating so Short can be pressed again', async () => {
356+
mockGate.mockImplementationOnce(async () => undefined);
357+
mockGate.mockImplementationOnce(async () => undefined);
358+
359+
const { getByTestId } = renderWithProvider(
360+
<AssetOverviewContent {...defaultProps} />,
361+
{ state: createState(true) },
362+
);
363+
364+
await act(async () => {
365+
fireEvent.press(getByTestId(TokenOverviewSelectorsIDs.SHORT_BUTTON));
366+
});
367+
expect(mockGate).toHaveBeenCalledTimes(1);
368+
369+
await act(async () => {
370+
fireEvent.press(getByTestId(TokenOverviewSelectorsIDs.SHORT_BUTTON));
371+
});
372+
expect(mockGate).toHaveBeenCalledTimes(2);
373+
expect(mockHandlePerpsAction).not.toHaveBeenCalled();
374+
});
375+
328376
it('closes geo block modal when closeEligibilityModal is called', () => {
329377
const { getByTestId } = renderWithProvider(
330378
<AssetOverviewContent {...defaultProps} />,

app/components/UI/TokenDetails/components/AssetOverviewContent.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,12 @@ const AssetOverviewContent: React.FC<AssetOverviewContentProps> = ({
278278
return;
279279
}
280280
handlePerpsAction?.('long');
281+
}).finally(() => {
282+
// Release the TokenDetailsActions nav lock whenever gate() settles
283+
// without navigating (compliance block modal or geo-block tooltip).
284+
// Safe no-op if handlePerpsAction navigated since the focus/state
285+
// listeners also clear the lock.
286+
resetNavigationLockRef.current?.();
281287
}),
282288
[gate, isEligible, track, handlePerpsAction],
283289
);
@@ -296,6 +302,8 @@ const AssetOverviewContent: React.FC<AssetOverviewContentProps> = ({
296302
return;
297303
}
298304
handlePerpsAction?.('short');
305+
}).finally(() => {
306+
resetNavigationLockRef.current?.();
299307
}),
300308
[gate, isEligible, track, handlePerpsAction],
301309
);

0 commit comments

Comments
 (0)