1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-11-22 18:00:18 +01:00
metamask-extension/app/scripts/metamask-controller.actions.test.js
Nicholas Ellul db92bef002 Update @metamask/phishing-controller to v4.0.0 (#18840)
* Update phishing controller to v4.0.0

* Move phishing e2e test utilities into its own helper.js

* Update phishing detection e2e test

* Update MetaMask Controller test mocks

* Update mv3 phishing tests

* Fix test for 500 error on warning page

* Allow for directories in test folder

* Update migration number

* Linting fixes

* Remove fail on console error

* Separate mocks from helpers

* Have migration delete PhishingController state entirely

* Remove phishing detection directory

* Only delete the listState in migration

* Bump migration version
2023-07-31 17:55:48 -02:30

390 lines
12 KiB
JavaScript

import { strict as assert } from 'assert';
import sinon from 'sinon';
import proxyquire from 'proxyquire';
import {
ListNames,
METAMASK_STALELIST_URL,
METAMASK_HOTLIST_DIFF_URL,
PHISHING_CONFIG_BASE_URL,
METAMASK_STALELIST_FILE,
METAMASK_HOTLIST_DIFF_FILE,
} from '@metamask/phishing-controller';
import { ApprovalRequestNotFoundError } from '@metamask/approval-controller';
import { PermissionsRequestNotFoundError } from '@metamask/permission-controller';
import nock from 'nock';
const Ganache = require('../../test/e2e/ganache');
const ganacheServer = new Ganache();
const browserPolyfillMock = {
runtime: {
id: 'fake-extension-id',
onInstalled: {
addListener: () => undefined,
},
onMessageExternal: {
addListener: () => undefined,
},
getPlatformInfo: async () => 'mac',
},
storage: {
local: {
get: sinon.stub().resolves({}),
set: sinon.stub().resolves(),
},
},
};
let loggerMiddlewareMock;
const createLoggerMiddlewareMock = () => (req, res, next) => {
if (loggerMiddlewareMock) {
loggerMiddlewareMock.requests.push(req);
next((cb) => {
loggerMiddlewareMock.responses.push(res);
cb();
});
return;
}
next();
};
const TEST_SEED =
'debris dizzy just program just float decrease vacant alarm reduce speak stadium';
const MetaMaskController = proxyquire('./metamask-controller', {
'./lib/createLoggerMiddleware': { default: createLoggerMiddlewareMock },
}).default;
describe('MetaMaskController', function () {
let metamaskController;
const sandbox = sinon.createSandbox();
const noop = () => undefined;
before(async function () {
await ganacheServer.start();
});
beforeEach(function () {
nock(PHISHING_CONFIG_BASE_URL)
.persist()
.get(METAMASK_STALELIST_FILE)
.reply(
200,
JSON.stringify({
version: 2,
tolerance: 2,
lastUpdated: 1,
eth_phishing_detect_config: {
fuzzylist: [],
allowlist: [],
blocklist: ['127.0.0.1'],
name: ListNames.MetaMask,
},
phishfort_hotlist: {
blocklist: [],
name: ListNames.Phishfort,
},
}),
)
.get(METAMASK_HOTLIST_DIFF_FILE)
.reply(
200,
JSON.stringify([
{ url: '127.0.0.1', targetList: 'blocklist', timestamp: 0 },
]),
);
metamaskController = new MetaMaskController({
showUserConfirmation: noop,
encryptor: {
encrypt(_, object) {
this.object = object;
return Promise.resolve('mock-encrypted');
},
decrypt() {
return Promise.resolve(this.object);
},
},
initLangCode: 'en_US',
platform: {
showTransactionNotification: () => undefined,
getVersion: () => 'foo',
},
browser: browserPolyfillMock,
infuraProjectId: 'foo',
});
});
afterEach(function () {
sandbox.restore();
nock.cleanAll();
});
after(async function () {
await ganacheServer.quit();
});
describe('Phishing Detection Mock', function () {
it('should be updated to use v1 of the API', function () {
// Update the fixture above if this test fails
assert.equal(
METAMASK_STALELIST_URL,
'https://phishing-detection.metafi.codefi.network/v1/stalelist',
);
assert.equal(
METAMASK_HOTLIST_DIFF_URL,
'https://phishing-detection.metafi.codefi.network/v1/diffsSince',
);
});
});
describe('#addNewAccount', function () {
it('two parallel calls with same accountCount give same result', async function () {
await metamaskController.createNewVaultAndKeychain('test@123');
const [addNewAccountResult1, addNewAccountResult2] = await Promise.all([
metamaskController.addNewAccount(1),
metamaskController.addNewAccount(1),
]);
assert.deepEqual(
Object.keys(addNewAccountResult1.identities),
Object.keys(addNewAccountResult2.identities),
);
});
it('two successive calls with same accountCount give same result', async function () {
await metamaskController.createNewVaultAndKeychain('test@123');
const addNewAccountResult1 = await metamaskController.addNewAccount(1);
const addNewAccountResult2 = await metamaskController.addNewAccount(1);
assert.deepEqual(
Object.keys(addNewAccountResult1.identities),
Object.keys(addNewAccountResult2.identities),
);
});
it('two successive calls with different accountCount give different results', async function () {
await metamaskController.createNewVaultAndKeychain('test@123');
const addNewAccountResult1 = await metamaskController.addNewAccount(1);
const addNewAccountResult2 = await metamaskController.addNewAccount(2);
assert.notDeepEqual(addNewAccountResult1, addNewAccountResult2);
});
});
describe('#importAccountWithStrategy', function () {
it('two sequential calls with same strategy give same result', async function () {
let keyringControllerState1;
let keyringControllerState2;
const importPrivkey =
'4cfd3e90fc78b0f86bf7524722150bb8da9c60cd532564d7ff43f5716514f553';
await metamaskController.createNewVaultAndKeychain('test@123');
await Promise.all([
metamaskController.importAccountWithStrategy('Private Key', [
importPrivkey,
]),
Promise.resolve(1).then(() => {
keyringControllerState1 = JSON.stringify(
metamaskController.keyringController.memStore.getState(),
);
metamaskController.importAccountWithStrategy('Private Key', [
importPrivkey,
]);
}),
Promise.resolve(2).then(() => {
keyringControllerState2 = JSON.stringify(
metamaskController.keyringController.memStore.getState(),
);
}),
]);
assert.deepEqual(keyringControllerState1, keyringControllerState2);
});
});
describe('#createNewVaultAndRestore', function () {
it('two successive calls with same inputs give same result', async function () {
const result1 = await metamaskController.createNewVaultAndRestore(
'test@123',
TEST_SEED,
);
const result2 = await metamaskController.createNewVaultAndRestore(
'test@123',
TEST_SEED,
);
assert.deepEqual(result1, result2);
});
});
describe('#createNewVaultAndKeychain', function () {
it('two successive calls with same inputs give same result', async function () {
const result1 = await metamaskController.createNewVaultAndKeychain(
'test@123',
);
const result2 = await metamaskController.createNewVaultAndKeychain(
'test@123',
);
assert.notEqual(result1, undefined);
assert.deepEqual(result1, result2);
});
});
describe('#addToken', function () {
const address = '0x514910771af9ca656af840dff83e8264ecf986ca';
const symbol = 'LINK';
const decimals = 18;
it('two parallel calls with same token details give same result', async function () {
const supportsInterfaceStub = sinon
.stub()
.returns(Promise.resolve(false));
sinon
.stub(metamaskController.tokensController, '_createEthersContract')
.callsFake(() =>
Promise.resolve({ supportsInterface: supportsInterfaceStub }),
);
const [token1, token2] = await Promise.all([
metamaskController.getApi().addToken(address, symbol, decimals),
metamaskController.getApi().addToken(address, symbol, decimals),
]);
assert.deepEqual(token1, token2);
});
});
describe('#removePermissionsFor', function () {
it('should not propagate PermissionsRequestNotFoundError', function () {
const error = new PermissionsRequestNotFoundError('123');
metamaskController.permissionController = {
revokePermissions: () => {
throw error;
},
};
// Line below will not throw error, in case it throws this test case will fail.
metamaskController.removePermissionsFor({ subject: 'test_subject' });
});
it('should propagate Error other than PermissionsRequestNotFoundError', function () {
const error = new Error();
metamaskController.permissionController = {
revokePermissions: () => {
throw error;
},
};
assert.throws(() => {
metamaskController.removePermissionsFor({ subject: 'test_subject' });
}, error);
});
});
describe('#rejectPermissionsRequest', function () {
it('should not propagate PermissionsRequestNotFoundError', function () {
const error = new PermissionsRequestNotFoundError('123');
metamaskController.permissionController = {
rejectPermissionsRequest: () => {
throw error;
},
};
// Line below will not throw error, in case it throws this test case will fail.
metamaskController.rejectPermissionsRequest('DUMMY_ID');
});
it('should propagate Error other than PermissionsRequestNotFoundError', function () {
const error = new Error();
metamaskController.permissionController = {
rejectPermissionsRequest: () => {
throw error;
},
};
assert.throws(() => {
metamaskController.rejectPermissionsRequest('DUMMY_ID');
}, error);
});
});
describe('#acceptPermissionsRequest', function () {
it('should not propagate PermissionsRequestNotFoundError', function () {
const error = new PermissionsRequestNotFoundError('123');
metamaskController.permissionController = {
acceptPermissionsRequest: () => {
throw error;
},
};
// Line below will not throw error, in case it throws this test case will fail.
metamaskController.acceptPermissionsRequest('DUMMY_ID');
});
it('should propagate Error other than PermissionsRequestNotFoundError', function () {
const error = new Error();
metamaskController.permissionController = {
acceptPermissionsRequest: () => {
throw error;
},
};
assert.throws(() => {
metamaskController.acceptPermissionsRequest('DUMMY_ID');
}, error);
});
});
describe('#resolvePendingApproval', function () {
it('should not propagate ApprovalRequestNotFoundError', async function () {
const error = new ApprovalRequestNotFoundError('123');
metamaskController.approvalController = {
accept: () => {
throw error;
},
};
// Line below will not throw error, in case it throws this test case will fail.
await metamaskController.resolvePendingApproval(
'DUMMY_ID',
'DUMMY_VALUE',
);
});
it('should propagate Error other than ApprovalRequestNotFoundError', function () {
const error = new Error();
metamaskController.approvalController = {
accept: () => {
throw error;
},
};
assert.rejects(
() =>
metamaskController.resolvePendingApproval('DUMMY_ID', 'DUMMY_VALUE'),
error,
);
});
});
describe('#rejectPendingApproval', function () {
it('should not propagate ApprovalRequestNotFoundError', function () {
const error = new ApprovalRequestNotFoundError('123');
metamaskController.approvalController = {
reject: () => {
throw error;
},
};
// Line below will not throw error, in case it throws this test case will fail.
metamaskController.rejectPendingApproval('DUMMY_ID', {
code: 1,
message: 'DUMMY_MESSAGE',
data: 'DUMMY_DATA',
});
});
it('should propagate Error other than ApprovalRequestNotFoundError', function () {
const error = new Error();
metamaskController.approvalController = {
reject: () => {
throw error;
},
};
assert.throws(() => {
metamaskController.rejectPendingApproval('DUMMY_ID', {
code: 1,
message: 'DUMMY_MESSAGE',
data: 'DUMMY_DATA',
});
}, error);
});
});
});