Read only connection of gas price chart to redux

feature/default_network_editable
Dan Miller 6 years ago
parent 2dbae581ac
commit a2bbf504b8
  1. 4
      ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js
  2. 2
      ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js
  3. 4
      ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js
  4. 4
      ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js
  5. 45
      ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js
  6. 6
      ui/app/components/pages/confirm-transaction/confirm-transaction.component.js
  7. 4
      ui/app/components/pages/confirm-transaction/confirm-transaction.container.js
  8. 5
      ui/app/components/send/send.component.js
  9. 4
      ui/app/components/send/send.container.js
  10. 38
      ui/app/components/send/tests/send-component.test.js
  11. 85
      ui/app/ducks/gas.duck.js
  12. 3
      ui/app/ducks/mock-gas-estimate-data.js
  13. 69
      ui/app/ducks/tests/gas-duck.test.js

@ -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,

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…
Cancel
Save