Skip to content

Commit 9385d8c

Browse files
test: color-no-hex shared-unowned batch (MetaMask#27153)
## **Description** Split from MetaMask#26651 to reduce CODEOWNERS fanout. Batch: shared Standardizes unit tests to avoid hardcoded hex colors by switching theme mocks and style assertions to the shared `mockTheme` from `app/util/theme`. Also updates a small number of test mocks to match current hook signatures (e.g. `useNetworkEnablement` now returns `popularEvmNetworks` / `popularMultichainNetworks` / `popularNetworks`, and `useAnalytics` requires `identify`). Related color-no-hex PRs (same initiative): - MetaMask#26958 - MetaMask#26963 - MetaMask#27008 - MetaMask#27030 - MetaMask#27031 - MetaMask#27149 - MetaMask#27150 - MetaMask#27151 ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** ```gherkin Feature: color-no-hex test updates Scenario: TypeScript and unit tests are healthy Given the branch is checked out When I run yarn lint:tsc Then it passes ``` ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed MetaMask Contributor Docs and MetaMask Mobile Coding Standards. - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable (updated mocks + ran yarn lint:tsc) - [ ] I've documented my code using JSDoc format if applicable - [ ] I've applied the right labels on the PR (see labeling guidelines). Not required for external contributors. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk because changes are confined to unit tests/mocks; main risk is brittle test failures if the shared `mockTheme` shape or mocked hook contracts diverge from production interfaces. > > **Overview** > Refactors a batch of unit tests to stop hardcoding hex colors by switching theme mocks and style assertions to the shared `mockTheme` from `app/util/theme`. > > Updates several test-only mocks to match current hook contracts (notably `useNetworkEnablement` now returning `popularEvmNetworks`/`popularMultichainNetworks`/`popularNetworks`, `useAnalytics` including additional required methods, and `useTailwind` mock shape changes), plus a small Perps test adjustment to mock `usePerpsLivePrices`. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 32fe395. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 57308b4 commit 9385d8c

29 files changed

Lines changed: 316 additions & 374 deletions

File tree

app/components/Base/InfoModal.test.tsx

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,25 +48,12 @@ jest.mock('./Title', () => {
4848
});
4949

5050
// Mock useTheme hook
51-
jest.mock('../../util/theme', () => ({
52-
useTheme: jest.fn(() => ({
53-
colors: {
54-
background: { default: '#FFFFFF' },
55-
text: { default: '#000000' },
56-
overlay: { default: '#00000099' },
57-
},
58-
shadows: {
59-
size: {
60-
sm: {
61-
shadowColor: '#000',
62-
shadowOffset: { width: 0, height: 2 },
63-
shadowOpacity: 0.1,
64-
shadowRadius: 4,
65-
},
66-
},
67-
},
68-
})),
69-
}));
51+
jest.mock('../../util/theme', () => {
52+
const { mockTheme } = jest.requireActual('../../util/theme');
53+
return {
54+
useTheme: jest.fn(() => mockTheme),
55+
};
56+
});
7057

7158
describe('InfoModal', () => {
7259
const mockToggleModal = jest.fn();

app/components/Base/RemoteImage/index.test.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { backgroundState } from '../../../util/test/initial-root-state';
77
import Logger from '../../../util/Logger';
88
import { Dimensions } from 'react-native';
99
import { Image } from 'expo-image';
10+
import { mockTheme } from '../../../util/theme';
1011

1112
jest.mock('react-redux', () => ({
1213
...jest.requireActual('react-redux'),
@@ -582,7 +583,9 @@ describe('RemoteImage', () => {
582583
});
583584

584585
it('renders with fadeIn but not as token image', async () => {
585-
const testPlaceholderStyle = { backgroundColor: '#808080' };
586+
const testPlaceholderStyle = {
587+
backgroundColor: mockTheme.colors.background.alternative,
588+
};
586589
const { UNSAFE_getByType } = render(
587590
<RemoteImage
588591
fadeIn

app/components/Base/TokenIcon/index.test.tsx

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,12 @@ jest.mock('../RemoteImage', () => ({
3535
}));
3636

3737
// Mock useTheme hook
38-
jest.mock('../../../util/theme', () => ({
39-
useTheme: jest.fn(() => ({
40-
colors: {
41-
background: {
42-
default: '#FFFFFF',
43-
alternative: '#F2F4F6',
44-
},
45-
text: {
46-
default: '#24292E',
47-
},
48-
},
49-
})),
50-
}));
38+
jest.mock('../../../util/theme', () => {
39+
const { mockTheme } = jest.requireActual('../../../util/theme');
40+
return {
41+
useTheme: jest.fn(() => mockTheme),
42+
};
43+
});
5144

5245
// Mock image imports with various types
5346
jest.mock('../../../images/image-icons', () => ({

app/components/UI/Card/components/DaimoPayModal/DaimoPayModal.test.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,9 @@ jest.mock('../../../../../../locales/i18n', () => ({
120120

121121
jest.mock('@metamask/design-system-twrnc-preset', () => ({
122122
useTailwind: () => {
123-
const { mockTheme } = jest.requireActual('../../../../../util/theme');
124-
return {
125-
style: jest.fn(() => ({})),
126-
color: jest.fn(() => mockTheme.colors.text.default),
127-
};
123+
const tw = () => ({});
124+
tw.style = jest.fn(() => ({}));
125+
return tw;
128126
},
129127
}));
130128

app/components/UI/Carousel/StackCard/StackCard.test.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import { CarouselSlide } from '../types';
66

77
// Mock dependencies
88
jest.mock('@metamask/design-system-twrnc-preset', () => ({
9-
useTailwind: () => ({
10-
style: jest.fn(() => ({})),
11-
color: jest.fn(() => '#000000'),
12-
}),
9+
useTailwind: () => {
10+
const tw = () => ({});
11+
tw.style = jest.fn(() => ({}));
12+
return tw;
13+
},
1314
}));
1415

1516
// Mock design system components

app/components/UI/Carousel/StackCardEmpty/StackCardEmpty.test.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import { StackCardEmpty } from './StackCardEmpty';
66

77
// Mock dependencies
88
jest.mock('@metamask/design-system-twrnc-preset', () => ({
9-
useTailwind: () => ({
10-
style: jest.fn(() => ({})),
11-
color: jest.fn(() => '#000000'),
12-
}),
9+
useTailwind: () => {
10+
const tw = () => ({});
11+
tw.style = jest.fn(() => ({}));
12+
return tw;
13+
},
1314
}));
1415

1516
// Mock design system components

app/components/UI/CustomNetworkSelector/CustomNetworkSelector.test.tsx

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,17 @@ jest.mock('../../../../locales/i18n', () => ({
5757
}));
5858

5959
jest.mock('../../../component-library/hooks/useStyles', () => ({
60-
useStyles: jest.fn(() => ({
61-
styles: {
62-
container: {},
63-
addNetworkButtonContainer: {},
64-
iconContainer: {},
65-
},
66-
theme: {
67-
colors: {
68-
icon: {
69-
alternative: '#666666',
70-
},
71-
text: {
72-
alternative: '#999999',
73-
},
60+
useStyles: jest.fn(() => {
61+
const { mockTheme } = jest.requireActual('../../../util/theme');
62+
return {
63+
styles: {
64+
container: {},
65+
addNetworkButtonContainer: {},
66+
iconContainer: {},
7467
},
75-
},
76-
})),
68+
theme: mockTheme,
69+
};
70+
}),
7771
}));
7872

7973
jest.mock('../../../util/networks', () => ({

app/components/UI/NetworkConnectionBanner/NetworkConnectionBanner.test.tsx

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,10 @@ import renderWithProvider from '../../../util/test/renderWithProvider';
88
jest.mock('../../hooks/useNetworkConnectionBanner');
99

1010
jest.mock('../../../util/theme', () => {
11-
const mockThemeColors = {
12-
background: {
13-
default: '#FFFFFF',
14-
section: '#FFFFFF',
15-
},
16-
icon: {
17-
default: '#000000',
18-
},
19-
error: {
20-
muted: '#FFE5E5',
21-
default: '#FF0000',
22-
},
23-
};
24-
25-
const theme = {
26-
colors: mockThemeColors,
27-
themeAppearance: 'light',
28-
typography: {},
29-
shadows: {},
30-
brandColors: {},
31-
};
32-
11+
const { mockTheme } = jest.requireActual('../../../util/theme');
3312
return {
34-
useAppTheme: jest.fn(() => theme),
35-
mockTheme: theme,
13+
useAppTheme: jest.fn(() => mockTheme),
14+
mockTheme,
3615
};
3716
});
3817

app/components/UI/NetworkManager/index.test.tsx

Lines changed: 60 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -96,37 +96,35 @@ jest.mock('react-native-safe-area-context', () => ({
9696
}),
9797
}));
9898

99-
jest.mock('../../../util/theme', () => ({
100-
useTheme: () => ({
101-
colors: {
102-
text: {
103-
default: '#000000',
104-
alternative: '#666666',
105-
},
106-
background: {
107-
default: '#FFFFFF',
108-
},
109-
},
110-
}),
111-
}));
99+
jest.mock('../../../util/theme', () => {
100+
const { mockTheme } = jest.requireActual('../../../util/theme');
101+
return {
102+
useTheme: jest.fn(() => mockTheme),
103+
};
104+
});
112105

113106
jest.mock('../../../component-library/hooks/useStyles', () => ({
114-
useStyles: () => ({
115-
styles: {
116-
sheet: { backgroundColor: '#FFFFFF' },
117-
notch: { backgroundColor: '#CCCCCC' },
118-
networkTabsSelectorTitle: { fontSize: 18 },
119-
networkTabsSelectorWrapper: { flex: 1 },
120-
tabUnderlineStyle: { backgroundColor: '#0066CC' },
121-
inactiveUnderlineStyle: { backgroundColor: '#CCCCCC' },
122-
tabStyle: { backgroundColor: '#FFFFFF' },
123-
textStyle: { fontSize: 16 },
124-
tabBar: { backgroundColor: '#F8F9FA' },
125-
editNetworkMenu: { padding: 16 },
126-
containerDeleteText: { padding: 16 },
127-
textCentred: { textAlign: 'center' },
128-
},
129-
}),
107+
useStyles: () => {
108+
const { mockTheme } = jest.requireActual('../../../util/theme');
109+
return {
110+
styles: {
111+
sheet: { backgroundColor: mockTheme.colors.background.default },
112+
notch: { backgroundColor: mockTheme.colors.border.muted },
113+
networkTabsSelectorTitle: { fontSize: 18 },
114+
networkTabsSelectorWrapper: { flex: 1 },
115+
tabUnderlineStyle: { backgroundColor: mockTheme.colors.text.default },
116+
inactiveUnderlineStyle: {
117+
backgroundColor: mockTheme.colors.text.alternative,
118+
},
119+
tabStyle: {},
120+
textStyle: { fontSize: 16 },
121+
tabBar: { borderColor: mockTheme.colors.border.muted },
122+
editNetworkMenu: { padding: 16 },
123+
containerDeleteText: { padding: 16 },
124+
textCentred: { textAlign: 'center' },
125+
},
126+
};
127+
},
130128
}));
131129

132130
jest.mock('../../hooks/useAnalytics/useAnalytics', () => ({
@@ -608,20 +606,25 @@ jest.mock('../../../component-library/components/Icons/Icon', () => ({
608606

609607
jest.mock('./index.styles', () => ({
610608
__esModule: true,
611-
default: () => ({
612-
sheet: { backgroundColor: '#FFFFFF' },
613-
notch: { backgroundColor: '#CCCCCC' },
614-
networkTabsSelectorTitle: { fontSize: 18 },
615-
networkTabsSelectorWrapper: { flex: 1 },
616-
tabUnderlineStyle: { backgroundColor: '#0066CC' },
617-
inactiveUnderlineStyle: { backgroundColor: '#CCCCCC' },
618-
tabStyle: { backgroundColor: '#FFFFFF' },
619-
textStyle: { fontSize: 16 },
620-
tabBar: { backgroundColor: '#F8F9FA' },
621-
editNetworkMenu: { padding: 16 },
622-
containerDeleteText: { padding: 16 },
623-
textCentred: { textAlign: 'center' },
624-
}),
609+
default: () => {
610+
const { mockTheme } = jest.requireActual('../../../util/theme');
611+
return {
612+
sheet: { backgroundColor: mockTheme.colors.background.default },
613+
notch: { backgroundColor: mockTheme.colors.border.muted },
614+
networkTabsSelectorTitle: { fontSize: 18 },
615+
networkTabsSelectorWrapper: { flex: 1 },
616+
tabUnderlineStyle: { backgroundColor: mockTheme.colors.text.default },
617+
inactiveUnderlineStyle: {
618+
backgroundColor: mockTheme.colors.text.alternative,
619+
},
620+
tabStyle: {},
621+
textStyle: { fontSize: 16 },
622+
tabBar: { borderColor: mockTheme.colors.border.muted },
623+
editNetworkMenu: { padding: 16 },
624+
containerDeleteText: { padding: 16 },
625+
textCentred: { textAlign: 'center' },
626+
};
627+
},
625628
}));
626629

627630
jest.mock('../../../component-library/components/Texts/Text', () => {
@@ -1105,15 +1108,15 @@ describe('NetworkManager Component', () => {
11051108
isNetworkEnabled: jest.fn(),
11061109
hasOneEnabledNetwork: false,
11071110
enableAllPopularNetworks: jest.fn(),
1111+
popularEvmNetworks: [],
1112+
popularMultichainNetworks: [],
1113+
popularNetworks: [],
11081114
tryEnableEvmNetwork: jest.fn(),
11091115
enabledNetworksForAllNamespaces: {
11101116
'0x1': true,
11111117
'0x89': true,
11121118
'0xa': false,
11131119
},
1114-
popularEvmNetworks: [],
1115-
popularMultichainNetworks: [],
1116-
popularNetworks: [],
11171120
});
11181121

11191122
// The component internally processes enabledNetworksByNamespace
@@ -1143,15 +1146,15 @@ describe('NetworkManager Component', () => {
11431146
isNetworkEnabled: jest.fn(),
11441147
hasOneEnabledNetwork: false,
11451148
enableAllPopularNetworks: jest.fn(),
1149+
popularEvmNetworks: [],
1150+
popularMultichainNetworks: [],
1151+
popularNetworks: [],
11461152
tryEnableEvmNetwork: jest.fn(),
11471153
enabledNetworksForAllNamespaces: {
11481154
'0x1': true,
11491155
'0x89': false,
11501156
'0xa': false,
11511157
},
1152-
popularEvmNetworks: [],
1153-
popularMultichainNetworks: [],
1154-
popularNetworks: [],
11551158
});
11561159

11571160
// The component should handle nested namespace structures
@@ -1171,11 +1174,11 @@ describe('NetworkManager Component', () => {
11711174
isNetworkEnabled: jest.fn(),
11721175
hasOneEnabledNetwork: false,
11731176
enableAllPopularNetworks: jest.fn(),
1174-
tryEnableEvmNetwork: jest.fn(),
1175-
enabledNetworksForAllNamespaces: {},
11761177
popularEvmNetworks: [],
11771178
popularMultichainNetworks: [],
11781179
popularNetworks: [],
1180+
tryEnableEvmNetwork: jest.fn(),
1181+
enabledNetworksForAllNamespaces: {},
11791182
});
11801183

11811184
const { getByTestId } = renderComponent();
@@ -1201,16 +1204,16 @@ describe('NetworkManager Component', () => {
12011204
isNetworkEnabled: jest.fn(),
12021205
hasOneEnabledNetwork: false,
12031206
enableAllPopularNetworks: jest.fn(),
1207+
popularEvmNetworks: [],
1208+
popularMultichainNetworks: [],
1209+
popularNetworks: [],
12041210
tryEnableEvmNetwork: jest.fn(),
12051211
enabledNetworksForAllNamespaces: {
12061212
'0x1': true,
12071213
'0x89': false,
12081214
'0xa': false,
12091215
'0xa4b1': true,
12101216
},
1211-
popularEvmNetworks: [],
1212-
popularMultichainNetworks: [],
1213-
popularNetworks: [],
12141217
});
12151218

12161219
// Component should only include enabled (true) networks
@@ -1235,14 +1238,14 @@ describe('NetworkManager Component', () => {
12351238
isNetworkEnabled: jest.fn(),
12361239
hasOneEnabledNetwork: false,
12371240
enableAllPopularNetworks: jest.fn(),
1241+
popularEvmNetworks: [],
1242+
popularMultichainNetworks: [],
1243+
popularNetworks: [],
12381244
tryEnableEvmNetwork: jest.fn(),
12391245
enabledNetworksForAllNamespaces: {
12401246
'0x1': true,
12411247
'0x89': true,
12421248
},
1243-
popularEvmNetworks: [],
1244-
popularMultichainNetworks: [],
1245-
popularNetworks: [],
12461249
});
12471250

12481251
const { getByTestId } = renderComponent();

0 commit comments

Comments
 (0)