Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/Version-v12.2.0' into v12.2.0-sy…
Browse files Browse the repository at this point in the history
…nc-v12.1.1

* origin/Version-v12.2.0:
  fix(cherry-pick): remove BTC accounts from send flow (#26271) (#26821)
  • Loading branch information
Gudahtt committed Sep 2, 2024
2 parents 4a5a71a + d91ea1d commit 7da24fb
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 105 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/* eslint-disable jest/require-top-level-describe */
import React from 'react';
import reactRouterDom from 'react-router-dom';
import { EthAccountType } from '@metamask/keyring-api';
import {
BtcAccountType,
EthAccountType,
KeyringAccountType,
} from '@metamask/keyring-api';
import { merge } from 'lodash';
import { fireEvent, renderWithProvider, waitFor } from '../../../../test/jest';
import configureStore from '../../../store/store';
import mockState from '../../../../test/data/mock-state.json';
Expand All @@ -10,6 +15,7 @@ import messages from '../../../../app/_locales/en/messages.json';
import { CONNECT_HARDWARE_ROUTE } from '../../../helpers/constants/routes';
///: END:ONLY_INCLUDE_IF
import { ETH_EOA_METHODS } from '../../../../shared/constants/eth-methods';
import { createMockInternalAccount } from '../../../../test/jest/mocks';
import { AccountListMenu } from '.';

///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
Expand All @@ -27,8 +33,17 @@ jest.mock('react-router-dom', () => ({
useHistory: jest.fn(() => []),
}));

const render = (props = { onClose: () => jest.fn() }) => {
const store = configureStore({
const render = (
state = {},
props: {
onClose: () => void;
allowedAccountTypes: KeyringAccountType[];
} = {
onClose: () => jest.fn(),
allowedAccountTypes: [EthAccountType.Eoa, EthAccountType.Erc4337],
},
) => {
const defaultState = {
...mockState,
metamask: {
...mockState.metamask,
Expand Down Expand Up @@ -68,7 +83,8 @@ const render = (props = { onClose: () => jest.fn() }) => {
unconnectedAccount: {
state: 'OPEN',
},
});
};
const store = configureStore(merge(defaultState, state));
return renderWithProvider(<AccountListMenu {...props} />, store);
};

Expand All @@ -79,6 +95,7 @@ describe('AccountListMenu', () => {
jest
.spyOn(reactRouterDom, 'useHistory')
.mockImplementation()
// @ts-expect-error mocking history return
.mockReturnValue({ push: historyPushMock });
});

Expand All @@ -101,7 +118,7 @@ describe('AccountListMenu', () => {
);
expect(listItems).toHaveLength(6);

const searchBox = document.querySelector('input[type=search]');
const searchBox = document.querySelector('input[type=search]') as Element;
fireEvent.change(searchBox, {
target: { value: 'Le' },
});
Expand All @@ -115,7 +132,7 @@ describe('AccountListMenu', () => {
it('displays the "no accounts" message when search finds nothing', () => {
const { getByTestId } = render();

const searchBox = document.querySelector('input[type=search]');
const searchBox = document.querySelector('input[type=search]') as Element;
fireEvent.change(searchBox, {
target: { value: 'adslfkjlx' },
});
Expand Down Expand Up @@ -209,11 +226,11 @@ describe('AccountListMenu', () => {
});

it('add / Import / Hardware button functions as it should', () => {
const { getByText } = render();
const { getByText, getAllByTestId, getByLabelText } = render();

// Ensure the button is displaying
const button = document.querySelectorAll(
'[data-testid="multichain-account-menu-popover-action-button"]',
const button = getAllByTestId(
'multichain-account-menu-popover-action-button',
);
expect(button).toHaveLength(1);

Expand All @@ -222,25 +239,23 @@ describe('AccountListMenu', () => {
expect(getByText('Add a new Ethereum account')).toBeInTheDocument();
expect(getByText('Import account')).toBeInTheDocument();
expect(getByText('Add hardware wallet')).toBeInTheDocument();
const header = document.querySelector('header');
const header = document.querySelector('header') as Element;
expect(header.innerHTML).toContain('Add account');
expect(
document.querySelector('button[aria-label="Close"]'),
).toBeInTheDocument();

const backButton = document.querySelector('button[aria-label="Back"]');
const backButton = getByLabelText('Back');
expect(backButton).toBeInTheDocument();
backButton.click();

expect(getByText('Select an account')).toBeInTheDocument();
});

it('shows the account creation UI when Add Account is clicked', () => {
const { getByText, getByPlaceholderText } = render();
const { getByText, getByPlaceholderText, getByTestId } = render();

const button = document.querySelector(
'[data-testid="multichain-account-menu-popover-action-button"]',
);
const button = getByTestId('multichain-account-menu-popover-action-button');
button.click();

fireEvent.click(getByText('Add a new Ethereum account'));
Expand All @@ -252,11 +267,9 @@ describe('AccountListMenu', () => {
});

it('shows the account import UI when Import Account is clicked', () => {
const { getByText, getByPlaceholderText } = render();
const { getByText, getByPlaceholderText, getByTestId } = render();

const button = document.querySelector(
'[data-testid="multichain-account-menu-popover-action-button"]',
);
const button = getByTestId('multichain-account-menu-popover-action-button');
button.click();

fireEvent.click(getByText('Import account'));
Expand All @@ -268,11 +281,9 @@ describe('AccountListMenu', () => {
});

it('navigates to hardware wallet connection screen when clicked', () => {
const { getByText } = render();
const { getByText, getByTestId } = render();

const button = document.querySelector(
'[data-testid="multichain-account-menu-popover-action-button"]',
);
const button = getByTestId('multichain-account-menu-popover-action-button');
button.click();

fireEvent.click(getByText('Add hardware wallet'));
Expand All @@ -281,7 +292,10 @@ describe('AccountListMenu', () => {

///: BEGIN:ONLY_INCLUDE_IF(keyring-snaps)
describe('addSnapAccountButton', () => {
const renderWithState = (state, props = { onClose: mockOnClose }) => {
const renderWithState = (
state: { addSnapAccountEnabled: boolean },
props = { onClose: mockOnClose },
) => {
const store = configureStore({
...mockState,
...{
Expand Down Expand Up @@ -327,9 +341,11 @@ describe('AccountListMenu', () => {
};

it("doesn't render the add snap account button if it's disabled", async () => {
const { getByText } = renderWithState({ addSnapAccountEnabled: false });
const button = document.querySelector(
'[data-testid="multichain-account-menu-popover-action-button"]',
const { getByText, getByTestId } = renderWithState({
addSnapAccountEnabled: false,
});
const button = getByTestId(
'multichain-account-menu-popover-action-button',
);
button.click();
expect(() => getByText(messages.settingAddSnapAccount.message)).toThrow(
Expand All @@ -338,10 +354,13 @@ describe('AccountListMenu', () => {
});

it('renders the "Add account Snap" button if it\'s enabled', async () => {
// @ts-expect-error mocking platform
global.platform = { openTab: jest.fn() };
const { getByText } = renderWithState({ addSnapAccountEnabled: true });
const button = document.querySelector(
'[data-testid="multichain-account-menu-popover-action-button"]',
const { getByText, getByTestId } = renderWithState({
addSnapAccountEnabled: true,
});
const button = getByTestId(
'multichain-account-menu-popover-action-button',
);
button.click();
const addSnapAccountButton = getByText(
Expand All @@ -357,13 +376,16 @@ describe('AccountListMenu', () => {

it('opens the Snaps registry in a new tab', async () => {
// Set up mock state
// @ts-expect-error mocking platform
global.platform = { openTab: jest.fn() };
const { getByText } = renderWithState({ addSnapAccountEnabled: true });
const { getByText, getByTestId } = renderWithState({
addSnapAccountEnabled: true,
});
mockGetEnvironmentType.mockReturnValueOnce('fullscreen');

// Open account picker
const button = document.querySelector(
'[data-testid="multichain-account-menu-popover-action-button"]',
const button = getByTestId(
'multichain-account-menu-popover-action-button',
);
button.click();

Expand Down Expand Up @@ -439,45 +461,13 @@ describe('AccountListMenu', () => {
const listItems = document.querySelectorAll(
'.multichain-account-list-item',
);
const tag = listItems[0].querySelector('.mm-tag');
const tag = listItems[0].querySelector('.mm-tag') as Element;
expect(tag.textContent).toBe('Snaps (Beta)');
});

it('displays the correct label for named snap accounts', () => {
const mockStore = configureStore({
activeTab: {
title: 'Eth Sign Tests',
origin: 'https://remix.ethereum.org',
protocol: 'https:',
url: 'https://remix.ethereum.org/',
},
render({
metamask: {
...mockState.metamask,
permissionHistory: {
'https://test.dapp': {
eth_accounts: {
accounts: {
'0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc': 1596681857076,
},
},
},
},
subjects: {
'https://test.dapp': {
permissions: {
eth_accounts: {
caveats: [
{
type: 'restrictReturnedAccounts',
value: ['0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc'],
},
],
invoker: 'https://test.dapp',
parentCapability: 'eth_accounts',
},
},
},
},
internalAccounts: {
accounts: {
...mockState.metamask.internalAccounts.accounts,
Expand All @@ -501,12 +491,63 @@ describe('AccountListMenu', () => {
},
},
});
renderWithProvider(<AccountListMenu onClose={jest.fn()} />, mockStore);
const listItems = document.querySelectorAll(
'.multichain-account-list-item',
);
const tag = listItems[0].querySelector('.mm-tag');
const tag = listItems[0].querySelector('.mm-tag') as Element;
expect(tag.textContent).toBe('Test Snap Name (Beta)');
});
///: END:ONLY_INCLUDE_IF

describe('prop `allowedAccountTypes`', () => {
const mockAccount = createMockInternalAccount();
const mockBtcAccount = createMockInternalAccount({
name: 'Bitcoin Account',
type: BtcAccountType.P2wpkh,
address: 'bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq',
});
const defaultMockState = {
...mockState,
metamask: {
...mockState.metamask,
internalAccounts: {
accounts: {
[mockAccount.id]: mockAccount,
[mockBtcAccount.id]: mockBtcAccount,
},
selectedAccount: mockAccount.id,
},
keyrings: [
{
type: 'HD Key Tree',
accounts: [mockAccount.address],
},
{
type: 'Snap Keyring',
accounts: [mockBtcAccount.address],
},
],
},
};

it('allows only EthAccountTypes', () => {
const { queryByText } = render(defaultMockState, {
onClose: jest.fn(),
allowedAccountTypes: [EthAccountType.Eoa, EthAccountType.Erc4337],
});

expect(queryByText(mockAccount.metadata.name)).toBeInTheDocument();
expect(queryByText(mockBtcAccount.metadata.name)).not.toBeInTheDocument();
});

it('allows only BtcAccountType', () => {
const { queryByText } = render(defaultMockState, {
onClose: jest.fn(),
allowedAccountTypes: [BtcAccountType.P2wpkh],
});

expect(queryByText(mockAccount.metadata.name)).not.toBeInTheDocument();
expect(queryByText(mockBtcAccount.metadata.name)).toBeInTheDocument();
});
});
});
Loading

0 comments on commit 7da24fb

Please sign in to comment.