-
Notifications
You must be signed in to change notification settings - Fork 5k
Commit
## **Description** This PR splits off the new UI components from #26433. They support the new UI for editing networks directly via the network picker. - `MultiRpcEditModal` - A modal shown only to users who have multiple networks for a given chain. Allows them to customize via the network form if they don't like how we merged them. <img width="321" alt="Screenshot 2024-09-11 at 4 32 42 PM" src="https://github.com/user-attachments/assets/38623a28-a753-46c0-9e13-e6fb51b761bb"> - `DropdownEditor` - A generic dropdown for selecting, adding, and deleting items. Currently shared by the editing experience for RPC endpoints and block explorers. <img width="305" alt="Screenshot 2024-09-11 at 4 34 40 PM" src="https://github.com/user-attachments/assets/cbebcc56-9615-48ce-96ac-548b677c8320"> <img width="304" alt="Screenshot 2024-09-11 at 4 34 18 PM" src="https://github.com/user-attachments/assets/bfa29f61-9e85-4314-96e5-5d181e1ef259"> - `AddBlockExplorerModal` - The sub page within the network form where you add a block explorer <img width="320" alt="Screenshot 2024-09-11 at 4 35 49 PM" src="https://github.com/user-attachments/assets/78fb3bfe-5dcc-4303-be0e-f8d0be559985"> - `AddRpcUrlModal` - The sub page within the network form where you add an RPC url <img width="319" alt="Screenshot 2024-09-11 at 4 35 56 PM" src="https://github.com/user-attachments/assets/5412cd87-2c39-4fb6-9163-1c540f7dd0ec"> - `RpcListItem` - A component representing a single RPC endpoint with a list. Currently shared between selecting via the `SelectRpcUrlModal` and editing via the RPC `DropdownEditor` <img width="335" alt="Screenshot 2024-09-11 at 4 50 43 PM" src="https://github.com/user-attachments/assets/249eeb2e-b09d-49f9-9d04-d232a18d6d59"> - `SelectRpcUrlModal` - The page used to switch RPC endpoints for a chain. <img width="334" alt="Screenshot 2024-09-11 at 4 52 09 PM" src="https://github.com/user-attachments/assets/1aa66829-ed35-4549-8569-f5c0b61610c4"> Additionally some actions are modified to support new features used by these components. [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/MetaMask/metamask-extension/pull/27085?quickstart=1) ## **Related issues** ## **Manual testing steps** None of these are visible in the product yet, but will be after #26433 ## **Screenshots/Recordings** <!-- If applicable, add screenshots and/or recordings to visualize the before and after of your change. --> ### **Before** <!-- [screenshots/recordings] --> ### **After** <!-- [screenshots/recordings] --> ## **Pre-merge author checklist** - [ ] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Extension Coding Standards](https://github.com/MetaMask/metamask-extension/blob/develop/.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-extension/blob/develop/.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: sahar-fehri <[email protected]>
- Loading branch information
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`MultiRpcEditModal renders correctly with required props 1`] = ` | ||
<body> | ||
<div | ||
id="popover-content" | ||
/> | ||
<div /> | ||
<div | ||
class="mm-modal" | ||
data-testid="multi-rpc-edit-modal" | ||
> | ||
<div | ||
aria-hidden="true" | ||
class="mm-box mm-modal-overlay mm-box--width-full mm-box--height-full mm-box--background-color-overlay-default" | ||
/> | ||
<div | ||
data-focus-guard="true" | ||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;" | ||
tabindex="0" | ||
/> | ||
<div | ||
data-focus-lock-disabled="false" | ||
> | ||
<div | ||
class="mm-box mm-modal-content mm-box--padding-top-4 mm-box--sm:padding-top-8 mm-box--md:padding-top-12 mm-box--padding-right-4 mm-box--padding-bottom-4 mm-box--sm:padding-bottom-8 mm-box--md:padding-bottom-12 mm-box--padding-left-4 mm-box--display-flex mm-box--justify-content-center mm-box--align-items-flex-start mm-box--width-screen mm-box--height-screen" | ||
> | ||
<section | ||
aria-modal="true" | ||
class="mm-box mm-modal-content__dialog mm-modal-content__dialog--size-sm mm-box--padding-top-4 mm-box--padding-bottom-4 mm-box--display-flex mm-box--flex-direction-column mm-box--width-full mm-box--background-color-background-default mm-box--rounded-lg" | ||
role="dialog" | ||
> | ||
<div | ||
class="mm-box mm-modal-body mm-box--padding-right-4 mm-box--padding-left-4 mm-box--display-flex mm-box--flex-direction-column" | ||
> | ||
<div | ||
class="mm-box mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center mm-box--rounded-sm" | ||
> | ||
<img | ||
src="/images/networks1.png" | ||
/> | ||
</div> | ||
<p | ||
class="mm-box mm-text mm-text--body-md-bold mm-text--text-align-center mm-box--color-text-default" | ||
> | ||
updatedRpcForNetworks | ||
</p> | ||
<p | ||
class="mm-box mm-text mm-text--body-md mm-text--text-align-center mm-box--padding-top-2 mm-box--color-text-default" | ||
> | ||
supportMultiRpcInformation | ||
</p> | ||
<div | ||
class="mm-box mm-box--padding-bottom-6" | ||
> | ||
<div | ||
class="mm-box mm-box--margin-top-4 mm-box--margin-bottom-1" | ||
/> | ||
</div> | ||
</div> | ||
<div | ||
class="mm-box mm-modal-footer mm-box--padding-top-4 mm-box--padding-right-4 mm-box--padding-left-4" | ||
> | ||
<div | ||
class="mm-box mm-container mm-container--max-width-sm mm-box--margin-right-auto mm-box--margin-left-auto mm-box--display-flex mm-box--gap-4 mm-box--flex-wrap-wrap mm-box--align-items-center" | ||
> | ||
<button | ||
class="mm-box mm-text mm-button-base mm-button-base--size-lg mm-button-base--block mm-modal-footer__button mm-button-primary mm-text--body-md-medium mm-box--padding-0 mm-box--padding-right-4 mm-box--padding-left-4 mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-primary-inverse mm-box--background-color-primary-default mm-box--rounded-pill" | ||
data-theme="light" | ||
> | ||
accept | ||
</button> | ||
</div> | ||
</div> | ||
</section> | ||
</div> | ||
</div> | ||
<div | ||
data-focus-guard="true" | ||
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;" | ||
tabindex="0" | ||
/> | ||
</div> | ||
</body> | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import React from 'react'; | ||
import { render, screen } from '@testing-library/react'; | ||
import { Provider } from 'react-redux'; | ||
import configureStore from 'redux-mock-store'; | ||
import thunk from 'redux-thunk'; | ||
import { useI18nContext } from '../../../hooks/useI18nContext'; | ||
import MultiRpcEditModal from './multi-rpc-edit-modal'; | ||
import '@testing-library/jest-dom/extend-expect'; | ||
|
||
const mockStore = configureStore([thunk]); | ||
|
||
const initialState = { | ||
metamask: { | ||
networkConfigurationsByChainId: { | ||
'0x1': { | ||
blockExplorerUrls: [], | ||
chainId: '0x1', | ||
defaultRpcEndpointIndex: 0, | ||
name: 'Ethereum Mainnet', | ||
nativeCurrency: 'ETH', | ||
rpcEndpoints: [ | ||
{ | ||
name: 'Eth test 1', | ||
networkClientId: '96d93309-dab5-45dd-9fff-0d9d7f0843cc', | ||
type: 'custom', | ||
url: 'https://eth-mainnet.public.blastapi.io', | ||
}, | ||
{ | ||
networkClientId: 'mainnet', | ||
type: 'infura', | ||
url: 'https://mainnet.infura.io/v3/{infuraProjectId}', | ||
}, | ||
{ | ||
name: 'Alchemyyyy', | ||
networkClientId: '40cd2a17-1085-4077-8ffb-1ea1bdc65289', | ||
type: 'custom', | ||
url: 'https://eth-mainnet.g.alchemy.com/v2/fCe_AL0z95whoz8H6hvdKvwNAE3goTa0', | ||
}, | ||
{ | ||
name: 'onfinality', | ||
networkClientId: '42d0d494-b92f-43f0-9270-51eb660d35a0', | ||
type: 'custom', | ||
url: 'https://eth.api.onfinality.io/public', | ||
}, | ||
{ | ||
name: 'mevBlocker', | ||
networkClientId: '53107ebb-6184-44b5-ae53-057772795de7', | ||
type: 'custom', | ||
url: 'https://rpc.mevblocker.io', | ||
}, | ||
], | ||
}, | ||
}, | ||
}, | ||
TransactionController: { | ||
transactions: [ | ||
{ | ||
chainId: '0x1', | ||
history: [{ networkClientId: 'mainnet' }], | ||
}, | ||
], | ||
}, | ||
}; | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const setup = (props: any) => { | ||
const store = mockStore(initialState); | ||
return render( | ||
<Provider store={store}> | ||
<MultiRpcEditModal {...props} /> | ||
</Provider>, | ||
); | ||
}; | ||
|
||
jest.mock('../../../hooks/useI18nContext', () => ({ | ||
useI18nContext: jest.fn(), | ||
})); | ||
|
||
describe('MultiRpcEditModal', () => { | ||
const useI18nContextMock = useI18nContext as jest.Mock; | ||
|
||
beforeEach(() => { | ||
useI18nContextMock.mockReturnValue((key: string) => key); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('renders correctly with required props', () => { | ||
const onCloseMock = jest.fn(); | ||
|
||
const { baseElement } = setup({ | ||
isOpen: true, | ||
onClose: onCloseMock, | ||
}); | ||
expect(baseElement).toMatchSnapshot(); | ||
}); | ||
|
||
it('renders the modal and displays the network information', () => { | ||
const onCloseMock = jest.fn(); | ||
|
||
setup({ | ||
isOpen: true, | ||
onClose: onCloseMock, | ||
}); | ||
|
||
expect(screen.getByTestId('multi-rpc-edit-modal')).toBeInTheDocument(); | ||
// TODO: enable with network controller v21 upgrade after `getNetworkConfigurationsByChainId` is implemented | ||
// expect(screen.getByText('Ethereum Mainnet')).toBeInTheDocument(); | ||
expect(screen.getByText('supportMultiRpcInformation')).toBeInTheDocument(); | ||
}); | ||
}); |