Skip to content

Commit 12a458a

Browse files
CopilotDDDDDanica
andauthored
test: add coverage for TokenBalancesPoller isolation and AssetPollingContext memoization
Agent-Logs-Url: https://github.com/MetaMask/metamask-extension/sessions/c94cdb5a-1d8d-41e0-b2cc-4060a80f5f24 Co-authored-by: DDDDDanica <12678455+DDDDDanica@users.noreply.github.com>
1 parent 75fde86 commit 12a458a

2 files changed

Lines changed: 83 additions & 6 deletions

File tree

ui/components/multichain/account-overview/account-overview-tabs.test.tsx

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,17 @@ import {
1010
MetaMetricsEventName,
1111
} from '../../../../shared/constants/metametrics';
1212
import { CHAIN_IDS } from '../../../../shared/constants/network';
13+
import { useTokenBalances } from '../../../hooks/useTokenBalances';
1314
import { AccountOverviewTabs } from './account-overview-tabs';
1415

1516
jest.mock('../../../store/actions', () => ({
1617
setDefaultHomeActiveTabName: jest.fn(),
1718
}));
1819

20+
jest.mock('../../../hooks/useTokenBalances', () => ({
21+
useTokenBalances: jest.fn(),
22+
}));
23+
1924
jest.mock('../../app/assets/asset-list', () => ({
2025
// eslint-disable-next-line @typescript-eslint/naming-convention
2126
__esModule: true,
@@ -46,6 +51,11 @@ jest.mock('../../app/perps/perps-tab', () => ({
4651
PerpsTab: () => <div data-testid="perps-tab-mock">PerpsTab</div>,
4752
}));
4853

54+
beforeEach(() => {
55+
jest.clearAllMocks();
56+
(useTokenBalances as jest.Mock).mockReturnValue({ tokenBalances: {} });
57+
});
58+
4959
describe('AccountOverviewTabs - event metrics', () => {
5060
const mockTrackEvent = jest.fn();
5161
const mockMetaMetricsContext = {
@@ -55,10 +65,6 @@ describe('AccountOverviewTabs - event metrics', () => {
5565
onboardingParentContext: { current: null },
5666
};
5767

58-
beforeEach(() => {
59-
jest.clearAllMocks();
60-
});
61-
6268
it('includes network_filter property with both EVM and non-EVM networks in CAIP format', () => {
6369
const store = configureStore({
6470
metamask: {
@@ -107,3 +113,39 @@ describe('AccountOverviewTabs - event metrics', () => {
107113
});
108114
});
109115
});
116+
117+
describe('AccountOverviewTabs - TokenBalancesPoller', () => {
118+
it('polls token balances for the enabled EVM chain IDs', () => {
119+
const store = configureStore({
120+
metamask: {
121+
...mockState.metamask,
122+
enabledNetworkMap: {
123+
eip155: {
124+
[CHAIN_IDS.MAINNET]: true,
125+
[CHAIN_IDS.POLYGON]: true,
126+
},
127+
},
128+
},
129+
});
130+
131+
renderWithProvider(
132+
<AccountOverviewTabs
133+
showTokens={true}
134+
showNfts={false}
135+
showActivity={false}
136+
setBasicFunctionalityModalOpen={jest.fn()}
137+
onSupportLinkClick={jest.fn()}
138+
/>,
139+
store,
140+
);
141+
142+
expect(useTokenBalances).toHaveBeenCalledWith(
143+
expect.objectContaining({
144+
chainIds: expect.arrayContaining([
145+
CHAIN_IDS.MAINNET,
146+
CHAIN_IDS.POLYGON,
147+
]),
148+
}),
149+
);
150+
});
151+
});

ui/contexts/assetPolling.test.tsx

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useContext, useEffect } from 'react';
22
import { render, screen } from '@testing-library/react';
33
import '@testing-library/jest-dom';
44
import * as redux from 'react-redux';
@@ -9,7 +9,11 @@ import useTokenListPolling from '../hooks/useTokenListPolling';
99
import useStaticTokensPollingHook from '../hooks/useStaticTokensPolling';
1010
import useDeFiPolling from '../hooks/defi/useDeFiPolling';
1111
import useMultichainAssetsRatesPolling from '../hooks/useMultichainAssetsRatesPolling';
12-
import { AssetPollingProvider } from './assetPolling';
12+
import {
13+
AssetPollingContext,
14+
AssetPollingContextValue,
15+
AssetPollingProvider,
16+
} from './assetPolling';
1317

1418
jest.mock('../hooks/useCurrencyRatePolling');
1519
jest.mock('../hooks/useTokenRatesPolling');
@@ -97,4 +101,35 @@ describe('AssetPollingProvider', () => {
97101
expect(mockUseMultichainAssetsRatesPolling).not.toHaveBeenCalled();
98102
});
99103
});
104+
105+
describe('context value memoization', () => {
106+
it('provides a stable context value object across re-renders', () => {
107+
jest.spyOn(redux, 'useSelector').mockReturnValue(false);
108+
109+
const capturedValues: AssetPollingContextValue[] = [];
110+
111+
const TestConsumer = () => {
112+
const ctx = useContext(AssetPollingContext);
113+
useEffect(() => {
114+
capturedValues.push(ctx);
115+
});
116+
return null;
117+
};
118+
119+
const { rerender } = render(
120+
<AssetPollingProvider>
121+
<TestConsumer />
122+
</AssetPollingProvider>,
123+
);
124+
125+
rerender(
126+
<AssetPollingProvider>
127+
<TestConsumer />
128+
</AssetPollingProvider>,
129+
);
130+
131+
expect(capturedValues.length).toBeGreaterThanOrEqual(2);
132+
expect(capturedValues[0]).toBe(capturedValues[1]);
133+
});
134+
});
100135
});

0 commit comments

Comments
 (0)