Tidy up transaction-related unit tests (#8362)

Co-Authored-By: Erik Marks <25517051+rekmarks@users.noreply.github.com>
feature/default_network_editable
Whymarrh Whitby 5 years ago committed by GitHub
parent a83d26486c
commit e05db747f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 128
      test/unit/app/controllers/transactions/pending-tx-test.js
  2. 4
      test/unit/app/controllers/transactions/recipient-blacklist-checker-test.js
  3. 184
      test/unit/app/controllers/transactions/tx-controller-test.js
  4. 7
      test/unit/app/controllers/transactions/tx-gas-util-test.js
  5. 2
      test/unit/app/controllers/transactions/tx-helper-test.js
  6. 22
      test/unit/app/controllers/transactions/tx-state-history-helper-test.js
  7. 6
      test/unit/app/controllers/transactions/tx-state-manager-test.js
  8. 20
      test/unit/app/controllers/transactions/tx-utils-test.js

@ -1,13 +1,11 @@
import assert from 'assert' import { strict as assert } from 'assert'
import sinon from 'sinon'
import { createTestProviderTools } from '../../../../stub/provider' import { createTestProviderTools } from '../../../../stub/provider'
import PendingTransactionTracker from '../../../../../app/scripts/controllers/transactions/pending-tx-tracker' import PendingTransactionTracker from '../../../../../app/scripts/controllers/transactions/pending-tx-tracker'
import MockTxGen from '../../../../lib/mock-tx-gen' import MockTxGen from '../../../../lib/mock-tx-gen'
import sinon from 'sinon'
describe('PendingTransactionTracker', function () { describe('PendingTransactionTracker', function () {
let pendingTxTracker, txMeta, txMetaNoHash, providerResultStub, let pendingTxTracker, txMeta, txMetaNoHash, providerResultStub, provider, txMeta3, txList, knownErrors
provider, txMeta3, txList, knownErrors
this.timeout(10000) this.timeout(10000)
beforeEach(function () { beforeEach(function () {
@ -90,9 +88,9 @@ describe('PendingTransactionTracker', function () {
}) })
describe('#_checkPendingTx', function () { describe('#_checkPendingTx', function () {
it('should emit \'tx:failed\' if the txMeta does not have a hash', function (done) { it("should emit 'tx:failed' if the txMeta does not have a hash", function (done) {
pendingTxTracker.once('tx:failed', (txId) => { pendingTxTracker.once('tx:failed', (txId) => {
assert(txId, txMetaNoHash.id, 'should pass txId') assert.equal(txId, txMetaNoHash.id, 'should pass txId')
done() done()
}) })
pendingTxTracker._checkPendingTx(txMetaNoHash) pendingTxTracker._checkPendingTx(txMetaNoHash)
@ -116,29 +114,27 @@ describe('PendingTransactionTracker', function () {
providerResultStub['eth_getTransactionCount'] = '0x02' providerResultStub['eth_getTransactionCount'] = '0x02'
providerResultStub['eth_getTransactionReceipt'] = {} providerResultStub['eth_getTransactionReceipt'] = {}
pendingTxTracker.once('tx:dropped', (id) => { pendingTxTracker.once('tx:dropped', (id) => {
if (id === txMeta.id) { if (id !== txMeta.id) {
delete providerResultStub['eth_getTransactionCount']
delete providerResultStub['eth_getTransactionReceipt']
if (counter === 3) {
return done()
} else {
return done(new Error(`Counter does not equal 3 got ${counter} instead`))
}
} else {
done(new Error('wrong tx Id')) done(new Error('wrong tx Id'))
return
}
delete providerResultStub['eth_getTransactionCount']
delete providerResultStub['eth_getTransactionReceipt']
if (counter === 3) {
return done()
} else {
return done(new Error(`Counter does not equal 3 got ${counter} instead`))
} }
}) })
pendingTxTracker._checkPendingTx(txMeta).then(() => { /* eslint-disable no-sequences */
++counter pendingTxTracker._checkPendingTx(txMeta)
pendingTxTracker._checkPendingTx(txMeta).then(() => { .then(() => (counter++, pendingTxTracker._checkPendingTx(txMeta)))
++counter .then(() => (counter++, pendingTxTracker._checkPendingTx(txMeta)))
pendingTxTracker._checkPendingTx(txMeta).then(() => { .then(() => (counter++, pendingTxTracker._checkPendingTx(txMeta)))
++counter .catch(done)
pendingTxTracker._checkPendingTx(txMeta) /* eslint-enable no-sequences */
})
})
}).catch(done)
}) })
@ -149,7 +145,7 @@ describe('PendingTransactionTracker', function () {
}) })
describe('#_checkPendingTxs', function () { describe('#_checkPendingTxs', function () {
it('should warp all txMeta\'s in #updatePendingTxs', function (done) { it("should wrap all txMeta's in #updatePendingTxs", function (done) {
const txMeta2 = txMeta3 = txMeta const txMeta2 = txMeta3 = txMeta
txMeta2.id = 2 txMeta2.id = 2
txMeta3.id = 3 txMeta3.id = 3
@ -196,7 +192,7 @@ describe('PendingTransactionTracker', function () {
.catch(done) .catch(done)
pendingTxTracker.resubmitPendingTxs(blockNumberStub) pendingTxTracker.resubmitPendingTxs(blockNumberStub)
}) })
it('should not emit \'tx:failed\' if the txMeta throws a known txError', function (done) { it("should not emit 'tx:failed' if the txMeta throws a known txError", function (done) {
knownErrors = [ knownErrors = [
// geth // geth
' Replacement transaction Underpriced ', ' Replacement transaction Underpriced ',
@ -223,7 +219,7 @@ describe('PendingTransactionTracker', function () {
pendingTxTracker.resubmitPendingTxs(blockNumberStub) pendingTxTracker.resubmitPendingTxs(blockNumberStub)
}) })
it('should emit \'tx:warning\' if it encountered a real error', function (done) { it("should emit 'tx:warning' if it encountered a real error", function (done) {
pendingTxTracker.once('tx:warning', (txMeta, err) => { pendingTxTracker.once('tx:warning', (txMeta, err) => {
if (err.message === 'im some real error') { if (err.message === 'im some real error') {
const matchingTx = txList.find((tx) => tx.id === txMeta.id) const matchingTx = txList.find((tx) => tx.id === txMeta.id)
@ -269,47 +265,29 @@ describe('PendingTransactionTracker', function () {
pendingTxTracker.publishTransaction.restore() pendingTxTracker.publishTransaction.restore()
}) })
it('should publish the transaction', function (done) { it('should publish the transaction', async function () {
enoughBalance = '0x100000' enoughBalance = '0x100000'
// Stubbing out current account state: // Stubbing out current account state:
// Adding the fake tx: // Adding the fake tx:
pendingTxTracker._resubmitTx(txMeta) await pendingTxTracker._resubmitTx(txMeta)
.then(() => done()) assert.equal(pendingTxTracker.publishTransaction.callCount, 1, 'should call publish transaction')
.catch((err) => {
assert.ifError(err, 'should not throw an error')
done(err)
})
assert.equal(pendingTxTracker.publishTransaction.callCount, 1, 'Should call publish transaction')
}) })
it('should not publish the transaction if the limit of retries has been exceeded', function (done) { it('should not publish the transaction if the limit of retries has been exceeded', async function () {
enoughBalance = '0x100000' enoughBalance = '0x100000'
const mockLatestBlockNumber = '0x5' const mockLatestBlockNumber = '0x5'
pendingTxTracker._resubmitTx(txMetaToTestExponentialBackoff, mockLatestBlockNumber) await pendingTxTracker._resubmitTx(txMetaToTestExponentialBackoff, mockLatestBlockNumber)
.then(() => done()) assert.equal(pendingTxTracker.publishTransaction.callCount, 0, 'should NOT call publish transaction')
.catch((err) => {
assert.ifError(err, 'should not throw an error')
done(err)
})
assert.equal(pendingTxTracker.publishTransaction.callCount, 0, 'Should NOT call publish transaction')
}) })
it('should publish the transaction if the number of blocks since last retry exceeds the last set limit', function (done) { it('should publish the transaction if the number of blocks since last retry exceeds the last set limit', async function () {
enoughBalance = '0x100000' enoughBalance = '0x100000'
const mockLatestBlockNumber = '0x11' const mockLatestBlockNumber = '0x11'
pendingTxTracker._resubmitTx(txMetaToTestExponentialBackoff, mockLatestBlockNumber) await pendingTxTracker._resubmitTx(txMetaToTestExponentialBackoff, mockLatestBlockNumber)
.then(() => done()) assert.equal(pendingTxTracker.publishTransaction.callCount, 1, 'should call publish transaction')
.catch((err) => {
assert.ifError(err, 'should not throw an error')
done(err)
})
assert.equal(pendingTxTracker.publishTransaction.callCount, 1, 'Should call publish transaction')
}) })
it('should call opts.approveTransaction with the id if the tx is not signed', async function () { it('should call opts.approveTransaction with the id if the tx is not signed', async function () {
@ -318,8 +296,7 @@ describe('PendingTransactionTracker', function () {
} }
const approveMock = sinon.stub(pendingTxTracker, 'approveTransaction') const approveMock = sinon.stub(pendingTxTracker, 'approveTransaction')
pendingTxTracker._resubmitTx(stubTx) await pendingTxTracker._resubmitTx(stubTx)
assert.ok(approveMock.called) assert.ok(approveMock.called)
approveMock.restore() approveMock.restore()
}) })
@ -337,22 +314,18 @@ describe('PendingTransactionTracker', function () {
}, },
rawTx: '0xf86c808504a817c800827b0d940c62bb85faa3311a998d3aba8098c1235c564966880de0b6b3a7640000802aa08ff665feb887a25d4099e40e11f0fef93ee9608f404bd3f853dd9e84ed3317a6a02ec9d3d1d6e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d', rawTx: '0xf86c808504a817c800827b0d940c62bb85faa3311a998d3aba8098c1235c564966880de0b6b3a7640000802aa08ff665feb887a25d4099e40e11f0fef93ee9608f404bd3f853dd9e84ed3317a6a02ec9d3d1d6e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d',
} }
it('should return false when the nonce is the suggested network nonce', function (done) { it('should return false when the nonce is the suggested network nonce', async function () {
providerResultStub['eth_getTransactionCount'] = '0x01' providerResultStub['eth_getTransactionCount'] = '0x01'
providerResultStub['eth_getTransactionReceipt'] = {} providerResultStub['eth_getTransactionReceipt'] = {}
pendingTxTracker._checkIftxWasDropped(txMeta, {}).then((dropped) => { const dropped = await pendingTxTracker._checkIftxWasDropped(txMeta, {})
assert(!dropped, 'should be false') assert.ok(!dropped, 'should be false')
done()
}).catch(done)
}) })
it('should return true when the network nonce is higher then the txMeta nonce', function (done) { it('should return true when the network nonce is higher then the txMeta nonce', async function () {
providerResultStub['eth_getTransactionCount'] = '0x02' providerResultStub['eth_getTransactionCount'] = '0x02'
providerResultStub['eth_getTransactionReceipt'] = {} providerResultStub['eth_getTransactionReceipt'] = {}
pendingTxTracker._checkIftxWasDropped(txMeta, {}).then((dropped) => { const dropped = await pendingTxTracker._checkIftxWasDropped(txMeta, {})
assert(dropped, 'should be true') assert.ok(dropped, 'should be true')
done()
}).catch(done)
}) })
}) })
@ -387,33 +360,26 @@ describe('PendingTransactionTracker', function () {
} }
}) })
it('should return false if nonce has not been taken', function (done) { it('should return false if nonce has not been taken', async function () {
pendingTxTracker._checkIfNonceIsTaken({ const taken = await pendingTxTracker._checkIfNonceIsTaken({
txParams: { txParams: {
from: '0x1678a085c290ebd122dc42cba69373b5953b831d', from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
nonce: '0x3', nonce: '0x3',
value: '0xfffff', value: '0xfffff',
}, },
}) })
.then((taken) => { assert.ok(!taken)
assert.ok(!taken)
done()
})
.catch(done)
}) })
it('should return true if nonce has been taken', function (done) { it('should return true if nonce has been taken', async function () {
pendingTxTracker._checkIfNonceIsTaken({ const taken = await pendingTxTracker._checkIfNonceIsTaken({
txParams: { txParams: {
from: '0x1678a085c290ebd122dc42cba69373b5953b831d', from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
nonce: '0x2', nonce: '0x2',
value: '0xfffff', value: '0xfffff',
}, },
}).then((taken) => {
assert.ok(taken)
done()
}) })
.catch(done) assert.ok(taken)
}) })
}) })
}) })

@ -1,4 +1,4 @@
import assert from 'assert' import { strict as assert } from 'assert'
import recipientBlackListChecker from '../../../../../app/scripts/controllers/transactions/lib/recipient-blacklist-checker' import recipientBlackListChecker from '../../../../../app/scripts/controllers/transactions/lib/recipient-blacklist-checker'
import { ROPSTEN_CODE, RINKEBY_CODE, KOVAN_CODE, GOERLI_CODE } from '../../../../../app/scripts/controllers/network/enums' import { ROPSTEN_CODE, RINKEBY_CODE, KOVAN_CODE, GOERLI_CODE } from '../../../../../app/scripts/controllers/network/enums'
import KeyringController from 'eth-keyring-controller' import KeyringController from 'eth-keyring-controller'
@ -22,7 +22,7 @@ describe('Recipient Blacklist Checker', function () {
it('does not fail on test networks', function () { it('does not fail on test networks', function () {
let callCount = 0 let callCount = 0
const networks = [ROPSTEN_CODE, RINKEBY_CODE, KOVAN_CODE, GOERLI_CODE] const networks = [ROPSTEN_CODE, RINKEBY_CODE, KOVAN_CODE, GOERLI_CODE]
for (const networkId in networks) { for (const networkId of networks) {
publicAccounts.forEach((account) => { publicAccounts.forEach((account) => {
recipientBlackListChecker.checkAccount(networkId, account) recipientBlackListChecker.checkAccount(networkId, account)
callCount++ callCount++

@ -1,4 +1,4 @@
import assert from 'assert' import { strict as assert } from 'assert'
import EventEmitter from 'events' import EventEmitter from 'events'
import ethUtil from 'ethereumjs-util' import ethUtil from 'ethereumjs-util'
import EthTx from 'ethereumjs-tx' import EthTx from 'ethereumjs-tx'
@ -53,12 +53,12 @@ describe('Transaction Controller', function () {
}) })
describe('#getState', function () { describe('#getState', function () {
it('should return a state object with the right keys and datat types', function () { it('should return a state object with the right keys and data types', function () {
const exposedState = txController.getState() const exposedState = txController.getState()
assert('unapprovedTxs' in exposedState, 'state should have the key unapprovedTxs') assert.ok('unapprovedTxs' in exposedState, 'state should have the key unapprovedTxs')
assert('currentNetworkTxList' in exposedState, 'state should have the key currentNetworkTxList') assert.ok('currentNetworkTxList' in exposedState, 'state should have the key currentNetworkTxList')
assert(exposedState && typeof exposedState.unapprovedTxs === 'object', 'should be an object') assert.ok(typeof exposedState?.unapprovedTxs === 'object', 'should be an object')
assert(Array.isArray(exposedState.currentNetworkTxList), 'should be an array') assert.ok(Array.isArray(exposedState.currentNetworkTxList), 'should be an array')
}) })
}) })
@ -135,37 +135,29 @@ describe('Transaction Controller', function () {
stub.restore() stub.restore()
}) })
it('should resolve when finished and status is submitted and resolve with the hash', function (done) { it('should resolve when finished and status is submitted and resolve with the hash', async function () {
txController.once('newUnapprovedTx', (txMetaFromEmit) => { txController.once('newUnapprovedTx', (txMetaFromEmit) => {
setTimeout(() => { setTimeout(() => {
txController.setTxHash(txMetaFromEmit.id, '0x0') txController.setTxHash(txMetaFromEmit.id, '0x0')
txController.txStateManager.setTxStatusSubmitted(txMetaFromEmit.id) txController.txStateManager.setTxStatusSubmitted(txMetaFromEmit.id)
}, 10) })
}) })
txController.newUnapprovedTransaction(txParams) const hash = await txController.newUnapprovedTransaction(txParams)
.then((hash) => { assert.ok(hash, 'newUnapprovedTransaction needs to return the hash')
assert(hash, 'newUnapprovedTransaction needs to return the hash')
done()
})
.catch(done)
}) })
it('should reject when finished and status is rejected', function (done) { it('should reject when finished and status is rejected', async function () {
txController.once('newUnapprovedTx', (txMetaFromEmit) => { txController.once('newUnapprovedTx', (txMetaFromEmit) => {
setTimeout(() => { setTimeout(() => {
txController.txStateManager.setTxStatusRejected(txMetaFromEmit.id) txController.txStateManager.setTxStatusRejected(txMetaFromEmit.id)
}, 10) })
}) })
txController.newUnapprovedTransaction(txParams) await assert.rejects(
.catch((err) => { () => txController.newUnapprovedTransaction(txParams),
if (err.message === 'MetaMask Tx Signature: User denied transaction signature.') { { message: 'MetaMask Tx Signature: User denied transaction signature.' },
done() )
} else {
done(err)
}
})
}) })
}) })
@ -183,74 +175,55 @@ describe('Transaction Controller', function () {
getPermittedAccounts.restore() getPermittedAccounts.restore()
}) })
it('should add an unapproved transaction and return a valid txMeta', function (done) { it('should add an unapproved transaction and return a valid txMeta', async function () {
txController.addUnapprovedTransaction({ from: selectedAddress }) const txMeta = await txController.addUnapprovedTransaction({ from: selectedAddress })
.then((txMeta) => { assert.ok('id' in txMeta, 'should have a id')
assert(('id' in txMeta), 'should have a id') assert.ok('time' in txMeta, 'should have a time stamp')
assert(('time' in txMeta), 'should have a time stamp') assert.ok('metamaskNetworkId' in txMeta, 'should have a metamaskNetworkId')
assert(('metamaskNetworkId' in txMeta), 'should have a metamaskNetworkId') assert.ok('txParams' in txMeta, 'should have a txParams')
assert(('txParams' in txMeta), 'should have a txParams') assert.ok('history' in txMeta, 'should have a history')
assert(('history' in txMeta), 'should have a history')
const memTxMeta = txController.txStateManager.getTx(txMeta.id)
const memTxMeta = txController.txStateManager.getTx(txMeta.id) assert.deepEqual(txMeta, memTxMeta)
assert.deepEqual(txMeta, memTxMeta, `txMeta should be stored in txController after adding it\n expected: ${txMeta} \n got: ${memTxMeta}`)
done()
}).catch(done)
}) })
it('should emit newUnapprovedTx event and pass txMeta as the first argument', function (done) { it('should emit newUnapprovedTx event and pass txMeta as the first argument', function (done) {
providerResultStub.eth_gasPrice = '4a817c800' providerResultStub.eth_gasPrice = '4a817c800'
txController.once('newUnapprovedTx', (txMetaFromEmit) => { txController.once('newUnapprovedTx', (txMetaFromEmit) => {
assert(txMetaFromEmit, 'txMeta is falsey') assert.ok(txMetaFromEmit, 'txMeta is falsy')
done() done()
}) })
txController.addUnapprovedTransaction({ from: selectedAddress }) txController.addUnapprovedTransaction({ from: selectedAddress })
.catch(done) .catch(done)
}) })
it('should fail if recipient is public', function (done) { it('should fail if recipient is public', async function () {
txController.networkStore = new ObservableStore(1) txController.networkStore = new ObservableStore(1)
txController.addUnapprovedTransaction({ from: selectedAddress, to: '0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2' }) await assert.rejects(
.catch((err) => { () => txController.addUnapprovedTransaction({ from: selectedAddress, to: '0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2' }),
if (err.message === 'Recipient is a public account') { { message: 'Recipient is a public account' },
done() )
} else {
done(err)
}
})
}) })
it('should fail if the from address isn\'t the selected address', function (done) { it("should fail if the from address isn't the selected address", async function () {
txController.addUnapprovedTransaction({ from: '0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2' }) await assert.rejects(() => txController.addUnapprovedTransaction({ from: '0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2' }))
.then(() => {
assert.fail('transaction should not have been added')
done()
})
.catch(() => {
assert.ok('pass')
done()
})
}) })
it('should not fail if recipient is public but not on mainnet', function (done) { it('should not fail if recipient is public but not on mainnet', function (done) {
txController.once('newUnapprovedTx', (txMetaFromEmit) => { txController.once('newUnapprovedTx', (txMetaFromEmit) => {
assert(txMetaFromEmit, 'txMeta is falsey') assert.ok(txMetaFromEmit, 'txMeta is falsy')
done() done()
}) })
txController.addUnapprovedTransaction({ from: selectedAddress, to: '0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2' }) txController.addUnapprovedTransaction({ from: selectedAddress, to: '0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2' })
.catch(done) .catch(done)
}) })
it('should fail if netId is loading', function (done) { it('should fail if netId is loading', async function () {
txController.networkStore = new ObservableStore('loading') txController.networkStore = new ObservableStore('loading')
txController.addUnapprovedTransaction({ from: selectedAddress, to: '0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2' }) await assert.rejects(
.catch((err) => { () => txController.addUnapprovedTransaction({ from: selectedAddress, to: '0x0d1d4e623D10F9FBA5Db95830F7d3839406C6AF2' }),
if (err.message === 'MetaMask is having trouble connecting to the network') { { message: 'MetaMask is having trouble connecting to the network' },
done() )
} else {
done(err)
}
})
}) })
}) })
@ -268,9 +241,9 @@ describe('Transaction Controller', function () {
providerResultStub.eth_estimateGas = '5209' providerResultStub.eth_estimateGas = '5209'
const txMetaWithDefaults = await txController.addTxGasDefaults(txMeta) const txMetaWithDefaults = await txController.addTxGasDefaults(txMeta)
assert(txMetaWithDefaults.txParams.value, '0x0', 'should have added 0x0 as the value') assert.equal(txMetaWithDefaults.txParams.value, '0x0', 'should have added 0x0 as the value')
assert(txMetaWithDefaults.txParams.gasPrice, 'should have added the gas price') assert.ok(txMetaWithDefaults.txParams.gasPrice, 'should have added the gas price')
assert(txMetaWithDefaults.txParams.gas, 'should have added the gas field') assert.ok(txMetaWithDefaults.txParams.gas, 'should have added the gas field')
}) })
}) })
@ -303,7 +276,7 @@ describe('Transaction Controller', function () {
}) })
describe('#approveTransaction', function () { describe('#approveTransaction', function () {
it('does not overwrite set values', function (done) { it('does not overwrite set values', async function () {
const originalValue = '0x01' const originalValue = '0x01'
const txMeta = { const txMeta = {
id: '1', id: '1',
@ -329,29 +302,25 @@ describe('Transaction Controller', function () {
txController.txStateManager.setTxStatusSubmitted('1') txController.txStateManager.setTxStatusSubmitted('1')
}) })
txController.approveTransaction(txMeta.id).then(() => { await txController.approveTransaction(txMeta.id)
const result = txController.txStateManager.getTx(txMeta.id) const result = txController.txStateManager.getTx(txMeta.id)
const params = result.txParams const params = result.txParams
assert.equal(params.gas, originalValue, 'gas unmodified') assert.equal(params.gas, originalValue, 'gas unmodified')
assert.equal(params.gasPrice, originalValue, 'gas price unmodified') assert.equal(params.gasPrice, originalValue, 'gas price unmodified')
assert.equal(result.hash, originalValue, `hash was set \n got: ${result.hash} \n expected: ${originalValue}`) assert.equal(result.hash, originalValue)
assert.equal(result.status, 'submitted', 'Should have reached the submitted status.') assert.equal(result.status, 'submitted', 'should have reached the submitted status.')
signStub.restore() signStub.restore()
pubStub.restore() pubStub.restore()
done()
}).catch(done)
}) })
}) })
describe('#sign replay-protected tx', function () { describe('#sign replay-protected tx', function () {
it('prepares a tx with the chainId set', function (done) { it('prepares a tx with the chainId set', async function () {
txController.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop) txController.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, noop)
txController.signTransaction('1').then((rawTx) => { const rawTx = await txController.signTransaction('1')
const ethTx = new EthTx(ethUtil.toBuffer(rawTx)) const ethTx = new EthTx(ethUtil.toBuffer(rawTx))
assert.equal(ethTx.getChainId(), currentNetworkId) assert.equal(ethTx.getChainId(), currentNetworkId)
done()
}).catch(done)
}) })
}) })
@ -408,7 +377,6 @@ describe('Transaction Controller', function () {
txController.cancelTransaction(0) txController.cancelTransaction(0)
}) })
}) })
describe('#createSpeedUpTransaction', function () { describe('#createSpeedUpTransaction', function () {
@ -511,7 +479,7 @@ describe('Transaction Controller', function () {
}) })
describe('#retryTransaction', function () { describe('#retryTransaction', function () {
it('should create a new txMeta with the same txParams as the original one but with a higher gasPrice', function (done) { it('should create a new txMeta with the same txParams as the original one but with a higher gasPrice', async function () {
const txParams = { const txParams = {
gasPrice: '0xee6b2800', gasPrice: '0xee6b2800',
nonce: '0x00', nonce: '0x00',
@ -522,17 +490,14 @@ describe('Transaction Controller', function () {
txController.txStateManager._saveTxList([ txController.txStateManager._saveTxList([
{ id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams, history: [{}] }, { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams, history: [{}] },
]) ])
txController.retryTransaction(1) const txMeta = await txController.retryTransaction(1)
.then((txMeta) => { assert.equal(txMeta.txParams.gasPrice, '0x10642ac00', 'gasPrice should have a %10 gasPrice bump')
assert.equal(txMeta.txParams.gasPrice, '0x10642ac00', 'gasPrice should have a %10 gasPrice bump') assert.equal(txMeta.txParams.nonce, txParams.nonce, 'nonce should be the same')
assert.equal(txMeta.txParams.nonce, txParams.nonce, 'nonce should be the same') assert.equal(txMeta.txParams.from, txParams.from, 'from should be the same')
assert.equal(txMeta.txParams.from, txParams.from, 'from should be the same') assert.equal(txMeta.txParams.to, txParams.to, 'to should be the same')
assert.equal(txMeta.txParams.to, txParams.to, 'to should be the same') assert.equal(txMeta.txParams.data, txParams.data, 'data should be the same')
assert.equal(txMeta.txParams.data, txParams.data, 'data should be the same') assert.ok(('lastGasPrice' in txMeta), 'should have the key `lastGasPrice`')
assert.ok(('lastGasPrice' in txMeta), 'should have the key `lastGasPrice`') assert.equal(txController.txStateManager.getTxList().length, 2)
assert.equal(txController.txStateManager.getTxList().length, 2)
done()
}).catch(done)
}) })
}) })
@ -552,17 +517,16 @@ describe('Transaction Controller', function () {
const droppedTxs = txController.txStateManager.getFilteredTxList({ nonce: '0x01', status: 'dropped' }) const droppedTxs = txController.txStateManager.getFilteredTxList({ nonce: '0x01', status: 'dropped' })
assert.equal(confirmedTx.status, 'confirmed', 'the confirmedTx should remain confirmed') assert.equal(confirmedTx.status, 'confirmed', 'the confirmedTx should remain confirmed')
assert.equal(droppedTxs.length, 6, 'their should be 6 dropped txs') assert.equal(droppedTxs.length, 6, 'their should be 6 dropped txs')
}) })
}) })
describe('#_determineTransactionCategory', function () { describe('#_determineTransactionCategory', function () {
it('should return a simple send transactionCategory when to is truthy but data is falsey', async function () { it('should return a simple send transactionCategory when to is truthy but data is falsy', async function () {
const result = await txController._determineTransactionCategory({ const result = await txController._determineTransactionCategory({
to: '0xabc', to: '0xabc',
data: '', data: '',
}) })
assert.deepEqual(result, { transactionCategory: SEND_ETHER_ACTION_KEY, getCodeResponse: undefined }) assert.deepEqual(result, { transactionCategory: SEND_ETHER_ACTION_KEY, getCodeResponse: null })
}) })
it('should return a token transfer transactionCategory when data is for the respective method call', async function () { it('should return a token transfer transactionCategory when data is for the respective method call', async function () {
@ -581,7 +545,7 @@ describe('Transaction Controller', function () {
assert.deepEqual(result, { transactionCategory: TOKEN_METHOD_APPROVE, getCodeResponse: undefined }) assert.deepEqual(result, { transactionCategory: TOKEN_METHOD_APPROVE, getCodeResponse: undefined })
}) })
it('should return a contract deployment transactionCategory when to is falsey and there is data', async function () { it('should return a contract deployment transactionCategory when to is falsy and there is data', async function () {
const result = await txController._determineTransactionCategory({ const result = await txController._determineTransactionCategory({
to: '', to: '',
data: '0xabd', data: '0xabd',
@ -637,7 +601,7 @@ describe('Transaction Controller', function () {
assert.deepEqual(result, { transactionCategory: CONTRACT_INTERACTION_KEY, getCodeResponse: '0x0a' }) assert.deepEqual(result, { transactionCategory: CONTRACT_INTERACTION_KEY, getCodeResponse: '0x0a' })
}) })
it('should return a contract interaction transactionCategory with the correct getCodeResponse when to is a contract address and data is falsey', async function () { it('should return a contract interaction transactionCategory with the correct getCodeResponse when to is a contract address and data is falsy', async function () {
const _providerResultStub = { const _providerResultStub = {
// 1 gwei // 1 gwei
eth_gasPrice: '0x0de0b6b3a7640000', eth_gasPrice: '0x0de0b6b3a7640000',
@ -671,7 +635,7 @@ describe('Transaction Controller', function () {
}) })
describe('#getPendingTransactions', function () { describe('#getPendingTransactions', function () {
it('should show only submitted and approved transactions as pending transasction', function () { it('should show only submitted and approved transactions as pending transaction', function () {
txController.txStateManager._saveTxList([ txController.txStateManager._saveTxList([
{ id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }, { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} },
{ id: 2, status: 'rejected', metamaskNetworkId: currentNetworkId, txParams: {}, history: [{}] }, { id: 2, status: 'rejected', metamaskNetworkId: currentNetworkId, txParams: {}, history: [{}] },
@ -682,10 +646,10 @@ describe('Transaction Controller', function () {
{ id: 7, status: 'failed', metamaskNetworkId: currentNetworkId, txParams: {}, history: [{}] }, { id: 7, status: 'failed', metamaskNetworkId: currentNetworkId, txParams: {}, history: [{}] },
]) ])
assert(txController.pendingTxTracker.getPendingTransactions().length, 2) assert.equal(txController.pendingTxTracker.getPendingTransactions().length, 2)
const states = txController.pendingTxTracker.getPendingTransactions().map((tx) => tx.status) const states = txController.pendingTxTracker.getPendingTransactions().map((tx) => tx.status)
assert(states.includes('approved'), 'includes approved') assert.ok(states.includes('approved'), 'includes approved')
assert(states.includes('submitted'), 'includes submitted') assert.ok(states.includes('submitted'), 'includes submitted')
}) })
}) })
}) })

@ -1,9 +1,8 @@
import assert from 'assert' import { strict as assert } from 'assert'
import Transaction from 'ethereumjs-tx' import Transaction from 'ethereumjs-tx'
import { hexToBn, bnToHex } from '../../../../../app/scripts/lib/util' import { hexToBn, bnToHex } from '../../../../../app/scripts/lib/util'
import TxUtils from '../../../../../app/scripts/controllers/transactions/tx-gas-utils' import TxUtils from '../../../../../app/scripts/controllers/transactions/tx-gas-utils'
describe('txUtils', function () { describe('txUtils', function () {
let txUtils let txUtils
@ -42,7 +41,7 @@ describe('txUtils', function () {
const inputBn = hexToBn(inputHex) const inputBn = hexToBn(inputHex)
const outputBn = hexToBn(output) const outputBn = hexToBn(output)
const expectedBn = inputBn.muln(1.5) const expectedBn = inputBn.muln(1.5)
assert(outputBn.eq(expectedBn), 'returns 1.5 the input value') assert.ok(outputBn.eq(expectedBn), 'returns 1.5 the input value')
}) })
it('uses original estimatedGas, when above block gas limit', function () { it('uses original estimatedGas, when above block gas limit', function () {
@ -54,7 +53,7 @@ describe('txUtils', function () {
// const inputBn = hexToBn(inputHex) // const inputBn = hexToBn(inputHex)
const outputBn = hexToBn(output) const outputBn = hexToBn(output)
const expectedBn = hexToBn(inputHex) const expectedBn = hexToBn(inputHex)
assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value') assert.ok(outputBn.eq(expectedBn), 'returns the original estimatedGas value')
}) })
it('buffers up to recommend gas limit recommended ceiling', function () { it('buffers up to recommend gas limit recommended ceiling', function () {

@ -1,4 +1,4 @@
import assert from 'assert' import { strict as assert } from 'assert'
import txHelper from '../../../../../ui/lib/tx-helper' import txHelper from '../../../../../ui/lib/tx-helper'
describe('txHelper', function () { describe('txHelper', function () {

@ -1,9 +1,8 @@
import assert from 'assert' import { strict as assert } from 'assert'
import txStateHistoryHelper from '../../../../../app/scripts/controllers/transactions/lib/tx-state-history-helper' import txStateHistoryHelper from '../../../../../app/scripts/controllers/transactions/lib/tx-state-history-helper'
import testVault from '../../../../data/v17-long-history.json' import testVault from '../../../../data/v17-long-history.json'
describe('Transaction state history helper', function () { describe('Transaction state history helper', function () {
describe('#snapshotFromTxMeta', function () { describe('#snapshotFromTxMeta', function () {
it('should clone deep', function () { it('should clone deep', function () {
const input = { const input = {
@ -14,16 +13,16 @@ describe('Transaction state history helper', function () {
}, },
} }
const output = txStateHistoryHelper.snapshotFromTxMeta(input) const output = txStateHistoryHelper.snapshotFromTxMeta(input)
assert('foo' in output, 'has a foo key') assert.ok('foo' in output, 'has a foo key')
assert('bar' in output.foo, 'has a bar key') assert.ok('bar' in output.foo, 'has a bar key')
assert('bam' in output.foo.bar, 'has a bar key') assert.ok('bam' in output.foo.bar, 'has a bar key')
assert.equal(output.foo.bar.bam, 'baz', 'has a baz value') assert.equal(output.foo.bar.bam, 'baz', 'has a baz value')
}) })
it('should remove the history key', function () { it('should remove the history key', function () {
const input = { foo: 'bar', history: 'remembered' } const input = { foo: 'bar', history: 'remembered' }
const output = txStateHistoryHelper.snapshotFromTxMeta(input) const output = txStateHistoryHelper.snapshotFromTxMeta(input)
assert(typeof output.history, 'undefined', 'should remove history') assert.equal(typeof output.history, 'undefined', 'should remove history')
}) })
}) })
@ -47,7 +46,7 @@ describe('Transaction state history helper', function () {
}) })
describe('#replayHistory', function () { describe('#replayHistory', function () {
it('replaying history does not mutate the original obj', function () { it('replaying history does not mutate the original object', function () {
const initialState = { test: true, message: 'hello', value: 1 } const initialState = { test: true, message: 'hello', value: 1 }
const diff1 = [{ const diff1 = [{
'op': 'replace', 'op': 'replace',
@ -64,7 +63,6 @@ describe('Transaction state history helper', function () {
const beforeStateSnapshot = JSON.stringify(initialState) const beforeStateSnapshot = JSON.stringify(initialState)
const latestState = txStateHistoryHelper.replayHistory(history) const latestState = txStateHistoryHelper.replayHistory(history)
const afterStateSnapshot = JSON.stringify(initialState) const afterStateSnapshot = JSON.stringify(initialState)
assert.notEqual(initialState, latestState, 'initial state is not the same obj as the latest state') assert.notEqual(initialState, latestState, 'initial state is not the same obj as the latest state')
assert.equal(beforeStateSnapshot, afterStateSnapshot, 'initial state is not modified during run') assert.equal(beforeStateSnapshot, afterStateSnapshot, 'initial state is not modified during run')
}) })
@ -73,7 +71,6 @@ describe('Transaction state history helper', function () {
describe('#generateHistoryEntry', function () { describe('#generateHistoryEntry', function () {
function generateHistoryEntryTest (note) { function generateHistoryEntryTest (note) {
const prevState = { const prevState = {
someValue: 'value 1', someValue: 'value 1',
foo: { foo: {
@ -97,7 +94,6 @@ describe('Transaction state history helper', function () {
const before = new Date().getTime() const before = new Date().getTime()
const result = txStateHistoryHelper.generateHistoryEntry(prevState, nextState, note) const result = txStateHistoryHelper.generateHistoryEntry(prevState, nextState, note)
const after = new Date().getTime() const after = new Date().getTime()
assert.ok(Array.isArray(result)) assert.ok(Array.isArray(result))
assert.equal(result.length, 3) assert.equal(result.length, 3)
@ -105,11 +101,7 @@ describe('Transaction state history helper', function () {
assert.equal(result[0].op, expectedEntry1.op) assert.equal(result[0].op, expectedEntry1.op)
assert.equal(result[0].path, expectedEntry1.path) assert.equal(result[0].path, expectedEntry1.path)
assert.equal(result[0].value, expectedEntry1.value) assert.equal(result[0].value, expectedEntry1.value)
assert.equal(result[0].value, expectedEntry1.value) assert.equal(result[0].note, note)
if (note) {
assert.equal(result[0].note, note)
}
assert.ok(result[0].timestamp >= before && result[0].timestamp <= after) assert.ok(result[0].timestamp >= before && result[0].timestamp <= after)
const expectedEntry2 = { op: 'replace', path: '/someValue', value: 'value 2' } const expectedEntry2 = { op: 'replace', path: '/someValue', value: 'value 2' }

@ -1,4 +1,4 @@
import assert from 'assert' import { strict as assert } from 'assert'
import TxStateManager from '../../../../../app/scripts/controllers/transactions/tx-state-manager' import TxStateManager from '../../../../../app/scripts/controllers/transactions/tx-state-manager'
import txStateHistoryHelper from '../../../../../app/scripts/controllers/transactions/lib/tx-state-history-helper' import txStateHistoryHelper from '../../../../../app/scripts/controllers/transactions/lib/tx-state-history-helper'
@ -33,7 +33,6 @@ describe('TransactionStateManager', function () {
it('should emit a signed event to signal the exciton of callback', function (done) { it('should emit a signed event to signal the exciton of callback', function (done) {
const tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} } const tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }
const noop = function () { const noop = function () {
assert(true, 'event listener has been triggered and noop executed')
done() done()
} }
txStateManager.addTx(tx) txStateManager.addTx(tx)
@ -57,7 +56,6 @@ describe('TransactionStateManager', function () {
const tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} } const tx = { id: 1, status: 'unapproved', metamaskNetworkId: currentNetworkId, txParams: {} }
txStateManager.addTx(tx) txStateManager.addTx(tx)
const noop = () => { const noop = () => {
assert(true, 'event listener has been triggered and noop executed')
done() done()
} }
txStateManager.on('1:rejected', noop) txStateManager.on('1:rejected', noop)
@ -352,7 +350,7 @@ describe('TransactionStateManager', function () {
it('should remove the transaction from the storage', function () { it('should remove the transaction from the storage', function () {
txStateManager._saveTxList([ { id: 1 } ]) txStateManager._saveTxList([ { id: 1 } ])
txStateManager._removeTx(1) txStateManager._removeTx(1)
assert(!txStateManager.getFullTxList().length, 'txList should be empty') assert.ok(!txStateManager.getFullTxList().length, 'txList should be empty')
}) })
it('should only remove the transaction with ID 1 from the storage', function () { it('should only remove the transaction with ID 1 from the storage', function () {

@ -1,7 +1,6 @@
import assert from 'assert' import { strict as assert } from 'assert'
import * as txUtils from '../../../../../app/scripts/controllers/transactions/lib/util' import * as txUtils from '../../../../../app/scripts/controllers/transactions/lib/util'
describe('txUtils', function () { describe('txUtils', function () {
describe('#validateTxParams', function () { describe('#validateTxParams', function () {
it('does not throw for positive values', function () { it('does not throw for positive values', function () {
@ -37,27 +36,26 @@ describe('txUtils', function () {
let normalizedTxParams = txUtils.normalizeTxParams(txParams) let normalizedTxParams = txUtils.normalizeTxParams(txParams)
assert(!normalizedTxParams.chainId, 'their should be no chainId') assert.ok(!normalizedTxParams.chainId, 'there should be no chainId')
assert(!normalizedTxParams.to, 'their should be no to address if null') assert.ok(!normalizedTxParams.to, 'there should be no to address if null')
assert.equal(normalizedTxParams.from.slice(0, 2), '0x', 'from should be hexPrefixd') assert.equal(normalizedTxParams.from.slice(0, 2), '0x', 'from should be hex-prefixed')
assert.equal(normalizedTxParams.data.slice(0, 2), '0x', 'data should be hexPrefixd') assert.equal(normalizedTxParams.data.slice(0, 2), '0x', 'data should be hex-prefixed')
assert(!('random' in normalizedTxParams), 'their should be no random key in normalizedTxParams') assert.ok(!('random' in normalizedTxParams), 'there should be no random key in normalizedTxParams')
txParams.to = 'a7df1beDBF813f57096dF77FCd515f0B3900e402' txParams.to = 'a7df1beDBF813f57096dF77FCd515f0B3900e402'
normalizedTxParams = txUtils.normalizeTxParams(txParams) normalizedTxParams = txUtils.normalizeTxParams(txParams)
assert.equal(normalizedTxParams.to.slice(0, 2), '0x', 'to should be hexPrefixd') assert.equal(normalizedTxParams.to.slice(0, 2), '0x', 'to should be hex-prefixed')
}) })
}) })
describe('#validateRecipient', function () { describe('#validateRecipient', function () {
it('removes recipient for txParams with 0x when contract data is provided', function () { it('removes recipient for txParams with 0x when contract data is provided', function () {
const zeroRecipientandDataTxParams = { const zeroRecipientDataTxParams = {
from: '0x1678a085c290ebd122dc42cba69373b5953b831d', from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
to: '0x', to: '0x',
data: 'bytecode', data: 'bytecode',
} }
const sanitizedTxParams = txUtils.validateRecipient(zeroRecipientandDataTxParams) const sanitizedTxParams = txUtils.validateRecipient(zeroRecipientDataTxParams)
assert.deepEqual(sanitizedTxParams, { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', data: 'bytecode' }, 'no recipient with 0x') assert.deepEqual(sanitizedTxParams, { from: '0x1678a085c290ebd122dc42cba69373b5953b831d', data: 'bytecode' }, 'no recipient with 0x')
}) })

Loading…
Cancel
Save