diff options
author | kumavis <kumavis@users.noreply.github.com> | 2017-08-09 14:30:58 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-09 14:30:58 +0800 |
commit | 0188e7b94d85b45a783f9e3d5c182a8ffcaeac2e (patch) | |
tree | 428154973b91dfb2f8519777e67da7a6c75530b3 /test | |
parent | 5e9926b0d035a5ba946080e94777ac0bd887d396 (diff) | |
parent | 57f6fce6b2524c4b36b591da5e600d0652f4077e (diff) | |
download | tangerine-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.js | 25 | ||||
-rw-r--r-- | test/unit/message-manager-test.js | 2 | ||||
-rw-r--r-- | test/unit/nonce-tracker-test.js | 3 | ||||
-rw-r--r-- | test/unit/pending-tx-test.js | 260 | ||||
-rw-r--r-- | test/unit/tx-controller-test.js | 79 | ||||
-rw-r--r-- | test/unit/tx-utils-test.js | 58 | ||||
-rw-r--r-- | test/unit/util-test.js | 41 |
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 |