Skip to content

Commit

Permalink
fix: fix search feature + build
Browse files Browse the repository at this point in the history
  • Loading branch information
salimtb committed Feb 13, 2025
1 parent 8ceb069 commit b9e2aa6
Show file tree
Hide file tree
Showing 7 changed files with 382 additions and 109 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { useDispatch } from 'react-redux';

Check failure on line 3 in ui/components/multichain/network-list-menu/NetworkItems/NetworkItems.test.tsx

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

'/home/runner/work/metamask-extension/metamask-extension/node_modules/@types/react-redux/index.d.ts' imported multiple times
import configureStore from 'redux-mock-store';
import { Provider } from 'react-redux';

Check failure on line 5 in ui/components/multichain/network-list-menu/NetworkItems/NetworkItems.test.tsx

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

'/home/runner/work/metamask-extension/metamask-extension/node_modules/@types/react-redux/index.d.ts' imported multiple times

import { NetworkItems } from './NetworkItems';

Check failure on line 7 in ui/components/multichain/network-list-menu/NetworkItems/NetworkItems.test.tsx

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

`./NetworkItems` import should occur after import of `@metamask/transaction-controller`
import {
NetworkConfiguration,
RpcEndpointType,
} from '@metamask/network-controller';
import { ACTION_MODES } from '../network-list-menu';

Check failure on line 12 in ui/components/multichain/network-list-menu/NetworkItems/NetworkItems.test.tsx

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

`../network-list-menu` import should occur after import of `@metamask/transaction-controller`

Check failure on line 12 in ui/components/multichain/network-list-menu/NetworkItems/NetworkItems.test.tsx

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

'ACTION_MODES' is defined but never used
import { showModal, setEditedNetwork } from '../../../../store/actions';

Check failure on line 13 in ui/components/multichain/network-list-menu/NetworkItems/NetworkItems.test.tsx

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

`../../../../store/actions` import should occur after import of `@metamask/transaction-controller`

Check failure on line 13 in ui/components/multichain/network-list-menu/NetworkItems/NetworkItems.test.tsx

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

'showModal' is defined but never used

Check failure on line 13 in ui/components/multichain/network-list-menu/NetworkItems/NetworkItems.test.tsx

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

'setEditedNetwork' is defined but never used
import { CHAIN_IDS } from '@metamask/transaction-controller';

Check failure on line 14 in ui/components/multichain/network-list-menu/NetworkItems/NetworkItems.test.tsx

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

'CHAIN_IDS' is defined but never used

jest.mock('react-redux', () => ({
...jest.requireActual('react-redux'),
useDispatch: jest.fn(),
}));

describe('NetworkItems', () => {
const mockStore = configureStore([]);
const dispatchMock = jest.fn();

// Mock sample data
const mockNetwork: NetworkConfiguration = {
chainId: '0x99',
nativeCurrency: 'TEST',
name: 'Test Network',
rpcEndpoints: [
{
url: 'https://test-rpc',
name: 'test',
networkClientId: 'test',
type: RpcEndpointType.Custom,
},
],
defaultRpcEndpointIndex: 0,
blockExplorerUrls: ['https://test-explorer'],
defaultBlockExplorerUrlIndex: 0,
};

const baseProps = {
network: mockNetwork,
isUnlocked: true,
currentChainId: '0x99', // same as mockNetwork, so isCurrentNetwork will be true
handleNetworkChange: jest.fn(),
toggleNetworkMenu: jest.fn(),
setActionMode: jest.fn(),
focusSearch: false,
showMultiRpcSelectors: false,
};

beforeEach(() => {
(useDispatch as jest.Mock).mockReturnValue(dispatchMock);
dispatchMock.mockClear();
baseProps.handleNetworkChange.mockClear();
baseProps.toggleNetworkMenu.mockClear();
baseProps.setActionMode.mockClear();
});

const renderComponent = (props = {}) => {
const store = mockStore({});
return render(
<Provider store={store}>
<NetworkItems {...baseProps} {...props} />
</Provider>,
);
};

it('renders correctly and matches snapshot', () => {
const { container } = renderComponent();
expect(container).toMatchSnapshot();
});

it('renders NetworkListItem with correct name and default props', () => {
renderComponent();

expect(screen.getByText(/Test Network/i)).toBeInTheDocument();

Check failure on line 79 in ui/components/multichain/network-list-menu/NetworkItems/NetworkItems.test.tsx

View workflow job for this annotation

GitHub Actions / Test lint / Test lint

Use the 'u' flag
});

it('calls handleNetworkChange when the NetworkListItem is clicked', () => {
renderComponent();
const networkItem = screen.getByText('Test Network');

fireEvent.click(networkItem);

expect(baseProps.handleNetworkChange).toHaveBeenCalledWith(mockNetwork);
});

it('does NOT render Delete button if the network is MAINNET, or user is locked, or it is current network', () => {
renderComponent();

const deleteButton = screen.queryByLabelText(/delete/i);
expect(deleteButton).not.toBeInTheDocument();
});

it('does not render the RPC endpoint button if showMultiRpcSelectors is false', () => {
renderComponent();

const rpcButton = screen.queryByLabelText(/select rpc/i);
expect(rpcButton).not.toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { CHAIN_IDS } from '@metamask/transaction-controller';
import { NetworkConfiguration } from '@metamask/network-controller';
import React, { useCallback } from 'react';
import { useDispatch } from 'react-redux';
import { NetworkListItem } from '../..';
import { CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP } from '../../../../../shared/constants/network';
import { AvatarNetworkSize } from '../../../component-library';
import { showModal, setEditedNetwork } from '../../../../store/actions';
import { ACTION_MODES } from '../network-list-menu';

type NetworkItemsProps = {
network: NetworkConfiguration;
isUnlocked: boolean;
currentChainId: string;
handleNetworkChange: (network: NetworkConfiguration) => void;
toggleNetworkMenu: () => void;
setActionMode: React.Dispatch<React.SetStateAction<ACTION_MODES>>;
focusSearch: boolean;
showMultiRpcSelectors: boolean;
};

export const NetworkItems: React.FC<NetworkItemsProps> = ({
network,
isUnlocked,
currentChainId,
handleNetworkChange,
toggleNetworkMenu,
setActionMode,
focusSearch,
showMultiRpcSelectors,
}) => {
const isCurrentNetwork = network.chainId === currentChainId;
const canDeleteNetwork =
isUnlocked && !isCurrentNetwork && network.chainId !== CHAIN_IDS.MAINNET;
const dispatch = useDispatch();

const onClickCallback = useCallback(() => {
handleNetworkChange(network);
}, [handleNetworkChange, network]);

const onDeleteClickCallback = useCallback(() => {
dispatch(toggleNetworkMenu());
dispatch(
showModal({
name: 'CONFIRM_DELETE_NETWORK',
target: network.chainId,
onConfirm: () => undefined,
}),
);
}, [dispatch, toggleNetworkMenu, showModal, network]);

const onEditClickCallback = useCallback(() => {
dispatch(
setEditedNetwork({
chainId: network.chainId,
nickname: network.name,
}),
);
setActionMode(ACTION_MODES.ADD_EDIT);
}, [dispatch, network, setEditedNetwork, setActionMode, ACTION_MODES]);

const onRpcEndpointClickCallback = useCallback(() => {
setActionMode(ACTION_MODES.SELECT_RPC);
dispatch(setEditedNetwork({ chainId: network.chainId }));
}, [dispatch, network, setEditedNetwork, setActionMode, ACTION_MODES]);

return (
<NetworkListItem
name={network.name}
key={network.chainId}
iconSrc={
CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP[
network.chainId as keyof typeof CHAIN_ID_TO_NETWORK_IMAGE_URL_MAP
]
}
iconSize={AvatarNetworkSize.Sm}
rpcEndpoint={
showMultiRpcSelectors
? network.rpcEndpoints[network.defaultRpcEndpointIndex]
: undefined
}
chainId={network.chainId}
selected={isCurrentNetwork && !focusSearch}
focus={isCurrentNetwork && !focusSearch}
onClick={onClickCallback}
onDeleteClick={canDeleteNetwork ? onDeleteClickCallback : undefined}
onEditClick={onEditClickCallback}
onRpcEndpointClick={onRpcEndpointClickCallback}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`NetworkItems renders correctly and matches snapshot 1`] = `
<div>
<div
class="mm-box multichain-network-list-item multichain-network-list-item--selected mm-box--padding-top-4 mm-box--padding-right-4 mm-box--padding-bottom-4 mm-box--padding-left-4 mm-box--display-flex mm-box--gap-4 mm-box--justify-content-space-between mm-box--align-items-center mm-box--width-full mm-box--background-color-primary-muted"
>
<div
class="mm-box multichain-network-list-item__selected-indicator mm-box--background-color-primary-default mm-box--rounded-pill"
/>
<div
class="mm-box mm-text mm-avatar-base mm-avatar-base--size-sm mm-avatar-network mm-text--body-sm mm-text--text-transform-uppercase mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-text-default mm-box--background-color-background-alternative mm-box--rounded-md mm-box--border-color-background-default mm-box--border-width-1 box--border-style-solid"
>
T
</div>
<div
class="mm-box mm-box--display-flex mm-box--flex-direction-column mm-box--justify-content-flex-start mm-box--align-items-flex-start mm-box--width-full"
style="overflow: hidden;"
>
<div
class="mm-box mm-box--display-flex mm-box--align-items-center mm-box--width-full"
data-testid="Test Network"
>
<div
class="multichain-network-list-item__tooltip"
>
<div
class=""
style="display: inline;"
tabindex="0"
title=""
>
<p
class="mm-box mm-text mm-text--body-md mm-text--ellipsis mm-box--color-text-default mm-box--background-color-transparent"
tabindex="0"
>
Test Network
</p>
</div>
</div>
</div>
</div>
<button
aria-label="[networkOptions]"
class="mm-box mm-button-icon mm-button-icon--size-sm mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-icon-default mm-box--background-color-transparent mm-box--rounded-lg"
data-testid="network-list-item-options-button-0x99"
>
<span
class="mm-box mm-icon mm-icon--size-sm mm-box--display-inline-block mm-box--color-inherit"
style="mask-image: url('./images/icons/more-vertical.svg');"
/>
</button>
</div>
</div>
`;
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,107 @@ exports[`NetworkListMenu renders properly 1`] = `
</div>
</label>
</div>
<div
class="mm-box multichain-network-list-menu"
hidden=""
>
<div
class="mm-box multichain-network-list-item mm-box--padding-top-4 mm-box--padding-right-4 mm-box--padding-bottom-4 mm-box--padding-left-4 mm-box--display-flex mm-box--gap-4 mm-box--justify-content-space-between mm-box--align-items-center mm-box--width-full mm-box--background-color-transparent"
>
<div
class="mm-box mm-text mm-avatar-base mm-avatar-base--size-sm mm-avatar-network mm-text--body-sm mm-text--text-transform-uppercase mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-text-default mm-box--background-color-sepolia mm-box--rounded-md mm-box--border-color-background-default mm-box--border-width-1 box--border-style-solid"
>
S
</div>
<div
class="mm-box mm-box--display-flex mm-box--flex-direction-column mm-box--justify-content-flex-start mm-box--align-items-flex-start mm-box--width-full"
style="overflow: hidden;"
>
<div
class="mm-box mm-box--display-flex mm-box--align-items-center mm-box--width-full"
data-testid="Sepolia"
>
<div
class="multichain-network-list-item__tooltip"
>
<div
class=""
style="display: inline;"
tabindex="0"
title=""
>
<p
class="mm-box mm-text mm-text--body-md mm-text--ellipsis mm-box--color-text-default mm-box--background-color-transparent"
tabindex="0"
>
Sepolia
</p>
</div>
</div>
</div>
</div>
<button
aria-label="Network options"
class="mm-box mm-button-icon mm-button-icon--size-sm mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-icon-default mm-box--background-color-transparent mm-box--rounded-lg"
data-testid="network-list-item-options-button-0x539"
>
<span
class="mm-box mm-icon mm-icon--size-sm mm-box--display-inline-block mm-box--color-inherit"
style="mask-image: url('./images/icons/more-vertical.svg');"
/>
</button>
</div>
<div
class="mm-box multichain-network-list-item mm-box--padding-top-4 mm-box--padding-right-4 mm-box--padding-bottom-4 mm-box--padding-left-4 mm-box--display-flex mm-box--gap-4 mm-box--justify-content-space-between mm-box--align-items-center mm-box--width-full mm-box--background-color-transparent"
>
<div
class="mm-box mm-text mm-avatar-base mm-avatar-base--size-sm mm-avatar-network mm-text--body-sm mm-text--text-transform-uppercase mm-box--display-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-text-default mm-box--background-color-linea-sepolia mm-box--rounded-md mm-box--border-color-background-default mm-box--border-width-1 box--border-style-solid"
>
<img
alt="Linea Sepolia logo"
class="mm-avatar-network__network-image"
src="./images/linea-logo-testnet.png"
/>
</div>
<div
class="mm-box mm-box--display-flex mm-box--flex-direction-column mm-box--justify-content-flex-start mm-box--align-items-flex-start mm-box--width-full"
style="overflow: hidden;"
>
<div
class="mm-box mm-box--display-flex mm-box--align-items-center mm-box--width-full"
data-testid="Linea Sepolia"
>
<div
class="multichain-network-list-item__tooltip"
>
<div
class=""
style="display: inline;"
tabindex="0"
title=""
>
<p
class="mm-box mm-text mm-text--body-md mm-text--ellipsis mm-box--color-text-default mm-box--background-color-transparent"
tabindex="0"
>
Linea Sepolia
</p>
</div>
</div>
</div>
</div>
<button
aria-label="Network options"
class="mm-box mm-button-icon mm-button-icon--size-sm mm-box--display-inline-flex mm-box--justify-content-center mm-box--align-items-center mm-box--color-icon-default mm-box--background-color-transparent mm-box--rounded-lg"
data-testid="network-list-item-options-button-0xe705"
>
<span
class="mm-box mm-icon mm-icon--size-sm mm-box--display-inline-block mm-box--color-inherit"
style="mask-image: url('./images/icons/more-vertical.svg');"
/>
</button>
</div>
</div>
</div>
</div>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,8 @@ describe('NetworkListMenu', () => {
const networkItems = document.querySelectorAll(
'.multichain-network-list-item',
);
expect(networkItems).toHaveLength(4);
// expect 6 network items because of hidden test networks now
expect(networkItems).toHaveLength(6);

const selectedNodes = document.querySelectorAll(
'.multichain-network-list-item--selected',
Expand Down
Loading

0 comments on commit b9e2aa6

Please sign in to comment.