Skip to content

Commit

Permalink
Merge branch 'main' into salim/multichain-detect-tokens-feature
Browse files Browse the repository at this point in the history
  • Loading branch information
salimtb committed Nov 26, 2024
2 parents fd16443 + 16a6d6e commit c97faed
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 258 deletions.
74 changes: 45 additions & 29 deletions app/components/UI/AssetOverview/AssetOverview.test.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React from 'react';
import AssetOverview from './AssetOverview';
import { fireEvent } from '@testing-library/react-native';
import { zeroAddress } from 'ethereumjs-util';
import { NetworkController } from '@metamask/network-controller';
import AssetOverview from './AssetOverview';
import renderWithProvider from '../../../util/test/renderWithProvider';
import { backgroundState } from '../../../util/test/initial-root-state';
import { NetworkController } from '@metamask/network-controller';
import {
MOCK_ACCOUNTS_CONTROLLER_STATE,
MOCK_ADDRESS_2,
} from '../../../util/test/accountsControllerTestUtils';
import { fireEvent } from '@testing-library/react-native';
import { createBuyNavigationDetails } from '../Ramp/routes/utils';
import { getDecimalChainId } from '../../../util/networks';
import { TokenOverviewSelectorsIDs } from '../../../../e2e/selectors/TokenOverview.selectors';

const MOCK_CHAIN_ID = '0x1';

Expand Down Expand Up @@ -46,12 +49,14 @@ const mockInitialState = {
},
};

const mockNavigate = jest.fn();
const navigate = mockNavigate;
jest.mock('@react-navigation/native', () => {
const actualNav = jest.requireActual('@react-navigation/native');
return {
...actualNav,
useNavigation: () => ({
navigate: jest.fn(),
navigate: mockNavigate,
}),
};
});
Expand All @@ -67,10 +72,6 @@ jest.mock('../../hooks/useStyles', () => ({
}),
}));

// Mock the navigation object.
const navigation = {
navigate: jest.fn(),
};
const asset = {
balance: '400',
balanceFiat: '1500',
Expand All @@ -88,49 +89,51 @@ const asset = {
describe('AssetOverview', () => {
it('should render correctly', async () => {
const container = renderWithProvider(
<AssetOverview
asset={asset}
navigation={navigation}
displayBuyButton
displaySwapsButton
/>,
<AssetOverview asset={asset} displayBuyButton displaySwapsButton />,
{ state: mockInitialState },
);
expect(container).toMatchSnapshot();
});

it('should handle buy button press', async () => {
const { getByTestId } = renderWithProvider(
<AssetOverview asset={asset} displayBuyButton displaySwapsButton />,
{ state: mockInitialState },
);

const buyButton = getByTestId(TokenOverviewSelectorsIDs.BUY_BUTTON);
fireEvent.press(buyButton);

expect(navigate).toHaveBeenCalledWith(
...createBuyNavigationDetails({
address: asset.address,
chainId: getDecimalChainId(MOCK_CHAIN_ID),
}),
);
});

it('should handle send button press', async () => {
const { getByTestId } = renderWithProvider(
<AssetOverview
asset={asset}
navigation={navigation}
displayBuyButton
displaySwapsButton
/>,
<AssetOverview asset={asset} displayBuyButton displaySwapsButton />,
{ state: mockInitialState },
);

const sendButton = getByTestId('token-send-button');
fireEvent.press(sendButton);

expect(navigation.navigate).toHaveBeenCalledWith('SendFlowView', {});
expect(navigate).toHaveBeenCalledWith('SendFlowView', {});
});

it('should handle swap button press', async () => {
const { getByTestId } = renderWithProvider(
<AssetOverview
asset={asset}
navigation={navigation}
displayBuyButton
displaySwapsButton
/>,
<AssetOverview asset={asset} displayBuyButton displaySwapsButton />,
{ state: mockInitialState },
);

const swapButton = getByTestId('token-swap-button');
fireEvent.press(swapButton);

expect(navigation.navigate).toHaveBeenCalledWith('Swaps', {
expect(navigate).toHaveBeenCalledWith('Swaps', {
params: {
sourcePage: 'MainView',
sourceToken: asset.address,
Expand All @@ -143,7 +146,6 @@ describe('AssetOverview', () => {
const { queryByTestId } = renderWithProvider(
<AssetOverview
asset={asset}
navigation={navigation}
displayBuyButton
displaySwapsButton={false}
/>,
Expand All @@ -153,4 +155,18 @@ describe('AssetOverview', () => {
const swapButton = queryByTestId('token-swap-button');
expect(swapButton).toBeNull();
});

it('should not render buy button if displayBuyButton is false', async () => {
const { queryByTestId } = renderWithProvider(
<AssetOverview
asset={asset}
displayBuyButton={false}
displaySwapsButton
/>,
{ state: mockInitialState },
);

const buyButton = queryByTestId(TokenOverviewSelectorsIDs.BUY_BUTTON);
expect(buyButton).toBeNull();
});
});
14 changes: 8 additions & 6 deletions app/components/UI/AssetOverview/AssetOverview.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { zeroAddress } from 'ethereumjs-util';
import React, { useCallback, useEffect } from 'react';
import { TouchableOpacity, View } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { useDispatch, useSelector } from 'react-redux';
import { strings } from '../../../../locales/i18n';
import { TokenOverviewSelectorsIDs } from '../../../../e2e/selectors/TokenOverview.selectors';
Expand Down Expand Up @@ -54,20 +55,17 @@ import { TokenI } from '../Tokens/types';
import AssetDetailsActions from '../../../components/Views/AssetDetails/AssetDetailsActions';

interface AssetOverviewProps {
navigation: {
navigate: (route: string, params: Record<string, unknown>) => void;
};
asset: TokenI;
displayBuyButton?: boolean;
displaySwapsButton?: boolean;
}

const AssetOverview: React.FC<AssetOverviewProps> = ({
navigation,
asset,
displayBuyButton,
displaySwapsButton,
}: AssetOverviewProps) => {
const navigation = useNavigation();
const [timePeriod, setTimePeriod] = React.useState<TimePeriod>('1d');
const currentCurrency = useSelector(selectCurrentCurrency);
const conversionRate = useSelector(selectConversionRate);
Expand Down Expand Up @@ -150,8 +148,12 @@ const AssetOverview: React.FC<AssetOverviewProps> = ({
);
};
const onBuy = () => {
const [route, params] = createBuyNavigationDetails();
navigation.navigate(route, params || {});
navigation.navigate(
...createBuyNavigationDetails({
address: asset.address,
chainId: getDecimalChainId(chainId),
}),
);
trackEvent(
createEventBuilder(MetaMetricsEvents.BUY_BUTTON_CLICKED)
.addProperties({
Expand Down
19 changes: 15 additions & 4 deletions app/components/Views/Asset/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ import { getNetworkNavbarOptions } from '../../UI/Navbar';
import { isSwapsAllowed } from '../../UI/Swaps/utils';
import Transactions from '../../UI/Transactions';
import ActivityHeader from './ActivityHeader';
import { isNetworkRampNativeTokenSupported } from '../../UI/Ramp/utils';
import {
isNetworkRampNativeTokenSupported,
isNetworkRampSupported,
} from '../../UI/Ramp/utils';
import { getRampNetworks } from '../../../reducers/fiatOrders';
import Device from '../../../util/device';
import {
Expand Down Expand Up @@ -153,6 +156,10 @@ class Asset extends PureComponent {
route: PropTypes.object,
rpcUrl: PropTypes.string,
networkConfigurations: PropTypes.object,
/**
* Boolean that indicates if network is supported to buy
*/
isNetworkRampSupported: PropTypes.bool,
/**
* Boolean that indicates if native token is supported to buy
*/
Expand Down Expand Up @@ -465,8 +472,9 @@ class Asset extends PureComponent {
isAssetAllowed &&
AppConstants.SWAPS.ACTIVE;

const displayBuyButton =
asset.isETH && this.props.isNetworkBuyNativeTokenSupported;
const displayBuyButton = asset.isETH
? this.props.isNetworkBuyNativeTokenSupported
: this.props.isNetworkRampSupported;

return (
<View style={styles.wrapper}>
Expand All @@ -477,7 +485,6 @@ class Asset extends PureComponent {
header={
<>
<AssetOverview
navigation={navigation}
asset={asset}
displayBuyButton={displayBuyButton}
displaySwapsButton={displaySwapsButton}
Expand Down Expand Up @@ -518,6 +525,10 @@ const mapStateToProps = (state) => ({
transactions: state.engine.backgroundState.TransactionController.transactions,
rpcUrl: selectRpcUrl(state),
networkConfigurations: selectNetworkConfigurations(state),
isNetworkRampSupported: isNetworkRampSupported(
selectChainId(state),
getRampNetworks(state),
),
isNetworkBuyNativeTokenSupported: isNetworkRampNativeTokenSupported(
selectChainId(state),
getRampNetworks(state),
Expand Down
3 changes: 0 additions & 3 deletions app/core/Engine/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,6 @@ export class Engine {
});

const gasFeeController = new GasFeeController({
// @ts-expect-error TODO: Resolve mismatch between base-controller versions.
messenger: this.controllerMessenger.getRestricted({
name: 'GasFeeController',
allowedActions: [
Expand Down Expand Up @@ -1367,7 +1366,6 @@ export class Engine {
swapsUtils.LINEA_CHAIN_ID,
swapsUtils.BASE_CHAIN_ID,
],
// @ts-expect-error TODO: Resolve new typing for restricted controller messenger
messenger: this.controllerMessenger.getRestricted({
name: 'SwapsController',
// TODO: allow these internal calls once GasFeeController
Expand Down Expand Up @@ -1662,7 +1660,6 @@ export class Engine {
}
provider.sendAsync = provider.sendAsync.bind(provider);

// @ts-expect-error TODO: Resolve mismatch between base-controller versions.
SwapsController.setProvider(provider, {
chainId: NetworkController.getNetworkClientById(
NetworkController?.state.selectedNetworkClientId,
Expand Down
8 changes: 1 addition & 7 deletions app/selectors/tokenBalancesController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import { createSelector } from 'reselect';
import { RootState } from '../reducers';
import { TokenBalancesControllerState } from '@metamask/assets-controllers';
import { Hex } from '@metamask/utils';
import { selectSelectedInternalAccountAddress } from './accountsController';
import { selectChainId } from './networkController';
import { Hex } from '@metamask/utils';

const selectTokenBalancesControllerState = (state: RootState) =>
state.engine.backgroundState.TokenBalancesController;
Expand All @@ -28,9 +28,3 @@ export const selectAllTokenBalances = createSelector(
(tokenBalancesControllerState: TokenBalancesControllerState) =>
tokenBalancesControllerState.tokenBalances,
);

export const selectTokensBalances = createSelector(
selectTokenBalancesControllerState,
(tokenBalancesControllerState: TokenBalancesControllerState) =>
tokenBalancesControllerState.tokenBalances,
);
28 changes: 23 additions & 5 deletions bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pipelines:
stages:
- build_e2e_ios_android_stage: {}
- run_release_e2e_ios_android_stage: {}
- report_results_stage: {}
- notify: {}
#PR_e2e_verfication (build ios & android), run iOS (smoke), emulator Android
pr_smoke_e2e_pipeline:
Expand Down Expand Up @@ -161,16 +162,19 @@ stages:
- run_tag_smoke_confirmations_android: {}
- run_tag_smoke_accounts_ios: {}
- run_tag_smoke_accounts_android: {}
- run_tag_smoke_notifications_ios: {}
- run_tag_smoke_notifications_android: {}
- run_tag_smoke_assets_ios: {}
# - run_tag_smoke_notifications_ios: {}
# - run_tag_smoke_notifications_android: {}
# - run_tag_smoke_assets_ios: {}
- run_tag_smoke_assets_android: {}
- run_tag_smoke_swaps_ios: {}
- run_tag_smoke_swaps_android: {}
# - run_tag_smoke_swaps_ios: {}
# - run_tag_smoke_swaps_android: {}
- run_tag_smoke_core_ios: {}
- run_tag_smoke_core_android: {}
- run_tag_upgrade_android: {}
- run_android_app_launch_times_appium_test: {}
report_results_stage:
workflows:
- run_testrail_update_automated_test_results: {}
run_e2e_ios_android_stage:
workflows:
- ios_e2e_test: {}
Expand Down Expand Up @@ -520,6 +524,20 @@ workflows:
machine_type_id: elite-xl
after_run:
- wdio_android_e2e_test

### Report automated test results to TestRail
run_testrail_update_automated_test_results:
before_run:
- code_setup
steps:
- script@1:
title: 'Add Automated Test Results to TestRail'
inputs:
- content: |-
#!/usr/bin/env bash
echo 'REPORT AUTOMATED TEST RESULTS TO TESTRAIL'
node ./scripts/testrail/testrail.api.js
run_ios_app_launch_times_appium_test:
envs:
- TEST_TYPE: 'performance'
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@
"@metamask/ethjs-contract": "^0.4.1",
"@metamask/ethjs-query": "^0.7.1",
"@metamask/ethjs-unit": "^0.3.0",
"@metamask/gas-fee-controller": "^18.0.0",
"@metamask/gas-fee-controller": "^21.0.0",
"@metamask/json-rpc-middleware-stream": "^8.0.2",
"@metamask/key-tree": "^9.0.0",
"@metamask/keyring-api": "^8.1.0",
Expand Down Expand Up @@ -190,7 +190,7 @@
"@metamask/snaps-utils": "^8.1.1",
"@metamask/stake-sdk": "^0.2.13",
"@metamask/swappable-obj-proxy": "^2.1.0",
"@metamask/swaps-controller": "^10.0.0",
"@metamask/swaps-controller": "^11.0.0",
"@metamask/transaction-controller": "^39.1.0",
"@metamask/utils": "^9.2.1",
"@ngraveio/bc-ur": "^1.1.6",
Expand Down
4 changes: 2 additions & 2 deletions patches/@metamask+assets-controllers+44.1.0.patch
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ index 6ccbe9c..49270d6 100644
+_NftController_mutex = new WeakMap(), _NftController_selectedAccountId = new WeakMap(), _NftController_chainId = new WeakMap(), _NftController_ipfsGateway = new WeakMap(), _NftController_displayNftMedia = new WeakMap(), _NftController_useIpfsSubdomains = new WeakMap(), _NftController_isIpfsGatewayEnabled = new WeakMap(), _NftController_onNftAdded = new WeakMap(), _NftController_instances = new WeakSet(), _NftController_onNetworkControllerNetworkDidChange = function _NftController_onNetworkControllerNetworkDidChange({ selectedNetworkClientId, }) {
const { configuration: { chainId }, } = this.messagingSystem.call('NetworkController:getNetworkClientById', selectedNetworkClientId);
__classPrivateFieldSet(this, _NftController_chainId, chainId, "f");
}, _NftController_onPreferencesControllerStateChange =
}, _NftController_onPreferencesControllerStateChange =
@@ -597,16 +597,16 @@ _NftController_mutex = new WeakMap(), _NftController_selectedAccountId = new Wea
* Handles the state change of the preference controller.
* @param preferencesState - The new state of the preference controller.
Expand Down Expand Up @@ -117,7 +117,7 @@ index 6ccbe9c..49270d6 100644
+ error: 'URI import error',
};
}
}, _NftController_getNftURIAndStandard =
}, _NftController_getNftURIAndStandard =
@@ -840,10 +843,21 @@ async function _NftController_getNftInformation(contractAddress, tokenId, networ
});
const [blockchainMetadata, nftApiMetadata] = await Promise.all([
Expand Down
Loading

0 comments on commit c97faed

Please sign in to comment.