Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion shared/lib/selectors/smart-transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
} from '../../../ui/selectors/remote-feature-flags';
import { isProduction } from '../environment';
import { getCurrentChainId, type NetworkState } from './networks';
import { createDeepEqualSelector } from './util';
import { createDeepEqualSelector } from './selector-creators';

export type SmartTransactionsMetaMaskState = {
metamask: {
Expand Down
4 changes: 0 additions & 4 deletions shared/lib/selectors/util.ts

This file was deleted.

2 changes: 1 addition & 1 deletion ui/ducks/bridge/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import {
ALL_ALLOWED_BRIDGE_CHAIN_IDS,
ALLOWED_BRIDGE_CHAIN_IDS,
} from '../../../shared/constants/bridge';
import { createDeepEqualSelector } from '../../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../../shared/lib/selectors/selector-creators';
import { CHAIN_IDS, FEATURED_RPCS } from '../../../shared/constants/network';
import {
getCurrencyRateControllerCurrencyRates,
Expand Down
9 changes: 5 additions & 4 deletions ui/ducks/locale/locale.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Action } from 'redux'; // Import types for actions
import { createSelector } from 'reselect';
import * as actionConstants from '../../store/actionConstants';
import { FALLBACK_LOCALE } from '../../../shared/lib/i18n';
import { createDeepEqualSelector } from '../../../shared/lib/selectors/util';

/**
* Type for the locale messages part of the state
Expand Down Expand Up @@ -75,11 +75,12 @@ export const getCurrentLocale = (state: AppState): string | undefined =>
state.localeMessages?.currentLocale;

/**
* This selector returns a BCP 47 Language Tag for use with the Intl API.
* Selector to get the locale formatted for Intl API usage.
* Converts locale codes from underscore format (en_US) to hyphen format (en-US).
*
* @returns The user's selected locale in BCP 47 format
* @returns The canonicalized locale string for Intl API.
*/
export const getIntlLocale = createDeepEqualSelector(
export const getIntlLocale = createSelector(
getCurrentLocale,
(locale): string =>
Intl.getCanonicalLocales(
Expand Down
2 changes: 1 addition & 1 deletion ui/pages/confirmations/selectors/accounts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { InternalAccount } from '@metamask/keyring-internal-api';
import { createDeepEqualSelector } from '../../../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../../../shared/lib/selectors/selector-creators';
import { getAccountGroupsByAddress } from '../../../selectors/multichain-accounts/account-tree';
import {
AccountGroupWithInternalAccounts,
Expand Down
2 changes: 1 addition & 1 deletion ui/pages/confirmations/selectors/confirm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { QuoteResponse } from '@metamask/bridge-controller';

import { createSelector } from 'reselect';
import { getPendingApprovals } from '../../../selectors/approvals';
import { createDeepEqualSelector } from '../../../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../../../shared/lib/selectors/selector-creators';
import { ConfirmMetamaskState } from '../types/confirm';

const ConfirmationApprovalTypes = [
Expand Down
54 changes: 54 additions & 0 deletions ui/pages/notification-details/notification-details.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import { useAppSelector } from '../../store/store';
import { renderWithProvider } from '../../../test/lib/render-helpers-navigate';
import { NOTIFICATIONS_ROUTE } from '../../helpers/constants/routes';
import NotificationDetails from './notification-details';

const configureStore = jest.requireActual('../../store/store').default;

const mockUseNavigate = jest.fn();

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => mockUseNavigate,
}));

jest.mock('../../store/store', () => {
const actual = jest.requireActual('../../store/store');
return {
...actual,
useAppSelector: jest.fn(),
};
});

jest.mock('../../hooks/metamask-notifications/useNotifications', () => ({
useMarkNotificationAsRead: () => ({
markNotificationAsRead: jest.fn(),
}),
}));

jest.mock('../../hooks/useNotificationTimeouts', () => ({
useSnapNotificationTimeouts: () => ({
setNotificationTimeout: jest.fn(),
}),
}));

describe('NotificationDetails', () => {
beforeEach(() => {
mockUseNavigate.mockClear();
jest.mocked(useAppSelector).mockReturnValue(undefined);
});

it('navigates to the notifications list when the notification is not found', () => {
const store = configureStore({});

renderWithProvider(
<NotificationDetails />,
store,
`${NOTIFICATIONS_ROUTE}/missing-id`,
);

expect(mockUseNavigate).toHaveBeenCalledWith(NOTIFICATIONS_ROUTE);
expect(useAppSelector).toHaveBeenCalled();
});
});
6 changes: 4 additions & 2 deletions ui/pages/notification-details/notification-details.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React, { useEffect } from 'react';
import { useSelector } from 'react-redux';
import { useNavigate, useLocation } from 'react-router-dom';
import {
TRIGGER_TYPES,
Expand All @@ -21,6 +20,7 @@ import {
hasNotificationComponents,
} from '../notifications/notification-components';
import { useSnapNotificationTimeouts } from '../../hooks/useNotificationTimeouts';
import { useAppSelector } from '../../store/store';
import { getExtractIdentifier } from './utils/utils';
import { NotificationDetailsHeader } from './notification-details-header/notification-details-header';
import { NotificationDetailsBody } from './notification-details-body/notification-details-body';
Expand All @@ -29,7 +29,9 @@ import { NotificationDetailsFooter } from './notification-details-footer/notific
function useNotificationByPath() {
const { pathname } = useLocation();
const id = getExtractIdentifier(pathname);
const notification = useSelector(getMetamaskNotificationById(id));
const notification = useAppSelector((state) =>
getMetamaskNotificationById(state, id),
);

return {
notification,
Expand Down
2 changes: 1 addition & 1 deletion ui/selectors/approvals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
import { ApprovalType } from '@metamask/controller-utils';
import { createSelector } from 'reselect';
import { Json } from '@metamask/utils';
import { createDeepEqualSelector } from '../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../shared/lib/selectors/selector-creators';
import { EMPTY_OBJECT } from './shared';

export type ApprovalsMetaMaskState = {
Expand Down
2 changes: 1 addition & 1 deletion ui/selectors/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import type {
} from '@metamask/assets-controllers';
import { NetworkEnablementControllerState } from '@metamask/network-enablement-controller';
import { TEST_CHAINS } from '../../shared/constants/network';
import { createDeepEqualSelector } from '../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../shared/lib/selectors/selector-creators';
import { Token, TokenWithFiatAmount } from '../components/app/assets/types';
import { calculateTokenBalance } from '../components/app/assets/util/calculateTokenBalance';
import { calculateTokenFiatAmount } from '../components/app/assets/util/calculateTokenFiatAmount';
Expand Down
2 changes: 1 addition & 1 deletion ui/selectors/dapp.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isEvmAccountType } from '@metamask/keyring-api';
import { getNetworkConfigurationsByChainId } from '../../shared/lib/selectors/networks';
import { createDeepEqualSelector } from '../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../shared/lib/selectors/selector-creators';
import {
getOrderedConnectedAccountsForActiveTab,
getOriginOfCurrentTab,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { createMockNotificationEthReceived } from '@metamask/notification-servic
import {
selectIsMetamaskNotificationsEnabled,
getMetamaskNotifications,
getMetamaskNotificationById,
getMetamaskNotificationsReadList,
getMetamaskNotificationsUnreadCount,
selectIsFeatureAnnouncementsEnabled,
Expand Down Expand Up @@ -80,4 +81,25 @@ describe('Metamask Notifications Selectors', () => {
state.metamask.subscriptionAccountsSeen = ['0x1111'];
expect(getValidNotificationAccounts(state)).toStrictEqual(['0x1111']);
});

describe('getMetamaskNotificationById', () => {
it('returns the notification when the id matches', () => {
const state = mockState();
const [first] = mockNotifications;
expect(getMetamaskNotificationById(state, first.id)).toStrictEqual(first);
});

it('returns undefined when the id is not in the list', () => {
const state = mockState();
expect(
getMetamaskNotificationById(state, 'non-existent-id'),
).toBeUndefined();
});

it('returns undefined when the notifications list is empty', () => {
const state = mockState();
state.metamask.metamaskNotificationsList = [];
expect(getMetamaskNotificationById(state, 'any-id')).toBeUndefined();
});
});
});
25 changes: 11 additions & 14 deletions ui/selectors/metamask-notifications/metamask-notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
TRIGGER_TYPES,
defaultState,
} from '@metamask/notification-services-controller/notification-services';
import { createDeepEqualSelector } from '../../../shared/lib/selectors/util';
import { createParameterizedSelector } from '../../../shared/lib/selectors/selector-creators';
import {
getRemoteFeatureFlags,
type RemoteFeatureFlagsState,
Expand Down Expand Up @@ -54,21 +54,18 @@ export const getMetamaskNotifications = createSelector(
);

/**
* Factory function to create a selector that retrieves a specific MetaMask notification by ID.
* Selector to retrieve a specific MetaMask notification by its ID.
*
* This function returns a selector that is tailored to fetch a notification by its ID.
*
* @param id - The ID of the notification to retrieve.
* @returns A selector function that takes the AppState and returns the notification.
* @param _state - The current state of the Redux store.
* @param id - The unique identifier of the notification to retrieve.
* @returns The notification matching the given ID, or undefined if not found.
*/
export const getMetamaskNotificationById = (id: string) => {
return createDeepEqualSelector(
[getMetamaskNotifications],
(notifications: Notification[]): Notification | undefined => {
return notifications.find((notification) => notification.id === id);
},
);
};
export const getMetamaskNotificationById = createParameterizedSelector(20)(
[getMetamaskNotifications, (_state: NotificationAppState, id: string) => id],
(notifications: Notification[], id: string): Notification | undefined => {
return notifications.find((notification) => notification.id === id);
},
);

/**
* Selector to get the list of read MetaMask notifications.
Expand Down
2 changes: 1 addition & 1 deletion ui/selectors/multichain-accounts/account-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import {
import { type MultichainNetworkConfiguration } from '@metamask/multichain-network-controller';
import { type NetworkConfiguration } from '@metamask/network-controller';

import { createDeepEqualSelector } from '../../../shared/lib/selectors/util';
import {
createDeepEqualSelector,
createParameterizedSelector,
createParameterizedShallowEqualSelector,
} from '../../../shared/lib/selectors/selector-creators';
Expand Down
2 changes: 1 addition & 1 deletion ui/selectors/multichain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import {
} from '../../shared/lib/selectors/networks';
// eslint-disable-next-line import-x/no-restricted-paths
import { getConversionRatesForNativeAsset } from '../../app/scripts/lib/util';
import { createDeepEqualSelector } from '../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../shared/lib/selectors/selector-creators';
import {
AccountsState,
getInternalAccounts,
Expand Down
2 changes: 1 addition & 1 deletion ui/selectors/multichain/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import {
selectDefaultNetworkClientIdsByChainId,
getNetworksMetadata,
} from '../../../shared/lib/selectors/networks';
import { createDeepEqualSelector } from '../../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../../shared/lib/selectors/selector-creators';
import { getEnabledNetworks } from '../../../shared/lib/selectors/multichain';
import { getIsMetaMaskInfuraEndpointUrl } from '../../../shared/lib/network-utils';
import { type RemoteFeatureFlagsState } from '../remote-feature-flags';
Expand Down
12 changes: 7 additions & 5 deletions ui/selectors/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ import { MULTICHAIN_NETWORK_TO_ASSET_TYPES } from '../../shared/constants/multic
import { MULTICHAIN_PROVIDER_CONFIGS } from '../../shared/constants/multichain/networks';
import { hasTransactionData } from '../../shared/lib/transaction.utils';
import { toChecksumHexAddress } from '../../shared/lib/hexstring-utils';
import { createDeepEqualSelector } from '../../shared/lib/selectors/util';
import {
createDeepEqualSelector,
createParameterizedSelector,
createParameterizedShallowEqualSelector,
} from '../../shared/lib/selectors/selector-creators';
Expand Down Expand Up @@ -1291,7 +1291,8 @@ export function getTargetAccountWithSendEtherInfo(state, targetAddress) {
export function getCurrentEthBalance(state) {
return getCurrentAccountWithSendEtherInfo(state)?.balance;
}
export const getNetworkConfigurationIdByChainId = createDeepEqualSelector(

export const getNetworkConfigurationIdByChainId = createSelector(
(state) => state.metamask.networkConfigurationsByChainId,
(networkConfigurationsByChainId) =>
Object.entries(networkConfigurationsByChainId).reduce(
Expand Down Expand Up @@ -2251,13 +2252,14 @@ export const getConnectedSubjectsForAllAddresses = createDeepEqualSelector(
},
);

const getAllConnectedAccounts = createDeepEqualSelector(
const getAllConnectedAccounts = createSelector(
getConnectedSubjectsForAllAddresses,
(connectedSubjects) => {
return Object.keys(connectedSubjects);
},
);
export const getConnectedSitesList = createDeepEqualSelector(

export const getConnectedSitesList = createSelector(
getConnectedSubjectsForAllAddresses,
getInternalAccounts,
getAllConnectedAccounts,
Expand Down Expand Up @@ -2586,7 +2588,7 @@ export const getSelectedNetwork = createDeepEqualSelector(
},
);

export const getConnectedSitesListWithNetworkInfo = createDeepEqualSelector(
export const getConnectedSitesListWithNetworkInfo = createSelector(
getConnectedSitesList,
getAllDomains,
getNetworkConfigurationsByChainId,
Expand Down
2 changes: 1 addition & 1 deletion ui/selectors/signatures.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { createSelector } from 'reselect';
import { DefaultRootState } from 'react-redux';
import { createDeepEqualSelector } from '../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../shared/lib/selectors/selector-creators';
import {
unapprovedPersonalMsgsSelector,
unapprovedTypedMessagesSelector,
Expand Down
2 changes: 1 addition & 1 deletion ui/selectors/snaps/address-book.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AddressBookController } from '@metamask/address-book-controller';
import { createDeepEqualSelector } from '../../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../../shared/lib/selectors/selector-creators';
import { isEqualCaseInsensitive } from '../../../shared/lib/string-utils';

/**
Expand Down
2 changes: 1 addition & 1 deletion ui/selectors/snaps/currency.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createDeepEqualSelector } from '../../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../../shared/lib/selectors/selector-creators';
import { getCurrentCurrency } from '../../ducks/metamask/metamask';

export const getMemoizedCurrentCurrency = createDeepEqualSelector(
Expand Down
2 changes: 1 addition & 1 deletion ui/selectors/toast.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createSelector } from 'reselect';
import { createDeepEqualSelector } from '../../shared/lib/selectors/util';
import { createDeepEqualSelector } from '../../shared/lib/selectors/selector-creators';
import type { MetaMaskReduxState } from '../store/store';
import {
TOAST_EXCLUDED_TRANSACTION_TYPES,
Expand Down
3 changes: 2 additions & 1 deletion ui/selectors/transactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ import {
getProviderConfig,
getCurrentChainId,
} from '../../shared/lib/selectors/networks';
import { createDeepEqualSelector } from '../../shared/lib/selectors/util';

import {
createDeepEqualSelector,
createShallowEqualInputAndResultSelector,
createParameterizedShallowEqualSelector,
} from '../../shared/lib/selectors/selector-creators';
Expand Down
Loading