diff --git a/app/util/notifications/hooks/useNotifications.ts b/app/util/notifications/hooks/useNotifications.ts index d855a077a7e..46cf6902edc 100644 --- a/app/util/notifications/hooks/useNotifications.ts +++ b/app/util/notifications/hooks/useNotifications.ts @@ -109,11 +109,11 @@ export function useEnableNotifications(props = { nudgeEnablePush: true }) { const enableNotifications = useCallback(async () => { assertIsFeatureEnabled(); setError(null); + await enableNotificationsHelper().catch((e) => setError(e)); await togglePushNotification(true).catch(() => { /* Do Nothing */ }); await updateNotificationSubscriptionExpiration(); - await enableNotificationsHelper().catch((e) => setError(e)); }, [togglePushNotification]); const contiguousLoading = useContiguousLoading(loading, pushLoading); diff --git a/e2e/api-mocking/mock-config/mock-events.js b/e2e/api-mocking/mock-config/mock-events.js index ba97c095cac..daf027eee0f 100644 --- a/e2e/api-mocking/mock-config/mock-events.js +++ b/e2e/api-mocking/mock-config/mock-events.js @@ -8,6 +8,7 @@ import { suggestedGasFeesApiGanache, } from '../mock-responses/gas-api-responses.json'; import defiPositionsWithData from '../mock-responses/defi-api-response-data.json'; +import { DEFAULT_FIXTURE_ACCOUNT } from '../../framework/fixtures/FixtureBuilder'; export const mockEvents = { /** @@ -164,22 +165,19 @@ export const mockEvents = { }, defiPositionsWithNoData: { - urlEndpoint: - 'https://defiadapters.api.cx.metamask.io/positions/0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3', + urlEndpoint: `https://defiadapters.api.cx.metamask.io/positions/${DEFAULT_FIXTURE_ACCOUNT}`, response: { data: [] }, responseCode: 200, }, defiPositionsError: { - urlEndpoint: - 'https://defiadapters.api.cx.metamask.io/positions/0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3', + urlEndpoint: `https://defiadapters.api.cx.metamask.io/positions/${DEFAULT_FIXTURE_ACCOUNT}`, response: { error: 'Internal server error' }, responseCode: 500, }, defiPositionsWithData: { - urlEndpoint: - 'https://defiadapters.api.cx.metamask.io/positions/0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3', + urlEndpoint: `https://defiadapters.api.cx.metamask.io/positions/${DEFAULT_FIXTURE_ACCOUNT}`, response: { data: defiPositionsWithData }, responseCode: 200, }, diff --git a/e2e/fixtures/utils.js b/e2e/fixtures/utils.js index 2a3c9132264..04fd50e3481 100644 --- a/e2e/fixtures/utils.js +++ b/e2e/fixtures/utils.js @@ -78,6 +78,7 @@ export function buildPermissions(chainIds) { caveats: [ { type: Caip25CaveatType, + /** @type {import('@metamask/chain-agnostic-permission').Caip25CaveatValue} */ value: { optionalScopes, requiredScopes: {}, diff --git a/e2e/framework/fixtures/FixtureBuilder.ts b/e2e/framework/fixtures/FixtureBuilder.ts index faa1fc8cb1b..cc4717d2b8f 100644 --- a/e2e/framework/fixtures/FixtureBuilder.ts +++ b/e2e/framework/fixtures/FixtureBuilder.ts @@ -18,9 +18,14 @@ import { import { BackupAndSyncSettings, RampsRegion } from '../types'; import { MULTIPLE_ACCOUNTS_ACCOUNTS_CONTROLLER } from './constants'; -export const DEFAULT_FIXTURE_ACCOUNT = +export const DEFAULT_FIXTURE_ACCOUNT_CHECKSUM = '0x76cf1CdD1fcC252442b50D6e97207228aA4aefC3'; +export const DEFAULT_FIXTURE_ACCOUNT = + DEFAULT_FIXTURE_ACCOUNT_CHECKSUM.toLowerCase() as Lowercase< + typeof DEFAULT_FIXTURE_ACCOUNT_CHECKSUM + >; + export const DEFAULT_FIXTURE_ACCOUNT_2 = '0xcdd74c6eb517f687aa2c786bc7484eb2f9bae1da'; @@ -128,12 +133,12 @@ class FixtureBuilder { AccountTrackerController: { accountsByChainId: { 64: { - [DEFAULT_FIXTURE_ACCOUNT]: { + [DEFAULT_FIXTURE_ACCOUNT_CHECKSUM]: { balance: '0x0', }, }, 1: { - [DEFAULT_FIXTURE_ACCOUNT]: { + [DEFAULT_FIXTURE_ACCOUNT_CHECKSUM]: { balance: '0x0', }, }, @@ -818,7 +823,7 @@ class FixtureBuilder { const permittedEthAccounts = incomingEthAccounts.length > 0 ? incomingEthAccounts - : [DEFAULT_FIXTURE_ACCOUNT]; + : [DEFAULT_FIXTURE_ACCOUNT_CHECKSUM]; // Cast addresses to the required 0x${string} format const typedAddresses = permittedEthAccounts.map( @@ -932,7 +937,7 @@ class FixtureBuilder { ); const caip25CaveatValueWithDefaultAccount = setEthAccounts( caip25CaveatValueWithChains, - [DEFAULT_FIXTURE_ACCOUNT], + [DEFAULT_FIXTURE_ACCOUNT_CHECKSUM], ); const chainPermission = { [Caip25EndowmentPermissionName]: { diff --git a/e2e/framework/fixtures/FixtureHelper.ts b/e2e/framework/fixtures/FixtureHelper.ts index 88f2d4a428c..04e31cde826 100644 --- a/e2e/framework/fixtures/FixtureHelper.ts +++ b/e2e/framework/fixtures/FixtureHelper.ts @@ -26,6 +26,7 @@ import { DappOptions, AnvilNodeOptions, GanacheNodeOptions, + TestSpecificMock, } from '../types'; import { TestDapps, @@ -36,6 +37,8 @@ import { import ContractAddressRegistry from '../../../app/util/test/contract-address-registry'; import FixtureBuilder from './FixtureBuilder'; import { createLogger } from '../logger'; +import { mockNotificationServices } from '../../specs/notifications/utils/mocks'; +import { type Mockttp } from 'mockttp'; const logger = createLogger({ name: 'FixtureHelper', @@ -314,6 +317,67 @@ export const stopFixtureServer = async (fixtureServer: FixtureServer) => { logger.debug('The fixture server is stopped'); }; +export const createMockAPIServer = async ( + mockServerInstance?: Mockttp, + testSpecificMock?: TestSpecificMock, +) => { + // Handle mock server + let mockServer: Mockttp | undefined; + let mockServerPort: number = DEFAULT_MOCKSERVER_PORT; + + // Both + if (mockServerInstance && testSpecificMock) { + throw new Error( + 'Cannot use both mockServerInstance and testSpecificMock at the same time. Please use only one.', + ); + } + + // mockServerInstance only + if (mockServerInstance && !testSpecificMock) { + mockServer = mockServerInstance; + mockServerPort = mockServer.port; + logger.debug( + `Mock server started from mockServerInstance on port ${mockServerPort}`, + ); + + const endpoints = await mockServer.getMockedEndpoints(); + + logger.debug(`Mocked endpoints: ${endpoints.length}`); + } + + // testSpecificMock only + if (!mockServerInstance && testSpecificMock) { + mockServerPort = getMockServerPort(); + mockServer = await startMockServer(testSpecificMock, mockServerPort); + + logger.debug( + `Mock server started from testSpecificMock on port ${mockServerPort}`, + ); + } + + // neither + if (!mockServerInstance && !testSpecificMock) { + mockServerPort = getMockServerPort(); + mockServer = await startMockServer({}, mockServerPort); + + logger.debug( + `Mock server started from testSpecificMock on port ${mockServerPort}`, + ); + } + + if (!mockServer) { + throw new Error('Test setup failure, no mock server setup'); + } + + // Additional Global Mocks + await mockNotificationServices(mockServer); + + return { + mockServer, + mockServerPort, + }; +}; + /** * Executes a test suite with fixtures by setting up a fixture server, loading a specified fixture, * and running the test suite. After the test suite execution, it stops the fixture server. @@ -349,37 +413,14 @@ export async function withFixtures( endTestfn, } = options; - if (mockServerInstance && testSpecificMock) { - throw new Error( - 'Cannot use both mockServerInstance and testSpecificMock at the same time. Please use only one.', - ); - } + const { mockServer, mockServerPort } = await createMockAPIServer( + mockServerInstance, + testSpecificMock, + ); // Prepare android devices for testing to avoid having this in all tests await TestHelpers.reverseServerPort(); - // Handle mock server - let mockServer; - let mockServerPort = DEFAULT_MOCKSERVER_PORT; - - if (mockServerInstance && !testSpecificMock) { - mockServer = mockServerInstance; - mockServerPort = mockServer.port; - logger.debug( - `Mock server started from mockServerInstance on port ${mockServerPort}`, - ); - const endpoints = await mockServer.getMockedEndpoints(); - logger.debug(`Mocked endpoints: ${endpoints.length}`); - } - - if (testSpecificMock && !mockServerInstance) { - mockServerPort = getMockServerPort(); - mockServer = await startMockServer(testSpecificMock, mockServerPort); - logger.debug( - `Mock server started from testSpecificMock on port ${mockServerPort}`, - ); - } - // Handle local nodes let localNodes; // Start servers based on the localNodes array diff --git a/e2e/specs/assets/import-tokens-via-asset-watcher.spec.ts b/e2e/specs/assets/import-tokens-via-asset-watcher.spec.ts index e3aa6ecbeb0..4cc1105fcde 100644 --- a/e2e/specs/assets/import-tokens-via-asset-watcher.spec.ts +++ b/e2e/specs/assets/import-tokens-via-asset-watcher.spec.ts @@ -1,7 +1,9 @@ import { SmokeNetworkAbstractions } from '../../tags'; import TestHelpers from '../../helpers'; import { loginToApp } from '../../viewHelper'; -import FixtureBuilder from '../../framework/fixtures/FixtureBuilder'; +import FixtureBuilder, { + DEFAULT_FIXTURE_ACCOUNT, +} from '../../framework/fixtures/FixtureBuilder'; import { withFixtures } from '../../framework/fixtures/FixtureHelper'; import { SMART_CONTRACTS } from '../../../app/util/test/smart-contracts'; @@ -12,6 +14,7 @@ import AssetWatchBottomSheet from '../../pages/Transactions/AssetWatchBottomShee import WalletView from '../../pages/wallet/WalletView'; import { buildPermissions } from '../../fixtures/utils'; import { DappVariants } from '../../framework/Constants'; +import { setEthAccounts } from '@metamask/chain-agnostic-permission'; const ERC20_CONTRACT = SMART_CONTRACTS.HST; @@ -23,6 +26,16 @@ describe(SmokeNetworkAbstractions('Asset Watch:'), () => { await TestHelpers.reverseServerPort(); }); + const buildERC20PermsForAddress = () => { + const perms = buildPermissions(['0x539']); + perms['endowment:caip25'].caveats[0].value = setEthAccounts( + perms['endowment:caip25'].caveats[0].value, + [DEFAULT_FIXTURE_ACCOUNT], + ); + + return perms; + }; + it('Should Import ERC20 Token via Dapp', async () => { await withFixtures( { @@ -34,7 +47,7 @@ describe(SmokeNetworkAbstractions('Asset Watch:'), () => { fixture: new FixtureBuilder() .withGanacheNetwork() .withPermissionControllerConnectedToTestDapp( - buildPermissions(['0x539']), + buildERC20PermsForAddress(), ) .build(), restartDevice: true, diff --git a/e2e/specs/multichain-accounts/common.ts b/e2e/specs/multichain-accounts/common.ts index b6f8d7491a2..d6a98987aad 100644 --- a/e2e/specs/multichain-accounts/common.ts +++ b/e2e/specs/multichain-accounts/common.ts @@ -1,6 +1,6 @@ import { mockEvents } from '../../api-mocking/mock-config/mock-events'; import FixtureBuilder, { - DEFAULT_FIXTURE_ACCOUNT, + DEFAULT_FIXTURE_ACCOUNT_CHECKSUM, } from '../../framework/fixtures/FixtureBuilder'; import { withFixtures } from '../../framework/fixtures/FixtureHelper'; import AccountListBottomSheet from '../../pages/wallet/AccountListBottomSheet'; @@ -16,13 +16,13 @@ export interface Account { export const HD_ACCOUNT: Account = { name: 'Account 1', index: 0, - address: DEFAULT_FIXTURE_ACCOUNT, + address: DEFAULT_FIXTURE_ACCOUNT_CHECKSUM, }; export const SIMPLE_KEYPAIR_ACCOUNT: Account = { name: 'Account 4', index: 4, - address: DEFAULT_FIXTURE_ACCOUNT, + address: DEFAULT_FIXTURE_ACCOUNT_CHECKSUM, }; export const goToAccountDetails = async (account: Account) => { diff --git a/e2e/specs/notifications/notification-settings-flow.spec.ts b/e2e/specs/notifications/notification-settings-flow.spec.ts index 4761d6c2424..9dd97d14498 100644 --- a/e2e/specs/notifications/notification-settings-flow.spec.ts +++ b/e2e/specs/notifications/notification-settings-flow.spec.ts @@ -4,7 +4,7 @@ import Assertions from '../../framework/Assertions'; import { mockNotificationServices } from './utils/mocks'; import { withFixtures } from '../../framework/fixtures/FixtureHelper'; import FixtureBuilder, { - DEFAULT_FIXTURE_ACCOUNT, + DEFAULT_FIXTURE_ACCOUNT_CHECKSUM, } from '../../framework/fixtures/FixtureBuilder'; import { loginToApp } from '../../viewHelper'; import TabBarComponent from '../../pages/wallet/TabBarComponent'; @@ -66,11 +66,11 @@ describe(SmokeNetworkAbstractions('Notification Onboarding'), () => { // Test account notifications toggle functionality await NotificationSettingsView.tapAccountNotificationsToggleAndVerifyState( - DEFAULT_FIXTURE_ACCOUNT, + DEFAULT_FIXTURE_ACCOUNT_CHECKSUM, 'off', ); await NotificationSettingsView.tapAccountNotificationsToggleAndVerifyState( - DEFAULT_FIXTURE_ACCOUNT, + DEFAULT_FIXTURE_ACCOUNT_CHECKSUM, 'on', );