1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Jestify app/scripts/lib/**/*.test.js (#12890)

* Jestify app/scripts/lib/*.test.js

* Mocha config on mocha test script

* Add app/scripts/lib to include subdirs
This commit is contained in:
Thomas Huang 2021-12-06 10:40:39 -06:00 committed by GitHub
parent 6fc9b6b7a2
commit d78cfebd43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 356 additions and 460 deletions

View File

@ -138,6 +138,7 @@ module.exports = {
'development/**/*.test.js', 'development/**/*.test.js',
'app/scripts/migrations/*.test.js', 'app/scripts/migrations/*.test.js',
'app/scripts/platforms/*.test.js', 'app/scripts/platforms/*.test.js',
'app/scripts/lib/**/*.test.js',
], ],
extends: ['@metamask/eslint-config-mocha'], extends: ['@metamask/eslint-config-mocha'],
rules: { rules: {
@ -162,6 +163,7 @@ module.exports = {
'development/**/*.test.js', 'development/**/*.test.js',
'app/scripts/migrations/*.test.js', 'app/scripts/migrations/*.test.js',
'app/scripts/platforms/*.test.js', 'app/scripts/platforms/*.test.js',
'app/scripts/lib/**/*.test.js',
], ],
extends: ['@metamask/eslint-config-jest'], extends: ['@metamask/eslint-config-jest'],
rules: { rules: {

View File

@ -1,7 +1,11 @@
module.exports = { module.exports = {
// TODO: Remove the `exit` setting, it can hide broken tests. // TODO: Remove the `exit` setting, it can hide broken tests.
exit: true, exit: true,
ignore: ['./app/scripts/migrations/*.test.js', './app/scripts/platforms/*.test.js'], ignore: [
'./app/scripts/migrations/*.test.js',
'./app/scripts/platforms/*.test.js',
'./app/scripts/lib/**/*.test.js',
],
recursive: true, recursive: true,
require: ['test/env.js', 'test/setup.js'], require: ['test/env.js', 'test/setup.js'],
} }

View File

@ -1,4 +1,3 @@
import { strict as assert } from 'assert';
import { ObservableStore } from '@metamask/obs-store'; import { ObservableStore } from '@metamask/obs-store';
import { import {
BaseController, BaseController,
@ -48,17 +47,17 @@ class ExampleController extends BaseControllerV2 {
} }
} }
describe('ComposableObservableStore', function () { describe('ComposableObservableStore', () => {
it('should register initial state', function () { it('should register initial state', () => {
const controllerMessenger = new ControllerMessenger(); const controllerMessenger = new ControllerMessenger();
const store = new ComposableObservableStore({ const store = new ComposableObservableStore({
controllerMessenger, controllerMessenger,
state: 'state', state: 'state',
}); });
assert.strictEqual(store.getState(), 'state'); expect(store.getState()).toStrictEqual('state');
}); });
it('should register initial structure', function () { it('should register initial structure', () => {
const controllerMessenger = new ControllerMessenger(); const controllerMessenger = new ControllerMessenger();
const testStore = new ObservableStore(); const testStore = new ObservableStore();
const store = new ComposableObservableStore({ const store = new ComposableObservableStore({
@ -66,28 +65,28 @@ describe('ComposableObservableStore', function () {
controllerMessenger, controllerMessenger,
}); });
testStore.putState('state'); testStore.putState('state');
assert.deepEqual(store.getState(), { TestStore: 'state' }); expect(store.getState()).toStrictEqual({ TestStore: 'state' });
}); });
it('should update structure with observable store', function () { it('should update structure with observable store', () => {
const controllerMessenger = new ControllerMessenger(); const controllerMessenger = new ControllerMessenger();
const testStore = new ObservableStore(); const testStore = new ObservableStore();
const store = new ComposableObservableStore({ controllerMessenger }); const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({ TestStore: testStore }); store.updateStructure({ TestStore: testStore });
testStore.putState('state'); testStore.putState('state');
assert.deepEqual(store.getState(), { TestStore: 'state' }); expect(store.getState()).toStrictEqual({ TestStore: 'state' });
}); });
it('should update structure with BaseController-based controller', function () { it('should update structure with BaseController-based controller', () => {
const controllerMessenger = new ControllerMessenger(); const controllerMessenger = new ControllerMessenger();
const oldExampleController = new OldExampleController(); const oldExampleController = new OldExampleController();
const store = new ComposableObservableStore({ controllerMessenger }); const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({ OldExample: oldExampleController }); store.updateStructure({ OldExample: oldExampleController });
oldExampleController.updateBaz('state'); oldExampleController.updateBaz('state');
assert.deepEqual(store.getState(), { OldExample: { baz: 'state' } }); expect(store.getState()).toStrictEqual({ OldExample: { baz: 'state' } });
}); });
it('should update structure with BaseControllerV2-based controller', function () { it('should update structure with BaseControllerV2-based controller', () => {
const controllerMessenger = new ControllerMessenger(); const controllerMessenger = new ControllerMessenger();
const exampleController = new ExampleController({ const exampleController = new ExampleController({
messenger: controllerMessenger, messenger: controllerMessenger,
@ -95,11 +94,10 @@ describe('ComposableObservableStore', function () {
const store = new ComposableObservableStore({ controllerMessenger }); const store = new ComposableObservableStore({ controllerMessenger });
store.updateStructure({ Example: exampleController }); store.updateStructure({ Example: exampleController });
exampleController.updateBar('state'); exampleController.updateBar('state');
console.log(exampleController.state); expect(store.getState()).toStrictEqual({ Example: { bar: 'state' } });
assert.deepEqual(store.getState(), { Example: { bar: 'state' } });
}); });
it('should update structure with all three types of stores', function () { it('should update structure with all three types of stores', () => {
const controllerMessenger = new ControllerMessenger(); const controllerMessenger = new ControllerMessenger();
const exampleStore = new ObservableStore(); const exampleStore = new ObservableStore();
const exampleController = new ExampleController({ const exampleController = new ExampleController({
@ -115,14 +113,14 @@ describe('ComposableObservableStore', function () {
exampleStore.putState('state'); exampleStore.putState('state');
exampleController.updateBar('state'); exampleController.updateBar('state');
oldExampleController.updateBaz('state'); oldExampleController.updateBaz('state');
assert.deepEqual(store.getState(), { expect(store.getState()).toStrictEqual({
Example: { bar: 'state' }, Example: { bar: 'state' },
OldExample: { baz: 'state' }, OldExample: { baz: 'state' },
Store: 'state', Store: 'state',
}); });
}); });
it('should return flattened state', function () { it('should return flattened state', () => {
const controllerMessenger = new ControllerMessenger(); const controllerMessenger = new ControllerMessenger();
const fooStore = new ObservableStore({ foo: 'foo' }); const fooStore = new ObservableStore({ foo: 'foo' });
const barController = new ExampleController({ const barController = new ExampleController({
@ -142,46 +140,48 @@ describe('ComposableObservableStore', function () {
BazStore: bazController.state, BazStore: bazController.state,
}, },
}); });
assert.deepEqual(store.getFlatState(), { expect(store.getFlatState()).toStrictEqual({
foo: 'foo', foo: 'foo',
bar: 'bar', bar: 'bar',
baz: 'baz', baz: 'baz',
}); });
}); });
it('should return empty flattened state when not configured', function () { it('should return empty flattened state when not configured', () => {
const controllerMessenger = new ControllerMessenger(); const controllerMessenger = new ControllerMessenger();
const store = new ComposableObservableStore({ controllerMessenger }); const store = new ComposableObservableStore({ controllerMessenger });
assert.deepEqual(store.getFlatState(), {}); expect(store.getFlatState()).toStrictEqual({});
}); });
it('should throw if the controller messenger is omitted and the config includes a BaseControllerV2 controller', function () { it('should throw if the controller messenger is omitted and the config includes a BaseControllerV2 controller', () => {
const controllerMessenger = new ControllerMessenger(); const controllerMessenger = new ControllerMessenger();
const exampleController = new ExampleController({ const exampleController = new ExampleController({
messenger: controllerMessenger, messenger: controllerMessenger,
}); });
assert.throws( expect(
() => () =>
new ComposableObservableStore({ new ComposableObservableStore({
config: { config: {
Example: exampleController, Example: exampleController,
}, },
}), }),
); ).toThrow(`Cannot read property 'subscribe' of undefined`);
}); });
it('should throw if the controller messenger is omitted and updateStructure called with a BaseControllerV2 controller', function () { it('should throw if the controller messenger is omitted and updateStructure called with a BaseControllerV2 controller', () => {
const controllerMessenger = new ControllerMessenger(); const controllerMessenger = new ControllerMessenger();
const exampleController = new ExampleController({ const exampleController = new ExampleController({
messenger: controllerMessenger, messenger: controllerMessenger,
}); });
const store = new ComposableObservableStore({}); const store = new ComposableObservableStore({});
assert.throws(() => store.updateStructure({ Example: exampleController })); expect(() => store.updateStructure({ Example: exampleController })).toThrow(
`Cannot read property 'subscribe' of undefined`,
);
}); });
it('should throw if initialized with undefined config entry', function () { it('should throw if initialized with undefined config entry', () => {
const controllerMessenger = new ControllerMessenger(); const controllerMessenger = new ControllerMessenger();
assert.throws( expect(
() => () =>
new ComposableObservableStore({ new ComposableObservableStore({
config: { config: {
@ -189,6 +189,6 @@ describe('ComposableObservableStore', function () {
}, },
controllerMessenger, controllerMessenger,
}), }),
); ).toThrow(`Undefined 'Example'`);
}); });
}); });

View File

@ -1,4 +1,3 @@
import { strict as assert } from 'assert';
import nock from 'nock'; import nock from 'nock';
import { import {
KOVAN_CHAIN_ID, KOVAN_CHAIN_ID,
@ -27,8 +26,8 @@ const KOVAN = {
chainId: KOVAN_CHAIN_ID, chainId: KOVAN_CHAIN_ID,
}; };
describe('buy-eth-url', function () { describe('buy-eth-url', () => {
it('returns Wyre url with an ETH address for Ethereum mainnet', async function () { it('returns Wyre url with an ETH address for Ethereum mainnet', async () => {
nock(SWAPS_API_V2_BASE_URL) nock(SWAPS_API_V2_BASE_URL)
.get( .get(
`/networks/1/fiatOnRampUrl?serviceName=wyre&destinationAddress=${ETH_ADDRESS}`, `/networks/1/fiatOnRampUrl?serviceName=wyre&destinationAddress=${ETH_ADDRESS}`,
@ -37,43 +36,40 @@ describe('buy-eth-url', function () {
url: `https://pay.sendwyre.com/purchase?accountId=${WYRE_ACCOUNT_ID}&utm_campaign=${WYRE_ACCOUNT_ID}&destCurrency=ETH&utm_medium=widget&paymentMethod=debit-card&reservation=MLZVUF8FMXZUMARJC23B&dest=ethereum%3A${ETH_ADDRESS}&utm_source=checkout`, url: `https://pay.sendwyre.com/purchase?accountId=${WYRE_ACCOUNT_ID}&utm_campaign=${WYRE_ACCOUNT_ID}&destCurrency=ETH&utm_medium=widget&paymentMethod=debit-card&reservation=MLZVUF8FMXZUMARJC23B&dest=ethereum%3A${ETH_ADDRESS}&utm_source=checkout`,
}); });
const wyreUrl = await getBuyEthUrl(MAINNET); const wyreUrl = await getBuyEthUrl(MAINNET);
assert.equal( expect(wyreUrl).toStrictEqual(
wyreUrl,
`https://pay.sendwyre.com/purchase?accountId=${WYRE_ACCOUNT_ID}&utm_campaign=${WYRE_ACCOUNT_ID}&destCurrency=ETH&utm_medium=widget&paymentMethod=debit-card&reservation=MLZVUF8FMXZUMARJC23B&dest=ethereum%3A${ETH_ADDRESS}&utm_source=checkout`, `https://pay.sendwyre.com/purchase?accountId=${WYRE_ACCOUNT_ID}&utm_campaign=${WYRE_ACCOUNT_ID}&destCurrency=ETH&utm_medium=widget&paymentMethod=debit-card&reservation=MLZVUF8FMXZUMARJC23B&dest=ethereum%3A${ETH_ADDRESS}&utm_source=checkout`,
); );
nock.cleanAll(); nock.cleanAll();
}); });
it('returns a fallback Wyre url if /orders/reserve API call fails', async function () { it('returns a fallback Wyre url if /orders/reserve API call fails', async () => {
const wyreUrl = await getBuyEthUrl(MAINNET); const wyreUrl = await getBuyEthUrl(MAINNET);
assert.equal( expect(wyreUrl).toStrictEqual(
wyreUrl,
`https://pay.sendwyre.com/purchase?dest=ethereum:${ETH_ADDRESS}&destCurrency=ETH&accountId=${WYRE_ACCOUNT_ID}&paymentMethod=debit-card`, `https://pay.sendwyre.com/purchase?dest=ethereum:${ETH_ADDRESS}&destCurrency=ETH&accountId=${WYRE_ACCOUNT_ID}&paymentMethod=debit-card`,
); );
}); });
it('returns Transak url with an ETH address for Ethereum mainnet', async function () { it('returns Transak url with an ETH address for Ethereum mainnet', async () => {
const transakUrl = await getBuyEthUrl({ ...MAINNET, service: 'transak' }); const transakUrl = await getBuyEthUrl({ ...MAINNET, service: 'transak' });
assert.equal( expect(transakUrl).toStrictEqual(
transakUrl,
`https://global.transak.com/?apiKey=${TRANSAK_API_KEY}&hostURL=https%3A%2F%2Fmetamask.io&defaultCryptoCurrency=ETH&walletAddress=${ETH_ADDRESS}`, `https://global.transak.com/?apiKey=${TRANSAK_API_KEY}&hostURL=https%3A%2F%2Fmetamask.io&defaultCryptoCurrency=ETH&walletAddress=${ETH_ADDRESS}`,
); );
}); });
it('returns metamask ropsten faucet for network 3', async function () { it('returns metamask ropsten faucet for network 3', async () => {
const ropstenUrl = await getBuyEthUrl(ROPSTEN); const ropstenUrl = await getBuyEthUrl(ROPSTEN);
assert.equal(ropstenUrl, 'https://faucet.metamask.io/'); expect(ropstenUrl).toStrictEqual('https://faucet.metamask.io/');
}); });
it('returns rinkeby dapp for network 4', async function () { it('returns rinkeby dapp for network 4', async () => {
const rinkebyUrl = await getBuyEthUrl(RINKEBY); const rinkebyUrl = await getBuyEthUrl(RINKEBY);
assert.equal(rinkebyUrl, 'https://www.rinkeby.io/'); expect(rinkebyUrl).toStrictEqual('https://www.rinkeby.io/');
}); });
it('returns kovan github test faucet for network 42', async function () { it('returns kovan github test faucet for network 42', async () => {
const kovanUrl = await getBuyEthUrl(KOVAN); const kovanUrl = await getBuyEthUrl(KOVAN);
assert.equal(kovanUrl, 'https://github.com/kovan-testnet/faucet'); expect(kovanUrl).toStrictEqual('https://github.com/kovan-testnet/faucet');
}); });
}); });

View File

@ -1,34 +1,36 @@
import { strict as assert } from 'assert';
import cleanErrorStack from './cleanErrorStack'; import cleanErrorStack from './cleanErrorStack';
describe('Clean Error Stack', function () { describe('Clean Error Stack', () => {
const testMessage = 'Test Message'; const testMessage = 'Test Message';
const testError = new Error(testMessage); const testError = new Error(testMessage);
const undefinedErrorName = new Error(testMessage); const undefinedErrorName = new Error(testMessage);
const blankErrorName = new Error(testMessage); const blankErrorName = new Error(testMessage);
const blankMsgError = new Error(); const blankMsgError = new Error();
beforeEach(function () { beforeEach(() => {
undefinedErrorName.name = undefined; undefinedErrorName.name = undefined;
blankErrorName.name = ''; blankErrorName.name = '';
}); });
it('tests error with message', function () { it('tests error with message', () => {
assert.equal(cleanErrorStack(testError).toString(), 'Error: Test Message'); expect(cleanErrorStack(testError).toString()).toStrictEqual(
});
it('tests error with undefined name', function () {
assert.equal(
cleanErrorStack(undefinedErrorName).toString(),
'Error: Test Message', 'Error: Test Message',
); );
}); });
it('tests error with blank name', function () { it('tests error with undefined name', () => {
assert.equal(cleanErrorStack(blankErrorName).toString(), 'Test Message'); expect(cleanErrorStack(undefinedErrorName).toString()).toStrictEqual(
'Error: Test Message',
);
}); });
it('tests error with blank message', function () { it('tests error with blank name', () => {
assert.equal(cleanErrorStack(blankMsgError).toString(), 'Error'); expect(cleanErrorStack(blankErrorName).toString()).toStrictEqual(
'Test Message',
);
});
it('tests error with blank message', () => {
expect(cleanErrorStack(blankMsgError).toString()).toStrictEqual('Error');
}); });
}); });

View File

@ -1,13 +1,11 @@
import { strict as assert } from 'assert';
import { obj as createThoughStream } from 'through2'; import { obj as createThoughStream } from 'through2';
import createMetaRPCHandler from './createMetaRPCHandler'; import createMetaRPCHandler from './createMetaRPCHandler';
describe('createMetaRPCHandler', function () { describe('createMetaRPCHandler', () => {
it('can call the api when handler receives a JSON-RPC request', function (done) { it('can call the api when handler receives a JSON-RPC request', () => {
const api = { const api = {
foo: (param1) => { foo: (param1) => {
assert.strictEqual(param1, 'bar'); expect(param1).toStrictEqual('bar');
done();
}, },
}; };
const streamTest = createThoughStream(); const streamTest = createThoughStream();
@ -18,10 +16,10 @@ describe('createMetaRPCHandler', function () {
params: ['bar'], params: ['bar'],
}); });
}); });
it('can write the response to the outstream when api callback is called', function (done) { it('can write the response to the outstream when api callback is called', () => {
const api = { const api = {
foo: (param1, cb) => { foo: (param1, cb) => {
assert.strictEqual(param1, 'bar'); expect(param1).toStrictEqual('bar');
cb(null, 'foobarbaz'); cb(null, 'foobarbaz');
}, },
}; };
@ -33,15 +31,14 @@ describe('createMetaRPCHandler', function () {
params: ['bar'], params: ['bar'],
}); });
streamTest.on('data', (data) => { streamTest.on('data', (data) => {
assert.strictEqual(data.result, 'foobarbaz'); expect(data.result).toStrictEqual('foobarbaz');
streamTest.end(); streamTest.end();
done();
}); });
}); });
it('can write the error to the outstream when api callback is called with an error', function (done) { it('can write the error to the outstream when api callback is called with an error', () => {
const api = { const api = {
foo: (param1, cb) => { foo: (param1, cb) => {
assert.strictEqual(param1, 'bar'); expect(param1).toStrictEqual('bar');
cb(new Error('foo-error')); cb(new Error('foo-error'));
}, },
}; };
@ -53,32 +50,32 @@ describe('createMetaRPCHandler', function () {
params: ['bar'], params: ['bar'],
}); });
streamTest.on('data', (data) => { streamTest.on('data', (data) => {
assert.strictEqual(data.error.message, 'foo-error'); expect(data.error.message).toStrictEqual('foo-error');
streamTest.end(); streamTest.end();
done();
}); });
}); });
it('can not throw an error for writing an error after end', function (done) { it('can not throw an error for writing an error after end', () => {
const api = { const api = {
foo: (param1, cb) => { foo: (param1, cb) => {
assert.strictEqual(param1, 'bar'); expect(param1).toStrictEqual('bar');
cb(new Error('foo-error')); cb(new Error('foo-error'));
}, },
}; };
const streamTest = createThoughStream(); const streamTest = createThoughStream();
const handler = createMetaRPCHandler(api, streamTest); const handler = createMetaRPCHandler(api, streamTest);
streamTest.end(); streamTest.end();
handler({ expect(() => {
id: 1, handler({
method: 'foo', id: 1,
params: ['bar'], method: 'foo',
}); params: ['bar'],
done(); });
}).not.toThrow();
}); });
it('can not throw an error for write after end', function (done) { it('can not throw an error for write after end', () => {
const api = { const api = {
foo: (param1, cb) => { foo: (param1, cb) => {
assert.strictEqual(param1, 'bar'); expect(param1).toStrictEqual('bar');
cb(undefined, { cb(undefined, {
foo: 'bar', foo: 'bar',
}); });
@ -87,11 +84,12 @@ describe('createMetaRPCHandler', function () {
const streamTest = createThoughStream(); const streamTest = createThoughStream();
const handler = createMetaRPCHandler(api, streamTest); const handler = createMetaRPCHandler(api, streamTest);
streamTest.end(); streamTest.end();
handler({ expect(() => {
id: 1, handler({
method: 'foo', id: 1,
params: ['bar'], method: 'foo',
}); params: ['bar'],
done(); });
}).not.toThrow();
}); });
}); });

View File

@ -1,27 +1,25 @@
import { strict as assert } from 'assert';
import sinon from 'sinon';
import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction';
import MessageManager from './message-manager'; import MessageManager from './message-manager';
describe('Message Manager', function () { describe('Message Manager', () => {
let messageManager; let messageManager;
beforeEach(function () { beforeEach(() => {
messageManager = new MessageManager({ messageManager = new MessageManager({
metricsEvent: sinon.fake(), metricsEvent: jest.fn(),
}); });
}); });
describe('#getMsgList', function () { describe('#getMsgList', () => {
it('when new should return empty array', function () { it('when new should return empty array', () => {
const result = messageManager.messages; const result = messageManager.messages;
assert.ok(Array.isArray(result)); expect(Array.isArray(result)).toStrictEqual(true);
assert.equal(result.length, 0); expect(result).toHaveLength(0);
}); });
}); });
describe('#addMsg', function () { describe('#addMsg', () => {
it('adds a Msg returned in getMsgList', function () { it('adds a Msg returned in getMsgList', () => {
const Msg = { const Msg = {
id: 1, id: 1,
status: TRANSACTION_STATUSES.APPROVED, status: TRANSACTION_STATUSES.APPROVED,
@ -29,14 +27,14 @@ describe('Message Manager', function () {
}; };
messageManager.addMsg(Msg); messageManager.addMsg(Msg);
const result = messageManager.messages; const result = messageManager.messages;
assert.ok(Array.isArray(result)); expect(Array.isArray(result)).toStrictEqual(true);
assert.equal(result.length, 1); expect(result).toHaveLength(1);
assert.equal(result[0].id, 1); expect(result[0].id).toStrictEqual(1);
}); });
}); });
describe('#setMsgStatusApproved', function () { describe('#setMsgStatusApproved', () => {
it('sets the Msg status to approved', function () { it('sets the Msg status to approved', () => {
const Msg = { const Msg = {
id: 1, id: 1,
status: 'unapproved', status: 'unapproved',
@ -45,14 +43,14 @@ describe('Message Manager', function () {
messageManager.addMsg(Msg); messageManager.addMsg(Msg);
messageManager.setMsgStatusApproved(1); messageManager.setMsgStatusApproved(1);
const result = messageManager.messages; const result = messageManager.messages;
assert.ok(Array.isArray(result)); expect(Array.isArray(result)).toStrictEqual(true);
assert.equal(result.length, 1); expect(result).toHaveLength(1);
assert.equal(result[0].status, TRANSACTION_STATUSES.APPROVED); expect(result[0].status).toStrictEqual(TRANSACTION_STATUSES.APPROVED);
}); });
}); });
describe('#rejectMsg', function () { describe('#rejectMsg', () => {
it('sets the Msg status to rejected', function () { it('sets the Msg status to rejected', () => {
const Msg = { const Msg = {
id: 1, id: 1,
status: 'unapproved', status: 'unapproved',
@ -61,14 +59,14 @@ describe('Message Manager', function () {
messageManager.addMsg(Msg); messageManager.addMsg(Msg);
messageManager.rejectMsg(1); messageManager.rejectMsg(1);
const result = messageManager.messages; const result = messageManager.messages;
assert.ok(Array.isArray(result)); expect(Array.isArray(result)).toStrictEqual(true);
assert.equal(result.length, 1); expect(result).toHaveLength(1);
assert.equal(result[0].status, TRANSACTION_STATUSES.REJECTED); expect(result[0].status).toStrictEqual(TRANSACTION_STATUSES.REJECTED);
}); });
}); });
describe('#_updateMsg', function () { describe('#_updateMsg', () => {
it('replaces the Msg with the same id', function () { it('replaces the Msg with the same id', () => {
messageManager.addMsg({ messageManager.addMsg({
id: '1', id: '1',
status: 'unapproved', status: 'unapproved',
@ -86,12 +84,12 @@ describe('Message Manager', function () {
metamaskNetworkId: 'unit test', metamaskNetworkId: 'unit test',
}); });
const result = messageManager.getMsg('1'); const result = messageManager.getMsg('1');
assert.equal(result.hash, 'foo'); expect(result.hash).toStrictEqual('foo');
}); });
}); });
describe('#getUnapprovedMsgs', function () { describe('#getUnapprovedMsgs', () => {
it('returns unapproved Msgs in a hash', function () { it('returns unapproved Msgs in a hash', () => {
messageManager.addMsg({ messageManager.addMsg({
id: '1', id: '1',
status: 'unapproved', status: 'unapproved',
@ -103,14 +101,14 @@ describe('Message Manager', function () {
metamaskNetworkId: 'unit test', metamaskNetworkId: 'unit test',
}); });
const result = messageManager.getUnapprovedMsgs(); const result = messageManager.getUnapprovedMsgs();
assert.equal(typeof result, 'object'); expect(typeof result).toStrictEqual('object');
assert.equal(result['1'].status, 'unapproved'); expect(result['1'].status).toStrictEqual('unapproved');
assert.equal(result['2'], undefined); expect(result['2']).toBeUndefined();
}); });
}); });
describe('#getMsg', function () { describe('#getMsg', () => {
it('returns a Msg with the requested id', function () { it('returns a Msg with the requested id', () => {
messageManager.addMsg({ messageManager.addMsg({
id: '1', id: '1',
status: 'unapproved', status: 'unapproved',
@ -121,9 +119,8 @@ describe('Message Manager', function () {
status: TRANSACTION_STATUSES.APPROVED, status: TRANSACTION_STATUSES.APPROVED,
metamaskNetworkId: 'unit test', metamaskNetworkId: 'unit test',
}); });
assert.equal(messageManager.getMsg('1').status, 'unapproved'); expect(messageManager.getMsg('1').status).toStrictEqual('unapproved');
assert.equal( expect(messageManager.getMsg('2').status).toStrictEqual(
messageManager.getMsg('2').status,
TRANSACTION_STATUSES.APPROVED, TRANSACTION_STATUSES.APPROVED,
); );
}); });

View File

@ -1,24 +1,21 @@
import { strict as assert } from 'assert';
import { obj as createThoughStream } from 'through2'; import { obj as createThoughStream } from 'through2';
import metaRPCClientFactory from './metaRPCClientFactory'; import metaRPCClientFactory from './metaRPCClientFactory';
describe('metaRPCClientFactory', function () { describe('metaRPCClientFactory', () => {
it('should be able to make an rpc request with the method', function (done) { it('should be able to make an rpc request with the method', () => {
const streamTest = createThoughStream((chunk) => { const streamTest = createThoughStream((chunk) => {
assert.strictEqual(chunk.method, 'foo'); expect(chunk.method).toStrictEqual('foo');
done();
}); });
const metaRPCClient = metaRPCClientFactory(streamTest); const metaRPCClient = metaRPCClientFactory(streamTest);
metaRPCClient.foo(); metaRPCClient.foo();
}); });
it('should be able to make an rpc request/response with the method and params and node-style callback', function (done) { it('should be able to make an rpc request/response with the method and params and node-style callback', () => {
const streamTest = createThoughStream(); const streamTest = createThoughStream();
const metaRPCClient = metaRPCClientFactory(streamTest); const metaRPCClient = metaRPCClientFactory(streamTest);
// make a "foo" method call // make a "foo" method call
metaRPCClient.foo('bar', (_, result) => { metaRPCClient.foo('bar', (_, result) => {
assert.strictEqual(result, 'foobarbaz'); expect(result).toStrictEqual('foobarbaz');
done();
}); });
// fake a response // fake a response
@ -30,15 +27,14 @@ describe('metaRPCClientFactory', function () {
}); });
}); });
}); });
it('should be able to make an rpc request/error with the method and params and node-style callback', function (done) { it('should be able to make an rpc request/error with the method and params and node-style callback', () => {
const streamTest = createThoughStream(); const streamTest = createThoughStream();
const metaRPCClient = metaRPCClientFactory(streamTest); const metaRPCClient = metaRPCClientFactory(streamTest);
// make a "foo" method call // make a "foo" method call
metaRPCClient.foo('bar', (err) => { metaRPCClient.foo('bar', (err) => {
assert.strictEqual(err.message, 'foo-message'); expect(err.message).toStrictEqual('foo-message');
assert.strictEqual(err.code, 1); expect(err.code).toStrictEqual(1);
done();
}); });
metaRPCClient.requests.forEach((_, key) => { metaRPCClient.requests.forEach((_, key) => {
@ -53,17 +49,16 @@ describe('metaRPCClientFactory', function () {
}); });
}); });
it('should be able to make an rpc request/response with the method and params and node-style callback with multiple instances of metaRPCClientFactory and the same connectionStream', function (done) { it('should be able to make an rpc request/response with the method and params and node-style callback with multiple instances of metaRPCClientFactory and the same connectionStream', () => {
const streamTest = createThoughStream(); const streamTest = createThoughStream();
const metaRPCClient = metaRPCClientFactory(streamTest); const metaRPCClient = metaRPCClientFactory(streamTest);
const metaRPCClient2 = metaRPCClientFactory(streamTest); const metaRPCClient2 = metaRPCClientFactory(streamTest);
// make a "foo" method call, followed by "baz" call on metaRPCClient2 // make a "foo" method call, followed by "baz" call on metaRPCClient2
metaRPCClient.foo('bar', (_, result) => { metaRPCClient.foo('bar', (_, result) => {
assert.strictEqual(result, 'foobarbaz'); expect(result).toStrictEqual('foobarbaz');
metaRPCClient2.baz('bar', (err) => { metaRPCClient2.baz('bar', (err) => {
assert.strictEqual(err, null); expect(err).toBeNull();
done();
}); });
}); });
@ -86,13 +81,12 @@ describe('metaRPCClientFactory', function () {
}); });
}); });
it('should be able to handle notifications', function (done) { it('should be able to handle notifications', () => {
const streamTest = createThoughStream(); const streamTest = createThoughStream();
const metaRPCClient = metaRPCClientFactory(streamTest); const metaRPCClient = metaRPCClientFactory(streamTest);
metaRPCClient.onNotification((notification) => { metaRPCClient.onNotification((notification) => {
assert(notification.method, 'foobarbaz'); expect(notification.method).toStrictEqual('foobarbaz');
done();
}); });
// send a notification // send a notification
@ -103,13 +97,12 @@ describe('metaRPCClientFactory', function () {
}); });
}); });
it('should be able to handle errors with no id', function (done) { it('should be able to handle errors with no id', () => {
const streamTest = createThoughStream(); const streamTest = createThoughStream();
const metaRPCClient = metaRPCClientFactory(streamTest); const metaRPCClient = metaRPCClientFactory(streamTest);
metaRPCClient.onUncaughtError((error) => { metaRPCClient.onUncaughtError((error) => {
assert(error.code, 1); expect(error.code).toStrictEqual(1);
done();
}); });
streamTest.write({ streamTest.write({
@ -121,13 +114,12 @@ describe('metaRPCClientFactory', function () {
}); });
}); });
it('should be able to handle errors with null id', function (done) { it('should be able to handle errors with null id', () => {
const streamTest = createThoughStream(); const streamTest = createThoughStream();
const metaRPCClient = metaRPCClientFactory(streamTest); const metaRPCClient = metaRPCClientFactory(streamTest);
metaRPCClient.onUncaughtError((error) => { metaRPCClient.onUncaughtError((error) => {
assert(error.code, 1); expect(error.code).toStrictEqual(1);
done();
}); });
streamTest.write({ streamTest.write({

View File

@ -1,5 +1,5 @@
/* eslint-disable jest/no-conditional-expect */
import fs from 'fs'; import fs from 'fs';
import { strict as assert } from 'assert';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import liveMigrations from '../../migrations'; import liveMigrations from '../../migrations';
import data from '../../first-time-state'; import data from '../../first-time-state';
@ -39,11 +39,11 @@ const firstTimeState = {
data, data,
}; };
describe('migrations', function () { describe('migrations', () => {
describe('liveMigrations require list', function () { describe('liveMigrations require list', () => {
let migrationNumbers; let migrationNumbers;
before(function () { beforeAll(() => {
const fileNames = fs.readdirSync('./app/scripts/migrations/'); const fileNames = fs.readdirSync('./app/scripts/migrations/');
migrationNumbers = fileNames migrationNumbers = fileNames
.reduce((acc, filename) => { .reduce((acc, filename) => {
@ -56,21 +56,19 @@ describe('migrations', function () {
.map((num) => parseInt(num, 10)); .map((num) => parseInt(num, 10));
}); });
it('should include all migrations', function () { it('should include all migrations', () => {
migrationNumbers.forEach((num) => { migrationNumbers.forEach((num) => {
const migration = liveMigrations.find((m) => m.version === num); const migration = liveMigrations.find((m) => m.version === num);
assert( expect(migration.version).toStrictEqual(num);
migration,
`migration not included in 'migrations/index.js': ${num}`,
);
}); });
}); });
it('should have tests for all migrations', function () { it('should have tests for all migrations', () => {
const fileNames = fs.readdirSync('./app/scripts/migrations/'); const fileNames = fs.readdirSync('./app/scripts/migrations/');
const testNumbers = fileNames const testNumbers = fileNames
.reduce((acc, filename) => { .reduce((acc, filename) => {
const name = filename.split('.test.')[0]; const name = filename.split('.test.')[0];
// eslint-disable-next-line jest/no-if
if (/^\d+$/u.test(name)) { if (/^\d+$/u.test(name)) {
acc.push(name); acc.push(name);
} }
@ -80,30 +78,31 @@ describe('migrations', function () {
migrationNumbers.forEach((num) => { migrationNumbers.forEach((num) => {
if (num >= 33) { if (num >= 33) {
assert.ok( expect(testNumbers).toContain(num);
testNumbers.includes(num),
`no test found for migration: ${num}`,
);
} }
}); });
}); });
}); });
describe('Migrator', function () { describe('Migrator', () => {
it('migratedData version should be version 3', async function () { it('migratedData version should be version 3', async () => {
const migrator = new Migrator({ migrations: stubMigrations }); const migrator = new Migrator({ migrations: stubMigrations });
const migratedData = await migrator.migrateData(versionedData); const migratedData = await migrator.migrateData(versionedData);
assert.equal(migratedData.meta.version, stubMigrations[2].version); expect(migratedData.meta.version).toStrictEqual(
stubMigrations[2].version,
);
}); });
it('should match the last version in live migrations', async function () { it('should match the last version in live migrations', async () => {
const migrator = new Migrator({ migrations: liveMigrations }); const migrator = new Migrator({ migrations: liveMigrations });
const migratedData = await migrator.migrateData(firstTimeState); const migratedData = await migrator.migrateData(firstTimeState);
const last = liveMigrations.length - 1; const last = liveMigrations.length - 1;
assert.equal(migratedData.meta.version, liveMigrations[last].version); expect(migratedData.meta.version).toStrictEqual(
liveMigrations[last].version,
);
}); });
it('should emit an error', async function () { it('should emit an error', async () => {
const migrator = new Migrator({ const migrator = new Migrator({
migrations: [ migrations: [
{ {
@ -114,7 +113,9 @@ describe('migrations', function () {
}, },
], ],
}); });
await assert.rejects(migrator.migrateData({ meta: { version: 0 } })); await expect(async () => {
await migrator.migrateData({ meta: { version: 0 } });
}).rejects.toThrow('Error: MetaMask Migration Error #1: test');
}); });
}); });
}); });

View File

@ -1,7 +1,6 @@
import { strict as assert } from 'assert';
import nodeify from './nodeify'; import nodeify from './nodeify';
describe('nodeify', function () { describe('nodeify', () => {
const obj = { const obj = {
foo: 'bar', foo: 'bar',
promiseFunc(a) { promiseFunc(a) {
@ -10,65 +9,33 @@ describe('nodeify', function () {
}, },
}; };
it('should retain original context', function (done) { it('should retain original context', () => {
const nodified = nodeify(obj.promiseFunc, obj); const nodified = nodeify(obj.promiseFunc, obj);
nodified('baz', (err, res) => { nodified('baz', (_, res) => {
if (!err) { expect(res).toStrictEqual('barbaz');
assert.equal(res, 'barbaz');
done();
return;
}
done(new Error(err.toString()));
}); });
}); });
it('no callback - should allow the last argument to not be a function', function (done) { it('no callback - should allow the last argument to not be a function', async () => {
const nodified = nodeify(obj.promiseFunc, obj); const nodified = nodeify(obj.promiseFunc, obj);
try { await expect(() => {
nodified('baz'); nodified('baz');
done(); }).not.toThrow();
} catch (err) {
done(
new Error(
'should not have thrown if the last argument is not a function',
),
);
}
}); });
it('sync functions - returns value', function (done) { it('sync functions - returns value', async () => {
const nodified = nodeify(() => 42); const nodified = nodeify(() => 42);
try { nodified((_, result) => {
nodified((err, result) => { expect(42).toStrictEqual(result);
if (err) { });
done(new Error(`should not have thrown any error: ${err.message}`));
return;
}
assert.equal(42, result, 'got expected result');
});
done();
} catch (err) {
done(new Error(`should not have thrown any error: ${err.message}`));
}
}); });
it('sync functions - handles errors', function (done) { it('sync functions - handles errors', () => {
const nodified = nodeify(() => { const nodified = nodeify(() => {
throw new Error('boom!'); throw new Error('boom!');
}); });
try { nodified((err, _) => {
nodified((err, result) => { expect(err.message).toStrictEqual('boom!');
if (result) { });
done(new Error('should not have returned any result'));
return;
}
assert.ok(err, 'got expected error');
assert.ok(err.message.includes('boom!'), 'got expected error message');
});
done();
} catch (err) {
done(new Error(`should not have thrown any error: ${err.message}`));
}
}); });
}); });

View File

@ -1,25 +1,25 @@
import { strict as assert } from 'assert';
import sinon from 'sinon';
import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction';
import PersonalMessageManager from './personal-message-manager'; import PersonalMessageManager from './personal-message-manager';
describe('Personal Message Manager', function () { describe('Personal Message Manager', () => {
let messageManager; let messageManager;
beforeEach(function () { beforeEach(() => {
messageManager = new PersonalMessageManager({ metricsEvent: sinon.fake() }); messageManager = new PersonalMessageManager({
}); metricsEvent: jest.fn(),
describe('#getMsgList', function () {
it('when new should return empty array', function () {
const result = messageManager.messages;
assert.ok(Array.isArray(result));
assert.equal(result.length, 0);
}); });
}); });
describe('#addMsg', function () { describe('#getMsgList', () => {
it('adds a Msg returned in getMsgList', function () { it('when new should return empty array', () => {
const result = messageManager.messages;
expect(Array.isArray(result)).toStrictEqual(true);
expect(result).toHaveLength(0);
});
});
describe('#addMsg', () => {
it('adds a Msg returned in getMsgList', () => {
const Msg = { const Msg = {
id: 1, id: 1,
status: TRANSACTION_STATUSES.APPROVED, status: TRANSACTION_STATUSES.APPROVED,
@ -27,14 +27,14 @@ describe('Personal Message Manager', function () {
}; };
messageManager.addMsg(Msg); messageManager.addMsg(Msg);
const result = messageManager.messages; const result = messageManager.messages;
assert.ok(Array.isArray(result)); expect(Array.isArray(result)).toStrictEqual(true);
assert.equal(result.length, 1); expect(result).toHaveLength(1);
assert.equal(result[0].id, 1); expect(result[0].id).toStrictEqual(1);
}); });
}); });
describe('#setMsgStatusApproved', function () { describe('#setMsgStatusApproved', () => {
it('sets the Msg status to approved', function () { it('sets the Msg status to approved', () => {
const Msg = { const Msg = {
id: 1, id: 1,
status: TRANSACTION_STATUSES.UNAPPROVED, status: TRANSACTION_STATUSES.UNAPPROVED,
@ -43,14 +43,14 @@ describe('Personal Message Manager', function () {
messageManager.addMsg(Msg); messageManager.addMsg(Msg);
messageManager.setMsgStatusApproved(1); messageManager.setMsgStatusApproved(1);
const result = messageManager.messages; const result = messageManager.messages;
assert.ok(Array.isArray(result)); expect(Array.isArray(result)).toStrictEqual(true);
assert.equal(result.length, 1); expect(result).toHaveLength(1);
assert.equal(result[0].status, TRANSACTION_STATUSES.APPROVED); expect(result[0].status).toStrictEqual(TRANSACTION_STATUSES.APPROVED);
}); });
}); });
describe('#rejectMsg', function () { describe('#rejectMsg', () => {
it('sets the Msg status to rejected', function () { it('sets the Msg status to rejected', () => {
const Msg = { const Msg = {
id: 1, id: 1,
status: TRANSACTION_STATUSES.UNAPPROVED, status: TRANSACTION_STATUSES.UNAPPROVED,
@ -59,14 +59,14 @@ describe('Personal Message Manager', function () {
messageManager.addMsg(Msg); messageManager.addMsg(Msg);
messageManager.rejectMsg(1); messageManager.rejectMsg(1);
const result = messageManager.messages; const result = messageManager.messages;
assert.ok(Array.isArray(result)); expect(Array.isArray(result)).toStrictEqual(true);
assert.equal(result.length, 1); expect(result).toHaveLength(1);
assert.equal(result[0].status, TRANSACTION_STATUSES.REJECTED); expect(result[0].status).toStrictEqual(TRANSACTION_STATUSES.REJECTED);
}); });
}); });
describe('#_updateMsg', function () { describe('#_updateMsg', () => {
it('replaces the Msg with the same id', function () { it('replaces the Msg with the same id', () => {
messageManager.addMsg({ messageManager.addMsg({
id: '1', id: '1',
status: TRANSACTION_STATUSES.UNAPPROVED, status: TRANSACTION_STATUSES.UNAPPROVED,
@ -84,12 +84,12 @@ describe('Personal Message Manager', function () {
metamaskNetworkId: 'unit test', metamaskNetworkId: 'unit test',
}); });
const result = messageManager.getMsg('1'); const result = messageManager.getMsg('1');
assert.equal(result.hash, 'foo'); expect(result.hash).toStrictEqual('foo');
}); });
}); });
describe('#getUnapprovedMsgs', function () { describe('#getUnapprovedMsgs', () => {
it('returns unapproved Msgs in a hash', function () { it('returns unapproved Msgs in a hash', () => {
messageManager.addMsg({ messageManager.addMsg({
id: '1', id: '1',
status: TRANSACTION_STATUSES.UNAPPROVED, status: TRANSACTION_STATUSES.UNAPPROVED,
@ -101,14 +101,14 @@ describe('Personal Message Manager', function () {
metamaskNetworkId: 'unit test', metamaskNetworkId: 'unit test',
}); });
const result = messageManager.getUnapprovedMsgs(); const result = messageManager.getUnapprovedMsgs();
assert.equal(typeof result, 'object'); expect(typeof result).toStrictEqual('object');
assert.equal(result['1'].status, TRANSACTION_STATUSES.UNAPPROVED); expect(result['1'].status).toStrictEqual(TRANSACTION_STATUSES.UNAPPROVED);
assert.equal(result['2'], undefined); expect(result['2']).toBeUndefined();
}); });
}); });
describe('#getMsg', function () { describe('#getMsg', () => {
it('returns a Msg with the requested id', function () { it('returns a Msg with the requested id', () => {
messageManager.addMsg({ messageManager.addMsg({
id: '1', id: '1',
status: TRANSACTION_STATUSES.UNAPPROVED, status: TRANSACTION_STATUSES.UNAPPROVED,
@ -119,34 +119,32 @@ describe('Personal Message Manager', function () {
status: TRANSACTION_STATUSES.APPROVED, status: TRANSACTION_STATUSES.APPROVED,
metamaskNetworkId: 'unit test', metamaskNetworkId: 'unit test',
}); });
assert.equal( expect(messageManager.getMsg('1').status).toStrictEqual(
messageManager.getMsg('1').status,
TRANSACTION_STATUSES.UNAPPROVED, TRANSACTION_STATUSES.UNAPPROVED,
); );
assert.equal( expect(messageManager.getMsg('2').status).toStrictEqual(
messageManager.getMsg('2').status,
TRANSACTION_STATUSES.APPROVED, TRANSACTION_STATUSES.APPROVED,
); );
}); });
}); });
describe('#normalizeMsgData', function () { describe('#normalizeMsgData', () => {
it('converts text to a utf8 hex string', function () { it('converts text to a utf8 hex string', () => {
const input = 'hello'; const input = 'hello';
const output = messageManager.normalizeMsgData(input); const output = messageManager.normalizeMsgData(input);
assert.equal(output, '0x68656c6c6f', 'predictably hex encoded'); expect(output).toStrictEqual('0x68656c6c6f');
}); });
it('tolerates a hex prefix', function () { it('tolerates a hex prefix', () => {
const input = '0x12'; const input = '0x12';
const output = messageManager.normalizeMsgData(input); const output = messageManager.normalizeMsgData(input);
assert.equal(output, '0x12', 'un modified'); expect(output).toStrictEqual('0x12');
}); });
it('tolerates normal hex', function () { it('tolerates normal hex', () => {
const input = '12'; const input = '12';
const output = messageManager.normalizeMsgData(input); const output = messageManager.normalizeMsgData(input);
assert.equal(output, '0x12', 'adds prefix'); expect(output).toStrictEqual('0x12');
}); });
}); });
}); });

View File

@ -1,127 +1,118 @@
import { strict as assert } from 'assert'; /**
* @jest-environment node
* https://github.com/facebook/jest/issues/7780
*/
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import KeyringController from 'eth-keyring-controller'; import KeyringController from 'eth-keyring-controller';
import firstTimeState from '../first-time-state'; import firstTimeState from '../first-time-state';
import mockEncryptor from '../../../test/lib/mock-encryptor'; import mockEncryptor from '../../../test/lib/mock-encryptor';
import seedPhraseVerifier from './seed-phrase-verifier'; import seedPhraseVerifier from './seed-phrase-verifier';
describe('SeedPhraseVerifier', function () { describe('SeedPhraseVerifier', () => {
describe('verifyAccounts', function () { describe('verifyAccounts', () => {
const password = 'passw0rd1'; const password = 'passw0rd1';
const hdKeyTree = 'HD Key Tree'; const hdKeyTree = 'HD Key Tree';
let keyringController; let keyringController;
let primaryKeyring; let primaryKeyring;
beforeEach(async function () { beforeEach(async () => {
keyringController = new KeyringController({ keyringController = new KeyringController({
initState: cloneDeep(firstTimeState), initState: cloneDeep(firstTimeState),
encryptor: mockEncryptor, encryptor: mockEncryptor,
}); });
assert(keyringController); expect.any(keyringController);
await keyringController.createNewVaultAndKeychain(password); await keyringController.createNewVaultAndKeychain(password);
primaryKeyring = keyringController.getKeyringsByType(hdKeyTree)[0]; primaryKeyring = keyringController.getKeyringsByType(hdKeyTree)[0];
}); });
it('should be able to verify created account with seed words', async function () { it('should be able to verify created account with seed words', async () => {
const createdAccounts = await primaryKeyring.getAccounts(); const createdAccounts = await primaryKeyring.getAccounts();
assert.equal(createdAccounts.length, 1); expect(createdAccounts).toHaveLength(1);
const serialized = await primaryKeyring.serialize(); const serialized = await primaryKeyring.serialize();
const seedWords = serialized.mnemonic; const seedWords = serialized.mnemonic;
assert.notEqual(seedWords.length, 0); expect(seedWords).not.toHaveLength(0);
await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords); await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords);
}); });
it('should be able to verify created account (upper case) with seed words', async function () { it('should be able to verify created account (upper case) with seed words', async () => {
const createdAccounts = await primaryKeyring.getAccounts(); const createdAccounts = await primaryKeyring.getAccounts();
assert.equal(createdAccounts.length, 1); expect(createdAccounts).toHaveLength(1);
const upperCaseAccounts = [createdAccounts[0].toUpperCase()]; const upperCaseAccounts = [createdAccounts[0].toUpperCase()];
const serialized = await primaryKeyring.serialize(); const serialized = await primaryKeyring.serialize();
const seedWords = serialized.mnemonic; const seedWords = serialized.mnemonic;
assert.notEqual(seedWords.length, 0); expect(seedWords).not.toHaveLength(0);
await seedPhraseVerifier.verifyAccounts(upperCaseAccounts, seedWords); await seedPhraseVerifier.verifyAccounts(upperCaseAccounts, seedWords);
}); });
it('should be able to verify created account (lower case) with seed words', async function () { it('should be able to verify created account (lower case) with seed words', async () => {
const createdAccounts = await primaryKeyring.getAccounts(); const createdAccounts = await primaryKeyring.getAccounts();
assert.equal(createdAccounts.length, 1); expect(createdAccounts).toHaveLength(1);
const lowerCaseAccounts = [createdAccounts[0].toLowerCase()]; const lowerCaseAccounts = [createdAccounts[0].toLowerCase()];
const serialized = await primaryKeyring.serialize(); const serialized = await primaryKeyring.serialize();
const seedWords = serialized.mnemonic; const seedWords = serialized.mnemonic;
assert.notEqual(seedWords.length, 0); expect(seedWords).not.toHaveLength(0);
await seedPhraseVerifier.verifyAccounts(lowerCaseAccounts, seedWords); await seedPhraseVerifier.verifyAccounts(lowerCaseAccounts, seedWords);
}); });
it('should return error with good but different seed words', async function () { it('should return error with good but different seed words', async () => {
const createdAccounts = await primaryKeyring.getAccounts(); const createdAccounts = await primaryKeyring.getAccounts();
assert.equal(createdAccounts.length, 1); expect(createdAccounts).toHaveLength(1);
await primaryKeyring.serialize(); await primaryKeyring.serialize();
const seedWords = const seedWords =
'debris dizzy just program just float decrease vacant alarm reduce speak stadium'; 'debris dizzy just program just float decrease vacant alarm reduce speak stadium';
try { await expect(async () => {
await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords); await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords);
assert.fail('Should reject'); }).rejects.toThrow('Not identical accounts!');
} catch (err) {
assert.ok(
err.message.indexOf('Not identical accounts!') >= 0,
'Wrong error message',
);
}
}); });
it('should return error with undefined existing accounts', async function () { it('should return error with undefined existing accounts', async () => {
const createdAccounts = await primaryKeyring.getAccounts(); const createdAccounts = await primaryKeyring.getAccounts();
assert.equal(createdAccounts.length, 1); expect(createdAccounts).toHaveLength(1);
await primaryKeyring.serialize(); await primaryKeyring.serialize();
const seedWords = const seedWords =
'debris dizzy just program just float decrease vacant alarm reduce speak stadium'; 'debris dizzy just program just float decrease vacant alarm reduce speak stadium';
try { await expect(async () => {
await seedPhraseVerifier.verifyAccounts(undefined, seedWords); await seedPhraseVerifier.verifyAccounts(undefined, seedWords);
assert.fail('Should reject'); }).rejects.toThrow('No created accounts defined.');
} catch (err) {
assert.equal(err.message, 'No created accounts defined.');
}
}); });
it('should return error with empty accounts array', async function () { it('should return error with empty accounts array', async () => {
const createdAccounts = await primaryKeyring.getAccounts(); const createdAccounts = await primaryKeyring.getAccounts();
assert.equal(createdAccounts.length, 1); expect(createdAccounts).toHaveLength(1);
await primaryKeyring.serialize(); await primaryKeyring.serialize();
const seedWords = const seedWords =
'debris dizzy just program just float decrease vacant alarm reduce speak stadium'; 'debris dizzy just program just float decrease vacant alarm reduce speak stadium';
try { await expect(async () => {
await seedPhraseVerifier.verifyAccounts([], seedWords); await seedPhraseVerifier.verifyAccounts([], seedWords);
assert.fail('Should reject'); }).rejects.toThrow('No created accounts defined.');
} catch (err) {
assert.equal(err.message, 'No created accounts defined.');
}
}); });
it('should be able to verify more than one created account with seed words', async function () { it('should be able to verify more than one created account with seed words', async () => {
await keyringController.addNewAccount(primaryKeyring); await keyringController.addNewAccount(primaryKeyring);
await keyringController.addNewAccount(primaryKeyring); await keyringController.addNewAccount(primaryKeyring);
const createdAccounts = await primaryKeyring.getAccounts(); const createdAccounts = await primaryKeyring.getAccounts();
assert.equal(createdAccounts.length, 3); expect(createdAccounts).toHaveLength(3);
const serialized = await primaryKeyring.serialize(); const serialized = await primaryKeyring.serialize();
const seedWords = serialized.mnemonic; const seedWords = serialized.mnemonic;
assert.notEqual(seedWords.length, 0); expect(seedWords).not.toHaveLength(0);
await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords); await seedPhraseVerifier.verifyAccounts(createdAccounts, seedWords);
}); });

View File

@ -33,10 +33,7 @@ const SEGMENT_FLUSH_INTERVAL = SECOND * 5;
* @param {number} flushInterval - ms interval to flush queue and send to segment * @param {number} flushInterval - ms interval to flush queue and send to segment
* @returns {SegmentInterface} * @returns {SegmentInterface}
*/ */
export const createSegmentMock = ( export const createSegmentMock = (flushAt = SEGMENT_FLUSH_AT) => {
flushAt = SEGMENT_FLUSH_AT,
flushInterval = SEGMENT_FLUSH_INTERVAL,
) => {
const segmentMock = { const segmentMock = {
// Internal queue to keep track of events and properly mimic segment's // Internal queue to keep track of events and properly mimic segment's
// queueing behavior. // queueing behavior.
@ -77,8 +74,7 @@ export const createSegmentMock = (
// noop // noop
}, },
}; };
// Mimic the flushInterval behavior with an interval
setInterval(segmentMock.flush, flushInterval);
return segmentMock; return segmentMock;
}; };

View File

@ -1,9 +1,8 @@
import { strict as assert } from 'assert';
import sinon from 'sinon'; import sinon from 'sinon';
import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction'; import { TRANSACTION_STATUSES } from '../../../shared/constants/transaction';
import TypedMessageManager from './typed-message-manager'; import TypedMessageManager from './typed-message-manager';
describe('Typed Message Manager', function () { describe('Typed Message Manager', () => {
let typedMessageManager, let typedMessageManager,
msgParamsV1, msgParamsV1,
msgParamsV3, msgParamsV3,
@ -14,7 +13,7 @@ describe('Typed Message Manager', function () {
const address = '0xc42edfcc21ed14dda456aa0756c153f7985d8813'; const address = '0xc42edfcc21ed14dda456aa0756c153f7985d8813';
beforeEach(async function () { beforeEach(async () => {
typedMessageManager = new TypedMessageManager({ typedMessageManager = new TypedMessageManager({
getCurrentChainId: sinon.fake.returns('0x1'), getCurrentChainId: sinon.fake.returns('0x1'),
metricsEvent: sinon.fake(), metricsEvent: sinon.fake(),
@ -81,47 +80,48 @@ describe('Typed Message Manager', function () {
numberMsgId = parseInt(msgId, 10); numberMsgId = parseInt(msgId, 10);
}); });
it('supports version 1 of signedTypedData', function () { it('supports version 1 of signedTypedData', () => {
typedMessageManager.addUnapprovedMessage(msgParamsV1, null, 'V1'); typedMessageManager.addUnapprovedMessage(msgParamsV1, null, 'V1');
assert.equal( expect(messages[messages.length - 1].msgParams.data).toStrictEqual(
messages[messages.length - 1].msgParams.data,
msgParamsV1.data, msgParamsV1.data,
); );
}); });
it('has params address', function () { it('has params address', () => {
assert.equal(typedMsgs[msgId].msgParams.from, address); expect(typedMsgs[msgId].msgParams.from).toStrictEqual(address);
}); });
it('adds to unapproved messages and sets status to unapproved', function () { it('adds to unapproved messages and sets status to unapproved', () => {
assert.equal(typedMsgs[msgId].status, TRANSACTION_STATUSES.UNAPPROVED); expect(typedMsgs[msgId].status).toStrictEqual(
TRANSACTION_STATUSES.UNAPPROVED,
);
}); });
it('validates params', function () { it('validates params', async () => {
assert.doesNotThrow(() => { await expect(() => {
typedMessageManager.validateParams(messages[0].msgParams); typedMessageManager.validateParams(messages[0].msgParams);
}, 'Does not throw with valid parameters'); }).not.toThrow();
}); });
it('gets unapproved by id', function () { it('gets unapproved by id', () => {
const getMsg = typedMessageManager.getMsg(numberMsgId); const getMsg = typedMessageManager.getMsg(numberMsgId);
assert.equal(getMsg.id, numberMsgId); expect(getMsg.id).toStrictEqual(numberMsgId);
}); });
it('approves messages', async function () { it('approves messages', async () => {
const messageMetaMaskId = messages[0].msgParams; const messageMetaMaskId = messages[0].msgParams;
typedMessageManager.approveMessage(messageMetaMaskId); typedMessageManager.approveMessage(messageMetaMaskId);
assert.equal(messages[0].status, TRANSACTION_STATUSES.APPROVED); expect(messages[0].status).toStrictEqual(TRANSACTION_STATUSES.APPROVED);
}); });
it('sets msg status to signed and adds a raw sig to message details', function () { it('sets msg status to signed and adds a raw sig to message details', () => {
typedMessageManager.setMsgStatusSigned(numberMsgId, 'raw sig'); typedMessageManager.setMsgStatusSigned(numberMsgId, 'raw sig');
assert.equal(messages[0].status, TRANSACTION_STATUSES.SIGNED); expect(messages[0].status).toStrictEqual(TRANSACTION_STATUSES.SIGNED);
assert.equal(messages[0].rawSig, 'raw sig'); expect(messages[0].rawSig).toStrictEqual('raw sig');
}); });
it('rejects message', function () { it('rejects message', () => {
typedMessageManager.rejectMsg(numberMsgId); typedMessageManager.rejectMsg(numberMsgId);
assert.equal(messages[0].status, TRANSACTION_STATUSES.REJECTED); expect(messages[0].status).toStrictEqual(TRANSACTION_STATUSES.REJECTED);
}); });
}); });

View File

@ -1,5 +1,3 @@
import { strict as assert } from 'assert';
import sinon from 'sinon';
import { isPrefixedFormattedHexString } from '../../../shared/modules/network.utils'; import { isPrefixedFormattedHexString } from '../../../shared/modules/network.utils';
import { import {
ENVIRONMENT_TYPE_POPUP, ENVIRONMENT_TYPE_POPUP,
@ -13,201 +11,154 @@ import {
} from '../../../shared/constants/app'; } from '../../../shared/constants/app';
import { getEnvironmentType, getPlatform } from './util'; import { getEnvironmentType, getPlatform } from './util';
describe('app utils', function () { describe('app utils', () => {
describe('getEnvironmentType', function () { describe('getEnvironmentType', () => {
it('should return popup type', function () { it('should return popup type', () => {
const environmentType = getEnvironmentType( const environmentType = getEnvironmentType(
'http://extension-id/popup.html', 'http://extension-id/popup.html',
); );
assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP); expect(environmentType).toStrictEqual(ENVIRONMENT_TYPE_POPUP);
}); });
it('should return notification type', function () { it('should return notification type', () => {
const environmentType = getEnvironmentType( const environmentType = getEnvironmentType(
'http://extension-id/notification.html', 'http://extension-id/notification.html',
); );
assert.equal(environmentType, ENVIRONMENT_TYPE_NOTIFICATION); expect(environmentType).toStrictEqual(ENVIRONMENT_TYPE_NOTIFICATION);
}); });
it('should return fullscreen type for home.html', function () { it('should return fullscreen type for home.html', () => {
const environmentType = getEnvironmentType( const environmentType = getEnvironmentType(
'http://extension-id/home.html', 'http://extension-id/home.html',
); );
assert.equal(environmentType, ENVIRONMENT_TYPE_FULLSCREEN); expect(environmentType).toStrictEqual(ENVIRONMENT_TYPE_FULLSCREEN);
}); });
it('should return fullscreen type for phishing.html', function () { it('should return fullscreen type for phishing.html', () => {
const environmentType = getEnvironmentType( const environmentType = getEnvironmentType(
'http://extension-id/phishing.html', 'http://extension-id/phishing.html',
); );
assert.equal(environmentType, ENVIRONMENT_TYPE_FULLSCREEN); expect(environmentType).toStrictEqual(ENVIRONMENT_TYPE_FULLSCREEN);
}); });
it('should return background type', function () { it('should return background type', () => {
const environmentType = getEnvironmentType( const environmentType = getEnvironmentType(
'http://extension-id/_generated_background_page.html', 'http://extension-id/_generated_background_page.html',
); );
assert.equal(environmentType, ENVIRONMENT_TYPE_BACKGROUND); expect(environmentType).toStrictEqual(ENVIRONMENT_TYPE_BACKGROUND);
}); });
it('should return the correct type for a URL with a hash fragment', function () { it('should return the correct type for a URL with a hash fragment', () => {
const environmentType = getEnvironmentType( const environmentType = getEnvironmentType(
'http://extension-id/popup.html#hash', 'http://extension-id/popup.html#hash',
); );
assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP); expect(environmentType).toStrictEqual(ENVIRONMENT_TYPE_POPUP);
}); });
it('should return the correct type for a URL with query parameters', function () { it('should return the correct type for a URL with query parameters', () => {
const environmentType = getEnvironmentType( const environmentType = getEnvironmentType(
'http://extension-id/popup.html?param=foo', 'http://extension-id/popup.html?param=foo',
); );
assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP); expect(environmentType).toStrictEqual(ENVIRONMENT_TYPE_POPUP);
}); });
it('should return the correct type for a URL with query parameters and a hash fragment', function () { it('should return the correct type for a URL with query parameters and a hash fragment', () => {
const environmentType = getEnvironmentType( const environmentType = getEnvironmentType(
'http://extension-id/popup.html?param=foo#hash', 'http://extension-id/popup.html?param=foo#hash',
); );
assert.equal(environmentType, ENVIRONMENT_TYPE_POPUP); expect(environmentType).toStrictEqual(ENVIRONMENT_TYPE_POPUP);
}); });
}); });
describe('isPrefixedFormattedHexString', function () { describe('isPrefixedFormattedHexString', () => {
it('should return true for valid hex strings', function () { it('should return true for valid hex strings', () => {
assert.equal( expect(isPrefixedFormattedHexString('0x1')).toStrictEqual(true);
isPrefixedFormattedHexString('0x1'),
true,
'should return true',
);
assert.equal( expect(isPrefixedFormattedHexString('0xa')).toStrictEqual(true);
isPrefixedFormattedHexString('0xa'),
true,
'should return true',
);
assert.equal( expect(
isPrefixedFormattedHexString('0xabcd1123fae909aad87452'), isPrefixedFormattedHexString('0xabcd1123fae909aad87452'),
true, ).toStrictEqual(true);
'should return true',
);
}); });
it('should return false for invalid hex strings', function () { it('should return false for invalid hex strings', () => {
assert.equal( expect(isPrefixedFormattedHexString('0x')).toStrictEqual(false);
isPrefixedFormattedHexString('0x'),
false,
'should return false',
);
assert.equal( expect(isPrefixedFormattedHexString('0x0')).toStrictEqual(false);
isPrefixedFormattedHexString('0x0'),
false,
'should return false',
);
assert.equal( expect(isPrefixedFormattedHexString('0x01')).toStrictEqual(false);
isPrefixedFormattedHexString('0x01'),
false,
'should return false',
);
assert.equal( expect(isPrefixedFormattedHexString(' 0x1')).toStrictEqual(false);
isPrefixedFormattedHexString(' 0x1'),
false,
'should return false',
);
assert.equal( expect(isPrefixedFormattedHexString('0x1 ')).toStrictEqual(false);
isPrefixedFormattedHexString('0x1 '),
false,
'should return false',
);
assert.equal( expect(isPrefixedFormattedHexString('0x1afz')).toStrictEqual(false);
isPrefixedFormattedHexString('0x1afz'),
false,
'should return false',
);
assert.equal( expect(isPrefixedFormattedHexString('z')).toStrictEqual(false);
isPrefixedFormattedHexString('z'),
false,
'should return false',
);
assert.equal( expect(isPrefixedFormattedHexString(2)).toStrictEqual(false);
isPrefixedFormattedHexString(2),
false,
'should return false',
);
assert.equal( expect(isPrefixedFormattedHexString(['0x1'])).toStrictEqual(false);
isPrefixedFormattedHexString(['0x1']),
false,
'should return false',
);
assert.equal( expect(isPrefixedFormattedHexString()).toStrictEqual(false);
isPrefixedFormattedHexString(),
false,
'should return false',
);
}); });
}); });
describe('getPlatform', function () { describe('getPlatform', () => {
const setBrowserSpecificWindow = (browser) => { let userAgent, setBrowserSpecificWindow;
switch (browser) {
case 'firefox': { beforeEach(() => {
sinon.stub(window, 'navigator').value({ userAgent = jest.spyOn(window.navigator, 'userAgent', 'get');
userAgent:
setBrowserSpecificWindow = (browser) => {
switch (browser) {
case 'firefox': {
userAgent.mockReturnValue(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko/20100101 Firefox/95.0', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:95.0) Gecko/20100101 Firefox/95.0',
}); );
break; break;
} }
case 'edge': { case 'edge': {
sinon.stub(window, 'navigator').value({ userAgent.mockReturnValue(
userAgent:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36 Edg/95.0.1020.30',
}); );
break; break;
} }
case 'opera': { case 'opera': {
sinon.stub(window, 'navigator').value({ userAgent.mockReturnValue(
userAgent:
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36 OPR/80.0.4170.63', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36 OPR/80.0.4170.63',
}); );
break;
} break;
default: { }
sinon.stub(window, 'navigator').value({ default: {
userAgent: userAgent.mockReturnValue(
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',
}); );
break; break;
}
} }
} };
}; });
it('should detect Firefox', function () { it('should detect Firefox', () => {
setBrowserSpecificWindow('firefox'); setBrowserSpecificWindow('firefox');
assert.equal(getPlatform(), PLATFORM_FIREFOX); expect(getPlatform()).toStrictEqual(PLATFORM_FIREFOX);
}); });
it('should detect Edge', function () { it('should detect Edge', () => {
setBrowserSpecificWindow('edge'); setBrowserSpecificWindow('edge');
assert.equal(getPlatform(), PLATFORM_EDGE); expect(getPlatform()).toStrictEqual(PLATFORM_EDGE);
}); });
it('should detect Opera', function () { it('should detect Opera', () => {
setBrowserSpecificWindow('opera'); setBrowserSpecificWindow('opera');
assert.equal(getPlatform(), PLATFORM_OPERA); expect(getPlatform()).toStrictEqual(PLATFORM_OPERA);
}); });
it('should detect Chrome', function () { it('should detect Chrome', () => {
setBrowserSpecificWindow('chrome'); setBrowserSpecificWindow('chrome');
assert.equal(getPlatform(), PLATFORM_CHROME); expect(getPlatform()).toStrictEqual(PLATFORM_CHROME);
}); });
}); });
}); });

View File

@ -21,6 +21,7 @@ module.exports = {
'<rootDir>/shared/**/*.test.js', '<rootDir>/shared/**/*.test.js',
'<rootDir>/app/scripts/migrations/*.test.js', '<rootDir>/app/scripts/migrations/*.test.js',
'<rootDir>/app/scripts/platforms/*.test.js', '<rootDir>/app/scripts/platforms/*.test.js',
'<rootDir>/app/scripts/lib/**/*.test.js',
], ],
testTimeout: 2500, testTimeout: 2500,
transform: { transform: {

View File

@ -27,7 +27,7 @@
"test:unit": "./test/test-unit-combined.sh", "test:unit": "./test/test-unit-combined.sh",
"test:unit:jest": "./test/test-unit-jest.sh", "test:unit:jest": "./test/test-unit-jest.sh",
"test:unit:global": "mocha test/unit-global/*.test.js", "test:unit:global": "mocha test/unit-global/*.test.js",
"test:unit:mocha": "mocha './app/**/*.test.js'", "test:unit:mocha": "mocha --config '.mocharc.js' './app/**/*.test.js'",
"test:unit:lax": "mocha --config '.mocharc.lax.js' './app/**/*.test.js'", "test:unit:lax": "mocha --config '.mocharc.lax.js' './app/**/*.test.js'",
"test:unit:strict": "mocha './app/scripts/controllers/permissions/*.test.js'", "test:unit:strict": "mocha './app/scripts/controllers/permissions/*.test.js'",
"test:e2e:chrome": "SELENIUM_BROWSER=chrome node test/e2e/run-all.js", "test:e2e:chrome": "SELENIUM_BROWSER=chrome node test/e2e/run-all.js",