From dc133a596b13209cd6280bcce9991227db75ddf5 Mon Sep 17 00:00:00 2001 From: Salim TOUBAL Date: Wed, 2 Oct 2024 12:11:11 +0200 Subject: [PATCH] fix: fix duplicated network select (#11524) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## **Description** his PR introduces a fix for handling multiple networks with different RPC URLs in the NetworkSelector component, along with comprehensive unit tests to ensure the component's functionality. The tests verify that only one network can be selected at a time, even when the networks have the same chain ID but different RPC URLs. ## **Related issues** Fixes: #11509 ## **Manual testing steps** 1. add tow different polygon network with two different rpc 2. switch between them ## **Screenshots/Recordings** ### **Before** https://github.com/user-attachments/assets/4870882d-0029-459a-ad91-f409ed552183 ### **After** https://github.com/user-attachments/assets/1966eda3-2e10-4b93-babf-2afe3be48aed ## **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. --- .../NetworkSelector/NetworkSelector.test.tsx | 68 +++++++++++++++++++ .../Views/NetworkSelector/NetworkSelector.tsx | 15 ++-- .../NetworkSelector.test.tsx.snap | 8 +-- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/app/components/Views/NetworkSelector/NetworkSelector.test.tsx b/app/components/Views/NetworkSelector/NetworkSelector.test.tsx index 9fe6db9eb2e..9e53784fbb2 100644 --- a/app/components/Views/NetworkSelector/NetworkSelector.test.tsx +++ b/app/components/Views/NetworkSelector/NetworkSelector.test.tsx @@ -207,6 +207,7 @@ describe('Network Selector', () => { expect(testNetworksSwitch.props.value).toBeTruthy(); expect(testNetworksSwitch.props.disabled).toBeTruthy(); }); + it('changes to non infura network when another network cell is pressed', async () => { const { getByText } = renderComponent(initialState); const gnosisCell = getByText('Gnosis Chain'); @@ -238,6 +239,7 @@ describe('Network Selector', () => { expect(mockEngine.context.NetworkController.setActiveNetwork).toBeCalled(); }); + it('renders correctly with no network configurations', async () => { (isNetworkUiRedesignEnabled as jest.Mock).mockImplementation(() => true); const stateWithNoNetworkConfigurations = { @@ -287,4 +289,70 @@ describe('Network Selector', () => { fireEvent.press(rpcOption); }); }); + + // Add this test for selecting between two Polygon networks + it('should select only one Polygon network when two networks with different RPC URLs exist', async () => { + jest.clearAllMocks(); // Clears mock data, ensuring that no mock has been called + jest.resetAllMocks(); // Resets mock implementation and mock instances + + const customState = { + ...initialState, + engine: { + backgroundState: { + ...initialState.engine.backgroundState, + NetworkController: { + networkConfigurations: { + polygonNetwork1: { + chainId: '0x89', // Polygon Mainnet + nickname: 'Polygon Mainnet 1', + rpcUrl: 'https://polygon-mainnet-1.rpc', + ticker: 'POL', + }, + polygonNetwork2: { + chainId: '0x89', // Polygon Mainnet (same chainId, different RPC URL) + nickname: 'Polygon Mainnet 2', + rpcUrl: 'https://polygon-mainnet-2.rpc', + ticker: 'POL', + }, + }, + }, + }, + }, + }; + + ( + Engine.context.NetworkController.getNetworkClientById as jest.Mock + ).mockReturnValue({ + configuration: { + chainId: '0x89', // Polygon Mainnet + nickname: 'Polygon Mainnet 1', + rpcUrl: 'https://polygon-mainnet-1.rpc', + ticker: 'POL', + type: 'custom', + }, + }); + + const { getByText, queryByTestId } = renderComponent(customState); + + // Ensure both networks are rendered + const polygonNetwork1 = getByText('Polygon Mainnet 1'); + const polygonNetwork2 = getByText('Polygon Mainnet 2'); + expect(polygonNetwork1).toBeTruthy(); + expect(polygonNetwork2).toBeTruthy(); + + // Select the first network + fireEvent.press(polygonNetwork1); + + // Wait for the selection to be applied + await waitFor(() => { + const polygonNetwork1Selected = queryByTestId( + 'Polygon Mainnet 1-selected', + ); + expect(polygonNetwork1Selected).toBeTruthy(); + }); + + // Assert that the second network is NOT selected + const polygonNetwork2Selected = queryByTestId('Polygon Mainnet 2-selected'); + expect(polygonNetwork2Selected).toBeNull(); // Not selected + }); }); diff --git a/app/components/Views/NetworkSelector/NetworkSelector.tsx b/app/components/Views/NetworkSelector/NetworkSelector.tsx index 61414175187..eb18992d684 100644 --- a/app/components/Views/NetworkSelector/NetworkSelector.tsx +++ b/app/components/Views/NetworkSelector/NetworkSelector.tsx @@ -466,7 +466,7 @@ const NetworkSelector = () => { imageSource: images['LINEA-MAINNET'], size: avatarSize, }} - isSelected={chainId === selectedChainId} + isSelected={chainId === selectedChainId && !providerConfig.rpcUrl} onPress={() => onNetworkChange(LINEA_MAINNET)} /> ); @@ -520,7 +520,8 @@ const NetworkSelector = () => { return ( { imageSource: image, size: avatarSize, }} - isSelected={Boolean(chainId === selectedChainId && selectedRpcUrl)} + isSelected={Boolean( + chainId === selectedChainId && selectedRpcUrl === rpcUrl, + )} onPress={() => onSetRpcTarget(rpcUrl)} style={styles.networkCell} - /> + > + {Boolean( + chainId === selectedChainId && selectedRpcUrl === rpcUrl, + ) && } + ); }, ); diff --git a/app/components/Views/NetworkSelector/__snapshots__/NetworkSelector.test.tsx.snap b/app/components/Views/NetworkSelector/__snapshots__/NetworkSelector.test.tsx.snap index e7858e18e3e..8f50b91b23f 100644 --- a/app/components/Views/NetworkSelector/__snapshots__/NetworkSelector.test.tsx.snap +++ b/app/components/Views/NetworkSelector/__snapshots__/NetworkSelector.test.tsx.snap @@ -705,7 +705,7 @@ exports[`Network Selector renders correctly 1`] = ` "position": "relative", } } - testID="cellselect" + testID="network-cell-Avalanche Mainnet C-Chain" >