From 284dd85a99f538b77fd477f4952117d1792f64a5 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 6 Apr 2018 19:59:51 -0230 Subject: first commit --- ui/app/components/send_/tests/send-utils.test.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ui/app/components/send_/tests/send-utils.test.js (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js new file mode 100644 index 000000000..e69de29bb -- cgit From 7c490098548522c16be1b1e84bce37f5bf87f1f4 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 5 May 2018 11:11:53 -0400 Subject: Unit tests for containers, utils and selectors in send_/ --- ui/app/components/send_/tests/send-utils.test.js | 264 +++++++++++++++++++++++ 1 file changed, 264 insertions(+) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index e69de29bb..4d471bcc1 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -0,0 +1,264 @@ +import assert from 'assert' +import sinon from 'sinon' +import proxyquire from 'proxyquire' + +const { + INSUFFICIENT_FUNDS_ERROR, + INSUFFICIENT_TOKENS_ERROR, +} = require('../send.constants') + +const stubs = { + addCurrencies: sinon.stub().callsFake((a, b, obj) => a + b), + conversionUtil: sinon.stub().callsFake((val, obj) => parseInt(val, 16)), + conversionGTE: sinon.stub().callsFake((obj1, obj2) => obj1.value > obj2.value), + multiplyCurrencies: sinon.stub().callsFake((a, b) => a * b), + calcTokenAmount: sinon.stub().callsFake((a, d) => 'calc:' + a + d), + rawEncode: sinon.stub().returns([16, 1100]), +} + +const sendUtils = proxyquire('../send.utils.js', { + '../../conversion-util': { + addCurrencies: stubs.addCurrencies, + conversionUtil: stubs.conversionUtil, + conversionGTE: stubs.conversionGTE, + multiplyCurrencies: stubs.multiplyCurrencies, + }, + '../../token-util': { calcTokenAmount: stubs.calcTokenAmount }, + 'ethereumjs-abi': { + rawEncode: stubs.rawEncode, + }, +}) + +const { + calcGasTotal, + doesAmountErrorRequireUpdate, + generateTokenTransferData, + getAmountErrorObject, + getParamsForGasEstimate, + calcTokenBalance, + isBalanceSufficient, + isTokenBalanceSufficient, +} = sendUtils + +describe('send utils', () => { + + describe('calcGasTotal()', () => { + it('should call multiplyCurrencies with the correct params and return the multiplyCurrencies return', () => { + const result = calcGasTotal(12, 15) + assert.equal(result, 180) + const call_ = stubs.multiplyCurrencies.getCall(0).args + assert.deepEqual( + call_, + [12, 15, { + toNumericBase: 'hex', + multiplicandBase: 16, + multiplierBase: 16, + } ] + ) + }) + }) + + describe('doesAmountErrorRequireUpdate()', () => { + const config = { + 'should return true if balances are different': { + balance: 0, + prevBalance: 1, + expectedResult: true, + }, + 'should return true if gasTotals are different': { + gasTotal: 0, + prevGasTotal: 1, + expectedResult: true, + }, + 'should return true if token balances are different': { + tokenBalance: 0, + prevTokenBalance: 1, + selectedToken: 'someToken', + expectedResult: true, + }, + 'should return false if they are all the same': { + balance: 1, + prevBalance: 1, + gasTotal: 1, + prevGasTotal: 1, + tokenBalance: 1, + prevTokenBalance: 1, + selectedToken: 'someToken', + expectedResult: false, + }, + } + Object.entries(config).map(([description, obj]) => { + it(description, () => { + assert.equal(doesAmountErrorRequireUpdate(obj), obj.expectedResult) + }) + }) + + }) + + describe('generateTokenTransferData()', () => { + it('should return undefined if not passed a selected token', () => { + assert.equal(generateTokenTransferData('mockAddress', false), undefined) + }) + + it('should return encoded token transfer data', () => { + assert.equal(generateTokenTransferData('mockAddress', true), '104c') + }) + }) + + describe('getAmountErrorObject()', () => { + const config = { + 'should return insufficientFunds error if isBalanceSufficient returns false': { + amount: 15, + amountConversionRate: 2, + balance: 1, + conversionRate: 3, + gasTotal: 17, + primaryCurrency: 'ABC', + expectedResult: { amount: INSUFFICIENT_FUNDS_ERROR }, + }, + 'should return insufficientTokens error if token is selected and isTokenBalanceSufficient returns false': { + amount: '0x10', + amountConversionRate: 2, + balance: 100, + conversionRate: 3, + decimals: 10, + gasTotal: 17, + primaryCurrency: 'ABC', + selectedToken: 'someToken', + tokenBalance: 123, + expectedResult: { amount: INSUFFICIENT_TOKENS_ERROR }, + }, + } + Object.entries(config).map(([description, obj]) => { + it(description, () => { + assert.deepEqual(getAmountErrorObject(obj), obj.expectedResult) + }) + }) + }) + + describe('getParamsForGasEstimate()', () => { + it('should return from and gas properties if no symbol or data', () => { + assert.deepEqual( + getParamsForGasEstimate('mockAddress'), + { + from: 'mockAddress', + gas: '746a528800', + } + ) + }) + + it('should return value property if symbol provided', () => { + assert.deepEqual( + getParamsForGasEstimate('mockAddress', 'ABC'), + { + from: 'mockAddress', + gas: '746a528800', + value: '0x0', + } + ) + }) + + it('should return data property if data provided', () => { + assert.deepEqual( + getParamsForGasEstimate('mockAddress', 'ABC', 'somedata'), + { + from: 'mockAddress', + gas: '746a528800', + value: '0x0', + data: 'somedata', + } + ) + }) + }) + + describe('calcTokenBalance()', () => { + it('should return the calculated token blance', () => { + assert.equal(calcTokenBalance({ + selectedToken: { + decimals: 11, + }, + usersToken: { + balance: 20, + }, + }), 'calc:2011') + }) + }) + + describe('isBalanceSufficient()', () => { + it('should correctly call addCurrencies and return the result of calling conversionGTE', () => { + stubs.conversionGTE.resetHistory() + const result = isBalanceSufficient({ + amount: 15, + amountConversionRate: 2, + balance: 100, + conversionRate: 3, + gasTotal: 17, + primaryCurrency: 'ABC', + }) + assert.deepEqual( + stubs.addCurrencies.getCall(0).args, + [ + 15, 17, { + aBase: 16, + bBase: 16, + toNumericBase: 'hex', + }, + ] + ) + assert.deepEqual( + stubs.conversionGTE.getCall(0).args, + [ + { + value: 100, + fromNumericBase: 'hex', + fromCurrency: 'ABC', + conversionRate: 3, + }, + { + value: 32, + fromNumericBase: 'hex', + conversionRate: 2, + fromCurrency: 'ABC', + }, + ] + ) + + assert.equal(result, true) + }) + }) + + describe('isTokenBalanceSufficient()', () => { + it('should correctly call conversionUtil and return the result of calling conversionGTE', () => { + stubs.conversionGTE.resetHistory() + const result = isTokenBalanceSufficient({ + amount: '0x10', + tokenBalance: 123, + decimals: 10, + }) + assert.deepEqual( + stubs.conversionUtil.getCall(0).args, + [ + '0x10', { + fromNumericBase: 'hex', + }, + ] + ) + assert.deepEqual( + stubs.conversionGTE.getCall(0).args, + [ + { + value: 123, + fromNumericBase: 'dec', + }, + { + value: 'calc:1610', + fromNumericBase: 'dec', + }, + ] + ) + + assert.equal(result, false) + }) + }) + +}) -- cgit From 17909465f283179aad39166b1191dbaba3770bf6 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 19 May 2018 22:08:25 -0230 Subject: getParamsForGasEstimate extracts symbol from token instead of just accepting symbol. --- ui/app/components/send_/tests/send-utils.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index 4d471bcc1..903b531e6 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -147,9 +147,9 @@ describe('send utils', () => { ) }) - it('should return value property if symbol provided', () => { + it('should return value property if selected token provided', () => { assert.deepEqual( - getParamsForGasEstimate('mockAddress', 'ABC'), + getParamsForGasEstimate('mockAddress', { symbol: 'ABC' }), { from: 'mockAddress', gas: '746a528800', @@ -160,7 +160,7 @@ describe('send utils', () => { it('should return data property if data provided', () => { assert.deepEqual( - getParamsForGasEstimate('mockAddress', 'ABC', 'somedata'), + getParamsForGasEstimate('mockAddress', { symbol: 'ABC' }, 'somedata'), { from: 'mockAddress', gas: '746a528800', -- cgit From 166fda58777748141859c0a674a5fce454cfc3d3 Mon Sep 17 00:00:00 2001 From: Dan Date: Tue, 22 May 2018 05:40:06 -0230 Subject: Simplify gas estimate actions and add local estimateGasPriceFromRecentBlocks method. --- ui/app/components/send_/tests/send-utils.test.js | 106 +++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index 903b531e6..b5211a63d 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -1,6 +1,13 @@ import assert from 'assert' import sinon from 'sinon' import proxyquire from 'proxyquire' +import { + ONE_GWEI_IN_WEI_HEX, +} from '../send.constants' +const { + addCurrencies, + subtractCurrencies, +} = require('../../../conversion-util') const { INSUFFICIENT_FUNDS_ERROR, @@ -31,7 +38,9 @@ const sendUtils = proxyquire('../send.utils.js', { const { calcGasTotal, + estimateGas, doesAmountErrorRequireUpdate, + estimateGasPriceFromRecentBlocks, generateTokenTransferData, getAmountErrorObject, getParamsForGasEstimate, @@ -261,4 +270,101 @@ describe('send utils', () => { }) }) + describe('estimateGas', () => { + let tempEthQuery + beforeEach(() => { + tempEthQuery = global.ethQuery + global.ethQuery = { + estimateGas: sinon.stub().callsFake((data, cb) => { + return cb( + data.isMockErr ? 'mockErr' : null, + Object.assign(data, { estimateGasCalled: true }) + ) + }) + } + }) + + afterEach(() => { + global.ethQuery = tempEthQuery + }) + + it('should call ethQuery.estimateGas and resolve that call\'s data', async () => { + const result = await estimateGas({ mockParam: 'someData' }) + assert.equal(global.ethQuery.estimateGas.callCount, 1) + assert.deepEqual( + result, + { mockParam: 'someData', estimateGasCalled: true } + ) + }) + + it('should reject with ethQuery.estimateGas error', async () => { + try { + await estimateGas({ mockParam: 'someData', isMockErr: true }) + } catch (err) { + assert.equal(err, 'mockErr') + } + }) + }) + + describe('estimateGasPriceFromRecentBlocks', () => { + const ONE_GWEI_IN_WEI_HEX_PLUS_ONE = addCurrencies(ONE_GWEI_IN_WEI_HEX, '0x1', { + aBase: 16, + bBase: 16, + toNumericBase: 'hex', + }) + const ONE_GWEI_IN_WEI_HEX_PLUS_TWO = addCurrencies(ONE_GWEI_IN_WEI_HEX, '0x2', { + aBase: 16, + bBase: 16, + toNumericBase: 'hex', + }) + const ONE_GWEI_IN_WEI_HEX_MINUS_ONE = subtractCurrencies(ONE_GWEI_IN_WEI_HEX, '0x1', { + aBase: 16, + bBase: 16, + toNumericBase: 'hex', + }) + + it(`should return ${ONE_GWEI_IN_WEI_HEX} if recentBlocks is falsy`, () => { + assert.equal(estimateGasPriceFromRecentBlocks(), ONE_GWEI_IN_WEI_HEX) + }) + + it(`should return ${ONE_GWEI_IN_WEI_HEX} if recentBlocks is empty`, () => { + assert.equal(estimateGasPriceFromRecentBlocks([]), ONE_GWEI_IN_WEI_HEX) + }) + + it(`should estimate a block's gasPrice as ${ONE_GWEI_IN_WEI_HEX} if it has no gas prices`, () => { + const mockRecentBlocks = [ + { gasPrices: null }, + { gasPrices: [ ONE_GWEI_IN_WEI_HEX_PLUS_ONE ] }, + { gasPrices: [ ONE_GWEI_IN_WEI_HEX_MINUS_ONE ] }, + ] + assert.equal(estimateGasPriceFromRecentBlocks(mockRecentBlocks), ONE_GWEI_IN_WEI_HEX) + }) + + it(`should estimate a block's gasPrice as ${ONE_GWEI_IN_WEI_HEX} if it has empty gas prices`, () => { + const mockRecentBlocks = [ + { gasPrices: [] }, + { gasPrices: [ ONE_GWEI_IN_WEI_HEX_PLUS_ONE ] }, + { gasPrices: [ ONE_GWEI_IN_WEI_HEX_MINUS_ONE ] }, + ] + assert.equal(estimateGasPriceFromRecentBlocks(mockRecentBlocks), ONE_GWEI_IN_WEI_HEX) + }) + + it(`should return the middle value of all blocks lowest prices`, () => { + const mockRecentBlocks = [ + { gasPrices: [ ONE_GWEI_IN_WEI_HEX_PLUS_TWO ] }, + { gasPrices: [ ONE_GWEI_IN_WEI_HEX_MINUS_ONE ] }, + { gasPrices: [ ONE_GWEI_IN_WEI_HEX_PLUS_ONE ] }, + ] + assert.equal(estimateGasPriceFromRecentBlocks(mockRecentBlocks), ONE_GWEI_IN_WEI_HEX_PLUS_ONE) + }) + + it(`should work if a block has multiple gas prices`, () => { + const mockRecentBlocks = [ + { gasPrices: [ '0x1', '0x2', '0x3', '0x4', '0x5' ] }, + { gasPrices: [ '0x101', '0x100', '0x103', '0x104', '0x102' ] }, + { gasPrices: [ '0x150', '0x50', '0x100', '0x200', '0x5' ] }, + ] + assert.equal(estimateGasPriceFromRecentBlocks(mockRecentBlocks), '0x5') + }) + }) }) -- cgit From 4f0b4eef5030575e8ebdf35ca19fbc77376c70b9 Mon Sep 17 00:00:00 2001 From: Dan Date: Tue, 22 May 2018 12:46:53 -0230 Subject: Estimate gas using same algorithm as backend. --- ui/app/components/send_/tests/send-utils.test.js | 126 ++++++++++++----------- 1 file changed, 64 insertions(+), 62 deletions(-) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index b5211a63d..a01ab4eba 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -3,6 +3,7 @@ import sinon from 'sinon' import proxyquire from 'proxyquire' import { ONE_GWEI_IN_WEI_HEX, + SIMPLE_GAS_COST, } from '../send.constants' const { addCurrencies, @@ -18,11 +19,19 @@ const stubs = { addCurrencies: sinon.stub().callsFake((a, b, obj) => a + b), conversionUtil: sinon.stub().callsFake((val, obj) => parseInt(val, 16)), conversionGTE: sinon.stub().callsFake((obj1, obj2) => obj1.value > obj2.value), - multiplyCurrencies: sinon.stub().callsFake((a, b) => a * b), + multiplyCurrencies: sinon.stub().callsFake((a, b) => `${a}x${b}`), calcTokenAmount: sinon.stub().callsFake((a, d) => 'calc:' + a + d), rawEncode: sinon.stub().returns([16, 1100]), } +const EthQuery = function () {} +EthQuery.prototype.estimateGas = sinon.stub().callsFake( + (data) => Promise.resolve({ toString: (n) => `mockToString:${n}` }) +) +EthQuery.prototype.getCode = sinon.stub().callsFake( + (address) => Promise.resolve(address.match(/isContract/) ? 'not-0x' : '0x') +) + const sendUtils = proxyquire('../send.utils.js', { '../../conversion-util': { addCurrencies: stubs.addCurrencies, @@ -34,6 +43,7 @@ const sendUtils = proxyquire('../send.utils.js', { 'ethereumjs-abi': { rawEncode: stubs.rawEncode, }, + 'ethjs-query': EthQuery, }) const { @@ -43,7 +53,6 @@ const { estimateGasPriceFromRecentBlocks, generateTokenTransferData, getAmountErrorObject, - getParamsForGasEstimate, calcTokenBalance, isBalanceSufficient, isTokenBalanceSufficient, @@ -54,7 +63,7 @@ describe('send utils', () => { describe('calcGasTotal()', () => { it('should call multiplyCurrencies with the correct params and return the multiplyCurrencies return', () => { const result = calcGasTotal(12, 15) - assert.equal(result, 180) + assert.equal(result, '12x15') const call_ = stubs.multiplyCurrencies.getCall(0).args assert.deepEqual( call_, @@ -145,41 +154,6 @@ describe('send utils', () => { }) }) - describe('getParamsForGasEstimate()', () => { - it('should return from and gas properties if no symbol or data', () => { - assert.deepEqual( - getParamsForGasEstimate('mockAddress'), - { - from: 'mockAddress', - gas: '746a528800', - } - ) - }) - - it('should return value property if selected token provided', () => { - assert.deepEqual( - getParamsForGasEstimate('mockAddress', { symbol: 'ABC' }), - { - from: 'mockAddress', - gas: '746a528800', - value: '0x0', - } - ) - }) - - it('should return data property if data provided', () => { - assert.deepEqual( - getParamsForGasEstimate('mockAddress', { symbol: 'ABC' }, 'somedata'), - { - from: 'mockAddress', - gas: '746a528800', - value: '0x0', - data: 'somedata', - } - ) - }) - }) - describe('calcTokenBalance()', () => { it('should return the calculated token blance', () => { assert.equal(calcTokenBalance({ @@ -271,38 +245,66 @@ describe('send utils', () => { }) describe('estimateGas', () => { - let tempEthQuery - beforeEach(() => { - tempEthQuery = global.ethQuery - global.ethQuery = { - estimateGas: sinon.stub().callsFake((data, cb) => { - return cb( - data.isMockErr ? 'mockErr' : null, - Object.assign(data, { estimateGasCalled: true }) - ) - }) - } - }) + const baseMockParams = { + blockGasLimit: '0x64', + selectedAddress: 'mockAddress', + to: '0xisContract', + } + const baseExpectedCall = { + from: 'mockAddress', + gas: '0x64x0.95', + to: '0xisContract', + } afterEach(() => { - global.ethQuery = tempEthQuery + EthQuery.prototype.estimateGas.resetHistory() + EthQuery.prototype.getCode.resetHistory() + }) + + it('should call ethQuery.estimateGas with the expected params', async () => { + const result = await estimateGas(baseMockParams) + assert.equal(EthQuery.prototype.estimateGas.callCount, 1) + assert.deepEqual( + EthQuery.prototype.estimateGas.getCall(0).args[0], + baseExpectedCall + ) + assert.equal(result, 'mockToString:16') + }) + + it('should call ethQuery.estimateGas with a value of 0x0 if the passed selectedToken has a symbol', async () => { + const result = await estimateGas(Object.assign({ selectedToken: { symbol: true } }, baseMockParams)) + assert.equal(EthQuery.prototype.estimateGas.callCount, 1) + assert.deepEqual( + EthQuery.prototype.estimateGas.getCall(0).args[0], + Object.assign({ value: '0x0' }, baseExpectedCall) + ) + assert.equal(result, 'mockToString:16') + }) + + it('should call ethQuery.estimateGas with data if data is passed', async () => { + const result = await estimateGas(Object.assign({ data: 'mockData' }, baseMockParams)) + assert.equal(EthQuery.prototype.estimateGas.callCount, 1) + assert.deepEqual( + EthQuery.prototype.estimateGas.getCall(0).args[0], + Object.assign({ data: 'mockData' }, baseExpectedCall) + ) + assert.equal(result, 'mockToString:16') }) - it('should call ethQuery.estimateGas and resolve that call\'s data', async () => { - const result = await estimateGas({ mockParam: 'someData' }) - assert.equal(global.ethQuery.estimateGas.callCount, 1) + it('should call ethQuery.estimateGas with data if data is passed', async () => { + const result = await estimateGas(Object.assign({ data: 'mockData' }, baseMockParams)) + assert.equal(EthQuery.prototype.estimateGas.callCount, 1) assert.deepEqual( - result, - { mockParam: 'someData', estimateGasCalled: true } + EthQuery.prototype.estimateGas.getCall(0).args[0], + Object.assign({ data: 'mockData' }, baseExpectedCall) ) + assert.equal(result, 'mockToString:16') }) - it('should reject with ethQuery.estimateGas error', async () => { - try { - await estimateGas({ mockParam: 'someData', isMockErr: true }) - } catch (err) { - assert.equal(err, 'mockErr') - } + it(`should return ${SIMPLE_GAS_COST} if ethQuery.getCode does not return '0x'`, async () => { + assert.equal(EthQuery.prototype.estimateGas.callCount, 0) + const result = await estimateGas(Object.assign({}, baseMockParams, { to: '0x123' })) + assert.equal(result, SIMPLE_GAS_COST) }) }) -- cgit From 0f20fce9b761fc0aa16d61b2b739fa7f9b9f6a7d Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 23 May 2018 14:13:25 -0230 Subject: Auto update gas estimate when to changes. --- ui/app/components/send_/tests/send-utils.test.js | 54 ++++++++++-------------- 1 file changed, 23 insertions(+), 31 deletions(-) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index a01ab4eba..3c772ed47 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -24,14 +24,6 @@ const stubs = { rawEncode: sinon.stub().returns([16, 1100]), } -const EthQuery = function () {} -EthQuery.prototype.estimateGas = sinon.stub().callsFake( - (data) => Promise.resolve({ toString: (n) => `mockToString:${n}` }) -) -EthQuery.prototype.getCode = sinon.stub().callsFake( - (address) => Promise.resolve(address.match(/isContract/) ? 'not-0x' : '0x') -) - const sendUtils = proxyquire('../send.utils.js', { '../../conversion-util': { addCurrencies: stubs.addCurrencies, @@ -43,7 +35,6 @@ const sendUtils = proxyquire('../send.utils.js', { 'ethereumjs-abi': { rawEncode: stubs.rawEncode, }, - 'ethjs-query': EthQuery, }) const { @@ -249,6 +240,9 @@ describe('send utils', () => { blockGasLimit: '0x64', selectedAddress: 'mockAddress', to: '0xisContract', + estimateGasMethod: sinon.stub().callsFake( + (data, cb) => cb(null, { toString: (n) => `mockToString:${n}` }) + ), } const baseExpectedCall = { from: 'mockAddress', @@ -256,53 +250,51 @@ describe('send utils', () => { to: '0xisContract', } + beforeEach(() => { + global.eth = { + getCode: sinon.stub().callsFake( + (address) => Promise.resolve(address.match(/isContract/) ? 'not-0x' : '0x') + ), + } + }) + afterEach(() => { - EthQuery.prototype.estimateGas.resetHistory() - EthQuery.prototype.getCode.resetHistory() + baseMockParams.estimateGasMethod.resetHistory() + global.eth.getCode.resetHistory() }) it('should call ethQuery.estimateGas with the expected params', async () => { const result = await estimateGas(baseMockParams) - assert.equal(EthQuery.prototype.estimateGas.callCount, 1) + assert.equal(baseMockParams.estimateGasMethod.callCount, 1) assert.deepEqual( - EthQuery.prototype.estimateGas.getCall(0).args[0], - baseExpectedCall + baseMockParams.estimateGasMethod.getCall(0).args[0], + Object.assign({ gasPrice: undefined, value: undefined }, baseExpectedCall) ) assert.equal(result, 'mockToString:16') }) it('should call ethQuery.estimateGas with a value of 0x0 if the passed selectedToken has a symbol', async () => { const result = await estimateGas(Object.assign({ selectedToken: { symbol: true } }, baseMockParams)) - assert.equal(EthQuery.prototype.estimateGas.callCount, 1) - assert.deepEqual( - EthQuery.prototype.estimateGas.getCall(0).args[0], - Object.assign({ value: '0x0' }, baseExpectedCall) - ) - assert.equal(result, 'mockToString:16') - }) - - it('should call ethQuery.estimateGas with data if data is passed', async () => { - const result = await estimateGas(Object.assign({ data: 'mockData' }, baseMockParams)) - assert.equal(EthQuery.prototype.estimateGas.callCount, 1) + assert.equal(baseMockParams.estimateGasMethod.callCount, 1) assert.deepEqual( - EthQuery.prototype.estimateGas.getCall(0).args[0], - Object.assign({ data: 'mockData' }, baseExpectedCall) + baseMockParams.estimateGasMethod.getCall(0).args[0], + Object.assign({ gasPrice: undefined, value: '0x0' }, baseExpectedCall) ) assert.equal(result, 'mockToString:16') }) it('should call ethQuery.estimateGas with data if data is passed', async () => { const result = await estimateGas(Object.assign({ data: 'mockData' }, baseMockParams)) - assert.equal(EthQuery.prototype.estimateGas.callCount, 1) + assert.equal(baseMockParams.estimateGasMethod.callCount, 1) assert.deepEqual( - EthQuery.prototype.estimateGas.getCall(0).args[0], - Object.assign({ data: 'mockData' }, baseExpectedCall) + baseMockParams.estimateGasMethod.getCall(0).args[0], + Object.assign({ gasPrice: undefined, value: undefined, data: 'mockData' }, baseExpectedCall) ) assert.equal(result, 'mockToString:16') }) it(`should return ${SIMPLE_GAS_COST} if ethQuery.getCode does not return '0x'`, async () => { - assert.equal(EthQuery.prototype.estimateGas.callCount, 0) + assert.equal(baseMockParams.estimateGasMethod.callCount, 0) const result = await estimateGas(Object.assign({}, baseMockParams, { to: '0x123' })) assert.equal(result, SIMPLE_GAS_COST) }) -- cgit From 5a842e440f0ec565eba38aec4c1c953a775557ea Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 25 May 2018 11:07:16 -0230 Subject: Gas estimation uses block gas limit as fallback if query.estimateGas returns an expected error. --- ui/app/components/send_/tests/send-utils.test.js | 29 +++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index 3c772ed47..4801d4a09 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -241,7 +241,10 @@ describe('send utils', () => { selectedAddress: 'mockAddress', to: '0xisContract', estimateGasMethod: sinon.stub().callsFake( - (data, cb) => cb(null, { toString: (n) => `mockToString:${n}` }) + (data, cb) => cb( + data.to.match(/willFailBecauseOf:/) ? { message: data.to.match(/\:(.+)$/)[1] } : null, + { toString: (n) => `mockToString:${n}` } + ) ), } const baseExpectedCall = { @@ -298,6 +301,30 @@ describe('send utils', () => { const result = await estimateGas(Object.assign({}, baseMockParams, { to: '0x123' })) assert.equal(result, SIMPLE_GAS_COST) }) + + it(`should return the adjusted blockGasLimit if it fails with a 'Transaction execution error.'`, async () => { + const result = await estimateGas(Object.assign({}, baseMockParams, { + to: 'isContract willFailBecauseOf:Transaction execution error.', + })) + assert.equal(result, '0x64x0.95') + }) + + it(`should return the adjusted blockGasLimit if it fails with a 'gas required exceeds allowance or always failing transaction.'`, async () => { + const result = await estimateGas(Object.assign({}, baseMockParams, { + to: 'isContract willFailBecauseOf:gas required exceeds allowance or always failing transaction.', + })) + assert.equal(result, '0x64x0.95') + }) + + it(`should reject other errors`, async () => { + try { + await estimateGas(Object.assign({}, baseMockParams, { + to: 'isContract willFailBecauseOf:some other error', + })) + } catch (err) { + assert.deepEqual(err, { message: 'some other error' }) + } + }) }) describe('estimateGasPriceFromRecentBlocks', () => { -- cgit From 64aa56b5a6f753d198ceadc9cf2c79929046fc19 Mon Sep 17 00:00:00 2001 From: kumavis Date: Mon, 28 May 2018 12:54:19 -0700 Subject: test - send-utils.test - lint fix --- ui/app/components/send_/tests/send-utils.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index 4801d4a09..14125d7a6 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -242,7 +242,7 @@ describe('send utils', () => { to: '0xisContract', estimateGasMethod: sinon.stub().callsFake( (data, cb) => cb( - data.to.match(/willFailBecauseOf:/) ? { message: data.to.match(/\:(.+)$/)[1] } : null, + data.to.match(/willFailBecauseOf:/) ? { message: data.to.match(/:(.+)$/)[1] } : null, { toString: (n) => `mockToString:${n}` } ) ), -- cgit From 1b879f45bc0d53e8c0ffa9513b525e0055ed8f81 Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 2 Jun 2018 01:53:01 -0230 Subject: Fix calculation of data property for gas estimation on token transfers. --- ui/app/components/send_/tests/send-utils.test.js | 43 +++++++++++++++--------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index 14125d7a6..b3f6372ef 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -106,11 +106,23 @@ describe('send utils', () => { describe('generateTokenTransferData()', () => { it('should return undefined if not passed a selected token', () => { - assert.equal(generateTokenTransferData('mockAddress', false), undefined) + assert.equal(generateTokenTransferData({ toAddress: 'mockAddress', amount: '0xa', selectedToken: false}), undefined) + }) + + it('should call abi.rawEncode with the correct params', () => { + stubs.rawEncode.resetHistory() + generateTokenTransferData({ toAddress: 'mockAddress', amount: 'ab', selectedToken: true}) + assert.deepEqual( + stubs.rawEncode.getCall(0).args, + [['address', 'uint256'], ['mockAddress', '0xab']] + ) }) it('should return encoded token transfer data', () => { - assert.equal(generateTokenTransferData('mockAddress', true), '104c') + assert.equal( + generateTokenTransferData({ toAddress: 'mockAddress', amount: '0xa', selectedToken: true}), + '0xa9059cbb104c' + ) }) }) @@ -276,22 +288,17 @@ describe('send utils', () => { assert.equal(result, 'mockToString:16') }) - it('should call ethQuery.estimateGas with a value of 0x0 if the passed selectedToken has a symbol', async () => { - const result = await estimateGas(Object.assign({ selectedToken: { symbol: true } }, baseMockParams)) + it('should call ethQuery.estimateGas with a value of 0x0 and the expected data and to if passed a selectedToken', async () => { + const result = await estimateGas(Object.assign({ data: 'mockData', selectedToken: { address: 'mockAddress' } }, baseMockParams)) assert.equal(baseMockParams.estimateGasMethod.callCount, 1) assert.deepEqual( baseMockParams.estimateGasMethod.getCall(0).args[0], - Object.assign({ gasPrice: undefined, value: '0x0' }, baseExpectedCall) - ) - assert.equal(result, 'mockToString:16') - }) - - it('should call ethQuery.estimateGas with data if data is passed', async () => { - const result = await estimateGas(Object.assign({ data: 'mockData' }, baseMockParams)) - assert.equal(baseMockParams.estimateGasMethod.callCount, 1) - assert.deepEqual( - baseMockParams.estimateGasMethod.getCall(0).args[0], - Object.assign({ gasPrice: undefined, value: undefined, data: 'mockData' }, baseExpectedCall) + Object.assign({}, baseExpectedCall, { + gasPrice: undefined, + value: '0x0', + data: '0xa9059cbb104c', + to: 'mockAddress', + }) ) assert.equal(result, 'mockToString:16') }) @@ -302,6 +309,12 @@ describe('send utils', () => { assert.equal(result, SIMPLE_GAS_COST) }) + it(`should not return ${SIMPLE_GAS_COST} if passed a selectedToken`, async () => { + assert.equal(baseMockParams.estimateGasMethod.callCount, 0) + const result = await estimateGas(Object.assign({}, baseMockParams, { to: '0x123', selectedToken: { address: '' } })) + assert.notEqual(result, SIMPLE_GAS_COST) + }) + it(`should return the adjusted blockGasLimit if it fails with a 'Transaction execution error.'`, async () => { const result = await estimateGas(Object.assign({}, baseMockParams, { to: 'isContract willFailBecauseOf:Transaction execution error.', -- cgit From 1b9ed237527b9970c3dfcbb0234cfdb2ffa8c807 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Thu, 14 Jun 2018 14:04:14 -0700 Subject: Add hex-prefix to gas estimate result --- ui/app/components/send_/tests/send-utils.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index b3f6372ef..6db875342 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -285,7 +285,7 @@ describe('send utils', () => { baseMockParams.estimateGasMethod.getCall(0).args[0], Object.assign({ gasPrice: undefined, value: undefined }, baseExpectedCall) ) - assert.equal(result, 'mockToString:16') + assert.equal(result, '0xmockToString:16') }) it('should call ethQuery.estimateGas with a value of 0x0 and the expected data and to if passed a selectedToken', async () => { @@ -300,7 +300,7 @@ describe('send utils', () => { to: 'mockAddress', }) ) - assert.equal(result, 'mockToString:16') + assert.equal(result, '0xmockToString:16') }) it(`should return ${SIMPLE_GAS_COST} if ethQuery.getCode does not return '0x'`, async () => { -- cgit From e4d3bdba125964042480e35847747903f3de7ac3 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 14 Jun 2018 23:54:48 -0230 Subject: Update send.utils.js estimateGas tests. --- ui/app/components/send_/tests/send-utils.test.js | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index 6db875342..00804d074 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -18,10 +18,12 @@ const { const stubs = { addCurrencies: sinon.stub().callsFake((a, b, obj) => a + b), conversionUtil: sinon.stub().callsFake((val, obj) => parseInt(val, 16)), - conversionGTE: sinon.stub().callsFake((obj1, obj2) => obj1.value > obj2.value), + conversionGTE: sinon.stub().callsFake((obj1, obj2) => obj1.value >= obj2.value), multiplyCurrencies: sinon.stub().callsFake((a, b) => `${a}x${b}`), calcTokenAmount: sinon.stub().callsFake((a, d) => 'calc:' + a + d), rawEncode: sinon.stub().returns([16, 1100]), + conversionGreaterThan: sinon.stub().callsFake((obj1, obj2) => obj1.value > obj2.value), + conversionLessThan: sinon.stub().callsFake((obj1, obj2) => obj1.value < obj2.value), } const sendUtils = proxyquire('../send.utils.js', { @@ -30,6 +32,8 @@ const sendUtils = proxyquire('../send.utils.js', { conversionUtil: stubs.conversionUtil, conversionGTE: stubs.conversionGTE, multiplyCurrencies: stubs.multiplyCurrencies, + conversionGreaterThan: stubs.conversionGreaterThan, + conversionLessThan: stubs.conversionLessThan, }, '../../token-util': { calcTokenAmount: stubs.calcTokenAmount }, 'ethereumjs-abi': { @@ -255,7 +259,7 @@ describe('send utils', () => { estimateGasMethod: sinon.stub().callsFake( (data, cb) => cb( data.to.match(/willFailBecauseOf:/) ? { message: data.to.match(/:(.+)$/)[1] } : null, - { toString: (n) => `mockToString:${n}` } + { toString: (n) => `0xabc${n}` } ) ), } @@ -279,13 +283,23 @@ describe('send utils', () => { }) it('should call ethQuery.estimateGas with the expected params', async () => { - const result = await estimateGas(baseMockParams) + const result = await sendUtils.estimateGas(baseMockParams) assert.equal(baseMockParams.estimateGasMethod.callCount, 1) assert.deepEqual( baseMockParams.estimateGasMethod.getCall(0).args[0], Object.assign({ gasPrice: undefined, value: undefined }, baseExpectedCall) ) - assert.equal(result, '0xmockToString:16') + assert.equal(result, '0xabc16') + }) + + it('should call ethQuery.estimateGas with the expected params when initialGasLimitHex is lower than the upperGasLimit', async () => { + const result = await estimateGas(Object.assign({}, baseMockParams, { blockGasLimit: '0xbcd' })) + assert.equal(baseMockParams.estimateGasMethod.callCount, 1) + assert.deepEqual( + baseMockParams.estimateGasMethod.getCall(0).args[0], + Object.assign({ gasPrice: undefined, value: undefined }, baseExpectedCall, { gas: '0xbcdx0.95' }) + ) + assert.equal(result, '0xabc16x1.5') }) it('should call ethQuery.estimateGas with a value of 0x0 and the expected data and to if passed a selectedToken', async () => { @@ -300,7 +314,7 @@ describe('send utils', () => { to: 'mockAddress', }) ) - assert.equal(result, '0xmockToString:16') + assert.equal(result, '0xabc16') }) it(`should return ${SIMPLE_GAS_COST} if ethQuery.getCode does not return '0x'`, async () => { -- cgit From 70abe54c94d8c08aa1b73fd63f34b65bc3dff117 Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 18 Jun 2018 13:55:20 -0230 Subject: Send screen returns simple gas cost if no to address specified when not sending token. --- ui/app/components/send_/tests/send-utils.test.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index 00804d074..facc0e518 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -323,6 +323,12 @@ describe('send utils', () => { assert.equal(result, SIMPLE_GAS_COST) }) + it(`should return ${SIMPLE_GAS_COST} if not passed a selectedToken or truthy to address`, async () => { + assert.equal(baseMockParams.estimateGasMethod.callCount, 0) + const result = await estimateGas(Object.assign({}, baseMockParams, { to: null })) + assert.equal(result, SIMPLE_GAS_COST) + }) + it(`should not return ${SIMPLE_GAS_COST} if passed a selectedToken`, async () => { assert.equal(baseMockParams.estimateGasMethod.callCount, 0) const result = await estimateGas(Object.assign({}, baseMockParams, { to: '0x123', selectedToken: { address: '' } })) -- cgit From ac7c0277b503c7660d6894a9039d35c8713f52ab Mon Sep 17 00:00:00 2001 From: Dan Date: Mon, 18 Jun 2018 14:07:01 -0230 Subject: On send screen amount change, updateGas call now includes current to address. --- ui/app/components/send_/tests/send-utils.test.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index facc0e518..f3d5674b7 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -48,6 +48,7 @@ const { estimateGasPriceFromRecentBlocks, generateTokenTransferData, getAmountErrorObject, + getToAddressForGasUpdate, calcTokenBalance, isBalanceSufficient, isTokenBalanceSufficient, @@ -421,4 +422,15 @@ describe('send utils', () => { assert.equal(estimateGasPriceFromRecentBlocks(mockRecentBlocks), '0x5') }) }) + + describe('getToAddressForGasUpdate()', () => { + it('should return empty string if all params are undefined or null', () => { + assert.equal(getToAddressForGasUpdate(undefined, null), '') + }) + + it('should return the first string that is not defined or null in lower case', () => { + assert.equal(getToAddressForGasUpdate('A', null), 'a') + assert.equal(getToAddressForGasUpdate(undefined, 'B'), 'b') + }) + }) }) -- cgit From 696d6261338e96a3a7786e08940ab51cad98cb22 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 28 Jun 2018 21:03:09 -0230 Subject: Set based estimate for token sends to be updated once recipient address specified. --- ui/app/components/send_/tests/send-utils.test.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'ui/app/components/send_/tests/send-utils.test.js') diff --git a/ui/app/components/send_/tests/send-utils.test.js b/ui/app/components/send_/tests/send-utils.test.js index f3d5674b7..a518a64e9 100644 --- a/ui/app/components/send_/tests/send-utils.test.js +++ b/ui/app/components/send_/tests/send-utils.test.js @@ -2,6 +2,7 @@ import assert from 'assert' import sinon from 'sinon' import proxyquire from 'proxyquire' import { + BASE_TOKEN_GAS_COST, ONE_GWEI_IN_WEI_HEX, SIMPLE_GAS_COST, } from '../send.constants' @@ -336,6 +337,11 @@ describe('send utils', () => { assert.notEqual(result, SIMPLE_GAS_COST) }) + it(`should return ${BASE_TOKEN_GAS_COST} if passed a selectedToken but no to address`, async () => { + const result = await estimateGas(Object.assign({}, baseMockParams, { to: null, selectedToken: { address: '' } })) + assert.equal(result, BASE_TOKEN_GAS_COST) + }) + it(`should return the adjusted blockGasLimit if it fails with a 'Transaction execution error.'`, async () => { const result = await estimateGas(Object.assign({}, baseMockParams, { to: 'isContract willFailBecauseOf:Transaction execution error.', -- cgit