Skip to content

Commit 93aa4fb

Browse files
authored
Merge branch 'main' into skip-cash-out-predict-test
2 parents 8674c24 + deb715d commit 93aa4fb

File tree

13 files changed

+311
-90
lines changed

13 files changed

+311
-90
lines changed

app/components/Nav/Main/MainNavigator.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useEffect, useMemo, useCallback } from 'react';
1+
import React, { useState, useEffect, useMemo } from 'react';
22
import { Image, StyleSheet, Keyboard, Platform } from 'react-native';
33
import { createStackNavigator } from '@react-navigation/stack';
44
import { useSelector } from 'react-redux';
@@ -1192,7 +1192,7 @@ const MainNavigator = () => {
11921192
...GeneralSettings.navigationOptions,
11931193
}}
11941194
/>
1195-
{process.env.NODE_ENV !== 'production' && (
1195+
{process.env.METAMASK_ENVIRONMENT !== 'production' && (
11961196
<Stack.Screen
11971197
name={Routes.FEATURE_FLAG_OVERRIDE}
11981198
component={FeatureFlagOverride}

app/components/Nav/Main/MainNavigator.test.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,16 @@ jest.mock('@react-navigation/stack', () => ({
1313
}));
1414

1515
describe('MainNavigator', () => {
16+
const originalEnv = process.env.METAMASK_ENVIRONMENT;
17+
1618
beforeEach(() => {
1719
jest.clearAllMocks();
1820
});
1921

22+
afterEach(() => {
23+
process.env.METAMASK_ENVIRONMENT = originalEnv;
24+
});
25+
2026
it('matches rendered snapshot', () => {
2127
// Given the initial app state
2228
// When rendering the MainNavigator
@@ -60,4 +66,41 @@ describe('MainNavigator', () => {
6066
expect(sampleFeatureScreen).toBeDefined();
6167
expect(sampleFeatureScreen?.component.name).toBe('SampleFeatureFlow');
6268
});
69+
70+
it('includes FeatureFlagOverride screen when METAMASK_ENVIRONMENT is not production', () => {
71+
// Given a non-production environment
72+
process.env.METAMASK_ENVIRONMENT = 'dev';
73+
74+
// When rendering the MainNavigator
75+
const container = renderWithProvider(<MainNavigator />, {
76+
state: initialRootState,
77+
});
78+
79+
// Then it should contain the FeatureFlagOverride screen
80+
interface ScreenChild {
81+
name: string;
82+
component: { name: string };
83+
}
84+
const screenProps: ScreenChild[] = container.root.children
85+
.filter(
86+
(child): child is ReactTestInstance =>
87+
typeof child === 'object' &&
88+
'type' in child &&
89+
'props' in child &&
90+
child.type?.toString() === 'Screen',
91+
)
92+
.map((child) => ({
93+
name: child.props.name,
94+
component: child.props.component,
95+
}));
96+
97+
const featureFlagOverrideScreen = screenProps?.find(
98+
(screen) => screen?.name === Routes.FEATURE_FLAG_OVERRIDE,
99+
);
100+
101+
expect(featureFlagOverrideScreen).toBeDefined();
102+
expect(featureFlagOverrideScreen?.component.name).toBe(
103+
'FeatureFlagOverride',
104+
);
105+
});
63106
});

app/components/UI/Earn/Views/EarnInputView/EarnInputView.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -646,26 +646,27 @@ const EarnInputView = () => {
646646
// Call the original handler first
647647
handleCurrencySwitch();
648648

649-
if (shouldLogStablecoinEvent()) {
650-
trackEvent(
651-
createEventBuilder(MetaMetricsEvents.EARN_INPUT_CURRENCY_SWITCH_CLICKED)
652-
.addProperties({
653-
selected_provider: EVENT_PROVIDERS.CONSENSYS,
654-
text: 'Currency Switch Clicked',
655-
location: EVENT_LOCATIONS.EARN_INPUT_VIEW,
656-
currency_type: !isFiat ? 'fiat' : 'native',
657-
experience: earnToken?.experience?.type,
658-
})
659-
.build(),
660-
);
661-
}
649+
trackEvent(
650+
createEventBuilder(MetaMetricsEvents.EARN_INPUT_CURRENCY_SWITCH_CLICKED)
651+
.addProperties({
652+
selected_provider: EVENT_PROVIDERS.CONSENSYS,
653+
text: 'Currency Switch Clicked',
654+
location: EVENT_LOCATIONS.EARN_INPUT_VIEW,
655+
currency_type: !isFiat ? 'fiat' : 'native',
656+
experience: earnToken?.experience?.type,
657+
token_symbol: earnToken?.symbol,
658+
chain_id: earnToken?.chainId ? toHex(earnToken.chainId) : undefined,
659+
})
660+
.build(),
661+
);
662662
}, [
663-
shouldLogStablecoinEvent,
664663
handleCurrencySwitch,
665664
trackEvent,
666665
createEventBuilder,
667666
isFiat,
668667
earnToken?.experience?.type,
668+
earnToken?.symbol,
669+
earnToken?.chainId,
669670
]);
670671

671672
const getButtonLabel = () => {

app/components/UI/Earn/Views/EarnWithdrawInputView/EarnWithdrawInputView.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { toHex } from '@metamask/controller-utils';
12
import { Hex } from '@metamask/utils';
23
import {
34
useFocusEffect,
@@ -576,6 +577,10 @@ const EarnWithdrawInputView = () => {
576577
// We want to track the currency switching to. Not the current currency.
577578
currency_type: isFiat ? 'native' : 'fiat',
578579
experience: receiptToken?.experience?.type,
580+
token_symbol: receiptToken?.symbol,
581+
chain_id: receiptToken?.chainId
582+
? toHex(receiptToken.chainId)
583+
: undefined,
579584
})
580585
.build(),
581586
);
@@ -591,6 +596,10 @@ const EarnWithdrawInputView = () => {
591596
// We want to track the currency switching to. Not the current currency.
592597
currency_type: isFiat ? 'native' : 'fiat',
593598
experience: receiptToken?.experience?.type,
599+
token_symbol: receiptToken?.symbol,
600+
chain_id: receiptToken?.chainId
601+
? toHex(receiptToken.chainId)
602+
: undefined,
594603
})
595604
.build(),
596605
);
@@ -603,6 +612,8 @@ const EarnWithdrawInputView = () => {
603612
createEventBuilder,
604613
isFiat,
605614
receiptToken?.experience?.type,
615+
receiptToken?.symbol,
616+
receiptToken?.chainId,
606617
]);
607618

608619
const handleQuickAmountPressWithTracking = useCallback(

app/components/UI/Ramp/Aggregator/Views/BuildQuote/BuildQuote.tsx

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,6 @@ const BuildQuote = () => {
139139
selectedRegion,
140140
selectedAsset,
141141
selectedFiatCurrencyId,
142-
setSelectedFiatCurrencyId,
143142
selectedAddress,
144143
selectedNetworkName,
145144
sdkError,
@@ -183,7 +182,6 @@ const BuildQuote = () => {
183182
}, [paymentMethods, themeAppearance]);
184183

185184
const {
186-
defaultFiatCurrency,
187185
queryDefaultFiatCurrency,
188186
fiatCurrencies,
189187
queryGetFiatCurrencies,
@@ -245,31 +243,6 @@ const BuildQuote = () => {
245243
}, [shouldShowUnsupportedModal, navigation, regions, selectedRegion]),
246244
);
247245

248-
useEffect(() => {
249-
const handleRegionChange = async () => {
250-
if (
251-
selectedRegion &&
252-
selectedFiatCurrencyId === defaultFiatCurrency?.id
253-
) {
254-
const newRegionCurrency = await queryDefaultFiatCurrency(
255-
selectedRegion.id,
256-
);
257-
if (newRegionCurrency?.id) {
258-
setSelectedFiatCurrencyId(newRegionCurrency.id);
259-
}
260-
}
261-
};
262-
263-
handleRegionChange();
264-
}, [
265-
selectedRegion,
266-
selectedFiatCurrencyId,
267-
defaultFiatCurrency?.id,
268-
queryDefaultFiatCurrency,
269-
selectedPaymentMethodId,
270-
setSelectedFiatCurrencyId,
271-
]);
272-
273246
const gasLimitEstimation = useERC20GasLimitEstimation({
274247
tokenAddress: selectedAsset?.address,
275248
fromAddress: selectedAddress,

app/components/UI/Ramp/Aggregator/hooks/useFiatCurrencies.test.ts

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { act } from '@testing-library/react-native';
12
import { RampSDK } from '../sdk';
23
import useFiatCurrencies from './useFiatCurrencies';
34
import useSDKMethod from './useSDKMethod';
@@ -325,4 +326,107 @@ describe('useFiatCurrencies', () => {
325326
mockUseRampSDKValues.setSelectedFiatCurrencyId,
326327
).not.toHaveBeenCalled();
327328
});
329+
330+
it('updates currency when region changes and using default currency', async () => {
331+
const mockQueryDefaultFiatCurrency = jest.fn();
332+
const mockSetSelectedFiatCurrencyId = jest.fn();
333+
334+
mockUseRampSDKValues.selectedRegion = { id: 'region-1' };
335+
mockUseRampSDKValues.selectedFiatCurrencyId = 'default-fiat-currency-id';
336+
mockUseRampSDKValues.setSelectedFiatCurrencyId =
337+
mockSetSelectedFiatCurrencyId;
338+
339+
mockQueryDefaultFiatCurrency.mockResolvedValue({
340+
id: 'new-region-currency',
341+
});
342+
343+
(useSDKMethod as jest.Mock)
344+
.mockReturnValueOnce([
345+
{
346+
data: { id: 'default-fiat-currency-id' },
347+
error: null,
348+
isFetching: false,
349+
},
350+
mockQueryDefaultFiatCurrency,
351+
])
352+
.mockReturnValueOnce([
353+
{
354+
data: [{ id: 'default-fiat-currency-id' }],
355+
error: null,
356+
isFetching: false,
357+
},
358+
jest.fn(),
359+
])
360+
.mockReturnValueOnce([
361+
{
362+
data: { id: 'default-fiat-currency-id' },
363+
error: null,
364+
isFetching: false,
365+
},
366+
mockQueryDefaultFiatCurrency,
367+
])
368+
.mockReturnValueOnce([
369+
{
370+
data: [{ id: 'default-fiat-currency-id' }],
371+
error: null,
372+
isFetching: false,
373+
},
374+
jest.fn(),
375+
]);
376+
377+
const { rerender } = renderHookWithProvider(() => useFiatCurrencies());
378+
379+
mockUseRampSDKValues.selectedRegion = { id: 'region-2' };
380+
381+
await act(async () => {
382+
rerender(() => useFiatCurrencies());
383+
await new Promise((resolve) => setTimeout(resolve, 50));
384+
});
385+
386+
expect(mockQueryDefaultFiatCurrency).toHaveBeenCalledWith('region-2');
387+
expect(mockSetSelectedFiatCurrencyId).toHaveBeenCalledWith(
388+
'new-region-currency',
389+
);
390+
});
391+
392+
it('does not update currency when region changes but not using default currency', async () => {
393+
const mockQueryDefaultFiatCurrency = jest.fn();
394+
const mockSetSelectedFiatCurrencyId = jest.fn();
395+
396+
mockUseRampSDKValues.selectedRegion = { id: 'region-1' };
397+
mockUseRampSDKValues.selectedFiatCurrencyId = 'custom-currency-id';
398+
mockUseRampSDKValues.setSelectedFiatCurrencyId =
399+
mockSetSelectedFiatCurrencyId;
400+
401+
(useSDKMethod as jest.Mock)
402+
.mockReturnValue([
403+
{
404+
data: { id: 'default-fiat-currency-id' },
405+
error: null,
406+
isFetching: false,
407+
},
408+
mockQueryDefaultFiatCurrency,
409+
])
410+
.mockReturnValue([
411+
{
412+
data: [
413+
{ id: 'custom-currency-id' },
414+
{ id: 'default-fiat-currency-id' },
415+
],
416+
error: null,
417+
isFetching: false,
418+
},
419+
jest.fn(),
420+
]);
421+
422+
const { rerender } = renderHookWithProvider(() => useFiatCurrencies());
423+
424+
mockUseRampSDKValues.selectedRegion = { id: 'region-2' };
425+
426+
rerender(() => useFiatCurrencies());
427+
428+
await new Promise((resolve) => setTimeout(resolve, 50));
429+
430+
expect(mockSetSelectedFiatCurrencyId).not.toHaveBeenCalled();
431+
});
328432
});

app/components/UI/Ramp/Aggregator/hooks/useFiatCurrencies.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useEffect, useMemo } from 'react';
22
import { useRampSDK } from '../sdk';
33
import useSDKMethod from './useSDKMethod';
4+
import usePrevious from '../../../../hooks/usePrevious';
45

56
export default function useFiatCurrencies() {
67
const {
@@ -75,6 +76,35 @@ export default function useFiatCurrencies() {
7576
setSelectedFiatCurrencyId,
7677
]);
7778

79+
const previousRegion = usePrevious(selectedRegion);
80+
81+
/**
82+
* Update fiat currency when region changes and using default currency.
83+
*/
84+
useEffect(() => {
85+
const handleRegionChange = async () => {
86+
if (selectedRegion && previousRegion?.id !== selectedRegion.id) {
87+
if (selectedFiatCurrencyId === defaultFiatCurrency?.id) {
88+
const newRegionCurrency = await queryDefaultFiatCurrency(
89+
selectedRegion.id,
90+
);
91+
if (newRegionCurrency?.id) {
92+
setSelectedFiatCurrencyId(newRegionCurrency.id);
93+
}
94+
}
95+
}
96+
};
97+
98+
handleRegionChange();
99+
}, [
100+
selectedRegion,
101+
previousRegion,
102+
selectedFiatCurrencyId,
103+
defaultFiatCurrency?.id,
104+
queryDefaultFiatCurrency,
105+
setSelectedFiatCurrencyId,
106+
]);
107+
78108
/**
79109
* Get the fiat currency object by id
80110
*/

0 commit comments

Comments
 (0)