// Copyright 2015-2017 Parity Technologies (UK) Ltd. // This file is part of Parity. // Parity is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Parity is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Parity. If not, see . import BigNumber from 'bignumber.js'; import sinon from 'sinon'; import { DEFAULT_GAS, DEFAULT_GASPRICE, MAX_GAS_ESTIMATION } from '@parity/shared/util/constants'; import { ERRORS } from '@parity/shared/util/validation'; import GasPriceEditor from './gasPriceEditor'; import { CONDITIONS } from './store'; const { Store } = GasPriceEditor; const GASPRICE = new BigNumber(123456); const GASLIMIT = 100000; const HISTOGRAM = { bucketBounds: [1, 2], counts: [3, 4] }; let api; // TODO: share with gasPriceEditor.spec.js function createApi () { api = { eth: { blockNumber: sinon.stub().resolves(new BigNumber(2)), gasPrice: sinon.stub().resolves(GASPRICE) }, parity: { gasPriceHistogram: sinon.stub().resolves(HISTOGRAM) } }; return api; } describe('ui/GasPriceEditor/Store', () => { let store = null; beforeEach(() => { createApi(); }); it('is available via GasPriceEditor.Store', () => { expect(new Store(null, {})).to.be.ok; }); describe('constructor (defaults)', () => { beforeEach(() => { store = new Store(api, { gasLimit: GASLIMIT }); }); it('retrieves the histogram and gasPrice', () => { expect(api.eth.gasPrice).to.have.been.called; expect(api.parity.gasPriceHistogram).to.have.been.called; }); it('sets the gasLimit as passed', () => { expect(store.gasLimit).to.equal(GASLIMIT); }); }); describe('constructor (defaults) when histogram not available', () => { const api = { eth: { blockNumber: sinon.stub().resolves(new BigNumber(2)), gasPrice: sinon.stub().resolves(GASPRICE) }, parity: { gasPriceHistogram: sinon.stub().rejects('Data not available') } }; beforeEach(() => { store = new Store(api, { gasLimit: GASLIMIT }); }); it('retrieves the histogram and gasPrice', done => { expect(api.eth.gasPrice).to.have.been.called; expect(api.parity.gasPriceHistogram).to.have.been.called; setImmediate(() => { expect(store.histogram).not.to.be.null; expect(store.histogram.bucketBounds).not.to.be.null; done(); }); }); }); describe('setters', () => { beforeEach(() => { store = new Store(null, { gasLimit: GASLIMIT }); }); describe('setConditionType', () => { it('sets the actual type', () => { store.setConditionType('testingType'); expect(store.conditionType).to.equal('testingType'); }); it('clears any block error on changing type', () => { store.setConditionBlockNumber(-1); expect(store.conditionBlockError).not.to.be.null; store.setConditionType(CONDITIONS.BLOCK); expect(store.conditionBlockError).to.be.null; }); it('sets condition.block when type === CONDITIONS.BLOCK', () => { store.setConditionType(CONDITIONS.BLOCK); expect(store.condition.block).to.be.ok; }); it('clears condition when type === CONDITIONS.NONE', () => { store.setConditionType(CONDITIONS.BLOCK); store.setConditionType(CONDITIONS.NONE); expect(store.condition).to.deep.equal({}); }); it('sets condition.time when type === CONDITIONS.TIME', () => { store.setConditionType(CONDITIONS.TIME); expect(store.condition.time).to.be.ok; }); }); describe('setConditionBlockNumber', () => { beforeEach(() => { store.setConditionBlockNumber('testingBlock'); }); it('sets the blockNumber', () => { expect(store.condition.block).to.equal('testingBlock'); }); it('sets the error on invalid numbers', () => { expect(store.conditionBlockError).not.to.be.null; }); it('sets the error on negative numbers', () => { store.setConditionBlockNumber(-1); expect(store.conditionBlockError).not.to.be.null; }); it('clears the error on positive numbers', () => { store.setConditionBlockNumber(1000); expect(store.conditionBlockError).to.be.null; }); }); describe('setConditionDateTime', () => { const BASEDATE = '1973-06-11 07:52'; const ZEROTIME = new Date(BASEDATE).getTime(); it('sets the datetime', () => { store.setConditionDateTime(new Date(`${BASEDATE}:00.000`)); expect(store.condition.time.getTime()).to.equal(ZEROTIME); }); it('zeros both seconds and miliseconds', () => { store.setConditionDateTime(new Date(`${BASEDATE}:12.345`)); expect(store.condition.time.getTime()).to.equal(ZEROTIME); }); }); describe('setEditing', () => { it('sets the value', () => { expect(store.isEditing).to.be.false; store.setEditing(true); expect(store.isEditing).to.be.true; }); }); describe('setErrorTotal', () => { it('sets the value', () => { store.setErrorTotal('errorTotal'); expect(store.errorTotal).to.equal('errorTotal'); }); }); describe('setEstimatedError', () => { it('sets the value as provided', () => { store.setEstimatedError('errorTest'); expect(store.errorEstimated).to.equal('errorTest'); }); it('sets the null value as provided', () => { store.setEstimatedError('errorTest'); store.setEstimatedError(null); expect(store.errorEstimated).to.be.null; }); it('sets a default error when none provided', () => { store.setEstimatedError(); expect(store.errorEstimated).to.equal(ERRORS.gasException); }); }); describe('setEstimated', () => { it('sets the value', () => { store.setEstimated('789'); expect(store.estimated).to.equal('789'); }); it('sets error when above exception max', () => { store.setEstimated(MAX_GAS_ESTIMATION); expect(store.errorEstimated).to.equal(ERRORS.gasException); }); it('sets error when above gaslimit', () => { store.setEstimated(GASLIMIT); expect(store.errorEstimated).to.equal(ERRORS.gasBlockLimit); }); }); describe('setEthValue', () => { it('sets the value', () => { store.setEthValue('123'); expect(store.weiValue).to.equal('123'); }); }); describe('setGas', () => { it('sets the value', () => { store.setGas('123'); expect(store.gas).to.equal('123'); expect(store.errorGas).to.be.null; }); it('sets error on negative numbers', () => { store.setGas(-123); expect(store.errorGas).not.to.be.null; }); it('sets error when above block limit', () => { store.setGas(GASLIMIT); expect(store.errorGas).to.equal(ERRORS.gasBlockLimit); }); }); describe('setGasLimit', () => { it('sets the value', () => { store.setGasLimit('123'); expect(store.gasLimit).to.equal('123'); }); }); describe('setHistogram', () => { it('sets the value', () => { store.setHistogram(HISTOGRAM); expect(store.histogram).to.deep.equal(HISTOGRAM); }); }); describe('setPrice', () => { it('sets the value', () => { store.setPrice('123'); expect(store.price).to.equal('123'); expect(store.errorPrice).to.be.null; }); it('sets error on negative numbers', () => { store.setPrice(-123); expect(store.errorPrice).not.to.be.null; }); }); }); describe('computed', () => { beforeEach(() => { store = new Store(null, { gasLimit: GASLIMIT }); }); describe('totalValue', () => { it('holds the total including eth, price & gas', () => { store.setPrice('123'); store.setGas('123'); store.setEthValue('123'); expect(store.totalValue).to.deep.equal(new BigNumber(123 + 123 * 123)); }); }); }); describe('methods', () => { beforeEach(() => { store = new Store(null, { gasLimit: GASLIMIT }); }); describe('overrideTransaction', () => { const TRANSACTION = { gas: '123', gasPrice: '456' }; it('overrides gas & gasPrice with values', () => { store.setGas(DEFAULT_GAS); const transaction = store.overrideTransaction(TRANSACTION); expect(transaction.gas).to.deep.equal(new BigNumber(DEFAULT_GAS)); expect(transaction.gasPrice).to.deep.equal(new BigNumber(DEFAULT_GASPRICE)); }); it('does not override with invalid gas', () => { store.setGas(-123); expect(store.overrideTransaction(TRANSACTION)).to.deep.equal(TRANSACTION); }); it('does not override with invalid price', () => { store.setPrice(-123); expect(store.overrideTransaction(TRANSACTION)).to.deep.equal(TRANSACTION); }); }); }); });