mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Read only connection of gas price chart to redux
This commit is contained in:
parent
2dbae581ac
commit
a2bbf504b8
@ -15,6 +15,7 @@ export default class AdvancedTabContent extends Component {
|
|||||||
millisecondsRemaining: PropTypes.number,
|
millisecondsRemaining: PropTypes.number,
|
||||||
totalFee: PropTypes.string,
|
totalFee: PropTypes.string,
|
||||||
timeRemaining: PropTypes.string,
|
timeRemaining: PropTypes.string,
|
||||||
|
gasChartProps: PropTypes.object,
|
||||||
}
|
}
|
||||||
|
|
||||||
gasInput (value, onChange, min, precision, showGWEI) {
|
gasInput (value, onChange, min, precision, showGWEI) {
|
||||||
@ -82,6 +83,7 @@ export default class AdvancedTabContent extends Component {
|
|||||||
customGasPrice,
|
customGasPrice,
|
||||||
customGasLimit,
|
customGasLimit,
|
||||||
totalFee,
|
totalFee,
|
||||||
|
gasChartProps,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -95,7 +97,7 @@ export default class AdvancedTabContent extends Component {
|
|||||||
updateCustomGasLimit
|
updateCustomGasLimit
|
||||||
) }
|
) }
|
||||||
<div className="advanced-tab__fee-chart__title">Live Gas Price Predictions</div>
|
<div className="advanced-tab__fee-chart__title">Live Gas Price Predictions</div>
|
||||||
<GasPriceChart />
|
<GasPriceChart {...gasChartProps} />
|
||||||
<div className="advanced-tab__fee-chart__speed-buttons">
|
<div className="advanced-tab__fee-chart__speed-buttons">
|
||||||
<span>Slower</span>
|
<span>Slower</span>
|
||||||
<span>Faster</span>
|
<span>Faster</span>
|
||||||
|
@ -46,6 +46,7 @@ export default class GasModalPageContainer extends Component {
|
|||||||
customGasPrice,
|
customGasPrice,
|
||||||
customGasLimit,
|
customGasLimit,
|
||||||
newTotalFiat,
|
newTotalFiat,
|
||||||
|
gasChartProps,
|
||||||
}) {
|
}) {
|
||||||
const { transactionFee } = this.props
|
const { transactionFee } = this.props
|
||||||
return (
|
return (
|
||||||
@ -57,6 +58,7 @@ export default class GasModalPageContainer extends Component {
|
|||||||
timeRemaining="1 min 31 sec"
|
timeRemaining="1 min 31 sec"
|
||||||
transactionFee={transactionFee}
|
transactionFee={transactionFee}
|
||||||
totalFee={newTotalFiat}
|
totalFee={newTotalFiat}
|
||||||
|
gasChartProps={gasChartProps}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -73,12 +73,14 @@ const mapStateToProps = state => {
|
|||||||
customGasPrice: calcCustomGasPrice(customModalGasPriceInHex),
|
customGasPrice: calcCustomGasPrice(customModalGasPriceInHex),
|
||||||
customGasLimit: calcCustomGasLimit(customModalGasLimitInHex),
|
customGasLimit: calcCustomGasLimit(customModalGasLimitInHex),
|
||||||
newTotalFiat,
|
newTotalFiat,
|
||||||
transactionFee: addHexWEIsToRenderableFiat('0x0', customGasTotal, currentCurrency, conversionRate),
|
|
||||||
gasPriceButtonGroupProps: {
|
gasPriceButtonGroupProps: {
|
||||||
buttonDataLoading,
|
buttonDataLoading,
|
||||||
defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex),
|
defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex),
|
||||||
gasButtonInfo,
|
gasButtonInfo,
|
||||||
},
|
},
|
||||||
|
gasChartProps: {
|
||||||
|
priceAndTimeEstimates: state.gas.priceAndTimeEstimates,
|
||||||
|
},
|
||||||
infoRowProps: {
|
infoRowProps: {
|
||||||
originalTotalFiat: addHexWEIsToRenderableFiat(value, gasTotal, currentCurrency, conversionRate),
|
originalTotalFiat: addHexWEIsToRenderableFiat(value, gasTotal, currentCurrency, conversionRate),
|
||||||
originalTotalEth: addHexWEIsToRenderableEth(value, gasTotal),
|
originalTotalEth: addHexWEIsToRenderableEth(value, gasTotal),
|
||||||
|
@ -75,6 +75,7 @@ describe('gas-modal-page-container container', () => {
|
|||||||
limit: 'aaaaaaaa',
|
limit: 'aaaaaaaa',
|
||||||
price: 'ffffffff',
|
price: 'ffffffff',
|
||||||
},
|
},
|
||||||
|
priceAndTimeEstimates: 'mockPriceAndTimeEstimates',
|
||||||
},
|
},
|
||||||
confirmTransaction: {
|
confirmTransaction: {
|
||||||
txData: {
|
txData: {
|
||||||
@ -95,6 +96,9 @@ describe('gas-modal-page-container container', () => {
|
|||||||
newTotalFiat: '637.41',
|
newTotalFiat: '637.41',
|
||||||
customModalGasLimitInHex: 'aaaaaaaa',
|
customModalGasLimitInHex: 'aaaaaaaa',
|
||||||
customModalGasPriceInHex: 'ffffffff',
|
customModalGasPriceInHex: 'ffffffff',
|
||||||
|
gasChartProps: {
|
||||||
|
priceAndTimeEstimates: 'mockPriceAndTimeEstimates',
|
||||||
|
},
|
||||||
gasPriceButtonGroupProps: {
|
gasPriceButtonGroupProps: {
|
||||||
buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4',
|
buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4',
|
||||||
defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff',
|
defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff',
|
||||||
|
@ -1,18 +1,57 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import assert from 'assert'
|
import assert from 'assert'
|
||||||
|
import proxyquire from 'proxyquire'
|
||||||
|
import sinon from 'sinon'
|
||||||
import shallow from '../../../../../lib/shallow-with-context'
|
import shallow from '../../../../../lib/shallow-with-context'
|
||||||
import GasPriceChart from '../gas-price-chart.component.js'
|
import * as d3 from 'd3'
|
||||||
|
|
||||||
|
const mockSelectReturn = {
|
||||||
|
...d3.select('div'),
|
||||||
|
node: () => ({
|
||||||
|
getBoundingClientRect: () => ({ x: 123, y: 321, width: 400 }),
|
||||||
|
}),
|
||||||
|
select: d3.select,
|
||||||
|
attr: sinon.spy(),
|
||||||
|
on: sinon.spy(),
|
||||||
|
}
|
||||||
|
|
||||||
|
const GasPriceChart = proxyquire('../gas-price-chart.component.js', {
|
||||||
|
'c3': {
|
||||||
|
generate: function () {
|
||||||
|
return {
|
||||||
|
internal: {
|
||||||
|
showTooltip: () => {},
|
||||||
|
showXGridFocus: () => {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'd3': {
|
||||||
|
...d3,
|
||||||
|
select: function (...args) {
|
||||||
|
const result = d3.select(...args)
|
||||||
|
return result.empty()
|
||||||
|
? mockSelectReturn
|
||||||
|
: result
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}).default
|
||||||
|
|
||||||
describe('GasPriceChart Component', function () {
|
describe('GasPriceChart Component', function () {
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
wrapper = shallow(<GasPriceChart />)
|
wrapper = shallow(<GasPriceChart
|
||||||
|
priceAndTimeEstimates={[
|
||||||
|
{ gasprice: 1, expectedTime: 10 },
|
||||||
|
{ gasprice: 2, expectedTime: 20 },
|
||||||
|
{ gasprice: 3, expectedTime: 30 },
|
||||||
|
]}
|
||||||
|
/>)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('render()', () => {
|
describe('render()', () => {
|
||||||
it('should render', () => {
|
it('should render', () => {
|
||||||
console.log('wrapper', wrapper.html())
|
|
||||||
assert(wrapper.hasClass('gas-price-chart'))
|
assert(wrapper.hasClass('gas-price-chart'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ export default class ConfirmTransaction extends Component {
|
|||||||
setTransactionToConfirm: PropTypes.func,
|
setTransactionToConfirm: PropTypes.func,
|
||||||
confirmTransaction: PropTypes.object,
|
confirmTransaction: PropTypes.object,
|
||||||
clearConfirmTransaction: PropTypes.func,
|
clearConfirmTransaction: PropTypes.func,
|
||||||
fetchGasEstimates: PropTypes.func,
|
fetchBasicGasEstimates: PropTypes.func,
|
||||||
}
|
}
|
||||||
|
|
||||||
getParamsTransactionId () {
|
getParamsTransactionId () {
|
||||||
@ -46,7 +46,7 @@ export default class ConfirmTransaction extends Component {
|
|||||||
send = {},
|
send = {},
|
||||||
history,
|
history,
|
||||||
confirmTransaction: { txData: { id: transactionId } = {} },
|
confirmTransaction: { txData: { id: transactionId } = {} },
|
||||||
fetchGasEstimates,
|
fetchBasicGasEstimates,
|
||||||
} = this.props
|
} = this.props
|
||||||
|
|
||||||
if (!totalUnapprovedCount && !send.to) {
|
if (!totalUnapprovedCount && !send.to) {
|
||||||
@ -55,7 +55,7 @@ export default class ConfirmTransaction extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!transactionId) {
|
if (!transactionId) {
|
||||||
fetchGasEstimates()
|
fetchBasicGasEstimates()
|
||||||
this.setTransactionToConfirm()
|
this.setTransactionToConfirm()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
clearConfirmTransaction,
|
clearConfirmTransaction,
|
||||||
} from '../../../ducks/confirm-transaction.duck'
|
} from '../../../ducks/confirm-transaction.duck'
|
||||||
import {
|
import {
|
||||||
fetchGasEstimates,
|
fetchBasicGasEstimates,
|
||||||
} from '../../../ducks/gas.duck'
|
} from '../../../ducks/gas.duck'
|
||||||
import ConfirmTransaction from './confirm-transaction.component'
|
import ConfirmTransaction from './confirm-transaction.component'
|
||||||
import { getTotalUnapprovedCount } from '../../../selectors'
|
import { getTotalUnapprovedCount } from '../../../selectors'
|
||||||
@ -27,7 +27,7 @@ const mapDispatchToProps = dispatch => {
|
|||||||
return {
|
return {
|
||||||
setTransactionToConfirm: transactionId => dispatch(setTransactionToConfirm(transactionId)),
|
setTransactionToConfirm: transactionId => dispatch(setTransactionToConfirm(transactionId)),
|
||||||
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
clearConfirmTransaction: () => dispatch(clearConfirmTransaction()),
|
||||||
fetchGasEstimates: () => dispatch(fetchGasEstimates()),
|
fetchBasicGasEstimates: () => dispatch(fetchBasicGasEstimates()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -163,9 +163,10 @@ export default class SendTransactionScreen extends PersistentForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this.props.fetchGasEstimates()
|
this.props.fetchBasicGasEstimates()
|
||||||
.then(() => {
|
.then(basicEstimates => {
|
||||||
this.updateGas()
|
this.updateGas()
|
||||||
|
this.props.fetchGasEstimates(basicEstimates.blockTime)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ import {
|
|||||||
updateSendErrors,
|
updateSendErrors,
|
||||||
} from '../../ducks/send.duck'
|
} from '../../ducks/send.duck'
|
||||||
import {
|
import {
|
||||||
|
fetchBasicGasEstimates,
|
||||||
fetchGasEstimates,
|
fetchGasEstimates,
|
||||||
} from '../../ducks/gas.duck'
|
} from '../../ducks/gas.duck'
|
||||||
import {
|
import {
|
||||||
@ -107,6 +108,7 @@ function mapDispatchToProps (dispatch) {
|
|||||||
scanQrCode: () => dispatch(showQrScanner(SEND_ROUTE)),
|
scanQrCode: () => dispatch(showQrScanner(SEND_ROUTE)),
|
||||||
qrCodeDetected: (data) => dispatch(qrCodeDetected(data)),
|
qrCodeDetected: (data) => dispatch(qrCodeDetected(data)),
|
||||||
updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)),
|
updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)),
|
||||||
fetchGasEstimates: () => dispatch(fetchGasEstimates()),
|
fetchBasicGasEstimates: () => dispatch(fetchBasicGasEstimates()),
|
||||||
|
fetchGasEstimates: (blockTime) => dispatch(fetchGasEstimates(blockTime)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,23 @@ import SendHeader from '../send-header/send-header.container'
|
|||||||
import SendContent from '../send-content/send-content.component'
|
import SendContent from '../send-content/send-content.component'
|
||||||
import SendFooter from '../send-footer/send-footer.container'
|
import SendFooter from '../send-footer/send-footer.container'
|
||||||
|
|
||||||
|
function timeout (time) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
setTimeout(resolve, time || 1500)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const mockBasicGasEstimates = {
|
||||||
|
blockTime: 'mockBlockTime',
|
||||||
|
}
|
||||||
|
|
||||||
const propsMethodSpies = {
|
const propsMethodSpies = {
|
||||||
updateAndSetGasLimit: sinon.spy(),
|
updateAndSetGasLimit: sinon.spy(),
|
||||||
updateSendErrors: sinon.spy(),
|
updateSendErrors: sinon.spy(),
|
||||||
updateSendTokenBalance: sinon.spy(),
|
updateSendTokenBalance: sinon.spy(),
|
||||||
resetSendState: sinon.spy(),
|
resetSendState: sinon.spy(),
|
||||||
fetchGasEstimates: sinon.stub().returns(Promise.resolve()),
|
fetchBasicGasEstimates: sinon.stub().returns(Promise.resolve(mockBasicGasEstimates)),
|
||||||
|
fetchGasEstimates: sinon.spy(),
|
||||||
}
|
}
|
||||||
const utilsMethodStubs = {
|
const utilsMethodStubs = {
|
||||||
getAmountErrorObject: sinon.stub().returns({ amount: 'mockAmountError' }),
|
getAmountErrorObject: sinon.stub().returns({ amount: 'mockAmountError' }),
|
||||||
@ -38,6 +49,7 @@ describe('Send Component', function () {
|
|||||||
blockGasLimit={'mockBlockGasLimit'}
|
blockGasLimit={'mockBlockGasLimit'}
|
||||||
conversionRate={10}
|
conversionRate={10}
|
||||||
editingTransactionId={'mockEditingTransactionId'}
|
editingTransactionId={'mockEditingTransactionId'}
|
||||||
|
fetchBasicGasEstimates={propsMethodSpies.fetchBasicGasEstimates}
|
||||||
fetchGasEstimates={propsMethodSpies.fetchGasEstimates}
|
fetchGasEstimates={propsMethodSpies.fetchGasEstimates}
|
||||||
from={ { address: 'mockAddress', balance: 'mockBalance' } }
|
from={ { address: 'mockAddress', balance: 'mockBalance' } }
|
||||||
gasLimit={'mockGasLimit'}
|
gasLimit={'mockGasLimit'}
|
||||||
@ -65,7 +77,7 @@ describe('Send Component', function () {
|
|||||||
utilsMethodStubs.doesAmountErrorRequireUpdate.resetHistory()
|
utilsMethodStubs.doesAmountErrorRequireUpdate.resetHistory()
|
||||||
utilsMethodStubs.getAmountErrorObject.resetHistory()
|
utilsMethodStubs.getAmountErrorObject.resetHistory()
|
||||||
utilsMethodStubs.getGasFeeErrorObject.resetHistory()
|
utilsMethodStubs.getGasFeeErrorObject.resetHistory()
|
||||||
propsMethodSpies.fetchGasEstimates.resetHistory()
|
propsMethodSpies.fetchBasicGasEstimates.resetHistory()
|
||||||
propsMethodSpies.updateAndSetGasLimit.resetHistory()
|
propsMethodSpies.updateAndSetGasLimit.resetHistory()
|
||||||
propsMethodSpies.updateSendErrors.resetHistory()
|
propsMethodSpies.updateSendErrors.resetHistory()
|
||||||
propsMethodSpies.updateSendTokenBalance.resetHistory()
|
propsMethodSpies.updateSendTokenBalance.resetHistory()
|
||||||
@ -76,19 +88,29 @@ describe('Send Component', function () {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('componentDidMount', () => {
|
describe('componentDidMount', () => {
|
||||||
it('should call props.fetchGasEstimates', () => {
|
it('should call props.fetchBasicGasEstimates', () => {
|
||||||
propsMethodSpies.fetchGasEstimates.resetHistory()
|
propsMethodSpies.fetchBasicGasEstimates.resetHistory()
|
||||||
assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 0)
|
assert.equal(propsMethodSpies.fetchBasicGasEstimates.callCount, 0)
|
||||||
wrapper.instance().componentDidMount()
|
wrapper.instance().componentDidMount()
|
||||||
assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 1)
|
assert.equal(propsMethodSpies.fetchBasicGasEstimates.callCount, 1)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should call this.updateGas', () => {
|
it('should call this.updateGas', async () => {
|
||||||
SendTransactionScreen.prototype.updateGas.resetHistory()
|
SendTransactionScreen.prototype.updateGas.resetHistory()
|
||||||
propsMethodSpies.updateSendErrors.resetHistory()
|
propsMethodSpies.updateSendErrors.resetHistory()
|
||||||
assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0)
|
assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0)
|
||||||
wrapper.instance().componentDidMount()
|
wrapper.instance().componentDidMount()
|
||||||
setTimeout(() => assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1), 250)
|
await timeout(250)
|
||||||
|
assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should call props.fetchGasEstimates with the block time returned by fetchBasicGasEstimates', async () => {
|
||||||
|
propsMethodSpies.fetchGasEstimates.resetHistory()
|
||||||
|
assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 0)
|
||||||
|
wrapper.instance().componentDidMount()
|
||||||
|
await timeout(250)
|
||||||
|
assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 1)
|
||||||
|
assert.equal(propsMethodSpies.fetchGasEstimates.getCall(0).args[0], 'mockBlockTime')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
import { clone } from 'ramda'
|
import { mockGasEstimateData } from './mock-gas-estimate-data'
|
||||||
|
import { clone, uniqBy } from 'ramda'
|
||||||
|
import BigNumber from 'bignumber.js'
|
||||||
|
|
||||||
// Actions
|
// Actions
|
||||||
const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED'
|
const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED'
|
||||||
const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED'
|
const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED'
|
||||||
|
const GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/GAS_ESTIMATE_LOADING_FINISHED'
|
||||||
|
const GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/GAS_ESTIMATE_LOADING_STARTED'
|
||||||
const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE'
|
const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE'
|
||||||
const RESET_CUSTOM_DATA = 'metamask/gas/RESET_CUSTOM_DATA'
|
const RESET_CUSTOM_DATA = 'metamask/gas/RESET_CUSTOM_DATA'
|
||||||
const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA'
|
const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA'
|
||||||
@ -10,6 +14,7 @@ const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS'
|
|||||||
const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT'
|
const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT'
|
||||||
const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE'
|
const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE'
|
||||||
const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL'
|
const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL'
|
||||||
|
const SET_PRICE_AND_TIME_ESTIMATES = 'metamask/gas/SET_PRICE_AND_TIME_ESTIMATES'
|
||||||
|
|
||||||
// TODO: determine if this approach to initState is consistent with conventional ducks pattern
|
// TODO: determine if this approach to initState is consistent with conventional ducks pattern
|
||||||
const initState = {
|
const initState = {
|
||||||
@ -31,6 +36,8 @@ const initState = {
|
|||||||
safeLow: null,
|
safeLow: null,
|
||||||
},
|
},
|
||||||
basicEstimateIsLoading: true,
|
basicEstimateIsLoading: true,
|
||||||
|
gasEstimatesLoading: true,
|
||||||
|
priceAndTimeEstimates: [],
|
||||||
errors: {},
|
errors: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +56,16 @@ export default function reducer ({ gas: gasState = initState }, action = {}) {
|
|||||||
...newState,
|
...newState,
|
||||||
basicEstimateIsLoading: false,
|
basicEstimateIsLoading: false,
|
||||||
}
|
}
|
||||||
|
case GAS_ESTIMATE_LOADING_STARTED:
|
||||||
|
return {
|
||||||
|
...newState,
|
||||||
|
gasEstimatesLoading: true,
|
||||||
|
}
|
||||||
|
case GAS_ESTIMATE_LOADING_FINISHED:
|
||||||
|
return {
|
||||||
|
...newState,
|
||||||
|
gasEstimatesLoading: false,
|
||||||
|
}
|
||||||
case SET_BASIC_GAS_ESTIMATE_DATA:
|
case SET_BASIC_GAS_ESTIMATE_DATA:
|
||||||
return {
|
return {
|
||||||
...newState,
|
...newState,
|
||||||
@ -78,6 +95,11 @@ export default function reducer ({ gas: gasState = initState }, action = {}) {
|
|||||||
total: action.value,
|
total: action.value,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
case SET_PRICE_AND_TIME_ESTIMATES:
|
||||||
|
return {
|
||||||
|
...newState,
|
||||||
|
priceAndTimeEstimates: action.value,
|
||||||
|
}
|
||||||
case SET_CUSTOM_GAS_ERRORS:
|
case SET_CUSTOM_GAS_ERRORS:
|
||||||
return {
|
return {
|
||||||
...newState,
|
...newState,
|
||||||
@ -111,7 +133,19 @@ export function basicGasEstimatesLoadingFinished () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchGasEstimates () {
|
export function gasEstimatesLoadingStarted () {
|
||||||
|
return {
|
||||||
|
type: GAS_ESTIMATE_LOADING_STARTED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function gasEstimatesLoadingFinished () {
|
||||||
|
return {
|
||||||
|
type: GAS_ESTIMATE_LOADING_FINISHED,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchBasicGasEstimates () {
|
||||||
return (dispatch) => {
|
return (dispatch) => {
|
||||||
dispatch(basicGasEstimatesLoadingStarted())
|
dispatch(basicGasEstimatesLoadingStarted())
|
||||||
|
|
||||||
@ -137,7 +171,7 @@ export function fetchGasEstimates () {
|
|||||||
safeLowWait,
|
safeLowWait,
|
||||||
speed,
|
speed,
|
||||||
}) => {
|
}) => {
|
||||||
dispatch(setBasicGasEstimateData({
|
const basicEstimates = {
|
||||||
average,
|
average,
|
||||||
avgWait,
|
avgWait,
|
||||||
blockTime,
|
blockTime,
|
||||||
@ -149,8 +183,44 @@ export function fetchGasEstimates () {
|
|||||||
safeLow,
|
safeLow,
|
||||||
safeLowWait,
|
safeLowWait,
|
||||||
speed,
|
speed,
|
||||||
}))
|
}
|
||||||
|
dispatch(setBasicGasEstimateData(basicEstimates))
|
||||||
dispatch(basicGasEstimatesLoadingFinished())
|
dispatch(basicGasEstimatesLoadingFinished())
|
||||||
|
return basicEstimates
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchGasEstimates (blockTime) {
|
||||||
|
return (dispatch) => {
|
||||||
|
dispatch(gasEstimatesLoadingStarted())
|
||||||
|
|
||||||
|
// TODO: uncomment code when live api is ready
|
||||||
|
// return fetch('https://ethgasstation.info/json/predictTable.json', {
|
||||||
|
// 'headers': {},
|
||||||
|
// 'referrer': 'http://ethgasstation.info/json/',
|
||||||
|
// 'referrerPolicy': 'no-referrer-when-downgrade',
|
||||||
|
// 'body': null,
|
||||||
|
// 'method': 'GET',
|
||||||
|
// 'mode': 'cors'}
|
||||||
|
// )
|
||||||
|
return new Promise(resolve => {
|
||||||
|
resolve(mockGasEstimateData)
|
||||||
|
})
|
||||||
|
// .then(r => r.json())
|
||||||
|
.then(r => {
|
||||||
|
const estimatedPricesAndTimes = r.map(({ expectedTime, expectedWait, gasprice }) => ({ expectedTime, expectedWait, gasprice }))
|
||||||
|
const estimatedTimeWithUniquePrices = uniqBy(({ expectedTime }) => expectedTime, estimatedPricesAndTimes)
|
||||||
|
const timeMappedToSeconds = estimatedTimeWithUniquePrices.map(({ expectedWait, gasprice }) => {
|
||||||
|
const expectedTime = (new BigNumber(expectedWait)).times(Number(blockTime), 10).div(60, 10).toString(10)
|
||||||
|
return {
|
||||||
|
expectedTime,
|
||||||
|
expectedWait,
|
||||||
|
gasprice,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
dispatch(setPricesAndTimeEstimates(timeMappedToSeconds.slice(1)))
|
||||||
|
dispatch(gasEstimatesLoadingFinished())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,6 +232,13 @@ export function setBasicGasEstimateData (basicGasEstimateData) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setPricesAndTimeEstimates (estimatedPricesAndTimes) {
|
||||||
|
return {
|
||||||
|
type: SET_PRICE_AND_TIME_ESTIMATES,
|
||||||
|
value: estimatedPricesAndTimes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function setCustomGasPrice (newPrice) {
|
export function setCustomGasPrice (newPrice) {
|
||||||
return {
|
return {
|
||||||
type: SET_CUSTOM_GAS_PRICE,
|
type: SET_CUSTOM_GAS_PRICE,
|
||||||
|
3
ui/app/ducks/mock-gas-estimate-data.js
Normal file
3
ui/app/ducks/mock-gas-estimate-data.js
Normal file
File diff suppressed because one or more lines are too long
@ -10,7 +10,10 @@ import GasReducer, {
|
|||||||
setCustomGasTotal,
|
setCustomGasTotal,
|
||||||
setCustomGasErrors,
|
setCustomGasErrors,
|
||||||
resetCustomGasState,
|
resetCustomGasState,
|
||||||
fetchGasEstimates,
|
fetchBasicGasEstimates,
|
||||||
|
gasEstimatesLoadingStarted,
|
||||||
|
gasEstimatesLoadingFinished,
|
||||||
|
setPricesAndTimeEstimates,
|
||||||
} from '../gas.duck.js'
|
} from '../gas.duck.js'
|
||||||
|
|
||||||
describe('Gas Duck', () => {
|
describe('Gas Duck', () => {
|
||||||
@ -65,15 +68,21 @@ describe('Gas Duck', () => {
|
|||||||
},
|
},
|
||||||
basicEstimateIsLoading: true,
|
basicEstimateIsLoading: true,
|
||||||
errors: {},
|
errors: {},
|
||||||
|
gasEstimatesLoading: true,
|
||||||
|
priceAndTimeEstimates: [],
|
||||||
|
|
||||||
}
|
}
|
||||||
const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED'
|
const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED'
|
||||||
const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED'
|
const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED'
|
||||||
|
const GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/GAS_ESTIMATE_LOADING_FINISHED'
|
||||||
|
const GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/GAS_ESTIMATE_LOADING_STARTED'
|
||||||
const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE'
|
const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE'
|
||||||
const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA'
|
const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA'
|
||||||
const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS'
|
const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS'
|
||||||
const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT'
|
const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT'
|
||||||
const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE'
|
const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE'
|
||||||
const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL'
|
const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL'
|
||||||
|
const SET_PRICE_AND_TIME_ESTIMATES = 'metamask/gas/SET_PRICE_AND_TIME_ESTIMATES'
|
||||||
|
|
||||||
describe('GasReducer()', () => {
|
describe('GasReducer()', () => {
|
||||||
it('should initialize state', () => {
|
it('should initialize state', () => {
|
||||||
@ -111,6 +120,24 @@ describe('Gas Duck', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should set gasEstimatesLoading to true when receiving a GAS_ESTIMATE_LOADING_STARTED action', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
GasReducer(mockState, {
|
||||||
|
type: GAS_ESTIMATE_LOADING_STARTED,
|
||||||
|
}),
|
||||||
|
Object.assign({gasEstimatesLoading: true}, mockState.gas)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should set gasEstimatesLoading to false when receiving a GAS_ESTIMATE_LOADING_FINISHED action', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
GasReducer(mockState, {
|
||||||
|
type: GAS_ESTIMATE_LOADING_FINISHED,
|
||||||
|
}),
|
||||||
|
Object.assign({gasEstimatesLoading: false}, mockState.gas)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it('should return a new object (and not just modify the existing state object)', () => {
|
it('should return a new object (and not just modify the existing state object)', () => {
|
||||||
assert.deepEqual(GasReducer(mockState), mockState.gas)
|
assert.deepEqual(GasReducer(mockState), mockState.gas)
|
||||||
assert.notEqual(GasReducer(mockState), mockState.gas)
|
assert.notEqual(GasReducer(mockState), mockState.gas)
|
||||||
@ -126,6 +153,16 @@ describe('Gas Duck', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should set priceAndTimeEstimates when receiving a SET_PRICE_AND_TIME_ESTIMATES action', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
GasReducer(mockState, {
|
||||||
|
type: SET_PRICE_AND_TIME_ESTIMATES,
|
||||||
|
value: { someProp: 'someData123' },
|
||||||
|
}),
|
||||||
|
Object.assign({priceAndTimeEstimates: {someProp: 'someData123'} }, mockState.gas)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it('should set customData.price when receiving a SET_CUSTOM_GAS_PRICE action', () => {
|
it('should set customData.price when receiving a SET_CUSTOM_GAS_PRICE action', () => {
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
GasReducer(mockState, {
|
GasReducer(mockState, {
|
||||||
@ -194,10 +231,10 @@ describe('Gas Duck', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('fetchGasEstimates', () => {
|
describe('fetchBasicGasEstimates', () => {
|
||||||
const mockDistpatch = sinon.spy()
|
const mockDistpatch = sinon.spy()
|
||||||
it('should call fetch with the expected params', async () => {
|
it('should call fetch with the expected params', async () => {
|
||||||
await fetchGasEstimates()(mockDistpatch)
|
await fetchBasicGasEstimates()(mockDistpatch)
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
mockDistpatch.getCall(0).args,
|
mockDistpatch.getCall(0).args,
|
||||||
[{ type: BASIC_GAS_ESTIMATE_LOADING_STARTED} ]
|
[{ type: BASIC_GAS_ESTIMATE_LOADING_STARTED} ]
|
||||||
@ -242,6 +279,32 @@ describe('Gas Duck', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('gasEstimatesLoadingStarted', () => {
|
||||||
|
it('should create the correct action', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
gasEstimatesLoadingStarted(),
|
||||||
|
{ type: GAS_ESTIMATE_LOADING_STARTED }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('gasEstimatesLoadingFinished', () => {
|
||||||
|
it('should create the correct action', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
gasEstimatesLoadingFinished(),
|
||||||
|
{ type: GAS_ESTIMATE_LOADING_FINISHED }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('setPricesAndTimeEstimates', () => {
|
||||||
|
it('should create the correct action', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
setPricesAndTimeEstimates('mockPricesAndTimeEstimates'),
|
||||||
|
{ type: SET_PRICE_AND_TIME_ESTIMATES, value: 'mockPricesAndTimeEstimates' }
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe('setBasicGasEstimateData', () => {
|
describe('setBasicGasEstimateData', () => {
|
||||||
it('should create the correct action', () => {
|
it('should create the correct action', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user