aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorkumavis <kumavis@users.noreply.github.com>2017-08-09 14:30:58 +0800
committerGitHub <noreply@github.com>2017-08-09 14:30:58 +0800
commit0188e7b94d85b45a783f9e3d5c182a8ffcaeac2e (patch)
tree428154973b91dfb2f8519777e67da7a6c75530b3 /test
parent5e9926b0d035a5ba946080e94777ac0bd887d396 (diff)
parent57f6fce6b2524c4b36b591da5e600d0652f4077e (diff)
downloadtangerine-wallet-browser-0188e7b94d85b45a783f9e3d5c182a8ffcaeac2e.tar.gz
tangerine-wallet-browser-0188e7b94d85b45a783f9e3d5c182a8ffcaeac2e.tar.zst
tangerine-wallet-browser-0188e7b94d85b45a783f9e3d5c182a8ffcaeac2e.zip
Merge branch 'master' into NewUI-flat
Diffstat (limited to 'test')
-rw-r--r--test/stub/provider.js25
-rw-r--r--test/unit/message-manager-test.js2
-rw-r--r--test/unit/nonce-tracker-test.js3
-rw-r--r--test/unit/pending-tx-test.js260
-rw-r--r--test/unit/tx-controller-test.js79
-rw-r--r--test/unit/tx-utils-test.js58
-rw-r--r--test/unit/util-test.js41
7 files changed, 345 insertions, 123 deletions
diff --git a/test/stub/provider.js b/test/stub/provider.js
new file mode 100644
index 000000000..8a306f6d9
--- /dev/null
+++ b/test/stub/provider.js
@@ -0,0 +1,25 @@
+const JsonRpcEngine = require('json-rpc-engine')
+const scaffoldMiddleware = require('eth-json-rpc-middleware/scaffold')
+
+module.exports = {
+ createEngineForTestData,
+ providerFromEngine,
+ scaffoldMiddleware,
+ createStubedProvider
+}
+
+
+function createEngineForTestData () {
+ return new JsonRpcEngine()
+}
+
+function providerFromEngine (engine) {
+ const provider = { sendAsync: engine.handle.bind(engine) }
+ return provider
+}
+
+function createStubedProvider (resultStub) {
+ const engine = createEngineForTestData()
+ engine.push(scaffoldMiddleware(resultStub))
+ return providerFromEngine(engine)
+} \ No newline at end of file
diff --git a/test/unit/message-manager-test.js b/test/unit/message-manager-test.js
index 30cb4f067..9b76241ed 100644
--- a/test/unit/message-manager-test.js
+++ b/test/unit/message-manager-test.js
@@ -1,7 +1,7 @@
const assert = require('assert')
const MessageManger = require('../../app/scripts/lib/message-manager')
-describe('Transaction Manager', function () {
+describe('Message Manager', function () {
let messageManager
beforeEach(function () {
diff --git a/test/unit/nonce-tracker-test.js b/test/unit/nonce-tracker-test.js
index b0283e159..36025a360 100644
--- a/test/unit/nonce-tracker-test.js
+++ b/test/unit/nonce-tracker-test.js
@@ -31,12 +31,11 @@ describe('Nonce Tracker', function () {
})
describe('#getNonceLock', function () {
- it('should work', async function (done) {
+ it('should work', async function () {
this.timeout(15000)
const nonceLock = await nonceTracker.getNonceLock('0x7d3517b0d011698406d6e0aed8453f0be2697926')
assert.equal(nonceLock.nextNonce, '1', 'nonce should be 1')
await nonceLock.releaseLock()
- done()
})
})
})
diff --git a/test/unit/pending-tx-test.js b/test/unit/pending-tx-test.js
new file mode 100644
index 000000000..8c6d287f8
--- /dev/null
+++ b/test/unit/pending-tx-test.js
@@ -0,0 +1,260 @@
+const assert = require('assert')
+const ethUtil = require('ethereumjs-util')
+const EthTx = require('ethereumjs-tx')
+const ObservableStore = require('obs-store')
+const clone = require('clone')
+const { createStubedProvider } = require('../stub/provider')
+const PendingTransactionTracker = require('../../app/scripts/lib/pending-tx-tracker')
+const noop = () => true
+const currentNetworkId = 42
+const otherNetworkId = 36
+const privKey = new Buffer('8718b9618a37d1fc78c436511fc6df3c8258d3250635bba617f33003270ec03e', 'hex')
+
+describe('PendingTransactionTracker', function () {
+ let pendingTxTracker, txMeta, txMetaNoHash, txMetaNoRawTx, providerResultStub, provider
+ this.timeout(10000)
+ beforeEach(function () {
+ txMeta = {
+ id: 1,
+ hash: '0x0593ee121b92e10d63150ad08b4b8f9c7857d1bd160195ee648fb9a0f8d00eeb',
+ status: 'signed',
+ txParams: {
+ from: '0x1678a085c290ebd122dc42cba69373b5953b831d',
+ nonce: '0x1',
+ value: '0xfffff',
+ },
+ rawTx: '0xf86c808504a817c800827b0d940c62bb85faa3311a998d3aba8098c1235c564966880de0b6b3a7640000802aa08ff665feb887a25d4099e40e11f0fef93ee9608f404bd3f853dd9e84ed3317a6a02ec9d3d1d6e176d4d2593dd760e74ccac753e6a0ea0d00cc9789d0d7ff1f471d',
+ }
+ txMetaNoHash = {
+ id: 2,
+ status: 'signed',
+ txParams: { from: '0x1678a085c290ebd122dc42cba69373b5953b831d'},
+ }
+ txMetaNoRawTx = {
+ hash: '0x0593ee121b92e10d63150ad08b4b8f9c7857d1bd160195ee648fb9a0f8d00eeb',
+ status: 'signed',
+ txParams: { from: '0x1678a085c290ebd122dc42cba69373b5953b831d'},
+ }
+ providerResultStub = {}
+ provider = createStubedProvider(providerResultStub)
+
+ pendingTxTracker = new PendingTransactionTracker({
+ provider,
+ getBalance: () => {},
+ nonceTracker: {
+ getGlobalLock: async () => {
+ return { releaseLock: () => {} }
+ }
+ },
+ getPendingTransactions: () => {return []},
+ sufficientBalance: () => {},
+ publishTransaction: () => {},
+ })
+ })
+
+ describe('#checkForTxInBlock', function () {
+ it('should return if no pending transactions', function () {
+ // throw a type error if it trys to do anything on the block
+ // thus failing the test
+ const block = Proxy.revocable({}, {}).revoke()
+ pendingTxTracker.checkForTxInBlock(block)
+ })
+ it('should emit \'txFailed\' if the txMeta does not have a hash', function (done) {
+ const block = Proxy.revocable({}, {}).revoke()
+ pendingTxTracker.getPendingTransactions = () => [txMetaNoHash]
+ pendingTxTracker.once('txFailed', (txId, err) => {
+ assert(txId, txMetaNoHash.id, 'should pass txId')
+ done()
+ })
+ pendingTxTracker.checkForTxInBlock(block)
+ })
+ it('should emit \'txConfirmed\' if the tx is in the block', function (done) {
+ const block = { transactions: [txMeta]}
+ pendingTxTracker.getPendingTransactions = () => [txMeta]
+ pendingTxTracker.once('txConfirmed', (txId) => {
+ assert(txId, txMeta.id, 'should pass txId')
+ done()
+ })
+ pendingTxTracker.once('txFailed', (_, err) => { done(err) })
+ pendingTxTracker.checkForTxInBlock(block)
+ })
+ })
+ describe('#queryPendingTxs', function () {
+ it('should call #_checkPendingTxs if their is no oldBlock', function (done) {
+ let newBlock, oldBlock
+ newBlock = { number: '0x01' }
+ pendingTxTracker._checkPendingTxs = done
+ pendingTxTracker.queryPendingTxs({oldBlock, newBlock})
+ })
+ it('should call #_checkPendingTxs if oldBlock and the newBlock have a diff of greater then 1', function (done) {
+ let newBlock, oldBlock
+ oldBlock = { number: '0x01' }
+ newBlock = { number: '0x03' }
+ pendingTxTracker._checkPendingTxs = done
+ pendingTxTracker.queryPendingTxs({oldBlock, newBlock})
+ })
+ it('should not call #_checkPendingTxs if oldBlock and the newBlock have a diff of 1 or less', function (done) {
+ let newBlock, oldBlock
+ oldBlock = { number: '0x1' }
+ newBlock = { number: '0x2' }
+ pendingTxTracker._checkPendingTxs = () => {
+ const err = new Error('should not call #_checkPendingTxs if oldBlock and the newBlock have a diff of 1 or less')
+ done(err)
+ }
+ pendingTxTracker.queryPendingTxs({oldBlock, newBlock})
+ done()
+ })
+ })
+
+ describe('#_checkPendingTx', function () {
+ it('should emit \'txFailed\' if the txMeta does not have a hash', function (done) {
+ pendingTxTracker.once('txFailed', (txId, err) => {
+ assert(txId, txMetaNoHash.id, 'should pass txId')
+ done()
+ })
+ pendingTxTracker._checkPendingTx(txMetaNoHash)
+ })
+
+ it('should should return if query does not return txParams', function () {
+ providerResultStub.eth_getTransactionByHash = null
+ pendingTxTracker._checkPendingTx(txMeta)
+ })
+
+ it('should emit \'txConfirmed\'', function (done) {
+ providerResultStub.eth_getTransactionByHash = {blockNumber: '0x01'}
+ pendingTxTracker.once('txConfirmed', (txId) => {
+ assert(txId, txMeta.id, 'should pass txId')
+ done()
+ })
+ pendingTxTracker.once('txFailed', (_, err) => { done(err) })
+ pendingTxTracker._checkPendingTx(txMeta)
+ })
+ })
+
+ describe('#_checkPendingTxs', function () {
+ beforeEach(function () {
+ const txMeta2 = txMeta3 = txMeta
+ txMeta2.id = 2
+ txMeta3.id = 3
+ txList = [txMeta, txMeta2, txMeta3].map((tx) => {
+ tx.processed = new Promise ((resolve) => { tx.resolve = resolve })
+ return tx
+ })
+ })
+
+ it('should warp all txMeta\'s in #_checkPendingTx', function (done) {
+ pendingTxTracker.getPendingTransactions = () => txList
+ pendingTxTracker._checkPendingTx = (tx) => { tx.resolve(tx) }
+ const list = txList.map
+ Promise.all(txList.map((tx) => tx.processed))
+ .then((txCompletedList) => done())
+ .catch(done)
+
+ pendingTxTracker._checkPendingTxs()
+ })
+ })
+
+ describe('#resubmitPendingTxs', function () {
+ beforeEach(function () {
+ const txMeta2 = txMeta3 = txMeta
+ txList = [txMeta, txMeta2, txMeta3].map((tx) => {
+ tx.processed = new Promise ((resolve) => { tx.resolve = resolve })
+ return tx
+ })
+ })
+
+ it('should return if no pending transactions', function () {
+ pendingTxTracker.resubmitPendingTxs()
+ })
+ it('should call #_resubmitTx for all pending tx\'s', function (done) {
+ pendingTxTracker.getPendingTransactions = () => txList
+ pendingTxTracker._resubmitTx = async (tx) => { tx.resolve(tx) }
+ Promise.all(txList.map((tx) => tx.processed))
+ .then((txCompletedList) => done())
+ .catch(done)
+ pendingTxTracker.resubmitPendingTxs()
+ })
+ it('should not emit \'txFailed\' if the txMeta throws a known txError', function (done) {
+ knownErrors =[
+ // geth
+ ' Replacement transaction Underpriced ',
+ ' known transaction',
+ // parity
+ 'Gas price too low to replace ',
+ ' transaction with the sAme hash was already imported',
+ // other
+ ' gateway timeout',
+ ' noncE too low ',
+ ]
+ const enoughForAllErrors = txList.concat(txList)
+
+ pendingTxTracker.on('txFailed', (_, err) => done(err))
+
+ pendingTxTracker.getPendingTransactions = () => enoughForAllErrors
+ pendingTxTracker._resubmitTx = async (tx) => {
+ tx.resolve()
+ throw new Error(knownErrors.pop())
+ }
+ Promise.all(txList.map((tx) => tx.processed))
+ .then((txCompletedList) => done())
+ .catch(done)
+
+ pendingTxTracker.resubmitPendingTxs()
+ })
+ it('should emit \'txFailed\' if it encountered a real error', function (done) {
+ pendingTxTracker.once('txFailed', (id, err) => err.message === 'im some real error' ? txList[id - 1].resolve() : done(err))
+
+ pendingTxTracker.getPendingTransactions = () => txList
+ pendingTxTracker._resubmitTx = async (tx) => { throw new TypeError('im some real error') }
+ Promise.all(txList.map((tx) => tx.processed))
+ .then((txCompletedList) => done())
+ .catch(done)
+
+ pendingTxTracker.resubmitPendingTxs()
+ })
+ })
+ describe('#_resubmitTx with a too-low balance', function () {
+ it('should return before publishing the transaction because to low of balance', function (done) {
+ const lowBalance = '0x0'
+ pendingTxTracker.getBalance = (address) => {
+ assert.equal(address, txMeta.txParams.from, 'Should pass the address')
+ return lowBalance
+ }
+ pendingTxTracker.publishTransaction = async (rawTx) => {
+ done(new Error('tried to publish transaction'))
+ }
+
+ // Stubbing out current account state:
+ // Adding the fake tx:
+ pendingTxTracker.once('txFailed', (txId, err) => {
+ assert(err, 'Should have a error')
+ done()
+ })
+ pendingTxTracker._resubmitTx(txMeta)
+ .catch((err) => {
+ assert.ifError(err, 'should not throw an error')
+ done(err)
+ })
+ })
+
+ it('should publishing the transaction', function (done) {
+ const enoughBalance = '0x100000'
+ pendingTxTracker.getBalance = (address) => {
+ assert.equal(address, txMeta.txParams.from, 'Should pass the address')
+ return enoughBalance
+ }
+ pendingTxTracker.publishTransaction = async (rawTx) => {
+ assert.equal(rawTx, txMeta.rawTx, 'Should pass the rawTx')
+ }
+
+ // Stubbing out current account state:
+ // Adding the fake tx:
+ pendingTxTracker._resubmitTx(txMeta)
+ .then(() => done())
+ .catch((err) => {
+ assert.ifError(err, 'should not throw an error')
+ done(err)
+ })
+ })
+ })
+}) \ No newline at end of file
diff --git a/test/unit/tx-controller-test.js b/test/unit/tx-controller-test.js
index f290088a1..57d7deccd 100644
--- a/test/unit/tx-controller-test.js
+++ b/test/unit/tx-controller-test.js
@@ -10,16 +10,20 @@ const noop = () => true
const currentNetworkId = 42
const otherNetworkId = 36
const privKey = new Buffer('8718b9618a37d1fc78c436511fc6df3c8258d3250635bba617f33003270ec03e', 'hex')
+const { createStubedProvider } = require('../stub/provider')
describe('Transaction Controller', function () {
- let txController
+ let txController, engine, provider, providerResultStub
beforeEach(function () {
+ providerResultStub = {}
+ provider = createStubedProvider(providerResultStub)
+
txController = new TransactionController({
+ provider,
networkStore: new ObservableStore(currentNetworkId),
txHistoryLimit: 10,
blockTracker: { getCurrentBlock: noop, on: noop, once: noop },
- provider: { sendAsync: noop },
ethStore: { getState: noop },
signTransaction: (ethTx) => new Promise((resolve) => {
ethTx.sign(privKey)
@@ -27,19 +31,7 @@ describe('Transaction Controller', function () {
}),
})
txController.nonceTracker.getNonceLock = () => Promise.resolve({ nextNonce: 0, releaseLock: noop })
- txController.query = new Proxy({}, {
- get: (queryStubResult, key) => {
- if (key === 'stubResult') {
- return function (method, ...args) {
- queryStubResult[method] = args
- }
- } else {
- const returnValues = queryStubResult[key]
- return () => Promise.resolve(...returnValues)
- }
- },
- })
- txController.txProviderUtils = new TxProvideUtils(txController.query)
+ txController.txProviderUtils = new TxProvideUtils(txController.provider)
})
describe('#newUnapprovedTransaction', function () {
@@ -76,7 +68,6 @@ describe('Transaction Controller', function () {
it('should resolve when finished and status is submitted and resolve with the hash', function (done) {
txController.once('newUnaprovedTx', (txMetaFromEmit) => {
setTimeout(() => {
- console.log('HELLLO')
txController.setTxHash(txMetaFromEmit.id, '0x0')
txController.setTxStatusSubmitted(txMetaFromEmit.id)
}, 10)
@@ -93,7 +84,6 @@ describe('Transaction Controller', function () {
it('should reject when finished and status is rejected', function (done) {
txController.once('newUnaprovedTx', (txMetaFromEmit) => {
setTimeout(() => {
- console.log('HELLLO')
txController.setTxStatusRejected(txMetaFromEmit.id)
}, 10)
})
@@ -133,11 +123,9 @@ describe('Transaction Controller', function () {
'to':'0xc684832530fcbddae4b4230a47e991ddcec2831d',
},
}
-
- txController.query.stubResult('gasPrice', '0x4a817c800')
- txController.query.stubResult('getBlockByNumber', { gasLimit: '0x47b784' })
- txController.query.stubResult('estimateGas', '0x5209')
-
+ providerResultStub.eth_gasPrice = '4a817c800'
+ providerResultStub.eth_getBlockByNumber = { gasLimit: '47b784' }
+ providerResultStub.eth_estimateGas = '5209'
txController.addTxDefaults(txMeta)
.then((txMetaWithDefaults) => {
assert(txMetaWithDefaults.txParams.value, '0x0','should have added 0x0 as the value')
@@ -394,9 +382,8 @@ describe('Transaction Controller', function () {
const wrongValue = '0x05'
txController.addTx(txMeta)
-
- txController.query.stubResult('estimateGas', wrongValue)
- txController.query.stubResult('gasPrice', wrongValue)
+ providerResultStub.eth_gasPrice = wrongValue
+ providerResultStub.eth_estimateGas = '0x5209'
const signStub = sinon.stub(txController, 'signTransaction').callsFake(() => Promise.resolve())
@@ -429,46 +416,4 @@ describe('Transaction Controller', function () {
}).catch(done)
})
})
-
- describe('#_resubmitTx with a too-low balance', function () {
- it('should fail the transaction', function (done) {
- const from = '0xda0da0'
- const txMeta = {
- id: 1,
- status: 'submitted',
- metamaskNetworkId: currentNetworkId,
- txParams: {
- from,
- nonce: '0x1',
- value: '0xfffff',
- },
- }
-
- const lowBalance = '0x0'
- const fakeStoreState = { accounts: {} }
- fakeStoreState.accounts[from] = {
- balance: lowBalance,
- nonce: '0x0',
- }
-
- // Stubbing out current account state:
- const getStateStub = sinon.stub(txController.ethStore, 'getState')
- .returns(fakeStoreState)
-
- // Adding the fake tx:
- txController.addTx(clone(txMeta))
-
- txController._resubmitTx(txMeta)
- .then(() => {
- const updatedMeta = txController.getTx(txMeta.id)
- assert.notEqual(updatedMeta.status, txMeta.status, 'status changed.')
- assert.equal(updatedMeta.status, 'failed', 'tx set to failed.')
- done()
- })
- .catch((err) => {
- assert.ifError(err, 'should not throw an error')
- done(err)
- })
- })
- })
}) \ No newline at end of file
diff --git a/test/unit/tx-utils-test.js b/test/unit/tx-utils-test.js
index a43bcfb35..43128b977 100644
--- a/test/unit/tx-utils-test.js
+++ b/test/unit/tx-utils-test.js
@@ -1,7 +1,7 @@
const assert = require('assert')
-const ethUtil = require('ethereumjs-util')
-const BN = ethUtil.BN
+const BN = require('bn.js')
+const { hexToBn, bnToHex } = require('../../app/scripts/lib/util')
const TxUtils = require('../../app/scripts/lib/tx-utils')
@@ -16,44 +16,6 @@ describe('txUtils', function () {
}))
})
- describe('#sufficientBalance', function () {
- it('returns true if max tx cost is equal to balance.', function () {
- const tx = {
- 'value': '0x1',
- 'gas': '0x2',
- 'gasPrice': '0x3',
- }
- const balance = '0x8'
-
- const result = txUtils.sufficientBalance(tx, balance)
- assert.ok(result, 'sufficient balance found.')
- })
-
- it('returns true if max tx cost is less than balance.', function () {
- const tx = {
- 'value': '0x1',
- 'gas': '0x2',
- 'gasPrice': '0x3',
- }
- const balance = '0x9'
-
- const result = txUtils.sufficientBalance(tx, balance)
- assert.ok(result, 'sufficient balance found.')
- })
-
- it('returns false if max tx cost is more than balance.', function () {
- const tx = {
- 'value': '0x1',
- 'gas': '0x2',
- 'gasPrice': '0x3',
- }
- const balance = '0x6'
-
- const result = txUtils.sufficientBalance(tx, balance)
- assert.ok(!result, 'insufficient balance found.')
- })
- })
-
describe('chain Id', function () {
it('prepares a transaction with the provided chainId', function () {
const txParams = {
@@ -96,7 +58,7 @@ describe('txUtils', function () {
assert(outputBn.eq(expectedBn), 'returns the original estimatedGas value')
})
- it('buffers up to reccomend gas limit reccomended ceiling', function () {
+ it('buffers up to recommend gas limit recommended ceiling', function () {
// naive estimatedGas: 0x16e360 (1.5 mil)
const inputHex = '0x16e360'
// dummy gas limit: 0x1e8480 (2 mil)
@@ -107,17 +69,7 @@ describe('txUtils', function () {
// const inputBn = hexToBn(inputHex)
// const outputBn = hexToBn(output)
const expectedHex = bnToHex(ceilGasLimitBn)
- assert.equal(output, expectedHex, 'returns the gas limit reccomended ceiling value')
+ assert.equal(output, expectedHex, 'returns the gas limit recommended ceiling value')
})
})
-})
-
-// util
-
-function hexToBn (inputHex) {
- return new BN(ethUtil.stripHexPrefix(inputHex), 16)
-}
-
-function bnToHex (inputBn) {
- return ethUtil.addHexPrefix(inputBn.toString(16))
-}
+}) \ No newline at end of file
diff --git a/test/unit/util-test.js b/test/unit/util-test.js
new file mode 100644
index 000000000..6da185b2c
--- /dev/null
+++ b/test/unit/util-test.js
@@ -0,0 +1,41 @@
+const assert = require('assert')
+const { sufficientBalance } = require('../../app/scripts/lib/util')
+
+
+describe('SufficientBalance', function () {
+ it('returns true if max tx cost is equal to balance.', function () {
+ const tx = {
+ 'value': '0x1',
+ 'gas': '0x2',
+ 'gasPrice': '0x3',
+ }
+ const balance = '0x8'
+
+ const result = sufficientBalance(tx, balance)
+ assert.ok(result, 'sufficient balance found.')
+ })
+
+ it('returns true if max tx cost is less than balance.', function () {
+ const tx = {
+ 'value': '0x1',
+ 'gas': '0x2',
+ 'gasPrice': '0x3',
+ }
+ const balance = '0x9'
+
+ const result = sufficientBalance(tx, balance)
+ assert.ok(result, 'sufficient balance found.')
+ })
+
+ it('returns false if max tx cost is more than balance.', function () {
+ const tx = {
+ 'value': '0x1',
+ 'gas': '0x2',
+ 'gasPrice': '0x3',
+ }
+ const balance = '0x6'
+
+ const result = sufficientBalance(tx, balance)
+ assert.ok(!result, 'insufficient balance found.')
+ })
+}) \ No newline at end of file