Skip to content

Commit 82c66c9

Browse files
authored
refactor: remove ScreenComponent any casts for Multichain navigators (MetaMask#28188)
## **Description** Migrate 3 Multichain navigator components from prop-based route access to `useRoute()` hook (PR 10 of 13). **Components:** AccountDetails, AccountGroupDetails, WalletDetails ## **Changelog** CHANGELOG entry: null ## **Related issues** Fixes: ## **Manual testing steps** N/A — pure refactoring. All 18 existing tests pass. ## **Screenshots/Recordings** ### **Before** N/A ### **After** N/A ## **Pre-merge author checklist** - [x] I've followed [MetaMask Contributor Docs](https://github.com/MetaMask/contributor-docs) and [MetaMask Mobile Coding Standards](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/CODING_GUIDELINES.md). - [x] I've completed the PR template to the best of my ability - [x] I've included tests if applicable - [x] I've documented my code using [JSDoc](https://jsdoc.app/) format if applicable - [x] I've applied the right labels on the PR (see [labeling guidelines](https://github.com/MetaMask/metamask-mobile/blob/main/.github/guidelines/LABELING_GUIDELINES.md)). Not required for external contributors. ## **Pre-merge reviewer checklist** - [ ] I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed). - [ ] I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots. Made with [Cursor](https://cursor.com) <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Low risk refactor limited to React Navigation param plumbing and test adjustments, with no functional changes expected beyond potential runtime issues if route params are missing/mistyped. > > **Overview** > Refactors `AccountDetails`, `AccountGroupDetails`, and `WalletDetails` to stop accepting `route` props and instead pull typed params via `useRoute()`. > > Updates the multichain stack navigators in `App.tsx` to pass these screens directly (removing `as ScreenComponent` casts), and adjusts existing tests to mock `useRoute()`; adds a new `WalletDetails` unit test to cover the new route-param behavior and null rendering when a wallet is absent. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e831d3f. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent df036a4 commit 82c66c9

7 files changed

Lines changed: 239 additions & 144 deletions

File tree

app/components/Nav/App/App.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ const MultichainAccountDetails = () => {
733733
>
734734
<Stack.Screen
735735
name={Routes.MULTICHAIN_ACCOUNTS.ACCOUNT_DETAILS}
736-
component={AccountDetails as ScreenComponent}
736+
component={AccountDetails}
737737
initialParams={route?.params}
738738
/>
739739
<Stack.Screen
@@ -760,7 +760,7 @@ const MultichainAccountGroupDetails = () => {
760760
>
761761
<Stack.Screen
762762
name={Routes.MULTICHAIN_ACCOUNTS.ACCOUNT_GROUP_DETAILS}
763-
component={AccountGroupDetails as ScreenComponent}
763+
component={AccountGroupDetails}
764764
initialParams={route?.params}
765765
/>
766766
<Stack.Screen
@@ -773,7 +773,7 @@ const MultichainAccountGroupDetails = () => {
773773
/>
774774
<Stack.Screen
775775
name={Routes.MULTICHAIN_ACCOUNTS.WALLET_DETAILS}
776-
component={WalletDetails as ScreenComponent}
776+
component={WalletDetails}
777777
initialParams={route?.params}
778778
options={{
779779
headerShown: false,

app/components/Views/MultichainAccounts/AccountDetails/AccountDetails.test.tsx

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,6 @@ jest.mock('../../confirmations/hooks/7702/useEIP7702Networks', () => ({
3535

3636
const mockNavigate = jest.fn();
3737
const mockGoBack = jest.fn();
38-
jest.mock('@react-navigation/native', () => ({
39-
...jest.requireActual('@react-navigation/native'),
40-
useNavigation: () => ({
41-
navigate: mockNavigate,
42-
goBack: mockGoBack,
43-
}),
44-
}));
4538

4639
const mockAddress = '0x67B2fAf7959fB61eb9746571041476Bbd0672569';
4740
const mockAccount = createMockInternalAccount(
@@ -51,11 +44,24 @@ const mockAccount = createMockInternalAccount(
5144
EthAccountType.Eoa,
5245
);
5346

47+
let mockRouteParams: { account: InternalAccount } = {
48+
account: mockAccount,
49+
};
50+
51+
jest.mock('@react-navigation/native', () => ({
52+
...jest.requireActual('@react-navigation/native'),
53+
useNavigation: () => ({
54+
navigate: mockNavigate,
55+
goBack: mockGoBack,
56+
}),
57+
useRoute: () => ({
58+
params: mockRouteParams,
59+
}),
60+
}));
61+
5462
const renderWithAccount = (account: InternalAccount | undefined) => {
55-
const mockRoute = {
56-
params: {
57-
account: account || mockAccount,
58-
},
63+
mockRouteParams = {
64+
account: account || mockAccount,
5965
};
6066

6167
// Create proper state that includes the account in the AccountsController
@@ -74,7 +80,7 @@ const renderWithAccount = (account: InternalAccount | undefined) => {
7480

7581
return renderWithProvider(
7682
<SafeAreaProvider>
77-
<AccountDetails route={mockRoute} />
83+
<AccountDetails />
7884
</SafeAreaProvider>,
7985
{
8086
state: {
@@ -106,6 +112,7 @@ const renderWithAccount = (account: InternalAccount | undefined) => {
106112
describe('AccountDetails', () => {
107113
beforeEach(() => {
108114
jest.clearAllMocks();
115+
mockRouteParams = { account: mockAccount };
109116
});
110117

111118
it('displays account name and address when account is defined', () => {
@@ -126,15 +133,13 @@ describe('AccountDetails', () => {
126133
EthAccountType.Eoa,
127134
);
128135

129-
const mockRoute = {
130-
params: {
131-
account: nonExistentAccount,
132-
},
136+
mockRouteParams = {
137+
account: nonExistentAccount,
133138
};
134139

135140
renderWithProvider(
136141
<SafeAreaProvider>
137-
<AccountDetails route={mockRoute} />
142+
<AccountDetails />
138143
</SafeAreaProvider>,
139144
{
140145
state: {

app/components/Views/MultichainAccounts/AccountDetails/AccountDetails.tsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,23 @@ import { getMemoizedInternalAccountByAddress } from '../../../../selectors/accou
77
import { useSelector } from 'react-redux';
88
import { RootState } from '../../../../reducers';
99
import Routes from '../../../../constants/navigation/Routes';
10-
import { useNavigation } from '@react-navigation/native';
10+
import { RouteProp, useNavigation, useRoute } from '@react-navigation/native';
1111
import PrivateKeyAccountDetails from './AccountTypes/PrivateKeyAccountDetails';
1212
import HardwareAccountDetails from './AccountTypes/HardwareAccountDetails';
1313
import { isHardwareAccount } from '../../../../util/address';
1414
import SnapAccountDetails from './AccountTypes/SnapAccountDetails';
1515

16-
interface AccountDetailsProps {
17-
route: {
18-
params: {
19-
account: InternalAccount;
20-
};
21-
};
16+
interface AccountDetailsRouteParams {
17+
account: InternalAccount;
2218
}
2319

24-
export const AccountDetails = (props: AccountDetailsProps) => {
20+
export const AccountDetails = () => {
21+
const route =
22+
useRoute<RouteProp<{ params: AccountDetailsRouteParams }, 'params'>>();
2523
const navigation = useNavigation();
2624
const {
2725
account: { address },
28-
} = props.route.params;
26+
} = route.params;
2927
const account: InternalAccount | undefined = useSelector((state: RootState) =>
3028
getMemoizedInternalAccountByAddress(state, address),
3129
);

0 commit comments

Comments
 (0)