From 241b8c6551788fcc7b501325339bb3f33c2e9707 Mon Sep 17 00:00:00 2001 From: sethkfman <10342624+sethkfman@users.noreply.github.com> Date: Mon, 4 Nov 2024 12:27:00 -0700 Subject: [PATCH] chore(runway): cherry-pick 23d311ca48e273c3aa2a63532ee881cf5fa75200 (#12164) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** cherry-pick 23d311ca48e273c3aa2a63532ee881cf5fa75200 ## **Related issues** Fixes: ## **Manual testing steps** 1. Go to this page... 2. 3. ## **Screenshots/Recordings** ### **Before** ### **After** ## **Pre-merge author checklist** - [ ] 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). - [ ] I've completed the PR template to the best of my ability - [ ] I’ve included tests if applicable - [ ] I’ve documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [ ] 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. --------- Co-authored-by: OGPoyraz --- .nvmrc | 2 +- app/components/Nav/App/index.js | 5 + .../ChangeInSimulationModal.test.tsx | 73 +++ .../ChangeInSimulationModal.tsx | 93 ++++ .../ChangeInSimulationModal.test.tsx.snap | 170 +++++++ .../__snapshots__/index.test.tsx.snap | 478 ++++++++++++++++-- .../Views/confirmations/Approval/index.js | 47 +- .../confirmations/Approval/index.test.tsx | 57 +-- .../ApproveView/Approve/index.js | 36 +- .../confirmations/SendFlow/Confirm/index.js | 21 + app/constants/navigation/Routes.ts | 2 + app/core/Engine.ts | 1 + .../smart-transactions/smart-publish-hook.ts | 1 + locales/languages/en.json | 6 + package.json | 4 +- yarn.lock | 62 ++- 16 files changed, 963 insertions(+), 95 deletions(-) create mode 100644 app/components/Views/ChangeInSimulationModal/ChangeInSimulationModal.test.tsx create mode 100644 app/components/Views/ChangeInSimulationModal/ChangeInSimulationModal.tsx create mode 100644 app/components/Views/ChangeInSimulationModal/__snapshots__/ChangeInSimulationModal.test.tsx.snap diff --git a/.nvmrc b/.nvmrc index 87834047a6f..3516580bbbc 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.12.2 +20.17.0 diff --git a/app/components/Nav/App/index.js b/app/components/Nav/App/index.js index 8f424320041..96f27495d74 100644 --- a/app/components/Nav/App/index.js +++ b/app/components/Nav/App/index.js @@ -123,6 +123,7 @@ import NftOptions from '../../../components/Views/NftOptions'; import ShowTokenIdSheet from '../../../components/Views/ShowTokenIdSheet'; import OriginSpamModal from '../../Views/OriginSpamModal/OriginSpamModal'; import { isNetworkUiRedesignEnabled } from '../../../util/networks/isNetworkUiRedesignEnabled'; +import ChangeInSimulationModal from '../../Views/ChangeInSimulationModal/ChangeInSimulationModal'; import TooltipModal from '../../../components/Views/TooltipModal'; ///: BEGIN:ONLY_INCLUDE_IF(preinstalled-snaps,external-snaps) import { SnapsExecutionWebView } from '../../../lib/snaps'; @@ -728,6 +729,10 @@ const App = (props) => { name={Routes.SHEET.ORIGIN_SPAM_MODAL} component={OriginSpamModal} /> + ({ + ...jest.requireActual('react-redux'), + useDispatch: () => jest.fn(), +})); + +jest.mock( + '../../../component-library/components/BottomSheets/BottomSheet', + () => + ({ children }: { children: React.ReactElement }) => + <>{children}, +); + +const NAVIGATION_PARAMS_MOCK = { + params: { + onProceed: jest.fn(), + onReject: jest.fn(), + }, +}; + +const mockInitialState: DeepPartial = { + engine: { + backgroundState: { + ...backgroundState, + }, + }, +}; + +describe('ChangeInSimulationModal', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('render matches snapshot', () => { + const { toJSON } = renderWithProvider( + , + { + state: mockInitialState, + }, + ); + expect(toJSON()).toMatchSnapshot(); + }); + + it('calls onProceed and onReject callbacks', () => { + const mockOnReject = jest.fn(); + const mockOnProceed = jest.fn(); + const wrapper = renderWithProvider( + , + { + state: mockInitialState, + }, + ); + fireEvent.press(wrapper.getByTestId(PROCEED_BUTTON_TEST_ID)); + expect(mockOnProceed).toHaveBeenCalledTimes(1); + + fireEvent.press(wrapper.getByTestId(REJECT_BUTTON_TEST_ID)); + expect(mockOnReject).toHaveBeenCalledTimes(1); + }); +}); diff --git a/app/components/Views/ChangeInSimulationModal/ChangeInSimulationModal.tsx b/app/components/Views/ChangeInSimulationModal/ChangeInSimulationModal.tsx new file mode 100644 index 00000000000..ccd7d604f47 --- /dev/null +++ b/app/components/Views/ChangeInSimulationModal/ChangeInSimulationModal.tsx @@ -0,0 +1,93 @@ +import React, { useCallback, useRef } from 'react'; +import { StyleSheet, View } from 'react-native'; +import { strings } from '../../../../locales/i18n'; +import BottomSheet, { + BottomSheetRef, +} from '../../../component-library/components/BottomSheets/BottomSheet'; +import Button from '../../../component-library/components/Buttons/Button/Button'; +import Icon, { + IconSize, + IconName, + IconColor, +} from '../../../component-library/components/Icons/Icon'; +import { + ButtonSize, + ButtonVariants, + ButtonWidthTypes, +} from '../../../component-library/components/Buttons/Button'; +import SheetHeader from '../../../component-library/components/Sheet/SheetHeader'; +import Text from '../../../component-library/components/Texts/Text'; + +export const PROCEED_BUTTON_TEST_ID = 'proceed-button'; +export const REJECT_BUTTON_TEST_ID = 'reject-button'; + +const createStyles = () => + StyleSheet.create({ + buttonsWrapper: { + alignSelf: 'stretch', + flexDirection: 'column', + gap: 16, + paddingTop: 24, + }, + wrapper: { + alignItems: 'center', + padding: 16, + }, + description: { + textAlign: 'center', + }, + }); + +const ChangeInSimulationModal = ({ + route, +}: { + route: { params: { onProceed: () => void; onReject: () => void } }; +}) => { + const styles = createStyles(); + const sheetRef = useRef(null); + const { onProceed, onReject } = route.params; + + const handleProceed = useCallback(() => { + sheetRef.current?.onCloseBottomSheet(); + onProceed(); + }, [onProceed, sheetRef]); + + const handleReject = useCallback(() => { + sheetRef.current?.onCloseBottomSheet(); + onReject(); + }, [onReject, sheetRef]); + + return ( + + + + + {strings('change_in_simulation_modal.description')} + +