Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: funding method modal #26426

Merged
merged 39 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
9d3de43
feat: funding method modal
Aug 14, 2024
d90c605
chore: move receive modal
Aug 14, 2024
cfbf763
fix: eslint errors
Aug 14, 2024
f43aac0
Merge branch 'develop' into MMPD-1296
julesat22 Aug 14, 2024
5fd6f9e
chore: update type to resolve linting error
Aug 14, 2024
76bf952
Merge branch 'MMPD-1296' of github.com:MetaMask/metamask-extension in…
Aug 14, 2024
2412d15
fix: linting errors
Aug 14, 2024
50ca969
chore: update url
Aug 14, 2024
248f9c4
chore: add tab to portfolio url
Aug 14, 2024
c0a6c52
fix: prettier and failing unit test
Aug 15, 2024
221d4a8
Merge branch 'develop' into MMPD-1296
julesat22 Aug 15, 2024
af3814d
chore: add tracking events in for nav items
Aug 16, 2024
a4da8ff
Merge branch 'develop' into MMPD-1296
julesat22 Aug 16, 2024
276c559
Merge branch 'MMPD-1296' of github.com:MetaMask/metamask-extension in…
Aug 16, 2024
4095418
chore: fix tests
Aug 16, 2024
16a45b6
chore: add deps
Aug 16, 2024
0420d34
Merge branch 'develop' into MMPD-1296
julesat22 Aug 19, 2024
40a0f16
Merge branch 'develop' into MMPD-1296
julesat22 Aug 20, 2024
f7ab659
Merge branch 'develop' into MMPD-1296
julesat22 Aug 20, 2024
6181009
Merge branch 'develop' into MMPD-1296
julesat22 Aug 21, 2024
7368d7c
Merge branch 'develop' into MMPD-1296
julesat22 Aug 21, 2024
507cf21
Merge branch 'develop' into MMPD-1296
Aug 22, 2024
8cf69d0
chore: remove unused message
Aug 22, 2024
bcd649d
Merge branch 'develop' into MMPD-1296
Aug 28, 2024
7ce01b2
Merge branch 'develop' into MMPD-1296
julesat22 Aug 28, 2024
bb57c7a
Merge branch 'develop' into MMPD-1296
julesat22 Aug 29, 2024
e524a8c
Merge branch 'develop' into MMPD-1296
julesat22 Sep 3, 2024
777f08d
Merge branch 'develop' into MMPD-1296
julesat22 Sep 4, 2024
79bed10
Merge branch 'develop' into MMPD-1296
julesat22 Sep 5, 2024
e7eaf09
Merge branch 'develop' into MMPD-1296
julesat22 Sep 6, 2024
317e976
Merge branch 'develop' into MMPD-1296
julesat22 Sep 6, 2024
d206128
Merge branch 'develop' into MMPD-1296
julesat22 Sep 9, 2024
615430d
Merge branch 'develop' into MMPD-1296
julesat22 Sep 9, 2024
617510d
chore: add conditional address check
Sep 9, 2024
8406107
Merge branch 'MMPD-1296' of github.com:MetaMask/metamask-extension in…
Sep 9, 2024
9a31f2a
Merge branch 'develop' into MMPD-1296
julesat22 Sep 10, 2024
0f146e2
Merge branch 'develop' into MMPD-1296
jclancy93 Sep 10, 2024
8b9e3c6
Merge branch 'develop' into MMPD-1296
julesat22 Sep 12, 2024
28c4fa9
Merge branch 'develop' into MMPD-1296
julesat22 Sep 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions app/_locales/en/messages.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 29 additions & 0 deletions ui/components/app/assets/asset-list/asset-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,17 @@ import {
DetectedTokensBanner,
TokenListItem,
ImportTokenLink,
ReceiveModal,
} from '../../../multichain';
import { useAccountTotalFiatBalance } from '../../../../hooks/useAccountTotalFiatBalance';
import { useIsOriginalNativeTokenSymbol } from '../../../../hooks/useIsOriginalNativeTokenSymbol';
import { useI18nContext } from '../../../../hooks/useI18nContext';
import {
showPrimaryCurrency,
showSecondaryCurrency,
} from '../../../../../shared/modules/currency-display.utils';
import { roundToDecimalPlacesRemovingExtraZeroes } from '../../../../helpers/utils/util';
import { FundingMethodModal } from '../../../multichain/funding-method-modal/funding-method-modal';
///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask)
import {
RAMPS_CARD_VARIANT_TYPES,
Expand All @@ -66,6 +69,7 @@ const AssetList = ({ onClickAsset, showTokensLinks }) => {
type,
rpcUrl,
);
const t = useI18nContext();
const trackEvent = useContext(MetaMetricsContext);
const balance = useSelector(getMultichainSelectedAccountCachedBalance);
const balanceIsLoading = !balance;
Expand Down Expand Up @@ -101,6 +105,14 @@ const AssetList = ({ onClickAsset, showTokensLinks }) => {
getIstokenDetectionInactiveOnNonMainnetSupportedNetwork,
);

const [showFundingMethodModal, setShowFundingMethodModal] = useState(false);
const [showReceiveModal, setShowReceiveModal] = useState(false);

const onClickReceive = () => {
setShowFundingMethodModal(false);
setShowReceiveModal(true);
};

const { tokensWithBalances, loading } = useAccountTotalFiatBalance(
selectedAccount,
shouldHideZeroBalanceTokens,
Expand Down Expand Up @@ -151,6 +163,9 @@ const AssetList = ({ onClickAsset, showTokensLinks }) => {
? RAMPS_CARD_VARIANT_TYPES.BTC
: RAMPS_CARD_VARIANT_TYPES.TOKEN
}
handleOnClick={
isBtc ? undefined : () => setShowFundingMethodModal(true)
}
/>
) : null
///: END:ONLY_INCLUDE_IF
Expand Down Expand Up @@ -213,6 +228,20 @@ const AssetList = ({ onClickAsset, showTokensLinks }) => {
{showDetectedTokens && (
<DetectedToken setShowDetectedTokens={setShowDetectedTokens} />
)}
{showReceiveModal && selectedAccount?.address && (
<ReceiveModal
address={selectedAccount.address}
onClose={() => setShowReceiveModal(false)}
/>
)}
{showFundingMethodModal && (
<FundingMethodModal
isOpen={showFundingMethodModal}
onClose={() => setShowFundingMethodModal(false)}
title={t('selectFundingMethod')}
onClickReceive={onClickReceive}
/>
)}
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { Box, Text, Icon, IconName } from '../../component-library';
import {
Display,
FlexDirection,
TextVariant,
TextColor,
AlignItems,
} from '../../../helpers/constants/design-system';

type FundingMethodItemProps = {
icon: IconName;
title: string;
description: string;
onClick: () => void;
};

const FundingMethodItem: React.FC<FundingMethodItemProps> = ({
icon,
title,
description,
onClick,
}) => (
<Box
display={[Display.Flex]}
gap={2}
alignItems={AlignItems.center}
onClick={onClick}
className="funding-method-item"
padding={4}
>
<Icon name={icon} />
<Box display={[Display.Flex]} flexDirection={FlexDirection.Column}>
<Text variant={TextVariant.bodyMdMedium}>{title}</Text>
<Text variant={TextVariant.bodySm} color={TextColor.textAlternative}>
{description}
</Text>
</Box>
</Box>
);

export default FundingMethodItem;
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import React from 'react';
import { fireEvent } from '@testing-library/react';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { renderWithProvider } from '../../../../test/jest/rendering';
import mockState from '../../../../test/data/mock-state.json';
import useRamps from '../../../hooks/ramps/useRamps/useRamps';
import { FundingMethodModal } from './funding-method-modal';

jest.mock('../../../hooks/ramps/useRamps/useRamps', () => ({
__esModule: true,
default: jest.fn(),
}));

const mockStore = configureMockStore([thunk]);

describe('FundingMethodModal', () => {
let store = configureMockStore([thunk])(mockState);
let openBuyCryptoInPdapp: jest.Mock<() => void>;

beforeEach(() => {
store = mockStore(mockState);
openBuyCryptoInPdapp = jest.fn();
(useRamps as jest.Mock).mockReturnValue({ openBuyCryptoInPdapp });
});

afterEach(() => {
jest.clearAllMocks();
});

it('should render the modal when isOpen is true', () => {
const { getByTestId, getByText } = renderWithProvider(
<FundingMethodModal
isOpen={true}
onClose={jest.fn()}
title="Test Modal"
onClickReceive={jest.fn()}
/>,
store,
);

expect(getByTestId('funding-method-modal')).toBeInTheDocument();
expect(getByText('Test Modal')).toBeInTheDocument();
});

it('should not render the modal when isOpen is false', () => {
const { queryByTestId } = renderWithProvider(
<FundingMethodModal
isOpen={false}
onClose={jest.fn()}
title="Test Modal"
onClickReceive={jest.fn()}
/>,
store,
);

expect(queryByTestId('funding-method-modal')).toBeNull();
});

it('should call openBuyCryptoInPdapp when the Buy Crypto item is clicked', () => {
const { getByText } = renderWithProvider(
<FundingMethodModal
isOpen={true}
onClose={jest.fn()}
title="Test Modal"
onClickReceive={jest.fn()}
/>,
store,
);

fireEvent.click(getByText('Buy crypto'));
expect(openBuyCryptoInPdapp).toHaveBeenCalled();
});

it('should call onClickReceive when the Receive Crypto item is clicked', () => {
const onClickReceive = jest.fn();
const { getByText } = renderWithProvider(
<FundingMethodModal
isOpen={true}
onClose={jest.fn()}
title="Test Modal"
onClickReceive={onClickReceive}
/>,
store,
);

fireEvent.click(getByText('Receive crypto'));
expect(onClickReceive).toHaveBeenCalled();
});

it('should open a new tab with the correct URL when Transfer Crypto item is clicked', () => {
global.platform.openTab = jest.fn();

const { getByText } = renderWithProvider(
<FundingMethodModal
isOpen={true}
onClose={jest.fn()}
title="Test Modal"
onClickReceive={jest.fn()}
/>,
store,
);

fireEvent.click(getByText('Transfer crypto'));
expect(global.platform.openTab).toHaveBeenCalledWith({
url: expect.stringContaining('transfer'),
});
});
});
Loading