@metamask/snaps-jest
Version:
A Jest preset for end-to-end testing MetaMask Snaps, including a Jest environment, and a set of Jest matchers
143 lines • 5.4 kB
JavaScript
import { logInfo } from "@metamask/snaps-utils";
import { assert, createModuleLogger } from "@metamask/utils";
import { rootLogger, getEnvironment, getPseudoRandomUuidGenerator, getScopesFromAssets } from "./internals/index.mjs";
const log = createModuleLogger(rootLogger, 'helpers');
/**
* Get the options for {@link installSnap}.
*
* @param snapId - The ID of the Snap, or the options.
* @param options - The options, if any.
* @returns The options.
*/
function getOptions(snapId, options) {
if (typeof snapId === 'object') {
return [undefined, snapId];
}
return [snapId, options];
}
/**
* Load a snap into the environment. This is the main entry point for testing
* snaps: It returns a {@link Snap} object that can be used to interact with the
* snap.
*
* @example
* import { installSnap } from '@metamask/snaps-jest';
*
* describe('My Snap', () => {
* it('should do something', async () => {
* const { request } = await installSnap('local:my-snap');
* const response = await request({
* method: 'foo',
* params: ['bar'],
* });
* expect(response).toRespondWith('bar');
* });
* });
* @param snapId - The ID of the snap, including the prefix (`local:`). Defaults
* to the URL of the built-in server, if it is running. This supports both
* local snap IDs and NPM snap IDs.
* @param options - The options to use.
* @param options.executionService - The execution service to use. Defaults to
* {@link NodeThreadExecutionService}. You do not need to provide this unless
* you are testing a custom execution service.
* @param options.executionServiceOptions - The options to use when creating the
* execution service, if any. This should only include options specific to the
* provided execution service.
* @param options.options - The simulation options.
* @returns The snap.
* @throws If the built-in server is not running, and no snap ID is provided.
*/
export async function installSnap(snapId, options = {}) {
const resolvedOptions = getOptions(snapId, options);
// TODO: Either fix this lint violation or explain why it's necessary to
// ignore.
/* eslint-disable @typescript-eslint/unbound-method */
const { request, onTransaction, sendTransaction, onSignature, onCronjob, runCronjob, onBackgroundEvent, onHomePage, onSettingsPage, onKeyringRequest, onInstall, onUpdate, onStart, onNameLookup, onProtocolRequest, onClientRequest, mockJsonRpc, close, } = await getEnvironment().installSnap(...resolvedOptions);
/* eslint-enable @typescript-eslint/unbound-method */
return {
request,
onTransaction,
sendTransaction,
onSignature,
onCronjob,
runCronjob,
onBackgroundEvent,
onHomePage,
onSettingsPage,
onKeyringRequest,
onInstall,
onUpdate,
onStart,
onNameLookup,
onProtocolRequest,
onClientRequest,
mockJsonRpc,
close: async () => {
log('Closing execution service.');
logInfo('Calling `snap.close()` is deprecated, and will be removed in a future release. Snaps are now automatically closed when the test ends.');
await close();
},
};
}
/**
* Get the state of an AccountSelector based on a {@link SimulationAccount}.
*
* @param account - The {@link SimulationAccount} to get the state from.
* @returns The state of the AccountSelector.
*/
export function getStateFromAccount(account) {
const { address, scopes } = account;
return {
addresses: scopes.map((scope) => `${scope}:${address}`),
accountId: account.id,
};
}
/**
* Get the state of an AssetSelector based on a {@link SimulationAsset}.
*
* @param id - The Asset id as a CAIP-19 asset type.
* @param assets - The {@link SimulationAsset} to get the state from.
* @returns The state of the AssetSelector.
*/
export function getStateFromAsset(id, assets) {
const asset = assets[id];
assert(asset, `Asset with ID "${id}" not found in simulation assets.`);
const { symbol, name } = asset;
return {
asset: id,
symbol,
name,
};
}
/**
* Generate a pseudo-random UUID.
*
* @returns A pseudo-random UUID string.
*/
const getPseudoRandomUuid = getPseudoRandomUuidGenerator();
/**
* Get a mock account object for testing purposes.
*
* @param options - The options for creating the mock account.
* @param options.address - The address of the account.
* @param options.scopes - The scopes associated with the account, in CAIP
* format. If not provided, they will be derived from the `assets`.
* @param options.assets - The assets associated with the account, in CAIP
* format. If not provided, it will default to an empty array.
* @param options.selected - Whether the account is selected by default.
* @param options.owned - Whether the account is owned by the snap.
* @param options.id - The ID of the account. If not provided, a pseudo-random
* UUID will be generated.
* @returns A mock account object with the specified properties.
*/
export function getMockAccount({ address, assets = [], selected = false, owned = false, id = getPseudoRandomUuid(), scopes = getScopesFromAssets(assets), }) {
return {
address,
id,
scopes,
selected,
owned,
assets,
};
}
//# sourceMappingURL=helpers.mjs.map