|
|
|
@ -1,3 +1,4 @@ |
|
|
|
|
/* eslint-disable */ |
|
|
|
|
// Used to inspect long objects
|
|
|
|
|
// util.inspect({JSON}, false, null))
|
|
|
|
|
// const util = require('util')
|
|
|
|
@ -29,6 +30,8 @@ describe('Actions', () => { |
|
|
|
|
|
|
|
|
|
const noop = () => {} |
|
|
|
|
|
|
|
|
|
const currentNetworkId = 42 |
|
|
|
|
|
|
|
|
|
let background, metamaskController |
|
|
|
|
|
|
|
|
|
const TEST_SEED = 'debris dizzy just program just float decrease vacant alarm reduce speak stadium' |
|
|
|
@ -37,7 +40,6 @@ describe('Actions', () => { |
|
|
|
|
|
|
|
|
|
beforeEach(async () => { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
metamaskController = new MetaMaskController({ |
|
|
|
|
provider, |
|
|
|
|
keyringController: new KeyringController({}), |
|
|
|
@ -88,11 +90,9 @@ describe('Actions', () => { |
|
|
|
|
submitPasswordSpy = sinon.spy(background, 'submitPassword') |
|
|
|
|
verifySeedPhraseSpy = sinon.spy(background, 'verifySeedPhrase') |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.tryUnlockMetamask()) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(submitPasswordSpy.calledOnce) |
|
|
|
|
assert(verifySeedPhraseSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
await store.dispatch(actions.tryUnlockMetamask()) |
|
|
|
|
assert(submitPasswordSpy.calledOnce) |
|
|
|
|
assert(verifySeedPhraseSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('errors on submitPassword will fail', async () => { |
|
|
|
@ -193,15 +193,17 @@ describe('Actions', () => { |
|
|
|
|
describe('#requestRevealSeedWords', () => { |
|
|
|
|
let submitPasswordSpy |
|
|
|
|
|
|
|
|
|
it('calls submitPassword in background', () => { |
|
|
|
|
afterEach(() => { |
|
|
|
|
submitPasswordSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls submitPassword in background', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
submitPasswordSpy = sinon.spy(background, 'verifySeedPhrase') |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.requestRevealSeedWords()) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(submitPasswordSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
await store.dispatch(actions.requestRevealSeedWords()) |
|
|
|
|
assert(submitPasswordSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('displays warning error message then callback in background errors', async () => { |
|
|
|
@ -235,8 +237,9 @@ describe('Actions', () => { |
|
|
|
|
removeAccountSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls removeAccount in background and expect actions to show account', () => { |
|
|
|
|
it('calls removeAccount in background and expect actions to show account', async () => { |
|
|
|
|
const store = mockStore(devState) |
|
|
|
|
|
|
|
|
|
const expectedActions = [ |
|
|
|
|
{ type: 'SHOW_LOADING_INDICATION', value: undefined }, |
|
|
|
|
{ type: 'HIDE_LOADING_INDICATION' }, |
|
|
|
@ -245,20 +248,20 @@ describe('Actions', () => { |
|
|
|
|
|
|
|
|
|
removeAccountSpy = sinon.spy(background, 'removeAccount') |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.removeAccount('0xe18035bf8712672935fdb4e5e431b1a0183d2dfc')) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(removeAccountSpy.calledOnce) |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
}) |
|
|
|
|
await store.dispatch(actions.removeAccount('0xe18035bf8712672935fdb4e5e431b1a0183d2dfc')) |
|
|
|
|
assert(removeAccountSpy.calledOnce) |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('displays warning error message when removeAccount callback errors', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
const expectedActions = [ |
|
|
|
|
{ type: 'SHOW_LOADING_INDICATION', value: undefined }, |
|
|
|
|
{ type: 'HIDE_LOADING_INDICATION' }, |
|
|
|
|
{ type: 'DISPLAY_WARNING', value: 'error' }, |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
removeAccountSpy = sinon.stub(background, 'removeAccount') |
|
|
|
|
removeAccountSpy.callsFake((_, callback) => { |
|
|
|
|
callback(new Error('error')) |
|
|
|
@ -331,11 +334,9 @@ describe('Actions', () => { |
|
|
|
|
|
|
|
|
|
resetAccountSpy = sinon.spy(background, 'resetAccount') |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.resetAccount()) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(resetAccountSpy.calledOnce) |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
}) |
|
|
|
|
await store.dispatch(actions.resetAccount()) |
|
|
|
|
assert(resetAccountSpy.calledOnce) |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('throws if resetAccount throws', async () => { |
|
|
|
@ -376,10 +377,8 @@ describe('Actions', () => { |
|
|
|
|
|
|
|
|
|
const importPrivkey = 'c87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3' |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.importNewAccount('Private Key', [ importPrivkey ])) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(importAccountWithStrategySpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
store.dispatch(actions.importNewAccount('Private Key', [ importPrivkey ])) |
|
|
|
|
assert(importAccountWithStrategySpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('displays warning error message when importAccount in background callback errors', async () => { |
|
|
|
@ -407,21 +406,181 @@ describe('Actions', () => { |
|
|
|
|
|
|
|
|
|
describe('#addNewAccount', () => { |
|
|
|
|
|
|
|
|
|
let addNewAccountSpy |
|
|
|
|
it('Adds a new account', () => { |
|
|
|
|
const store = mockStore({ metamask: devState }) |
|
|
|
|
|
|
|
|
|
const addNewAccountSpy = sinon.spy(background, 'addNewAccount') |
|
|
|
|
|
|
|
|
|
store.dispatch(actions.addNewAccount()) |
|
|
|
|
assert(addNewAccountSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#checkHardwareStatus', () => { |
|
|
|
|
|
|
|
|
|
let checkHardwareStatusSpy |
|
|
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
|
checkHardwareStatusSpy = sinon.stub(background, 'checkHardwareStatus') |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
|
addNewAccountSpy.restore() |
|
|
|
|
checkHardwareStatusSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('Adds a new account', () => { |
|
|
|
|
const store = mockStore({ metamask: devState }) |
|
|
|
|
it('calls checkHardwareStatus in background', async () => { |
|
|
|
|
|
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
store.dispatch(await actions.checkHardwareStatus('ledger', `m/44'/60'/0'/0`)) |
|
|
|
|
assert.equal(checkHardwareStatusSpy.calledOnce, true) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('shows loading indicator and displays error', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
const expectedActions = [ |
|
|
|
|
{ type: 'SHOW_LOADING_INDICATION', value: undefined }, |
|
|
|
|
{ type: 'DISPLAY_WARNING', value: 'error' }, |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
checkHardwareStatusSpy.callsFake((deviceName, hdPath, callback) => { |
|
|
|
|
callback(new Error('error')) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
await store.dispatch(actions.checkHardwareStatus()) |
|
|
|
|
assert.fail('Should have thrown error') |
|
|
|
|
} catch (_) { |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#forgetDevice', () => { |
|
|
|
|
|
|
|
|
|
let forgetDeviceSpy |
|
|
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
|
forgetDeviceSpy = sinon.stub(background, 'forgetDevice') |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
|
forgetDeviceSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls forgetDevice in background', () => { |
|
|
|
|
|
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
store.dispatch(actions.forgetDevice('ledger')) |
|
|
|
|
assert.equal(forgetDeviceSpy.calledOnce, true) |
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('shows loading indicator and displays error', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
const expectedActions = [ |
|
|
|
|
{ type: 'SHOW_LOADING_INDICATION', value: undefined }, |
|
|
|
|
{ type: 'DISPLAY_WARNING', value: 'error' }, |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
forgetDeviceSpy.callsFake((deviceName, callback) => { |
|
|
|
|
callback(new Error('error')) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
await store.dispatch(actions.forgetDevice()) |
|
|
|
|
assert.fail('Should have thrown error') |
|
|
|
|
} catch (_) { |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#connectHardware', () => { |
|
|
|
|
|
|
|
|
|
let connectHardwareSpy |
|
|
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
|
connectHardwareSpy = sinon.stub(background, 'connectHardware') |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
|
connectHardwareSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls connectHardware in background', () => { |
|
|
|
|
|
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
store.dispatch(actions.connectHardware('ledger', 0, `m/44'/60'/0'/0`)) |
|
|
|
|
assert.equal(connectHardwareSpy.calledOnce, true) |
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('shows loading indicator and displays error', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
const expectedActions = [ |
|
|
|
|
{ type: 'SHOW_LOADING_INDICATION', value: undefined }, |
|
|
|
|
{ type: 'DISPLAY_WARNING', value: 'error' }, |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
addNewAccountSpy = sinon.spy(background, 'addNewAccount') |
|
|
|
|
connectHardwareSpy.callsFake((deviceName, page, hdPath, callback) => { |
|
|
|
|
callback(new Error('error')) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.addNewAccount()) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(addNewAccountSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
try { |
|
|
|
|
await store.dispatch(actions.connectHardware()) |
|
|
|
|
assert.fail('Should have thrown error') |
|
|
|
|
} catch (_) { |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#unlockHardwareWalletAccount', () => { |
|
|
|
|
|
|
|
|
|
let unlockHardwareWalletAccountSpy |
|
|
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
|
unlockHardwareWalletAccountSpy = sinon.stub(background, 'unlockHardwareWalletAccount') |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
|
unlockHardwareWalletAccountSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls unlockHardwareWalletAccount in background', () => { |
|
|
|
|
|
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
store.dispatch(actions.unlockHardwareWalletAccount('ledger', 0, `m/44'/60'/0'/0`)) |
|
|
|
|
assert.equal(unlockHardwareWalletAccountSpy.calledOnce, true) |
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('shows loading indicator and displays error', async() => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
const expectedActions = [ |
|
|
|
|
{ type: 'SHOW_LOADING_INDICATION', value: undefined }, |
|
|
|
|
{ type: 'DISPLAY_WARNING', value: 'error' }, |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
unlockHardwareWalletAccountSpy.callsFake((deviceName, page, hdPath, callback) => { |
|
|
|
|
callback(new Error('error')) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
await store.dispatch(actions.unlockHardwareWalletAccount()) |
|
|
|
|
assert.fail('Should have thrown error') |
|
|
|
|
} catch (error) { |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
@ -485,11 +644,8 @@ describe('Actions', () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
signMessageSpy = sinon.spy(background, 'signMessage') |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.signMsg(msgParams)) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(signMessageSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
store.dispatch(actions.signMsg(msgParams)) |
|
|
|
|
assert(signMessageSpy.calledOnce) |
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
@ -543,10 +699,8 @@ describe('Actions', () => { |
|
|
|
|
|
|
|
|
|
signPersonalMessageSpy = sinon.spy(background, 'signPersonalMessage') |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.signPersonalMsg(msgParams)) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(signPersonalMessageSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
store.dispatch(actions.signPersonalMsg(msgParams)) |
|
|
|
|
assert(signPersonalMessageSpy.calledOnce) |
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
@ -574,12 +728,100 @@ describe('Actions', () => { |
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#signTypedMsg', () => { |
|
|
|
|
let signTypedMsgSpy, messages, typedMessages, msgId |
|
|
|
|
|
|
|
|
|
const msgParamsV3 = { |
|
|
|
|
from: '0x0DCD5D886577d5081B0c52e242Ef29E70Be3E7bc', |
|
|
|
|
data: JSON.stringify({ |
|
|
|
|
'types': { |
|
|
|
|
'EIP712Domain': [ |
|
|
|
|
{'name': 'name', 'type': 'string'}, |
|
|
|
|
{'name': 'version', 'type': 'string'}, |
|
|
|
|
{'name': 'chainId', 'type': 'uint256'}, |
|
|
|
|
{'name': 'verifyingContract', 'type': 'address'}, |
|
|
|
|
], |
|
|
|
|
'Person': [ |
|
|
|
|
{'name': 'name', 'type': 'string'}, |
|
|
|
|
{'name': 'wallet', 'type': 'address'}, |
|
|
|
|
], |
|
|
|
|
'Mail': [ |
|
|
|
|
{'name': 'from', 'type': 'Person'}, |
|
|
|
|
{'name': 'to', 'type': 'Person'}, |
|
|
|
|
{'name': 'contents', 'type': 'string'}, |
|
|
|
|
], |
|
|
|
|
}, |
|
|
|
|
'primaryType': 'Mail', |
|
|
|
|
'domain': { |
|
|
|
|
'name': 'Ether Mainl', |
|
|
|
|
'version': '1', |
|
|
|
|
'chainId': 1, |
|
|
|
|
'verifyingContract': '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC', |
|
|
|
|
}, |
|
|
|
|
'message': { |
|
|
|
|
'from': { |
|
|
|
|
'name': 'Cow', |
|
|
|
|
'wallet': '0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826', |
|
|
|
|
}, |
|
|
|
|
'to': { |
|
|
|
|
'name': 'Bob', |
|
|
|
|
'wallet': '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB', |
|
|
|
|
}, |
|
|
|
|
'contents': 'Hello, Bob!', |
|
|
|
|
}, |
|
|
|
|
}), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
|
metamaskController.newUnsignedTypedMessage(msgParamsV3, 'V3') |
|
|
|
|
messages = metamaskController.typedMessageManager.getUnapprovedMsgs() |
|
|
|
|
typedMessages = metamaskController.typedMessageManager.messages |
|
|
|
|
msgId = Object.keys(messages)[0] |
|
|
|
|
typedMessages[0].msgParams.metamaskId = parseInt(msgId) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
|
signTypedMsgSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls signTypedMsg in background with no error', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
signTypedMsgSpy = sinon.spy(background, 'signTypedMessage') |
|
|
|
|
|
|
|
|
|
await store.dispatch(actions.signTypedMsg(msgParamsV3)) |
|
|
|
|
assert(signTypedMsgSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('returns expected actions with error', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
const expectedActions = [ |
|
|
|
|
{ type: 'SHOW_LOADING_INDICATION', value: undefined }, |
|
|
|
|
{ type: 'UPDATE_METAMASK_STATE', value: undefined }, |
|
|
|
|
{ type: 'HIDE_LOADING_INDICATION' }, |
|
|
|
|
{ type: 'DISPLAY_WARNING', value: 'error' }, |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
signTypedMsgSpy = sinon.stub(background, 'signTypedMessage') |
|
|
|
|
|
|
|
|
|
signTypedMsgSpy.callsFake((_, callback) => { |
|
|
|
|
callback(new Error('error')) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
await store.dispatch(actions.signTypedMsg()) |
|
|
|
|
assert.fail('Should have thrown error') |
|
|
|
|
} catch (_) { |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#signTx', () => { |
|
|
|
|
|
|
|
|
|
let sendTransactionSpy |
|
|
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
|
global.ethQuery = new EthQuery(provider) |
|
|
|
|
sendTransactionSpy = sinon.stub(global.ethQuery, 'sendTransaction') |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
@ -589,6 +831,7 @@ describe('Actions', () => { |
|
|
|
|
|
|
|
|
|
it('calls sendTransaction in global ethQuery', () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
store.dispatch(actions.signTx()) |
|
|
|
|
assert(sendTransactionSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
@ -608,6 +851,71 @@ describe('Actions', () => { |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#updatedGasData', () => { |
|
|
|
|
it('errors when get code does not return', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
const expectedActions = [ |
|
|
|
|
{ type: 'GAS_LOADING_STARTED' }, |
|
|
|
|
{ type: 'UPDATE_SEND_ERRORS', value: { gasLoadingError: 'gasLoadingError' } }, |
|
|
|
|
{ type: 'GAS_LOADING_FINISHED' }, |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
const mockData = { |
|
|
|
|
gasPrice: '0x3b9aca00', //
|
|
|
|
|
blockGasLimit: '0x6ad79a', // 7002010
|
|
|
|
|
selectedAddress: '0x0DCD5D886577d5081B0c52e242Ef29E70Be3E7bc', |
|
|
|
|
to: '0xEC1Adf982415D2Ef5ec55899b9Bfb8BC0f29251B', |
|
|
|
|
value: '0xde0b6b3a7640000', // 1000000000000000000
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
await store.dispatch(actions.updateGasData(mockData)) |
|
|
|
|
assert.fail('Should have thrown error') |
|
|
|
|
} catch (error) { |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#updatedGasData', () => { |
|
|
|
|
|
|
|
|
|
const stub = sinon.stub().returns('0x') |
|
|
|
|
|
|
|
|
|
const mockData = { |
|
|
|
|
gasPrice: '0x3b9aca00', //
|
|
|
|
|
blockGasLimit: '0x6ad79a', // 7002010
|
|
|
|
|
selectedAddress: '0x0DCD5D886577d5081B0c52e242Ef29E70Be3E7bc', |
|
|
|
|
to: '0xEC1Adf982415D2Ef5ec55899b9Bfb8BC0f29251B', |
|
|
|
|
value: '0xde0b6b3a7640000', // 1000000000000000000
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
|
global.eth = { |
|
|
|
|
getCode: stub, |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
|
stub.reset() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('returns default gas limit for basic eth transaction', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
const expectedActions = [ |
|
|
|
|
{ type: 'GAS_LOADING_STARTED' }, |
|
|
|
|
{ type: 'UPDATE_GAS_LIMIT', value: '0x5208' }, |
|
|
|
|
{ type: 'metamask/gas/SET_CUSTOM_GAS_LIMIT', value: '0x5208' }, |
|
|
|
|
{ type: 'UPDATE_SEND_ERRORS', value: { gasLoadingError: null } }, |
|
|
|
|
{ type: 'GAS_LOADING_FINISHED' }, |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
await store.dispatch(actions.updateGasData(mockData)) |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#signTokenTx', () => { |
|
|
|
|
|
|
|
|
|
let tokenSpy |
|
|
|
@ -628,6 +936,61 @@ describe('Actions', () => { |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#updateTransaction', () => { |
|
|
|
|
|
|
|
|
|
let updateTransactionSpy, updateTransactionParamsSpy |
|
|
|
|
|
|
|
|
|
const txParams = { |
|
|
|
|
'from': '0x1', |
|
|
|
|
'gas': '0x5208', |
|
|
|
|
'gasPrice': '0x3b9aca00', |
|
|
|
|
'to': '0x2', |
|
|
|
|
'value': '0x0', |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const txData = { id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: txParams } |
|
|
|
|
|
|
|
|
|
beforeEach( async () => { |
|
|
|
|
await metamaskController.txController.txStateManager.addTx(txData) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
|
updateTransactionSpy.restore() |
|
|
|
|
updateTransactionParamsSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('updates transaction', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
updateTransactionSpy = sinon.spy(background, 'updateTransaction') |
|
|
|
|
updateTransactionParamsSpy = sinon.spy(actions, 'updateTransactionParams') |
|
|
|
|
|
|
|
|
|
const result = [ txData.id, txParams ] |
|
|
|
|
|
|
|
|
|
await store.dispatch(actions.updateTransaction(txData)) |
|
|
|
|
assert(updateTransactionSpy.calledOnce) |
|
|
|
|
assert(updateTransactionParamsSpy.calledOnce) |
|
|
|
|
|
|
|
|
|
assert.deepEqual(updateTransactionParamsSpy.args[0], result) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('rejects with error message', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
updateTransactionSpy = sinon.stub(background, 'updateTransaction') |
|
|
|
|
updateTransactionSpy.callsFake((res, callback) => { |
|
|
|
|
callback(new Error('error')) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
await store.dispatch(actions.updateTransaction(txData)) |
|
|
|
|
assert.fail('Should have thrown error') |
|
|
|
|
} catch (error) { |
|
|
|
|
assert.equal(error.message, 'error') |
|
|
|
|
} |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#lockMetamask', () => { |
|
|
|
|
let backgroundSetLockedSpy |
|
|
|
|
|
|
|
|
@ -635,18 +998,16 @@ describe('Actions', () => { |
|
|
|
|
backgroundSetLockedSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls setLocked', () => { |
|
|
|
|
it('calls setLocked', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
backgroundSetLockedSpy = sinon.spy(background, 'setLocked') |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.lockMetamask()) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(backgroundSetLockedSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
await store.dispatch(actions.lockMetamask()) |
|
|
|
|
assert(backgroundSetLockedSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('returns display warning error with value when setLocked in background callback errors', () => { |
|
|
|
|
it('returns display warning error with value when setLocked in background callback errors', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
const expectedActions = [ |
|
|
|
@ -660,10 +1021,13 @@ describe('Actions', () => { |
|
|
|
|
callback(new Error('error')) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.lockMetamask()) |
|
|
|
|
.then(() => { |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
}) |
|
|
|
|
try { |
|
|
|
|
await store.dispatch(actions.lockMetamask()) |
|
|
|
|
assert.fail('Should have thrown error') |
|
|
|
|
} catch (error) { |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
@ -748,13 +1112,11 @@ describe('Actions', () => { |
|
|
|
|
addTokenSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls addToken in background', () => { |
|
|
|
|
it('calls addToken in background', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
|
|
|
|
|
store.dispatch(actions.addToken()) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(addTokenSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
assert(addTokenSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('errors when addToken in background throws', async () => { |
|
|
|
@ -790,12 +1152,10 @@ describe('Actions', () => { |
|
|
|
|
removeTokenSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls removeToken in background', () => { |
|
|
|
|
it('calls removeToken in background', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
store.dispatch(actions.removeToken()) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(removeTokenSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
store.dispatch(await actions.removeToken()) |
|
|
|
|
assert(removeTokenSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('errors when removeToken in background fails', async () => { |
|
|
|
@ -910,7 +1270,7 @@ describe('Actions', () => { |
|
|
|
|
exportAccountSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('returns expected actions for successful action', () => { |
|
|
|
|
it('returns expected actions for successful action', async () => { |
|
|
|
|
const store = mockStore(devState) |
|
|
|
|
const expectedActions = [ |
|
|
|
|
{ type: 'SHOW_LOADING_INDICATION', value: undefined }, |
|
|
|
@ -921,12 +1281,10 @@ describe('Actions', () => { |
|
|
|
|
submitPasswordSpy = sinon.spy(background, 'submitPassword') |
|
|
|
|
exportAccountSpy = sinon.spy(background, 'exportAccount') |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.exportAccount(password, '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc')) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(submitPasswordSpy.calledOnce) |
|
|
|
|
assert(exportAccountSpy.calledOnce) |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
}) |
|
|
|
|
await store.dispatch(actions.exportAccount(password, '0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc')) |
|
|
|
|
assert(submitPasswordSpy.calledOnce) |
|
|
|
|
assert(exportAccountSpy.calledOnce) |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('returns action errors when first func callback errors', async () => { |
|
|
|
@ -1082,9 +1440,7 @@ describe('Actions', () => { |
|
|
|
|
getTransactionCountSpy = sinon.spy(global.ethQuery, 'getTransactionCount') |
|
|
|
|
|
|
|
|
|
store.dispatch(actions.updateNetworkNonce()) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(getTransactionCountSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
assert(getTransactionCountSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('errors when getTransactionCount throws', async () => { |
|
|
|
@ -1155,7 +1511,7 @@ describe('Actions', () => { |
|
|
|
|
fetchMock.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls expected actions', () => { |
|
|
|
|
it('calls expected actions', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
setCurrentLocaleSpy = sinon.spy(background, 'setCurrentLocale') |
|
|
|
|
|
|
|
|
@ -1165,14 +1521,12 @@ describe('Actions', () => { |
|
|
|
|
{ type: 'HIDE_LOADING_INDICATION' }, |
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.updateCurrentLocale('en')) |
|
|
|
|
.then(() => { |
|
|
|
|
assert(setCurrentLocaleSpy.calledOnce) |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
}) |
|
|
|
|
await store.dispatch(actions.updateCurrentLocale('en')) |
|
|
|
|
assert(setCurrentLocaleSpy.calledOnce) |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls expected actions', () => { |
|
|
|
|
it('errors when setCurrentLocale throws', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
const expectedActions = [ |
|
|
|
|
{ type: 'SHOW_LOADING_INDICATION', value: undefined }, |
|
|
|
@ -1184,48 +1538,54 @@ describe('Actions', () => { |
|
|
|
|
callback(new Error('error')) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
return store.dispatch(actions.updateCurrentLocale('en')) |
|
|
|
|
.then(() => { |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
}) |
|
|
|
|
try { |
|
|
|
|
await store.dispatch(actions.updateCurrentLocale('en')) |
|
|
|
|
assert.fail('Should have thrown error') |
|
|
|
|
} catch (_) { |
|
|
|
|
assert.deepEqual(store.getActions(), expectedActions) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#markPasswordForgotten', () => { |
|
|
|
|
let markPasswordForgottenSpy |
|
|
|
|
let markPasswordForgottenSpy, forgotPasswordSpy |
|
|
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
|
markPasswordForgottenSpy = sinon.stub(background, 'markPasswordForgotten') |
|
|
|
|
markPasswordForgottenSpy = sinon.spy(background, 'markPasswordForgotten') |
|
|
|
|
forgotPasswordSpy = sinon.spy(actions, 'forgotPassword') |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
|
markPasswordForgottenSpy.restore() |
|
|
|
|
forgotPasswordSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls markPasswordForgotten', () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
store.dispatch(actions.markPasswordForgotten()) |
|
|
|
|
assert(forgotPasswordSpy.calledOnce) |
|
|
|
|
assert(markPasswordForgottenSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
describe('#unMarkPasswordForgotten', () => { |
|
|
|
|
let unMarkPasswordForgottenSpy |
|
|
|
|
let unMarkPasswordForgottenSpy, forgotPasswordSpy |
|
|
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
|
unMarkPasswordForgottenSpy = sinon.stub(background, 'unMarkPasswordForgotten') |
|
|
|
|
unMarkPasswordForgottenSpy = sinon.stub(background, 'unMarkPasswordForgotten').returns(forgotPasswordSpy) |
|
|
|
|
forgotPasswordSpy = sinon.spy(actions, 'forgotPassword') |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
afterEach(() => { |
|
|
|
|
unMarkPasswordForgottenSpy.restore() |
|
|
|
|
forgotPasswordSpy.restore() |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
it('calls unMarkPasswordForgotten', () => { |
|
|
|
|
it('calls unMarkPasswordForgotten', async () => { |
|
|
|
|
const store = mockStore() |
|
|
|
|
store.dispatch(actions.unMarkPasswordForgotten()) |
|
|
|
|
store.dispatch(await actions.unMarkPasswordForgotten()) |
|
|
|
|
assert(unMarkPasswordForgottenSpy.calledOnce) |
|
|
|
|
}) |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}) |
|
|
|
|