mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-11-22 09:57:02 +01:00
Expand network controller unit test coverage (#17498)
The network controller has some tests, but they are incomplete and don't follow our latest best practices for writing unit tests. This commit greatly increases the amount of test coverage for the API that we want to retain in NetworkController, in particular the seemingly myriad paths that the code takes starting from `initializeProvider`, `resetConnection`, `setRpcTarget`, `setProviderType`, `rollbackToPreviousProvider`, and `lookupNetwork`. There were a couple of pieces of logic I noted which don't seem to have any effect due to being redundant or unreachable, but they also don't make our lives more difficult, either, so I opted to leave them in. Co-authored-by: Mark Stacey <markjstacey@gmail.com> Co-authored-by: Zachary Belford <belfordz66@gmail.com>
This commit is contained in:
parent
53205b6bff
commit
7e97ff2be4
@ -125,7 +125,9 @@ export default class NetworkController extends EventEmitter {
|
|||||||
}
|
}
|
||||||
this._infuraProjectId = infuraProjectId;
|
this._infuraProjectId = infuraProjectId;
|
||||||
|
|
||||||
this.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, this.lookupNetwork);
|
this.on(NETWORK_EVENTS.NETWORK_DID_CHANGE, () => {
|
||||||
|
this.lookupNetwork();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -158,6 +160,8 @@ export default class NetworkController extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
async getEIP1559Compatibility() {
|
async getEIP1559Compatibility() {
|
||||||
const { EIPS } = this.networkDetails.getState();
|
const { EIPS } = this.networkDetails.getState();
|
||||||
|
// NOTE: This isn't necessary anymore because the block cache middleware
|
||||||
|
// already prevents duplicate requests from taking place
|
||||||
if (EIPS[1559] !== undefined) {
|
if (EIPS[1559] !== undefined) {
|
||||||
return EIPS[1559];
|
return EIPS[1559];
|
||||||
}
|
}
|
||||||
@ -185,6 +189,9 @@ export default class NetworkController extends EventEmitter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: This will never happen in practice because you can't pass null or
|
||||||
|
// undefined for chainId to setRpcTarget, and all of the known networks have
|
||||||
|
// a chain ID
|
||||||
const chainId = this.getCurrentChainId();
|
const chainId = this.getCurrentChainId();
|
||||||
if (!chainId) {
|
if (!chainId) {
|
||||||
log.warn(
|
log.warn(
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,80 @@ jest.mock('webextension-polyfill', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const UNRESOLVED = Symbol('timedOut');
|
||||||
|
|
||||||
|
// Store this in case it gets stubbed later
|
||||||
|
const originalSetTimeout = global.setTimeout;
|
||||||
|
|
||||||
|
const TIME_TO_WAIT_UNTIL_UNRESOLVED = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Produces a sort of dummy promise which can be used in conjunction with a
|
||||||
|
* "real" promise to determine whether the "real" promise was ever resolved. If
|
||||||
|
* the promise that is produced by this function resolves first, then the other
|
||||||
|
* one must be unresolved.
|
||||||
|
*
|
||||||
|
* @param {number} duration - How long to wait before resolving the promise returned by
|
||||||
|
* this function.
|
||||||
|
* @returns A promise that resolves to a symbol.
|
||||||
|
*/
|
||||||
|
function treatUnresolvedAfter(duration) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
originalSetTimeout(resolve, duration, UNRESOLVED);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* eslint-disable-next-line jest/require-top-level-describe */
|
/* eslint-disable-next-line jest/require-top-level-describe */
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
nock.cleanAll();
|
nock.cleanAll();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
expect.extend({
|
||||||
|
/**
|
||||||
|
* Tests that the given promise is never fulfilled or rejected past a certain
|
||||||
|
* amount of time (which is the default time that Jest tests wait before
|
||||||
|
* timing out as configured in the Jest configuration file).
|
||||||
|
*
|
||||||
|
* Inspired by <https://stackoverflow.com/a/68409467/260771>.
|
||||||
|
*
|
||||||
|
* @param {Promise<any>} promise - The promise to test.
|
||||||
|
* @returns The result of the matcher.
|
||||||
|
*/
|
||||||
|
async toNeverResolve(promise) {
|
||||||
|
if (this.isNot) {
|
||||||
|
throw new Error(
|
||||||
|
'Using `.not.toNeverResolve(...)` is not supported. ' +
|
||||||
|
'You probably want to either `await` the promise and test its ' +
|
||||||
|
'resolution value or use `.rejects` to test its rejection value instead.',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let resolutionValue;
|
||||||
|
let rejectionValue;
|
||||||
|
try {
|
||||||
|
resolutionValue = await Promise.race([
|
||||||
|
promise,
|
||||||
|
treatUnresolvedAfter(TIME_TO_WAIT_UNTIL_UNRESOLVED),
|
||||||
|
]);
|
||||||
|
} catch (e) {
|
||||||
|
rejectionValue = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolutionValue === UNRESOLVED
|
||||||
|
? {
|
||||||
|
message: () =>
|
||||||
|
`Expected promise to resolve after ${TIME_TO_WAIT_UNTIL_UNRESOLVED}ms, but it did not`,
|
||||||
|
pass: true,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
message: () => {
|
||||||
|
return `Expected promise to never resolve after ${TIME_TO_WAIT_UNTIL_UNRESOLVED}ms, but it ${
|
||||||
|
rejectionValue
|
||||||
|
? `was rejected with ${rejectionValue}`
|
||||||
|
: `resolved with ${resolutionValue}`
|
||||||
|
}`;
|
||||||
|
},
|
||||||
|
pass: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user