Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { configureStore } from '@reduxjs/toolkit';
import { Box } from '@metamask/design-system-react-native';
import AccountCell from '.';
import initialBackgroundState from '../../../../util/test/initial-background-state.json';
import { AvatarAccountType } from '../../../components/Avatars/Avatar/variants/AvatarAccount';
import { AvatarAccountType } from '../avatarAccountVariant';

interface StoryArgs {
accountGroup: AccountGroupObject;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ import {
createMockState,
createMockWallet,
} from '../test-utils';
import { AvatarAccountType } from '../../../components/Avatars/Avatar';
import { Maskicon } from '@metamask/design-system-react-native';
import JazzIcon from 'react-native-jazzicon';
import { Image as RNImage } from 'react-native';
import {
Blockies,
Jazzicon,
Maskicon,
} from '@metamask/design-system-react-native';
import { AccountCellIds } from './AccountCell.testIds';
import { backgroundState } from '../../../../util/test/initial-root-state';
import { AvatarAccountType } from '../avatarAccountVariant';

// Configurable mock balance for selector
const mockBalance: { value: number; currency: string } = {
Expand Down Expand Up @@ -159,18 +161,18 @@ describe('AccountCell', () => {
expect(UNSAFE_getByType(Maskicon)).toBeTruthy();
});

it('renders JazzIcon AvatarAccount when avatarAccountType is JazzIcon', () => {
it('renders Jazzicon AvatarAccount when avatarAccountType is JazzIcon', () => {
const { UNSAFE_getByType } = renderAccountCell({
avatarAccountType: AvatarAccountType.JazzIcon,
});
expect(UNSAFE_getByType(JazzIcon)).toBeTruthy();
expect(UNSAFE_getByType(Jazzicon)).toBeTruthy();
});

it('renders Blockies AvatarAccount when avatarAccountType is Blockies', () => {
const { UNSAFE_getByType } = renderAccountCell({
avatarAccountType: AvatarAccountType.Blockies,
});
expect(UNSAFE_getByType(RNImage)).toBeTruthy();
expect(UNSAFE_getByType(Blockies)).toBeTruthy();
});

it('calls onSelectAccount when account name is pressed', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,36 @@
import { AccountGroupObject } from '@metamask/account-tree-controller';
import React, { useCallback, useMemo } from 'react';
import { type ImageSourcePropType, TouchableOpacity, View } from 'react-native';
import { TouchableOpacity, View } from 'react-native';
import { useSelector } from 'react-redux';
import { useNavigation } from '@react-navigation/native';
import {
AvatarAccount,
AvatarAccountSize,
AvatarNetwork,
AvatarNetworkSize,
FontWeight,
Icon,
IconColor,
IconName,
IconSize,
SensitiveText,
SensitiveTextLength,
Text,
TextColor,
TextVariant,
} from '@metamask/design-system-react-native';
import { useStyles } from '../../../hooks';
import styleSheet from './AccountCell.styles';
import Text, { TextColor, TextVariant } from '../../../components/Texts/Text';
import SensitiveText, {
SensitiveTextLength,
} from '../../../components/Texts/SensitiveText';
import { Box } from '../../../../components/UI/Box/Box';
import {
AlignItems,
FlexDirection,
JustifyContent,
} from '../../../../components/UI/Box/box.types';
import Icon, { IconName, IconSize } from '../../../components/Icons/Icon';
import { AccountCellIds } from './AccountCell.testIds';
import { selectBalanceByAccountGroup } from '../../../../selectors/assets/balances';
import { formatWithThreshold } from '../../../../util/assets';
import I18n from '../../../../../locales/i18n';
import AvatarAccount, {
AvatarAccountType,
} from '../../../components/Avatars/Avatar/variants/AvatarAccount';
import Avatar, { AvatarVariant } from '../../../components/Avatars/Avatar';
import { AvatarSize } from '../../../components/Avatars/Avatar/Avatar.types';
import {
selectIconSeedAddressByAccountGroupId,
selectInternalAccountByAccountGroupAndScope,
Expand All @@ -34,10 +40,14 @@ import { createAccountGroupDetailsNavigationDetails } from '../../../../componen
import { getNetworkImageSource } from '../../../../util/networks';
import { formatChainIdToCaip } from '@metamask/bridge-controller';
import { renderShortAddress } from '../../../../util/address';
import {
type AccountAvatarVariant,
getAvatarAccountVariant,
} from '../avatarAccountVariant';

interface AccountCellProps {
accountGroup: AccountGroupObject;
avatarAccountType: AvatarAccountType;
avatarAccountType: AccountAvatarVariant;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: IDK if we want to align naming here too? Might not really be part of the DS migration initiative (I couldn't find a AvatarAccountType on the DS package, so "variant" seems to be the only term we use for this now)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are you suggesting specifically? Change the type name or the prop name?

hideMenu?: boolean;
startAccessory?: React.ReactNode;
endContainer?: React.ReactNode;
Expand All @@ -49,7 +59,7 @@ type BalanceEndContainerProps = Pick<
AccountCellProps,
'accountGroup' | 'hideMenu' | 'onSelectAccount'
> & {
networkImageSource?: ImageSourcePropType;
networkImageSource?: React.ComponentProps<typeof AvatarNetwork>['src'];
};

const BalanceEndContainer = ({
Expand Down Expand Up @@ -89,8 +99,9 @@ const BalanceEndContainer = ({
<TouchableOpacity onPress={onSelectAccount}>
<View style={styles.balanceContainer}>
<SensitiveText
variant={TextVariant.BodyMDMedium}
color={TextColor.Default}
variant={TextVariant.BodyMd}
color={TextColor.TextDefault}
fontWeight={FontWeight.Medium}
length={SensitiveTextLength.Long}
isHidden={
privacyMode && Boolean(displayBalance) && Boolean(totalBalance)
Expand All @@ -100,11 +111,10 @@ const BalanceEndContainer = ({
{totalBalance ? displayBalance : null}
</SensitiveText>
{networkImageSource && (
<Avatar
variant={AvatarVariant.Network}
size={AvatarSize.Xs}
<AvatarNetwork
size={AvatarNetworkSize.Xs}
style={styles.networkBadge}
imageSource={networkImageSource}
src={networkImageSource}
/>
)}
</View>
Expand All @@ -118,7 +128,7 @@ const BalanceEndContainer = ({
<Icon
name={IconName.MoreVertical}
size={IconSize.Md}
color={TextColor.Alternative}
color={IconColor.IconAlternative}
/>
</TouchableOpacity>
)}
Expand All @@ -136,6 +146,7 @@ const AccountCell = ({
onSelectAccount,
}: AccountCellProps) => {
const { styles } = useStyles(styleSheet, {});
const avatarAccountVariant = getAvatarAccountVariant(avatarAccountType);

const selectEvmAddress = useMemo(
() => selectIconSeedAddressByAccountGroupId(accountGroup.id),
Expand Down Expand Up @@ -170,16 +181,17 @@ const AccountCell = ({
<TouchableOpacity onPress={onSelectAccount} style={styles.mainTouchable}>
{startAccessory}
<AvatarAccount
accountAddress={evmAddress}
type={avatarAccountType}
size={AvatarSize.Md}
address={evmAddress ?? ''}
variant={avatarAccountVariant}
size={AvatarAccountSize.Md}
testID={AccountCellIds.AVATAR}
/>
<View style={styles.accountName}>
<View style={styles.accountNameRow}>
<Text
variant={TextVariant.BodyMDMedium}
color={TextColor.Default}
variant={TextVariant.BodyMd}
color={TextColor.TextDefault}
fontWeight={FontWeight.Medium}
numberOfLines={1}
style={styles.accountNameText}
testID={AccountCellIds.ADDRESS}
Expand All @@ -190,8 +202,8 @@ const AccountCell = ({
{networkAccountAddress && (
<View style={styles.accountSubRow}>
<Text
variant={TextVariant.BodySM}
color={TextColor.Alternative}
variant={TextVariant.BodySm}
color={TextColor.TextAlternative}
numberOfLines={1}
style={styles.accountSubText}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import {
createMockState,
createMockWallet,
} from '../../test-utils';
import { AvatarAccountType } from '../../../../components/Avatars/Avatar';
import { AvatarAccountType } from '../../avatarAccountVariant';
import { RootState } from '../../../../../reducers';
import { CHECKBOX_ICON_TESTID } from '../../../../components/Checkbox/Checkbox.constants';
import { ACCOUNT_LIST_CELL_CHECKBOX_ICON_TEST_ID } from './AccountListCell.testIds';

const mockNavigate = jest.fn();

Expand Down Expand Up @@ -169,7 +169,7 @@ describe('AccountListCell', () => {
expect(
getByTestId(`account-list-cell-checkbox-${mockAccountGroup.id}`),
).toBeTruthy();
expect(getByTestId(CHECKBOX_ICON_TESTID)).toBeTruthy();
expect(getByTestId(ACCOUNT_LIST_CELL_CHECKBOX_ICON_TEST_ID)).toBeTruthy();
});

it('renders unchecked checkbox when isSelected is false', () => {
Expand All @@ -188,7 +188,9 @@ describe('AccountListCell', () => {
expect(
getByTestId(`account-list-cell-checkbox-${mockAccountGroup.id}`),
).toBeTruthy();
expect(queryByTestId(CHECKBOX_ICON_TESTID)).toBeFalsy();
expect(
queryByTestId(ACCOUNT_LIST_CELL_CHECKBOX_ICON_TEST_ID),
).toBeFalsy();
});

it('calls onSelectAccount when checkbox is pressed', () => {
Expand Down Expand Up @@ -246,7 +248,7 @@ describe('AccountListCell', () => {
expect(
getByTestId(`account-list-cell-checkbox-${mockAccountGroup.id}`),
).toBeTruthy();
expect(getByTestId(CHECKBOX_ICON_TESTID)).toBeTruthy();
expect(getByTestId(ACCOUNT_LIST_CELL_CHECKBOX_ICON_TEST_ID)).toBeTruthy();
expect(getByText('Test Account')).toBeTruthy();
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
export const ACCOUNT_LIST_CELL_TEST_IDS = {
ACCOUNT_LIST_CELL: 'account-list-cell-checkbox-',
} as const;

export const ACCOUNT_LIST_CELL_CHECKBOX_ICON_TEST_ID =
'account-list-cell-checkbox-icon';
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import React, { memo, useCallback } from 'react';
import { View } from 'react-native';
import { Checkbox } from '@metamask/design-system-react-native';

import { useStyles } from '../../../../hooks';
import AccountCell from '../../AccountCell';
import createStyles from '../MultichainAccountSelectorList.styles';
import { AccountListCellProps } from './AccountListCell.types';
import Checkbox from '../../../../components/Checkbox';
import { ACCOUNT_LIST_CELL_TEST_IDS } from './AccountListCell.testIds';
import {
ACCOUNT_LIST_CELL_CHECKBOX_ICON_TEST_ID,
ACCOUNT_LIST_CELL_TEST_IDS,
} from './AccountListCell.testIds';

const AccountListCell = memo(
({
Expand All @@ -32,10 +35,17 @@ const AccountListCell = memo(
<AccountCell
startAccessory={
showCheckbox ? (
<View
testID={`${ACCOUNT_LIST_CELL_TEST_IDS.ACCOUNT_LIST_CELL}${accountGroup.id}`}
>
<Checkbox isChecked={isSelected} onPress={handlePress} />
<View>
<Checkbox
testID={`${ACCOUNT_LIST_CELL_TEST_IDS.ACCOUNT_LIST_CELL}${accountGroup.id}`}
isSelected={isSelected}
onChange={handlePress}
checkedIconProps={
isSelected
? { testID: ACCOUNT_LIST_CELL_CHECKBOX_ICON_TEST_ID }
: undefined
}
/>
</View>
) : undefined
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { AccountGroupObject } from '@metamask/account-tree-controller';
import { AvatarAccountType } from '../../../../components/Avatars/Avatar/variants/AvatarAccount';
import type { AccountAvatarVariant } from '../../avatarAccountVariant';

export interface AccountListCellProps {
accountGroup: AccountGroupObject;
avatarAccountType: AvatarAccountType;
avatarAccountType: AccountAvatarVariant;
isSelected: boolean;
onSelectAccount: (accountGroup: AccountGroupObject) => void;
showCheckbox?: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import React, { memo } from 'react';
import { View } from 'react-native';

import { useStyles } from '../../../../hooks';
import Text, {
import {
FontWeight,
Text,
TextColor,
TextVariant,
} from '../../../../components/Texts/Text';
} from '@metamask/design-system-react-native';

import { useStyles } from '../../../../hooks';
import createStyles from '../MultichainAccountSelectorList.styles';
import { AccountListHeaderProps } from './AccountListHeader.types';

Expand All @@ -16,8 +18,9 @@ const AccountListHeader = memo(
return (
<View style={[styles.sectionHeader, containerStyle]}>
<Text
variant={TextVariant.BodyMDMedium}
color={TextColor.Alternative}
variant={TextVariant.BodyMd}
color={TextColor.TextAlternative}
fontWeight={FontWeight.Medium}
style={styles.sectionHeaderText}
>
{title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { fireEvent } from '@testing-library/react-native';
import ExternalAccountCell from './ExternalAccountCell';
import renderWithProvider from '../../../../../util/test/renderWithProvider';
import { strings } from '../../../../../../locales/i18n';
import { EXTERNAL_ACCOUNT_CELL_TEST_IDS } from './ExternalAccountCell.testIds';

// Mock the settings selector
jest.mock('../../../../../selectors/settings', () => ({
Expand Down Expand Up @@ -75,7 +76,9 @@ describe('ExternalAccountCell', () => {
);

// Network avatar should not be rendered
expect(queryByTestId('network-avatar-image')).toBeFalsy();
expect(
queryByTestId(EXTERNAL_ACCOUNT_CELL_TEST_IDS.NETWORK_AVATAR),
).toBeFalsy();
});

it('renders with network avatar when chainId is provided', () => {
Expand All @@ -88,7 +91,9 @@ describe('ExternalAccountCell', () => {
);

// Network avatar should be rendered
expect(getByTestId('network-avatar-image')).toBeTruthy();
expect(
getByTestId(EXTERNAL_ACCOUNT_CELL_TEST_IDS.NETWORK_AVATAR),
).toBeTruthy();
});

it('renders account avatar', () => {
Expand Down Expand Up @@ -205,7 +210,9 @@ describe('ExternalAccountCell', () => {
/>,
);

expect(getByTestId('network-avatar-image')).toBeTruthy();
expect(
getByTestId(EXTERNAL_ACCOUNT_CELL_TEST_IDS.NETWORK_AVATAR),
).toBeTruthy();
});

it('renders correctly with Polygon chain ID', () => {
Expand All @@ -217,7 +224,9 @@ describe('ExternalAccountCell', () => {
/>,
);

expect(getByTestId('network-avatar-image')).toBeTruthy();
expect(
getByTestId(EXTERNAL_ACCOUNT_CELL_TEST_IDS.NETWORK_AVATAR),
).toBeTruthy();
});

it('renders correctly with Optimism chain ID', () => {
Expand All @@ -229,7 +238,9 @@ describe('ExternalAccountCell', () => {
/>,
);

expect(getByTestId('network-avatar-image')).toBeTruthy();
expect(
getByTestId(EXTERNAL_ACCOUNT_CELL_TEST_IDS.NETWORK_AVATAR),
).toBeTruthy();
});
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const EXTERNAL_ACCOUNT_CELL_TEST_IDS = {
CONTAINER: 'external-account-cell-touchable',
NETWORK_AVATAR: 'network-avatar-image',
} as const;
Loading
Loading