1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 03:12:42 +02:00

Convert NetworkController net client tests to TS (#18490)

In order to be able to better compare differences between the version of
NetworkController in this repo and the version in the `core` repo before
we replace this version with the `core` version, this commit converts
the NetworkController network client tests to TypeScript.

The added types here are copied from the `core` repo. We plan on
making more improvements on the `core` side at some point to polish the
tests and types and reduce some of the duplication, but for now we're
just trying to keep things as similar as possible.
This commit is contained in:
Elliot Winkler 2023-04-14 10:21:29 -06:00 committed by GitHub
parent 8fdbd07c91
commit 26db0aee46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 297 additions and 196 deletions

View File

@ -267,7 +267,7 @@ module.exports = {
'app/scripts/controllers/app-state.test.js',
'app/scripts/controllers/network/**/*.test.js',
'app/scripts/controllers/network/**/*.test.ts',
'app/scripts/controllers/network/provider-api-tests/*.js',
'app/scripts/controllers/network/provider-api-tests/*.ts',
'app/scripts/controllers/permissions/**/*.test.js',
'app/scripts/lib/**/*.test.js',
'app/scripts/migrations/*.test.js',

View File

@ -1,6 +1,15 @@
/* eslint-disable jest/require-top-level-describe, jest/no-export */
import { withMockedCommunications, withNetworkClient } from './helpers';
import {
ProviderType,
withMockedCommunications,
withNetworkClient,
} from './helpers';
type TestsForRpcMethodThatCheckForBlockHashInResponseOptions = {
providerType: ProviderType;
numberOfParameters: number;
};
/**
* Defines tests which exercise the behavior exhibited by an RPC method that
@ -15,8 +24,11 @@ import { withMockedCommunications, withNetworkClient } from './helpers';
* either `infura` or `custom` (default: "infura").
*/
export function testsForRpcMethodsThatCheckForBlockHashInResponse(
method,
{ numberOfParameters, providerType },
method: string,
{
numberOfParameters,
providerType,
}: TestsForRpcMethodThatCheckForBlockHashInResponseOptions,
) {
if (providerType !== 'infura' && providerType !== 'custom') {
throw new Error(

View File

@ -3,6 +3,7 @@
import {
buildMockParams,
buildRequestWithReplacedBlockParam,
ProviderType,
waitForPromiseToBeFulfilledAfterRunningAllTimers,
withMockedCommunications,
withNetworkClient,
@ -13,6 +14,12 @@ import {
buildJsonRpcEngineEmptyResponseErrorMessage,
} from './shared-tests';
type TestsForRpcMethodSupportingBlockParam = {
providerType: ProviderType;
blockParamIndex: number;
numberOfParameters: number;
};
/**
* Defines tests which exercise the behavior exhibited by an RPC method that
* takes a block parameter. The value of this parameter can be either a block
@ -28,8 +35,12 @@ import {
*/
/* eslint-disable-next-line jest/no-export */
export function testsForRpcMethodSupportingBlockParam(
method,
{ blockParamIndex, numberOfParameters, providerType },
method: string,
{
blockParamIndex,
numberOfParameters,
providerType,
}: TestsForRpcMethodSupportingBlockParam,
) {
describe.each([
['given no block tag', undefined],
@ -1718,9 +1729,9 @@ export function testsForRpcMethodSupportingBlockParam(
[
['less than the current block number', '0x200'],
['equal to the curent block number', '0x100'],
],
] as any,
'%s',
(_nestedDesc, currentBlockNumber) => {
(_nestedDesc: string, currentBlockNumber: string) => {
it('makes an additional request to the RPC endpoint', async () => {
await withMockedCommunications({ providerType }, async (comms) => {
const request = {

View File

@ -1,14 +1,13 @@
import nock from 'nock';
import nock, { Scope as NockScope } from 'nock';
import sinon from 'sinon';
import type { JSONRPCResponse } from '@json-rpc-specification/meta-schema';
import EthQuery from 'eth-query';
import { createNetworkClient } from '../create-network-client';
/**
* @typedef {import('nock').Scope} NockScope
*
* A object returned by the `nock` function for mocking requests to a particular
* base URL.
*/
import { Hex } from '@metamask/utils';
import { BuiltInInfuraNetwork } from '../../../../../shared/constants/network';
import {
createNetworkClient,
NetworkClientType,
} from '../create-network-client';
/**
* A dummy value for the `infuraProjectId` option that `createInfuraClient`
@ -41,9 +40,9 @@ const originalSetTimeout = setTimeout;
* keeps failing, you can set `process.env.DEBUG_PROVIDER_TESTS` to `1`. This
* will turn on some extra logging.
*
* @param {any[]} args - The arguments that `console.log` takes.
* @param args - The arguments that `console.log` takes.
*/
function debug(...args) {
function debug(...args: any) {
if (process.env.DEBUG_PROVIDER_TESTS === '1') {
console.log(...args);
}
@ -52,96 +51,89 @@ function debug(...args) {
/**
* Builds a Nock scope object for mocking provider requests.
*
* @param {string} rpcUrl - The URL of the RPC endpoint.
* @returns {NockScope} The nock scope.
* @param rpcUrl - The URL of the RPC endpoint.
* @returns The nock scope.
*/
function buildScopeForMockingRequests(rpcUrl) {
function buildScopeForMockingRequests(rpcUrl: string): NockScope {
return nock(rpcUrl).filteringRequestBody((body) => {
debug('Nock Received Request: ', body);
return body;
});
}
/**
* @typedef {{ nockScope: NockScope, blockNumber: string }} MockBlockTrackerRequestOptions
*
* The options to `mockNextBlockTrackerRequest` and `mockAllBlockTrackerRequests`.
*/
type Request = { method: string; params?: any[] };
type Response = {
id?: number | string;
jsonrpc?: '2.0';
error?: any;
result?: any;
httpStatus?: number;
};
type ResponseBody = { body: JSONRPCResponse };
type BodyOrResponse = ResponseBody | Response;
type CurriedMockRpcCallOptions = {
request: Request;
// The response data.
response?: BodyOrResponse;
/**
* An error to throw while making the request.
* Takes precedence over `response`.
*/
error?: Error | string;
/**
* The amount of time that should pass before the
* request resolves with the response.
*/
delay?: number;
/**
* The number of times that the request is
* expected to be made.
*/
times?: number;
};
/**
* Mocks the next request for the latest block that the block tracker will make.
*
* @param {MockBlockTrackerRequestOptions} args - The arguments.
* @param {NockScope} args.nockScope - A nock scope (a set of mocked requests
* scoped to a certain base URL).
* @param {string} args.blockNumber - The block number that the block tracker
* should report, as a 0x-prefixed hex string.
*/
async function mockNextBlockTrackerRequest({
nockScope,
blockNumber = DEFAULT_LATEST_BLOCK_NUMBER,
}) {
await mockRpcCall({
nockScope,
request: { method: 'eth_blockNumber', params: [] },
response: { result: blockNumber },
});
}
type MockRpcCallOptions = {
// A nock scope (a set of mocked requests scoped to a certain base URL).
nockScope: nock.Scope;
} & CurriedMockRpcCallOptions;
/**
* Mocks all requests for the latest block that the block tracker will make.
*
* @param {MockBlockTrackerRequestOptions} args - The arguments.
* @param {NockScope} args.nockScope - A nock scope (a set of mocked requests
* scoped to a certain base URL).
* @param {string} args.blockNumber - The block number that the block tracker
* should report, as a 0x-prefixed hex string.
*/
async function mockAllBlockTrackerRequests({
nockScope,
blockNumber = DEFAULT_LATEST_BLOCK_NUMBER,
}) {
await mockRpcCall({
nockScope,
request: { method: 'eth_blockNumber', params: [] },
response: { result: blockNumber },
}).persist();
}
/**
* @typedef {{ nockScope: NockScope, request: object, response: object, delay?: number }} MockRpcCallOptions
*
* The options to `mockRpcCall`.
*/
type MockRpcCallResult = nock.Interceptor | nock.Scope;
/**
* Mocks a JSON-RPC request sent to the provider with the given response.
* Provider type is inferred from the base url set on the nockScope.
*
* @param {MockRpcCallOptions} args - The arguments.
* @param {NockScope} args.nockScope - A nock scope (a set of mocked requests
* scoped to a certain base URL).
* @param {object} args.request - The request data.
* @param {{body: string} | {httpStatus?: number; id?: number; method?: string; params?: string[]}} [args.response] - Information
* concerning the response that the request should have. If a `body` property is
* present, this is taken as the complete response body. If an `httpStatus`
* property is present, then it is taken as the HTTP status code to respond
* with. Properties other than these two are used to build a complete response
* body (including `id` and `jsonrpc` properties).
* @param {Error | string} [args.error] - An error to throw while making the
* request. Takes precedence over `response`.
* @param {number} [args.delay] - The amount of time that should pass before the
* request resolves with the response.
* @param {number} [args.times] - The number of times that the request is
* expected to be made.
* @returns {NockScope} The nock scope.
* @param args - The arguments.
* @param args.nockScope - A nock scope (a set of mocked requests scoped to a
* certain base URL).
* @param args.request - The request data.
* @param args.response - Information concerning the response that the request
* should have. If a `body` property is present, this is taken as the complete
* response body. If an `httpStatus` property is present, then it is taken as
* the HTTP status code to respond with. Properties other than these two are
* used to build a complete response body (including `id` and `jsonrpc`
* properties).
* @param args.error - An error to throw while making the request. Takes
* precedence over `response`.
* @param args.delay - The amount of time that should pass before the request
* resolves with the response.
* @param args.times - The number of times that the request is expected to be
* made.
* @returns The nock scope.
*/
function mockRpcCall({ nockScope, request, response, error, delay, times }) {
function mockRpcCall({
nockScope,
request,
response,
error,
delay,
times,
}: MockRpcCallOptions): MockRpcCallResult {
// eth-query always passes `params`, so even if we don't supply this property,
// for consistency with makeRpcCall, assume that the `body` contains it
const { method, params = [], ...rest } = request;
let httpStatus = 200;
let completeResponse = { id: 2, jsonrpc: '2.0' };
let completeResponse: JSONRPCResponse = { id: 2, jsonrpc: '2.0' };
if (response !== undefined) {
if ('body' in response) {
completeResponse = response.body;
@ -156,6 +148,7 @@ function mockRpcCall({ nockScope, request, response, error, delay, times }) {
}
}
}
/* @ts-expect-error The types for Nock do not include `basePath` in the interface for Nock.Scope. */
const url = nockScope.basePath.includes('infura.io')
? `/v3/${MOCK_INFURA_PROJECT_ID}`
: '/';
@ -189,7 +182,7 @@ function mockRpcCall({ nockScope, request, response, error, delay, times }) {
if (error !== undefined) {
return nockRequest.replyWithError(error);
} else if (completeResponse !== undefined) {
return nockRequest.reply(httpStatus, (_, requestBody) => {
return nockRequest.reply(httpStatus, (_, requestBody: any) => {
if (response !== undefined && !('body' in response)) {
if (response.id === undefined) {
completeResponse.id = requestBody.id;
@ -204,16 +197,72 @@ function mockRpcCall({ nockScope, request, response, error, delay, times }) {
return nockRequest;
}
type MockBlockTrackerRequestOptions = {
/**
* A nock scope (a set of mocked requests scoped to a certain base url).
*/
nockScope: NockScope;
/**
* The block number that the block tracker should report, as a 0x-prefixed hex
* string.
*/
blockNumber: string;
};
/**
* Mocks the next request for the latest block that the block tracker will make.
*
* @param args - The arguments.
* @param args.nockScope - A nock scope (a set of mocked requests scoped to a
* certain base URL).
* @param args.blockNumber - The block number that the block tracker should
* report, as a 0x-prefixed hex string.
*/
function mockNextBlockTrackerRequest({
nockScope,
blockNumber = DEFAULT_LATEST_BLOCK_NUMBER,
}: MockBlockTrackerRequestOptions) {
mockRpcCall({
nockScope,
request: { method: 'eth_blockNumber', params: [] },
response: { result: blockNumber },
});
}
/**
* Mocks all requests for the latest block that the block tracker will make.
*
* @param args - The arguments.
* @param args.nockScope - A nock scope (a set of mocked requests scoped to a
* certain base URL).
* @param args.blockNumber - The block number that the block tracker should
* report, as a 0x-prefixed hex string.
*/
async function mockAllBlockTrackerRequests({
nockScope,
blockNumber = DEFAULT_LATEST_BLOCK_NUMBER,
}: MockBlockTrackerRequestOptions) {
const result = await mockRpcCall({
nockScope,
request: { method: 'eth_blockNumber', params: [] },
response: { result: blockNumber },
});
if ('persist' in result) {
result.persist();
}
}
/**
* Makes a JSON-RPC call through the given eth-query object.
*
* @param {any} ethQuery - The eth-query object.
* @param {object} request - The request data.
* @returns {Promise<any>} A promise that either resolves with the result from
* the JSON-RPC response if it is successful or rejects with the error from the
* JSON-RPC response otherwise.
* @param ethQuery - The eth-query object.
* @param request - The request data.
* @returns A promise that either resolves with the result from the JSON-RPC
* response if it is successful or rejects with the error from the JSON-RPC
* response otherwise.
*/
function makeRpcCall(ethQuery, request) {
function makeRpcCall(ethQuery: EthQuery, request: Request) {
return new Promise((resolve, reject) => {
debug('[makeRpcCall] making request', request);
ethQuery.sendAsync(request, (error, result) => {
@ -227,41 +276,43 @@ function makeRpcCall(ethQuery, request) {
});
}
/**
* @typedef {{providerType: 'infura' | 'custom', infuraNetwork?: string}} WithMockedCommunicationsOptions
*
* The options bag that `Communications` takes.
*/
export type ProviderType = 'infura' | 'custom';
/**
* @typedef {{mockNextBlockTrackerRequest: (options: Omit<MockBlockTrackerRequestOptions, 'nockScope'>) => void, mockAllBlockTrackerRequests: (options: Omit<MockBlockTrackerRequestOptions, 'nockScope'>) => void, mockRpcCall: (options: Omit<MockRpcCallOptions, 'nockScope'>) => NockScope, rpcUrl: string, infuraNetwork: string}} Communications
*
* Provides methods to mock different kinds of requests to the provider.
*/
export type MockOptions = {
infuraNetwork?: BuiltInInfuraNetwork;
providerType: ProviderType;
customRpcUrl?: string;
customChainId?: Hex;
};
/**
* @typedef {(comms: Communications) => Promise<any>} WithMockedCommunicationsCallback
*
* The callback that `mockingCommunications` takes.
*/
export type MockCommunications = {
mockNextBlockTrackerRequest: (options?: any) => void;
mockAllBlockTrackerRequests: (options?: any) => void;
mockRpcCall: (options: CurriedMockRpcCallOptions) => MockRpcCallResult;
rpcUrl: string;
infuraNetwork: BuiltInInfuraNetwork;
};
/**
* Sets up request mocks for requests to the provider.
*
* @param {WithMockedCommunicationsOptions} options - An options bag.
* @param {"infura" | "custom"} options.providerType - The type of network
* client being tested.
* @param {string} [options.infuraNetwork] - The name of the Infura network being
* tested, assuming that `providerType` is "infura" (default: "mainnet").
* @param {string} [options.customRpcUrl] - The URL of the custom RPC endpoint,
* assuming that `providerType` is "custom".
* @param {WithMockedCommunicationsCallback} fn - A function which will be
* called with an object that allows interaction with the network client.
* @returns {Promise<any>} The return value of the given function.
* @param options - An options bag.
* @param options.providerType - The type of network client being tested.
* @param options.infuraNetwork - The name of the Infura network being tested,
* assuming that `providerType` is "infura" (default: "mainnet").
* @param options.customRpcUrl - The URL of the custom RPC endpoint, assuming
* that `providerType` is "custom".
* @param fn - A function which will be called with an object that allows
* interaction with the network client.
* @returns The return value of the given function.
*/
export async function withMockedCommunications(
{ providerType, infuraNetwork = 'mainnet', customRpcUrl = MOCK_RPC_URL },
fn,
{
providerType,
infuraNetwork = 'mainnet',
customRpcUrl = MOCK_RPC_URL,
}: MockOptions,
fn: (comms: MockCommunications) => Promise<void>,
) {
if (providerType !== 'infura' && providerType !== 'custom') {
throw new Error(
@ -274,11 +325,11 @@ export async function withMockedCommunications(
? `https://${infuraNetwork}.infura.io`
: customRpcUrl;
const nockScope = buildScopeForMockingRequests(rpcUrl);
const curriedMockNextBlockTrackerRequest = (localOptions) =>
const curriedMockNextBlockTrackerRequest = (localOptions: any) =>
mockNextBlockTrackerRequest({ nockScope, ...localOptions });
const curriedMockAllBlockTrackerRequests = (localOptions) =>
const curriedMockAllBlockTrackerRequests = (localOptions: any) =>
mockAllBlockTrackerRequests({ nockScope, ...localOptions });
const curriedMockRpcCall = (localOptions) =>
const curriedMockRpcCall = (localOptions: any) =>
mockRpcCall({ nockScope, ...localOptions });
const comms = {
@ -297,12 +348,12 @@ export async function withMockedCommunications(
}
}
/**
* @typedef {{blockTracker: import('eth-block-tracker').PollingBlockTracker, clock: sinon.SinonFakeTimers, makeRpcCall: (request: Partial<JsonRpcRequest>) => Promise<any>, makeRpcCallsInSeries: (requests: Partial<JsonRpcRequest>[]) => Promise<any>}} MockNetworkClient
*
* Provides methods to interact with the suite of middleware that
* `createInfuraClient` or `createJsonRpcClient` exposes.
*/
type MockNetworkClient = {
blockTracker: any;
clock: sinon.SinonFakeTimers;
makeRpcCall: (request: Request) => Promise<any>;
makeRpcCallsInSeries: (requests: Request[]) => Promise<any[]>;
};
/**
* Some middleware contain logic which retries the request if some condition
@ -321,14 +372,14 @@ export async function withMockedCommunications(
* `setTimeout` handler.
*/
export async function waitForPromiseToBeFulfilledAfterRunningAllTimers(
promise,
clock,
promise: any,
clock: any,
) {
let hasPromiseBeenFulfilled = false;
let numTimesClockHasBeenAdvanced = 0;
promise
.catch((error) => {
.catch((error: any) => {
// This is used to silence Node.js warnings about the rejection
// being handled asynchronously. The error is handled later when
// `promise` is awaited, but we log it here anyway in case it gets
@ -350,36 +401,22 @@ export async function waitForPromiseToBeFulfilledAfterRunningAllTimers(
return promise;
}
/**
* @typedef {{providerType: "infura" | "custom", infuraNetwork?: string, customRpcUrl?: string, customChainId?: string}} WithClientOptions
*
* The options bag that `withNetworkClient` takes.
*/
/**
* @typedef {(client: MockNetworkClient) => Promise<any>} WithClientCallback
*
* The callback that `withNetworkClient` takes.
*/
/**
* Builds a provider from the middleware (for the provider type) along with a
* block tracker, runs the given function with those two things, and then
* ensures the block tracker is stopped at the end.
*
* @param {WithClientOptions} options - An options bag.
* @param {"infura" | "custom"} options.providerType - The type of network
* client being tested.
* @param {string} [options.infuraNetwork] - The name of the Infura network being
* tested, assuming that `providerType` is "infura" (default: "mainnet").
* @param {string} [options.customRpcUrl] - The URL of the custom RPC endpoint,
* assuming that `providerType` is "custom".
* @param {string} [options.customChainId] - The chain id belonging to the
* custom RPC endpoint, assuming that `providerType` is "custom" (default:
* "0x1").
* @param {WithClientCallback} fn - A function which will be called with an
* object that allows interaction with the network client.
* @returns {Promise<any>} The return value of the given function.
* @param options - An options bag.
* @param options.providerType - The type of network client being tested.
* @param options.infuraNetwork - The name of the Infura network being tested,
* assuming that `providerType` is "infura" (default: "mainnet").
* @param options.customRpcUrl - The URL of the custom RPC endpoint, assuming
* that `providerType` is "custom".
* @param options.customChainId - The chain id belonging to the custom RPC
* endpoint, assuming that `providerType` is "custom" (default: "0x1").
* @param fn - A function which will be called with an object that allows
* interaction with the network client.
* @returns The return value of the given function.
*/
export async function withNetworkClient(
{
@ -387,8 +424,8 @@ export async function withNetworkClient(
infuraNetwork = 'mainnet',
customRpcUrl = MOCK_RPC_URL,
customChainId = '0x1',
},
fn,
}: MockOptions,
fn: (client: MockNetworkClient) => Promise<any>,
) {
if (providerType !== 'infura' && providerType !== 'custom') {
throw new Error(
@ -414,20 +451,21 @@ export async function withNetworkClient(
? createNetworkClient({
network: infuraNetwork,
infuraProjectId: MOCK_INFURA_PROJECT_ID,
type: 'infura',
type: NetworkClientType.Infura,
})
: createNetworkClient({
chainId: customChainId,
rpcUrl: customRpcUrl,
type: 'custom',
type: NetworkClientType.Custom,
});
process.env.IN_TEST = inTest;
const { provider, blockTracker } = clientUnderTest;
const ethQuery = new EthQuery(provider);
const curriedMakeRpcCall = (request) => makeRpcCall(ethQuery, request);
const makeRpcCallsInSeries = async (requests) => {
const curriedMakeRpcCall = (request: Request) =>
makeRpcCall(ethQuery, request);
const makeRpcCallsInSeries = async (requests: Request[]) => {
const responses = [];
for (const request of requests) {
responses.push(await curriedMakeRpcCall(request));
@ -451,6 +489,13 @@ export async function withNetworkClient(
}
}
type BuildMockParamsOptions = {
// The block parameter value to set.
blockParam: any;
// The index of the block parameter.
blockParamIndex: number;
};
/**
* Build mock parameters for a JSON-RPC call.
*
@ -460,16 +505,15 @@ export async function withNetworkClient(
* The block parameter can be set to a custom value. If no value is given, it
* is set as undefined.
*
* @param {object} args - Arguments.
* @param {number} args.blockParamIndex - The index of the block parameter.
* @param {any} [args.blockParam] - The block parameter value to set.
* @returns {any[]} The mock params.
* @param args - Arguments.
* @param args.blockParamIndex - The index of the block parameter.
* @param args.blockParam - The block parameter value to set.
* @returns The mock params.
*/
export function buildMockParams({ blockParam, blockParamIndex }) {
if (blockParamIndex === undefined) {
throw new Error(`Missing 'blockParamIndex'`);
}
export function buildMockParams({
blockParam,
blockParamIndex,
}: BuildMockParamsOptions) {
const params = new Array(blockParamIndex).fill('some value');
params[blockParamIndex] = blockParam;
@ -480,18 +524,18 @@ export function buildMockParams({ blockParam, blockParamIndex }) {
* Returns a partial JSON-RPC request object, with the "block" param replaced
* with the given value.
*
* @param {object} request - The request object.
* @param {string} request.method - The request method.
* @param {params} [request.params] - The request params.
* @param {number} blockParamIndex - The index within the `params` array of the
* block param.
* @param {any} blockParam - The desired block param value.
* @returns {object} The updated request object.
* @param request - The request object.
* @param request.method - The request method.
* @param request.params - The request params.
* @param blockParamIndex - The index within the `params` array of the block
* param.
* @param blockParam - The desired block param value.
* @returns The updated request object.
*/
export function buildRequestWithReplacedBlockParam(
{ method, params = [] },
blockParamIndex,
blockParam,
{ method, params = [] }: Request,
blockParamIndex: number,
blockParam: any,
) {
const updatedParams = params.slice();
updatedParams[blockParamIndex] = blockParam;

View File

@ -1,6 +1,7 @@
/* eslint-disable jest/require-top-level-describe, jest/no-export */
import {
ProviderType,
waitForPromiseToBeFulfilledAfterRunningAllTimers,
withMockedCommunications,
withNetworkClient,
@ -11,6 +12,11 @@ import {
buildJsonRpcEngineEmptyResponseErrorMessage,
} from './shared-tests';
type TestsForRpcMethodAssumingNoBlockParamOptions = {
providerType: ProviderType;
numberOfParameters: number;
};
/**
* Defines tests which exercise the behavior exhibited by an RPC method which is
* assumed to not take a block parameter. Even if it does, the value of this
@ -23,8 +29,11 @@ import {
* either `infura` or `custom` (default: "infura").
*/
export function testsForRpcMethodAssumingNoBlockParam(
method,
{ numberOfParameters, providerType },
method: string,
{
numberOfParameters,
providerType,
}: TestsForRpcMethodAssumingNoBlockParamOptions,
) {
if (providerType !== 'infura' && providerType !== 'custom') {
throw new Error(

View File

@ -1,7 +1,16 @@
/* eslint-disable jest/require-top-level-describe, jest/no-export */
import { fill } from 'lodash';
import { withMockedCommunications, withNetworkClient } from './helpers';
import {
ProviderType,
withMockedCommunications,
withNetworkClient,
} from './helpers';
type TestsForRpcMethodNotHandledByMiddlewareOptions = {
providerType: ProviderType;
numberOfParameters: number;
};
/**
* Defines tests which exercise the behavior exhibited by an RPC method that
@ -15,8 +24,11 @@ import { withMockedCommunications, withNetworkClient } from './helpers';
* RPC method takes.
*/
export function testsForRpcMethodNotHandledByMiddleware(
method,
{ providerType, numberOfParameters },
method: string,
{
providerType,
numberOfParameters,
}: TestsForRpcMethodNotHandledByMiddlewareOptions,
) {
if (providerType !== 'infura' && providerType !== 'custom') {
throw new Error(

View File

@ -2,7 +2,11 @@
import { testsForRpcMethodsThatCheckForBlockHashInResponse } from './block-hash-in-response';
import { testsForRpcMethodSupportingBlockParam } from './block-param';
import { withMockedCommunications, withNetworkClient } from './helpers';
import {
ProviderType,
withMockedCommunications,
withNetworkClient,
} from './helpers';
import { testsForRpcMethodAssumingNoBlockParam } from './no-block-param';
import { testsForRpcMethodNotHandledByMiddleware } from './not-handled-by-middleware';
@ -13,7 +17,7 @@ import { testsForRpcMethodNotHandledByMiddleware } from './not-handled-by-middle
* @param reason - The exact reason for failure.
* @returns The error message.
*/
export function buildInfuraClientRetriesExhaustedErrorMessage(reason) {
export function buildInfuraClientRetriesExhaustedErrorMessage(reason: string) {
return new RegExp(
`^InfuraProvider - cannot complete request. All retries exhausted\\..+${reason}`,
'us',
@ -27,7 +31,7 @@ export function buildInfuraClientRetriesExhaustedErrorMessage(reason) {
* @param method - The RPC method.
* @returns The error message.
*/
export function buildJsonRpcEngineEmptyResponseErrorMessage(method) {
export function buildJsonRpcEngineEmptyResponseErrorMessage(method: string) {
return new RegExp(
`^JsonRpcEngine: Response has no error or result for request:.+"method": "${method}"`,
'us',
@ -42,7 +46,7 @@ export function buildJsonRpcEngineEmptyResponseErrorMessage(method) {
* @param reason - The reason.
* @returns The error message.
*/
export function buildFetchFailedErrorMessage(url, reason) {
export function buildFetchFailedErrorMessage(url: string, reason: string) {
return new RegExp(
`^request to ${url}(/[^/ ]*)+ failed, reason: ${reason}`,
'us',
@ -57,7 +61,7 @@ export function buildFetchFailedErrorMessage(url, reason) {
* exposed by `createInfuraClient` is tested; if `custom`, then the middleware
* exposed by `createJsonRpcClient` will be tested.
*/
export function testsForProviderType(providerType) {
export function testsForProviderType(providerType: ProviderType) {
// Ethereum JSON-RPC spec: <https://ethereum.github.io/execution-apis/api-documentation/>
// Infura documentation: <https://docs.infura.io/infura/networks/ethereum/json-rpc-methods>

View File

@ -368,6 +368,7 @@
"@babel/preset-typescript": "^7.16.7",
"@babel/register": "^7.5.5",
"@ethersproject/bignumber": "^5.7.0",
"@json-rpc-specification/meta-schema": "^1.0.6",
"@lavamoat/allow-scripts": "^2.0.3",
"@lavamoat/lavapack": "^5.0.0",
"@metamask/auto-changelog": "^2.1.0",

View File

@ -3286,6 +3286,13 @@ __metadata:
languageName: node
linkType: hard
"@json-rpc-specification/meta-schema@npm:^1.0.6":
version: 1.0.6
resolution: "@json-rpc-specification/meta-schema@npm:1.0.6"
checksum: 2eb9c6c6c73bb38350c7180d1ad3c5b8462406926cae753741895b457d7b1b9f0b74148daf3462bb167cef39efdd1d9090308edf4d4938956863acb643c146eb
languageName: node
linkType: hard
"@keystonehq/base-eth-keyring@npm:^0.7.1":
version: 0.7.1
resolution: "@keystonehq/base-eth-keyring@npm:0.7.1"
@ -24143,6 +24150,7 @@ __metadata:
"@ethersproject/providers": ^5.7.2
"@formatjs/intl-relativetimeformat": ^5.2.6
"@fortawesome/fontawesome-free": ^5.13.0
"@json-rpc-specification/meta-schema": ^1.0.6
"@keystonehq/bc-ur-registry-eth": ^0.12.1
"@keystonehq/metamask-airgapped-keyring": ^0.6.1
"@lavamoat/allow-scripts": ^2.0.3