Skip to content

Commit bd5909f

Browse files
chore: updates
1 parent 7191eb2 commit bd5909f

File tree

2 files changed

+85
-7
lines changed

2 files changed

+85
-7
lines changed

app/components/UI/Tokens/TokenList/PortfolioBalance/index.test.tsx

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { backgroundState } from '../../../../../util/test/initial-root-state';
55
import { WalletViewSelectorsIDs } from '../../../../../../e2e/selectors/wallet/WalletView.selectors';
66
import { PortfolioBalance } from '.';
77
import Engine from '../../../../../core/Engine';
8+
import { useSelectedAccountMultichainBalances } from '../../../../hooks/useMultichainBalances';
89

910
const { PreferencesController } = Engine.context;
1011

@@ -17,9 +18,9 @@ const mockSelectedAccountMultichainBalance = {
1718
};
1819

1920
jest.mock('../../../../hooks/useMultichainBalances', () => ({
20-
useSelectedAccountMultichainBalances: () => ({
21+
useSelectedAccountMultichainBalances: jest.fn(() => ({
2122
selectedAccountMultichainBalance: mockSelectedAccountMultichainBalance,
22-
}),
23+
})),
2324
}));
2425

2526
jest.mock('../../../../../core/Engine', () => ({
@@ -47,6 +48,30 @@ jest.mock('../../../../../core/Engine', () => ({
4748
},
4849
}));
4950

51+
jest.mock('@react-navigation/native', () => {
52+
const actualNav = jest.requireActual('@react-navigation/native');
53+
return {
54+
...actualNav,
55+
useNavigation: () => ({
56+
navigate: jest.fn(),
57+
}),
58+
};
59+
});
60+
61+
jest.mock('../../../../../components/hooks/useMetrics', () => ({
62+
useMetrics: () => ({
63+
trackEvent: jest.fn(),
64+
createEventBuilder: jest.fn(() => ({
65+
addProperties: jest.fn().mockReturnThis(),
66+
build: jest.fn(),
67+
})),
68+
}),
69+
MetaMetricsEvents: {
70+
CARD_ADD_FUNDS_DEPOSIT_CLICKED: 'CARD_ADD_FUNDS_DEPOSIT_CLICKED',
71+
RAMPS_BUTTON_CLICKED: 'RAMPS_BUTTON_CLICKED',
72+
},
73+
}));
74+
5075
const initialState = {
5176
engine: {
5277
backgroundState: {
@@ -146,6 +171,15 @@ const renderPortfolioBalance = (state: any = {}) =>
146171
renderWithProvider(<PortfolioBalance />, { state });
147172

148173
describe('PortfolioBalance', () => {
174+
beforeEach(() => {
175+
jest.clearAllMocks();
176+
// Reset to default mock before each test
177+
const mockedHook = jest.mocked(useSelectedAccountMultichainBalances);
178+
mockedHook.mockReturnValue({
179+
selectedAccountMultichainBalance: mockSelectedAccountMultichainBalance,
180+
});
181+
});
182+
149183
it('fiat balance must be defined', () => {
150184
const { getByTestId } = renderPortfolioBalance(initialState);
151185
expect(
@@ -207,4 +241,40 @@ describe('PortfolioBalance', () => {
207241

208242
expect(PreferencesController.setPrivacyMode).toHaveBeenCalledWith(true);
209243
});
244+
245+
it('displays BalanceEmptyState when balance is zero', () => {
246+
// Mock zero balance
247+
const mockSelectedAccountMultichainBalanceZero = {
248+
displayBalance: '$0.00',
249+
totalFiatBalance: 0,
250+
shouldShowAggregatedPercentage: false,
251+
tokenFiatBalancesCrossChains: [],
252+
};
253+
254+
const mockedHook = jest.mocked(useSelectedAccountMultichainBalances);
255+
mockedHook.mockReturnValue({
256+
selectedAccountMultichainBalance:
257+
mockSelectedAccountMultichainBalanceZero,
258+
});
259+
260+
const { getByTestId, queryByTestId } = renderPortfolioBalance(initialState);
261+
262+
// Should render BalanceEmptyState instead of balance text
263+
expect(getByTestId('portfolio-balance-empty-state')).toBeDefined();
264+
expect(queryByTestId(WalletViewSelectorsIDs.TOTAL_BALANCE_TEXT)).toBeNull();
265+
});
266+
267+
it('displays loader when balance is not available', () => {
268+
// Mock null balance
269+
const mockedHook = jest.mocked(useSelectedAccountMultichainBalances);
270+
mockedHook.mockReturnValue({
271+
selectedAccountMultichainBalance: null,
272+
});
273+
274+
const { queryByTestId } = renderPortfolioBalance(initialState);
275+
276+
// Should not render balance text or empty state
277+
expect(queryByTestId(WalletViewSelectorsIDs.TOTAL_BALANCE_TEXT)).toBeNull();
278+
expect(queryByTestId('portfolio-balance-empty-state')).toBeNull();
279+
});
210280
});

app/components/UI/Tokens/TokenList/PortfolioBalance/index.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { useSelectedAccountMultichainBalances } from '../../../../hooks/useMulti
1515
import Loader from '../../../../../component-library/components-temp/Loader/Loader';
1616
import NonEvmAggregatedPercentage from '../../../../../component-library/components-temp/Price/AggregatedPercentage/NonEvmAggregatedPercentage';
1717
import { selectIsEvmNetworkSelected } from '../../../../../selectors/multichainNetworkController';
18+
import BalanceEmptyState from '../../../BalanceEmptyState';
1819

1920
export const PortfolioBalance = React.memo(() => {
2021
const { PreferencesController } = Engine.context;
@@ -57,10 +58,21 @@ export const PortfolioBalance = React.memo(() => {
5758
[PreferencesController],
5859
);
5960

61+
// Check if balance is zero (empty state) - only check when we have balance data
62+
const hasZeroBalance =
63+
selectedAccountMultichainBalance &&
64+
selectedAccountMultichainBalance.totalFiatBalance === 0;
65+
6066
return (
6167
<View style={styles.portfolioBalance}>
6268
<View>
63-
{selectedAccountMultichainBalance?.displayBalance ? (
69+
{!selectedAccountMultichainBalance ? (
70+
<View style={styles.loaderWrapper}>
71+
<Loader />
72+
</View>
73+
) : hasZeroBalance ? (
74+
<BalanceEmptyState testID="portfolio-balance-empty-state" />
75+
) : (
6476
<TouchableOpacity
6577
onPress={() => toggleIsBalanceAndAssetsHidden(!privacyMode)}
6678
testID="balance-container"
@@ -78,10 +90,6 @@ export const PortfolioBalance = React.memo(() => {
7890

7991
{renderAggregatedPercentage()}
8092
</TouchableOpacity>
81-
) : (
82-
<View style={styles.loaderWrapper}>
83-
<Loader />
84-
</View>
8593
)}
8694
</View>
8795
</View>

0 commit comments

Comments
 (0)