Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: decouple account sync logic from UserStorageController #5078

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,3 +1,65 @@
import type nock from 'nock';

import encryption from '../../../shared/encryption/encryption';
import type {
GetUserStorageAllFeatureEntriesResponse,
GetUserStorageResponse,
} from '../services';
import { MOCK_STORAGE_KEY } from './mockStorage';

/**
* Test Utility - creates a realistic mock user-storage entry
* @param data - data to encrypt
* @returns user storage entry
*/
export async function createMockUserStorageEntry(
data: unknown,
): Promise<GetUserStorageResponse> {
return {
HashedKey: 'HASHED_KEY',
Data: await encryption.encryptString(
JSON.stringify(data),
MOCK_STORAGE_KEY,
),
};
}

/**
* Test Utility - creates a realistic mock user-storage get-all entry
* @param data - data array to encrypt
* @returns user storage entry
*/
export async function createMockUserStorageEntries(
data: unknown[],
): Promise<GetUserStorageAllFeatureEntriesResponse> {
return await Promise.all(data.map((d) => createMockUserStorageEntry(d)));
}

/**
* Test Utility - decrypts a realistic batch upsert payload
* @param requestBody - nock body
* @param storageKey - storage key
* @returns decrypted body
*/
export async function decryptBatchUpsertBody(
requestBody: nock.Body,
storageKey: string,
) {
if (typeof requestBody === 'string') {
return requestBody;
}
return await Promise.all(
Object.entries<string>(requestBody.data).map(
async ([entryKey, entryValue]) => {
return [
entryKey,
await encryption.decryptString(entryValue, storageKey),
];
},
),
);
}

type WaitForOptions = {
intervalMs?: number;
timeoutMs?: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { EthAccountType } from '@metamask/keyring-api';
import { KeyringTypes } from '@metamask/keyring-controller';
import type { InternalAccount } from '@metamask/keyring-internal-api';

import { LOCALIZED_DEFAULT_ACCOUNT_NAMES } from '../accounts/constants';
import { mapInternalAccountToUserStorageAccount } from '../accounts/user-storage';
import { LOCALIZED_DEFAULT_ACCOUNT_NAMES } from '../constants';
import { mapInternalAccountToUserStorageAccount } from '../utils';

/**
* Map an array of internal accounts to an array of user storage accounts
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import type { InternalAccount } from '@metamask/keyring-internal-api';

import { createSHA256Hash } from '../../../../shared/encryption';
import { mockUserStorageMessenger } from '../../__fixtures__/mockMessenger';
import { mapInternalAccountToUserStorageAccount } from '../utils';
import { MOCK_INTERNAL_ACCOUNTS } from './mockAccounts';

/**
* Test Utility - create a mock user storage messenger for account syncing tests
*
* @param options - options for the mock messenger
* @param options.accounts - options for the accounts part of the controller
* @param options.accounts.accountsList - list of accounts to return for the 'AccountsController:listAccounts' action
* @returns Mock User Storage Messenger
*/
export function mockUserStorageMessengerForAccountSyncing(options?: {
accounts?: {
accountsList?: InternalAccount[];
};
}) {
const messengerMocks = mockUserStorageMessenger();

messengerMocks.mockKeyringAddNewAccount.mockImplementation(async () => {
messengerMocks.baseMessenger.publish(
'AccountsController:accountAdded',
MOCK_INTERNAL_ACCOUNTS.ONE[0] as InternalAccount,
);
return MOCK_INTERNAL_ACCOUNTS.ONE[0].address;
});

messengerMocks.mockAccountsListAccounts.mockReturnValue(
(options?.accounts?.accountsList ??
MOCK_INTERNAL_ACCOUNTS.ALL) as InternalAccount[],
);

return messengerMocks;
}

/**
* Test Utility - creates a realistic expected batch upsert payload
* @param data - data supposed to be upserted
* @param storageKey - storage key
* @returns expected body
*/
export function createExpectedAccountSyncBatchUpsertBody(
data: [string, InternalAccount][],
storageKey: string,
) {
return data.map(([entryKey, entryValue]) => [
createSHA256Hash(String(entryKey) + storageKey),
JSON.stringify(mapInternalAccountToUserStorageAccount(entryValue)),
]);
}

/**
* Test Utility - creates a realistic expected batch delete payload
* @param data - data supposed to be deleted
* @param storageKey - storage key
* @returns expected body
*/
export function createExpectedAccountSyncBatchDeleteBody(
data: string[],
storageKey: string,
) {
return data.map((entryKey) =>
createSHA256Hash(String(entryKey) + storageKey),
);
}
Loading
Loading