diff --git a/test/e2e/metamask-ui.spec.js b/test/e2e/metamask-ui.spec.js index eed712736e1b..27699537546f 100644 --- a/test/e2e/metamask-ui.spec.js +++ b/test/e2e/metamask-ui.spec.js @@ -494,8 +494,6 @@ describe('MetaMask', function () { await delay(50) - await gasPriceInput.sendKeys(Key.BACK_SPACE) - await delay(50) await gasPriceInput.sendKeys(Key.BACK_SPACE) await delay(50) await gasPriceInput.sendKeys('10') @@ -504,9 +502,9 @@ describe('MetaMask', function () { await delay(50) await gasLimitInput.sendKeys(Key.chord(Key.CONTROL, 'a')) await delay(50) - await gasLimitInput.sendKeys('25000') - await delay(largeDelayMs * 2) + + await delay(1000) const confirmButton = await findElement(driver, By.xpath(`//button[contains(text(), 'Confirm')]`), 10000) await confirmButton.click() @@ -792,14 +790,12 @@ describe('MetaMask', function () { await modalTabs[1].click() await delay(regularDelayMs) - const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-tab__gas-edit-row__input')) + const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-gas-inputs__gas-edit-row__input')) const gasLimitValue = await gasLimitInput.getAttribute('value') assert(Number(gasLimitValue) < 100000, 'Gas Limit too high') await gasPriceInput.sendKeys(Key.chord(Key.CONTROL, 'a')) await delay(50) - await gasPriceInput.sendKeys(Key.BACK_SPACE) - await delay(50) await gasPriceInput.sendKeys(Key.BACK_SPACE) await delay(50) await gasPriceInput.sendKeys('10') @@ -808,18 +804,9 @@ describe('MetaMask', function () { await delay(50) await gasLimitInput.sendKeys(Key.BACK_SPACE) await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) await gasLimitInput.sendKeys('60001') - await delay(50) - await gasLimitInput.sendKeys(Key.chord(Key.CONTROL, 'e')) - await delay(50) + + await delay(1000) const save = await findElement(driver, By.xpath(`//button[contains(text(), 'Save')]`)) await save.click() @@ -914,7 +901,7 @@ describe('MetaMask', function () { await advancedTabButton.click() await delay(tinyDelayMs) - const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-tab__gas-edit-row__input')) + const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-gas-inputs__gas-edit-row__input')) assert(gasPriceInput.getAttribute('value'), 20) assert(gasLimitInput.getAttribute('value'), 4700000) @@ -1103,12 +1090,10 @@ describe('MetaMask', function () { await modalTabs[1].click() await delay(regularDelayMs) - const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-tab__gas-edit-row__input')) + const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-gas-inputs__gas-edit-row__input')) await gasPriceInput.sendKeys(Key.chord(Key.CONTROL, 'a')) await delay(50) - await gasPriceInput.sendKeys(Key.BACK_SPACE) - await delay(50) await gasPriceInput.sendKeys(Key.BACK_SPACE) await delay(50) await gasPriceInput.sendKeys('10') @@ -1117,18 +1102,9 @@ describe('MetaMask', function () { await delay(50) await gasLimitInput.sendKeys(Key.BACK_SPACE) await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) await gasLimitInput.sendKeys('60000') - await delay(50) - await gasLimitInput.sendKeys(Key.chord(Key.CONTROL, 'e')) - await delay(50) + + await delay(1000) const save = await findElement(driver, By.css('.page-container__footer-button')) await save.click() @@ -1246,12 +1222,10 @@ describe('MetaMask', function () { await modalTabs[1].click() await delay(regularDelayMs) - const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-tab__gas-edit-row__input')) + const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-gas-inputs__gas-edit-row__input')) await gasPriceInput.sendKeys(Key.chord(Key.CONTROL, 'a')) await delay(50) - await gasPriceInput.sendKeys(Key.BACK_SPACE) - await delay(50) await gasPriceInput.sendKeys(Key.BACK_SPACE) await delay(50) await gasPriceInput.sendKeys('10') @@ -1260,18 +1234,9 @@ describe('MetaMask', function () { await delay(50) await gasLimitInput.sendKeys(Key.BACK_SPACE) await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) - await gasLimitInput.sendKeys(Key.BACK_SPACE) - await delay(50) await gasLimitInput.sendKeys('60001') - await delay(50) - await gasLimitInput.sendKeys(Key.chord(Key.CONTROL, 'e')) - await delay(50) + + await delay(1000) const save = await findElement(driver, By.css('.page-container__footer-button')) await save.click() diff --git a/test/e2e/send-edit.spec.js b/test/e2e/send-edit.spec.js index 3f12aaaf2c1b..039c14d9b369 100644 --- a/test/e2e/send-edit.spec.js +++ b/test/e2e/send-edit.spec.js @@ -113,7 +113,7 @@ describe('Using MetaMask with an existing account', function () { const gasModal = await driver.findElement(By.css('span .modal')) - const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-tab__gas-edit-row__input')) + const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-gas-inputs__gas-edit-row__input')) await gasPriceInput.sendKeys(Key.chord(Key.CONTROL, 'a')) await delay(50) @@ -131,6 +131,8 @@ describe('Using MetaMask with an existing account', function () { await gasLimitInput.sendKeys('25000') + await delay(1000) + const save = await findElement(driver, By.xpath(`//button[contains(text(), 'Save')]`)) await save.click() await driver.wait(until.stalenessOf(gasModal)) @@ -170,7 +172,7 @@ describe('Using MetaMask with an existing account', function () { const gasModal = await driver.findElement(By.css('span .modal')) - const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-tab__gas-edit-row__input')) + const [gasPriceInput, gasLimitInput] = await findElements(driver, By.css('.advanced-gas-inputs__gas-edit-row__input')) await gasPriceInput.sendKeys(Key.chord(Key.CONTROL, 'a')) await delay(50) @@ -187,6 +189,8 @@ describe('Using MetaMask with an existing account', function () { await gasLimitInput.sendKeys('100000') + await delay(1000) + const save = await findElement(driver, By.xpath(`//button[contains(text(), 'Save')]`)) await save.click() await driver.wait(until.stalenessOf(gasModal)) diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js index 7b87b3033960..51f3df74accb 100644 --- a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js +++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.component.js @@ -3,22 +3,11 @@ import PropTypes from 'prop-types' import classnames from 'classnames' import debounce from 'lodash.debounce' -export default class AdvancedTabContent extends Component { +export default class AdvancedGasInputs extends Component { static contextTypes = { t: PropTypes.func, } - constructor (props) { - super(props) - this.state = { - gasPrice: this.props.customGasPrice, - gasLimit: this.props.customGasLimit, - } - this.changeGasPrice = debounce(this.changeGasPrice, 500) - this.changeGasLimit = debounce(this.changeGasLimit, 500) - } - - static propTypes = { updateCustomGasPrice: PropTypes.func, updateCustomGasLimit: PropTypes.func, @@ -31,6 +20,16 @@ export default class AdvancedTabContent extends Component { showGasLimitInfoModal: PropTypes.func, } + constructor (props) { + super(props) + this.state = { + gasPrice: this.props.customGasPrice, + gasLimit: this.props.customGasLimit, + } + this.changeGasPrice = debounce(this.changeGasPrice, 500) + this.changeGasLimit = debounce(this.changeGasLimit, 500) + } + componentDidUpdate (prevProps) { const { customGasPrice: prevCustomGasPrice, customGasLimit: prevCustomGasLimit } = prevProps const { customGasPrice, customGasLimit } = this.props @@ -50,12 +49,7 @@ export default class AdvancedTabContent extends Component { } changeGasLimit = (e) => { - if (e.target.value < 21000) { - this.setState({ gasLimit: 21000 }) - this.props.updateCustomGasLimit(21000) - } else { - this.props.updateCustomGasLimit(Number(e.target.value)) - } + this.props.updateCustomGasLimit(Number(e.target.value)) } onChangeGasPrice = (e) => { @@ -67,89 +61,83 @@ export default class AdvancedTabContent extends Component { this.props.updateCustomGasPrice(Number(e.target.value)) } - gasInputError ({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) { + gasPriceError ({ insufficientBalance, customPriceIsSafe, isSpeedUp, gasPrice }) { const { t } = this.context - let errorText - let errorType - let isInError = true - if (insufficientBalance) { - errorText = t('insufficientBalance') - errorType = 'error' - } else if (labelKey === 'gasPrice' && isSpeedUp && value === 0) { - errorText = t('zeroGasPriceOnSpeedUpError') - errorType = 'error' - } else if (labelKey === 'gasPrice' && !customPriceIsSafe) { - errorText = t('gasPriceExtremelyLow') - errorType = 'warning' - } else { - isInError = false + return { + errorText: t('insufficientBalance'), + errorType: 'error', + } + } else if (isSpeedUp && gasPrice === 0) { + return { + errorText: t('zeroGasPriceOnSpeedUpError'), + errorType: 'error', + } + } else if (!customPriceIsSafe) { + return { + errorText: t('gasPriceExtremelyLow'), + errorType: 'warning', + } } - return { - isInError, - errorText, - errorType, - } + return {} } - gasInput ({ labelKey, value, onChange, insufficientBalance, customPriceIsSafe, isSpeedUp }) { - const { - isInError, - errorText, - errorType, - } = this.gasInputError({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) + gasLimitError ({ insufficientBalance, gasLimit }) { + const { t } = this.context - return ( -
- -
-
onChange({ target: { value: value + 1 } })} - > - -
-
onChange({ target: { value: Math.max(value - 1, 0) } })} - > - -
-
- { isInError - ?
- { errorText } -
- : null } -
- ) - } + if (insufficientBalance) { + return { + errorText: t('insufficientBalance'), + errorType: 'error', + } + } else if (gasLimit < 21000) { + return { + errorText: t('gasLimitTooLow'), + errorType: 'error', + } + } - infoButton (onClick) { - return + return {} } - renderGasEditRow (gasInputArgs) { + renderGasInput ({ value, onChange, errorComponent, errorType, infoOnClick, label }) { return (
- { this.context.t(gasInputArgs.labelKey) } - { this.infoButton(() => gasInputArgs.infoOnClick()) } + { label } + +
+
+ +
+
onChange({ target: { value: value + 1 } })} + > + +
+
onChange({ target: { value: Math.max(value - 1, 0) } })} + > + +
+
+ { errorComponent }
- { this.gasInput(gasInputArgs) }
) } @@ -162,25 +150,47 @@ export default class AdvancedTabContent extends Component { showGasPriceInfoModal, showGasLimitInfoModal, } = this.props + const { + gasPrice, + gasLimit, + } = this.state + + const { + errorText: gasPriceErrorText, + errorType: gasPriceErrorType, + } = this.gasPriceError({ insufficientBalance, customPriceIsSafe, isSpeedUp, gasPrice }) + const gasPriceErrorComponent = gasPriceErrorType ? +
+ { gasPriceErrorText } +
: + null + + const { + errorText: gasLimitErrorText, + errorType: gasLimitErrorType, + } = this.gasLimitError({ insufficientBalance, gasLimit }) + const gasLimitErrorComponent = gasLimitErrorType ? +
+ { gasLimitErrorText } +
: + null return (
- { this.renderGasEditRow({ - labelKey: 'gasPrice', + { this.renderGasInput({ + label: this.context.t('gasPrice'), value: this.state.gasPrice, onChange: this.onChangeGasPrice, - insufficientBalance, - customPriceIsSafe, - showGWEI: true, - isSpeedUp, + errorComponent: gasPriceErrorComponent, + errorType: gasPriceErrorType, infoOnClick: showGasPriceInfoModal, }) } - { this.renderGasEditRow({ - labelKey: 'gasLimit', + { this.renderGasInput({ + label: this.context.t('gasLimit'), value: this.state.gasLimit, onChange: this.onChangeGasLimit, - insufficientBalance, - customPriceIsSafe, + errorComponent: gasLimitErrorComponent, + errorType: gasLimitErrorType, infoOnClick: showGasLimitInfoModal, }) }
diff --git a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js index 73bc13481d18..5dbe89e3d8e0 100644 --- a/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js +++ b/ui/app/components/app/gas-customization/advanced-gas-inputs/advanced-gas-inputs.container.js @@ -25,9 +25,9 @@ const mapDispatchToProps = dispatch => { const mergeProps = (stateProps, dispatchProps, ownProps) => { const {customGasPrice, customGasLimit, updateCustomGasPrice, updateCustomGasLimit} = ownProps return { + ...ownProps, ...stateProps, ...dispatchProps, - ...ownProps, customGasPrice: convertGasPriceForInputs(customGasPrice), customGasLimit: convertGasLimitForInputs(customGasLimit), updateCustomGasPrice: (price) => updateCustomGasPrice(decGWEIToHexWEI(price)), diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index 88d28b9ed98a..853889e8dab1 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -1,9 +1,8 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import classnames from 'classnames' import Loading from '../../../../ui/loading-screen' import GasPriceChart from '../../gas-price-chart' -import debounce from 'lodash.debounce' +import AdvancedGasInputs from '../../advanced-gas-inputs' export default class AdvancedTabContent extends Component { static contextTypes = { @@ -13,8 +12,8 @@ export default class AdvancedTabContent extends Component { static propTypes = { updateCustomGasPrice: PropTypes.func, updateCustomGasLimit: PropTypes.func, - customGasPrice: PropTypes.number, - customGasLimit: PropTypes.number, + customModalGasPriceInHex: PropTypes.string, + customModalGasLimitInHex: PropTypes.string, gasEstimatesLoading: PropTypes.bool, millisecondsRemaining: PropTypes.number, transactionFee: PropTypes.string, @@ -26,95 +25,6 @@ export default class AdvancedTabContent extends Component { isEthereumNetwork: PropTypes.bool, } - constructor (props) { - super(props) - - this.debouncedGasLimitReset = debounce((dVal) => { - if (dVal < 21000) { - props.updateCustomGasLimit(21000) - } - }, 1000, { trailing: true }) - this.onChangeGasLimit = (val) => { - props.updateCustomGasLimit(val) - this.debouncedGasLimitReset(val) - } - } - - gasInputError ({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) { - const { t } = this.context - let errorText - let errorType - let isInError = true - - - if (insufficientBalance) { - errorText = t('insufficientBalance') - errorType = 'error' - } else if (labelKey === 'gasPrice' && isSpeedUp && value === 0) { - errorText = t('zeroGasPriceOnSpeedUpError') - errorType = 'error' - } else if (labelKey === 'gasPrice' && !customPriceIsSafe) { - errorText = t('gasPriceExtremelyLow') - errorType = 'warning' - } else { - isInError = false - } - - return { - isInError, - errorText, - errorType, - } - } - - gasInput ({ labelKey, value, onChange, insufficientBalance, customPriceIsSafe, isSpeedUp }) { - const { - isInError, - errorText, - errorType, - } = this.gasInputError({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) - - return ( -
- onChange(Number(event.target.value))} - /> -
-
onChange(value + 1)} - > - -
-
onChange(Math.max(value - 1, 0))} - > - -
-
- { isInError - ?
- { errorText } -
- : null } -
- ) - } - - infoButton (onClick) { - return - } - renderDataSummary (transactionFee, timeRemaining) { return (
@@ -132,56 +42,14 @@ export default class AdvancedTabContent extends Component { ) } - renderGasEditRow (gasInputArgs) { - return ( -
-
- { this.context.t(gasInputArgs.labelKey) } - { this.infoButton(() => {}) } -
- { this.gasInput(gasInputArgs) } -
- ) - } - - renderGasEditRows ({ - customGasPrice, - updateCustomGasPrice, - customGasLimit, - insufficientBalance, - customPriceIsSafe, - isSpeedUp, - }) { - return ( -
- { this.renderGasEditRow({ - labelKey: 'gasPrice', - value: customGasPrice, - onChange: updateCustomGasPrice, - insufficientBalance, - customPriceIsSafe, - showGWEI: true, - isSpeedUp, - }) } - { this.renderGasEditRow({ - labelKey: 'gasLimit', - value: customGasLimit, - onChange: this.onChangeGasLimit, - insufficientBalance, - customPriceIsSafe, - }) } -
- ) - } - render () { const { t } = this.context const { updateCustomGasPrice, updateCustomGasLimit, timeRemaining, - customGasPrice, - customGasLimit, + customModalGasPriceInHex, + customModalGasLimitInHex, insufficientBalance, gasChartProps, gasEstimatesLoading, @@ -195,15 +63,17 @@ export default class AdvancedTabContent extends Component {
{ this.renderDataSummary(transactionFee, timeRemaining) }
- { this.renderGasEditRows({ - customGasPrice, - updateCustomGasPrice, - customGasLimit, - updateCustomGasLimit, - insufficientBalance, - customPriceIsSafe, - isSpeedUp, - }) } +
+ +
{ isEthereumNetwork ?
{ t('liveGasPricePredictions') }
diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss index c107b540047a..18772bc3c698 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -92,137 +92,13 @@ padding-right: 27px; } - &__gas-edit-rows { - height: 73px; + &__gas-inputs { display: flex; flex-flow: row; justify-content: space-between; margin-left: 20px; margin-right: 10px; - margin-top: 9px; - } - - &__gas-edit-row { - display: flex; - flex-flow: column; - - &__label { - color: #313B5E; - font-size: 14px; - display: flex; - justify-content: space-between; - align-items: center; - - .fa-info-circle { - color: $silver; - margin-left: 10px; - cursor: pointer; - } - - .fa-info-circle:hover { - color: $mid-gray; - } - } - - &__error-text { - font-size: 12px; - color: red; - } - - &__warning-text { - font-size: 12px; - color: orange; - } - - &__input-wrapper { - position: relative; - } - - &__input { - /*rtl:ignore*/ - direction: ltr; - border: 1px solid $dusty-gray; - border-radius: 4px; - color: $mid-gray; - font-size: 16px; - height: 24px; - width: 155px; - padding-left: 8px; - padding-top: 2px; - margin-top: 7px; - } - - &__input--error { - border: 1px solid $red; - } - - &__input--warning { - border: 1px solid $orange; - } - - &__input-arrows { - position: absolute; - top: 7px; - /*rtl:ignore*/ - right: 0px; - width: 17px; - height: 24px; - border: 1px solid #dadada; - border-top-right-radius: 4px; - display: flex; - flex-direction: column; - color: #9b9b9b; - font-size: .8em; - border-bottom-right-radius: 4px; - cursor: pointer; - - &__i-wrap { - width: 100%; - height: 100%; - display: flex; - justify-content: center; - cursor: pointer; - } - - &__i-wrap:hover { - background: #4EADE7; - color: $white; - } - - i:hover { - background: #4EADE7; - } - - i { - font-size: 10px; - } - } - - &__input-arrows--error { - border: 1px solid $red; - } - - &__input-arrows--warning { - border: 1px solid $orange; - } - - input[type="number"]::-webkit-inner-spin-button { - -webkit-appearance: none; - -moz-appearance: none; - display: none; - } - - input[type="number"]:hover::-webkit-inner-spin-button { - -webkit-appearance: none; - -moz-appearance: none; - display: none; - } - - &__gwei-symbol { - position: absolute; - top: 8px; - right: 10px; - color: $dusty-gray; - } + margin-top: 10px; + margin-bottom: 20px } } diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index 683eeda9b9da..7ed5b8e0349d 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -12,11 +12,7 @@ const propsMethodSpies = { updateCustomGasLimit: sinon.spy(), } -sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRow') -sinon.spy(AdvancedTabContent.prototype, 'gasInput') -sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRows') sinon.spy(AdvancedTabContent.prototype, 'renderDataSummary') -sinon.spy(AdvancedTabContent.prototype, 'gasInputError') describe('AdvancedTabContent Component', function () { let wrapper @@ -25,23 +21,20 @@ describe('AdvancedTabContent Component', function () { wrapper = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) + />) }) afterEach(() => { propsMethodSpies.updateCustomGasPrice.resetHistory() propsMethodSpies.updateCustomGasLimit.resetHistory() - AdvancedTabContent.prototype.renderGasEditRow.resetHistory() - AdvancedTabContent.prototype.gasInput.resetHistory() - AdvancedTabContent.prototype.renderGasEditRows.resetHistory() AdvancedTabContent.prototype.renderDataSummary.resetHistory() }) @@ -59,7 +52,6 @@ describe('AdvancedTabContent Component', function () { const feeChartDiv = advancedTabChildren.at(1) - assert(feeChartDiv.childAt(0).hasClass('advanced-tab__gas-edit-rows')) assert(feeChartDiv.childAt(1).childAt(0).hasClass('advanced-tab__fee-chart__title')) assert(feeChartDiv.childAt(1).childAt(1).is(GasPriceChart)) assert(feeChartDiv.childAt(1).childAt(2).hasClass('advanced-tab__fee-chart__speed-buttons')) @@ -75,31 +67,15 @@ describe('AdvancedTabContent Component', function () { const feeChartDiv = advancedTabChildren.at(1) - assert(feeChartDiv.childAt(0).hasClass('advanced-tab__gas-edit-rows')) assert(feeChartDiv.childAt(1).childAt(0).hasClass('advanced-tab__fee-chart__title')) assert(feeChartDiv.childAt(1).childAt(1).is(Loading)) assert(feeChartDiv.childAt(1).childAt(2).hasClass('advanced-tab__fee-chart__speed-buttons')) }) it('should call renderDataSummary with the expected params', () => { - assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1) const renderDataSummaryArgs = AdvancedTabContent.prototype.renderDataSummary.getCall(0).args assert.deepEqual(renderDataSummaryArgs, ['$0.25', 21500]) }) - - it('should call renderGasEditRows with the expected params', () => { - assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1) - const renderGasEditRowArgs = AdvancedTabContent.prototype.renderGasEditRows.getCall(0).args - assert.deepEqual(renderGasEditRowArgs, [{ - customGasPrice: 11, - customGasLimit: 23456, - insufficientBalance: false, - customPriceIsSafe: true, - updateCustomGasPrice: propsMethodSpies.updateCustomGasPrice, - updateCustomGasLimit: propsMethodSpies.updateCustomGasLimit, - isSpeedUp: false, - }]) - }) }) describe('renderDataSummary()', () => { @@ -129,237 +105,4 @@ describe('AdvancedTabContent Component', function () { }) }) - describe('renderGasEditRow()', () => { - let gasEditRow - - beforeEach(() => { - AdvancedTabContent.prototype.gasInput.resetHistory() - gasEditRow = shallow(wrapper.instance().renderGasEditRow({ - labelKey: 'mockLabelKey', - someArg: 'argA', - })) - }) - - it('should render the gas-edit-row root node', () => { - assert(gasEditRow.hasClass('advanced-tab__gas-edit-row')) - }) - - it('should render a label and an input', () => { - const gasEditRowChildren = gasEditRow.children() - assert.equal(gasEditRowChildren.length, 2) - assert(gasEditRowChildren.at(0).hasClass('advanced-tab__gas-edit-row__label')) - assert(gasEditRowChildren.at(1).hasClass('advanced-tab__gas-edit-row__input-wrapper')) - }) - - it('should render the label key and info button', () => { - const gasRowLabelChildren = gasEditRow.children().at(0).children() - assert.equal(gasRowLabelChildren.length, 2) - assert(gasRowLabelChildren.at(0), 'mockLabelKey') - assert(gasRowLabelChildren.at(1).hasClass('fa-info-circle')) - }) - - it('should call this.gasInput with the correct args', () => { - const gasInputSpyArgs = AdvancedTabContent.prototype.gasInput.args - assert.deepEqual(gasInputSpyArgs[0], [ { labelKey: 'mockLabelKey', someArg: 'argA' } ]) - }) - }) - - describe('renderGasEditRows()', () => { - let gasEditRows - let tempOnChangeGasLimit - - beforeEach(() => { - tempOnChangeGasLimit = wrapper.instance().onChangeGasLimit - wrapper.instance().onChangeGasLimit = () => 'mockOnChangeGasLimit' - AdvancedTabContent.prototype.renderGasEditRow.resetHistory() - gasEditRows = shallow(wrapper.instance().renderGasEditRows( - 'mockGasPrice', - () => 'mockUpdateCustomGasPriceReturn', - 'mockGasLimit', - () => 'mockUpdateCustomGasLimitReturn', - false - )) - }) - - afterEach(() => { - wrapper.instance().onChangeGasLimit = tempOnChangeGasLimit - }) - - it('should render the gas-edit-rows root node', () => { - assert(gasEditRows.hasClass('advanced-tab__gas-edit-rows')) - }) - - it('should render two rows', () => { - const gasEditRowsChildren = gasEditRows.children() - assert.equal(gasEditRowsChildren.length, 2) - assert(gasEditRowsChildren.at(0).hasClass('advanced-tab__gas-edit-row')) - assert(gasEditRowsChildren.at(1).hasClass('advanced-tab__gas-edit-row')) - }) - - it('should call this.renderGasEditRow twice, with the expected args', () => { - const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args - assert.equal(renderGasEditRowSpyArgs.length, 2) - assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [{ - labelKey: 'gasPrice', - value: 'mockGasLimit', - onChange: () => 'mockOnChangeGasLimit', - insufficientBalance: false, - customPriceIsSafe: true, - showGWEI: true, - }].map(String)) - assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [{ - labelKey: 'gasPrice', - value: 'mockGasPrice', - onChange: () => 'mockUpdateCustomGasPriceReturn', - insufficientBalance: false, - customPriceIsSafe: true, - showGWEI: true, - }].map(String)) - }) - }) - - describe('infoButton()', () => { - let infoButton - - beforeEach(() => { - AdvancedTabContent.prototype.renderGasEditRow.resetHistory() - infoButton = shallow(wrapper.instance().infoButton(() => 'mockOnClickReturn')) - }) - - it('should render the i element', () => { - assert(infoButton.hasClass('fa-info-circle')) - }) - - it('should pass the onClick argument to the i tag onClick prop', () => { - assert(infoButton.props().onClick(), 'mockOnClickReturn') - }) - }) - - describe('gasInput()', () => { - let gasInput - - beforeEach(() => { - AdvancedTabContent.prototype.renderGasEditRow.resetHistory() - AdvancedTabContent.prototype.gasInputError.resetHistory() - gasInput = shallow(wrapper.instance().gasInput({ - labelKey: 'gasPrice', - value: 321, - onChange: value => value + 7, - insufficientBalance: false, - showGWEI: true, - customPriceIsSafe: true, - isSpeedUp: false, - })) - }) - - it('should render the input-wrapper root node', () => { - assert(gasInput.hasClass('advanced-tab__gas-edit-row__input-wrapper')) - }) - - it('should render two children, including an input', () => { - assert.equal(gasInput.children().length, 2) - assert(gasInput.children().at(0).hasClass('advanced-tab__gas-edit-row__input')) - }) - - it('should call the passed onChange method with the value of the input onChange event', () => { - const inputOnChange = gasInput.find('input').props().onChange - assert.equal(inputOnChange({ target: { value: 8} }), 15) - }) - - it('should have two input arrows', () => { - const upArrow = gasInput.find('.fa-angle-up') - assert.equal(upArrow.length, 1) - const downArrow = gasInput.find('.fa-angle-down') - assert.equal(downArrow.length, 1) - }) - - it('should call onChange with the value incremented decremented when its onchange method is called', () => { - const upArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(0) - assert.equal(upArrow.props().onClick(), 329) - const downArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(1) - assert.equal(downArrow.props().onClick(), 327) - }) - - it('should call gasInputError with the expected params', () => { - assert.equal(AdvancedTabContent.prototype.gasInputError.callCount, 1) - const gasInputErrorArgs = AdvancedTabContent.prototype.gasInputError.getCall(0).args - assert.deepEqual(gasInputErrorArgs, [{ - labelKey: 'gasPrice', - insufficientBalance: false, - customPriceIsSafe: true, - value: 321, - isSpeedUp: false, - }]) - }) - }) - - describe('gasInputError()', () => { - let gasInputError - - beforeEach(() => { - AdvancedTabContent.prototype.renderGasEditRow.resetHistory() - gasInputError = wrapper.instance().gasInputError({ - labelKey: '', - insufficientBalance: false, - customPriceIsSafe: true, - isSpeedUp: false, - }) - }) - - it('should return an insufficientBalance error', () => { - const gasInputError = wrapper.instance().gasInputError({ - labelKey: 'gasPrice', - insufficientBalance: true, - customPriceIsSafe: true, - isSpeedUp: false, - value: 1, - }) - assert.deepEqual(gasInputError, { - isInError: true, - errorText: 'insufficientBalance', - errorType: 'error', - }) - }) - - it('should return a zero gas on retry error', () => { - const gasInputError = wrapper.instance().gasInputError({ - labelKey: 'gasPrice', - insufficientBalance: false, - customPriceIsSafe: false, - isSpeedUp: true, - value: 0, - }) - assert.deepEqual(gasInputError, { - isInError: true, - errorText: 'zeroGasPriceOnSpeedUpError', - errorType: 'error', - }) - }) - - it('should return a low gas warning', () => { - const gasInputError = wrapper.instance().gasInputError({ - labelKey: 'gasPrice', - insufficientBalance: false, - customPriceIsSafe: false, - isSpeedUp: false, - value: 1, - }) - assert.deepEqual(gasInputError, { - isInError: true, - errorText: 'gasPriceExtremelyLow', - errorType: 'warning', - }) - }) - - it('should return isInError false if there is no error', () => { - gasInputError = wrapper.instance().gasInputError({ - labelKey: 'gasPrice', - insufficientBalance: false, - customPriceIsSafe: true, - value: 1, - }) - assert.equal(gasInputError.isInError, false) - }) - }) - }) diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 61e7b9c4db12..779dfc12d521 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -16,11 +16,15 @@ export default class GasModalPageContainer extends Component { hideBasic: PropTypes.bool, updateCustomGasPrice: PropTypes.func, updateCustomGasLimit: PropTypes.func, + currentTimeEstimate: PropTypes.string, customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, + insufficientBalance: PropTypes.bool, fetchBasicGasAndTimeEstimates: PropTypes.func, fetchGasEstimates: PropTypes.func, gasPriceButtonGroupProps: PropTypes.object, + gasChartProps: PropTypes.object, + gasEstimatesLoading: PropTypes.bool, infoRowProps: PropTypes.shape({ originalTotalFiat: PropTypes.string, originalTotalEth: PropTypes.string, @@ -64,30 +68,32 @@ export default class GasModalPageContainer extends Component { ) } - renderAdvancedTabContent ({ - convertThenUpdateCustomGasPrice, - convertThenUpdateCustomGasLimit, - customGasPrice, - customGasLimit, - newTotalFiat, - gasChartProps, - currentTimeEstimate, - insufficientBalance, - gasEstimatesLoading, - customPriceIsSafe, - isSpeedUp, - transactionFee, - isEthereumNetwork, - }) { + renderAdvancedTabContent () { + const { + updateCustomGasPrice, + updateCustomGasLimit, + customModalGasPriceInHex, + customModalGasLimitInHex, + gasChartProps, + currentTimeEstimate, + insufficientBalance, + gasEstimatesLoading, + customPriceIsSafe, + isSpeedUp, + infoRowProps: { + transactionFee, + }, + isEthereumNetwork, + } = this.props + return ( - {tabsToRender.map(({ name, content }, i) => + {tabsToRender.map(({ name, content }, i) =>
{ content } { this.renderInfoRows(newTotalFiat, newTotalEth, sendAmount, transactionFee) } @@ -158,13 +171,11 @@ export default class GasModalPageContainer extends Component { render () { const { cancelAndClose, - infoRowProps, onSubmit, customModalGasPriceInHex, customModalGasLimitInHex, disableSave, isSpeedUp, - ...tabProps } = this.props return ( @@ -172,7 +183,7 @@ export default class GasModalPageContainer extends Component { cancelAndClose()} onClose={() => cancelAndClose()} diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index c260d6798d8a..2533dec68043 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -56,7 +56,6 @@ import { addHexWEIsToDec, subtractHexWEIsToDec, decEthToConvertedCurrency as ethTotalToConvertedCurrency, - decGWEIToHexWEI, hexWEIToDecGWEI, } from '../../../../helpers/utils/conversions.util' import { @@ -175,8 +174,7 @@ const mapDispatchToProps = dispatch => { }, hideModal: () => dispatch(hideModal()), updateCustomGasPrice, - convertThenUpdateCustomGasPrice: newPrice => updateCustomGasPrice(decGWEIToHexWEI(newPrice)), - convertThenUpdateCustomGasLimit: newLimit => dispatch(setCustomGasLimit(addHexPrefix(newLimit.toString(16)))), + updateCustomGasLimit: newLimit => dispatch(setCustomGasLimit(addHexPrefix(newLimit))), setGasData: (newLimit, newPrice) => { dispatch(setGasLimit(newLimit)) dispatch(setGasPrice(newPrice)) @@ -219,7 +217,6 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { transaction, } = stateProps const { - updateCustomGasPrice: dispatchUpdateCustomGasPrice, hideGasButtonGroup: dispatchHideGasButtonGroup, setGasData: dispatchSetGasData, updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate, @@ -267,7 +264,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { }, gasPriceButtonGroupProps: { ...gasPriceButtonGroupProps, - handleGasPriceSelection: dispatchUpdateCustomGasPrice, + handleGasPriceSelection: otherDispatchProps.updateCustomGasPrice, }, cancelAndClose: () => { dispatchCancelAndClose() diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index 7557eefe5419..0a3efc4902d6 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -79,7 +79,7 @@ describe('GasModalPageContainer Component', function () { customGasLimitInHex={'mockCustomGasLimitInHex'} insufficientBalance={false} disableSave={false} - />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) + />) }) afterEach(() => { @@ -158,10 +158,7 @@ describe('GasModalPageContainer Component', function () { }) it('should render a Tabs component with "Basic" and "Advanced" tabs', () => { - const renderTabsResult = wrapper.instance().renderTabs(mockInfoRowProps, { - gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, - otherProps: 'mockAdvancedTabProps', - }) + const renderTabsResult = wrapper.instance().renderTabs() const renderedTabs = shallow(renderTabsResult) assert.equal(renderedTabs.props().className, 'tabs') @@ -175,23 +172,10 @@ describe('GasModalPageContainer Component', function () { assert.equal(tabs.at(1).childAt(0).props().className, 'gas-modal-content') }) - it('should call renderBasicTabContent and renderAdvancedTabContent with the expected props', () => { - assert.equal(GP.renderBasicTabContent.callCount, 0) - assert.equal(GP.renderAdvancedTabContent.callCount, 0) - - wrapper.instance().renderTabs(mockInfoRowProps, { gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, otherProps: 'mockAdvancedTabProps' }) - - assert.equal(GP.renderBasicTabContent.callCount, 1) - assert.equal(GP.renderAdvancedTabContent.callCount, 1) - - assert.deepEqual(GP.renderBasicTabContent.getCall(0).args[0], mockGasPriceButtonGroupProps) - assert.deepEqual(GP.renderAdvancedTabContent.getCall(0).args[0], { transactionFee: 'mockTransactionFee', otherProps: 'mockAdvancedTabProps' }) - }) - it('should call renderInfoRows with the expected props', () => { assert.equal(GP.renderInfoRows.callCount, 0) - wrapper.instance().renderTabs(mockInfoRowProps, { gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, otherProps: 'mockAdvancedTabProps' }) + wrapper.instance().renderTabs() assert.equal(GP.renderInfoRows.callCount, 2) @@ -200,11 +184,25 @@ describe('GasModalPageContainer Component', function () { }) it('should not render the basic tab if hideBasic is true', () => { - const renderTabsResult = wrapper.instance().renderTabs(mockInfoRowProps, { - gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, - otherProps: 'mockAdvancedTabProps', - hideBasic: true, - }) + wrapper = shallow( 'mockupdateCustomGasPrice'} + updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} + customGasPrice={21} + customGasLimit={54321} + gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} + infoRowProps={mockInfoRowProps} + currentTimeEstimate={'1 min 31 sec'} + customGasPriceInHex={'mockCustomGasPriceInHex'} + customGasLimitInHex={'mockCustomGasLimitInHex'} + insufficientBalance={false} + disableSave={false} + hideBasic={true} + />) + const renderTabsResult = wrapper.instance().renderTabs() const renderedTabs = shallow(renderTabsResult) const tabs = renderedTabs.find(Tab) @@ -224,28 +222,6 @@ describe('GasModalPageContainer Component', function () { }) }) - describe('renderAdvancedTabContent', () => { - it('should render with the correct props', () => { - const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent({ - convertThenUpdateCustomGasPrice: () => 'mockConvertThenUpdateCustomGasPrice', - convertThenUpdateCustomGasLimit: () => 'mockConvertThenUpdateCustomGasLimit', - customGasPrice: 123, - customGasLimit: 456, - newTotalFiat: '$0.30', - currentTimeEstimate: '1 min 31 sec', - gasEstimatesLoading: 'mockGasEstimatesLoading', - }) - const advancedTabContentProps = renderAdvancedTabContentResult.props - assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice') - assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockConvertThenUpdateCustomGasLimit') - assert.equal(advancedTabContentProps.customGasPrice, 123) - assert.equal(advancedTabContentProps.customGasLimit, 456) - assert.equal(advancedTabContentProps.timeRemaining, '1 min 31 sec') - assert.equal(advancedTabContentProps.totalFee, '$0.30') - assert.equal(advancedTabContentProps.gasEstimatesLoading, 'mockGasEstimatesLoading') - }) - }) - describe('renderInfoRows', () => { it('should render the info rows with the passed data', () => { const baseClassName = 'gas-modal-content__info-row' diff --git a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index d5f3837a9c7b..7a21ac36ae32 100644 --- a/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/app/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -297,19 +297,19 @@ describe('gas-modal-page-container container', () => { }) }) - describe('convertThenUpdateCustomGasPrice()', () => { - it('should dispatch a setCustomGasPrice action with the arg passed to convertThenUpdateCustomGasPrice converted to WEI', () => { - mapDispatchToPropsObject.convertThenUpdateCustomGasPrice('0xffff') + describe('updateCustomGasPrice()', () => { + it('should dispatch a setCustomGasPrice action', () => { + mapDispatchToPropsObject.updateCustomGasPrice('0xffff') assert(dispatchSpy.calledOnce) assert(gasActionSpies.setCustomGasPrice.calledOnce) - assert.equal(gasActionSpies.setCustomGasPrice.getCall(0).args[0], '0x3b9a8e653600') + assert.equal(gasActionSpies.setCustomGasPrice.getCall(0).args[0], '0xffff') }) }) - describe('convertThenUpdateCustomGasLimit()', () => { - it('should dispatch a setCustomGasLimit action with the arg passed to convertThenUpdateCustomGasLimit converted to hex', () => { - mapDispatchToPropsObject.convertThenUpdateCustomGasLimit(16) + describe('updateCustomGasLimit()', () => { + it('should dispatch a setCustomGasLimit action', () => { + mapDispatchToPropsObject.updateCustomGasLimit('0x10') assert(dispatchSpy.calledOnce) assert(gasActionSpies.setCustomGasLimit.calledOnce) assert.equal(gasActionSpies.setCustomGasLimit.getCall(0).args[0], '0x10') diff --git a/ui/app/components/app/gas-customization/gas-price-button-group/gas-price-button-group.component.js b/ui/app/components/app/gas-customization/gas-price-button-group/gas-price-button-group.component.js index 14952a49ab7f..0412b3381d11 100644 --- a/ui/app/components/app/gas-customization/gas-price-button-group/gas-price-button-group.component.js +++ b/ui/app/components/app/gas-customization/gas-price-button-group/gas-price-button-group.component.js @@ -2,9 +2,11 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import ButtonGroup from '../../../ui/button-group' import Button from '../../../ui/button' +import { GAS_ESTIMATE_TYPES } from '../../../../helpers/constants/common' + const GAS_OBJECT_PROPTYPES_SHAPE = { - label: PropTypes.string, + gasEstimateType: PropTypes.oneOf(Object.values(GAS_ESTIMATE_TYPES)).isRequired, feeInPrimaryCurrency: PropTypes.string, feeInSecondaryCurrency: PropTypes.string, timeEstimate: PropTypes.string, @@ -27,8 +29,19 @@ export default class GasPriceButtonGroup extends Component { showCheck: PropTypes.bool, } + gasEstimateTypeLabel (gasEstimateType) { + if (gasEstimateType === GAS_ESTIMATE_TYPES.SLOW) { + return this.context.t('slow') + } else if (gasEstimateType === GAS_ESTIMATE_TYPES.AVERAGE) { + return this.context.t('average') + } else if (gasEstimateType === GAS_ESTIMATE_TYPES.FAST) { + return this.context.t('fast') + } + throw new Error(`Unrecognized gas estimate type: ${gasEstimateType}`) + } + renderButtonContent ({ - labelKey, + gasEstimateType, feeInPrimaryCurrency, feeInSecondaryCurrency, timeEstimate, @@ -37,7 +50,7 @@ export default class GasPriceButtonGroup extends Component { showCheck, }) { return (
- { labelKey &&
{ this.context.t(labelKey) }
} + { gasEstimateType &&
{ this.gasEstimateTypeLabel(gasEstimateType) }
} { timeEstimate &&
{ timeEstimate }
} { feeInPrimaryCurrency &&
{ feeInPrimaryCurrency }
} { feeInSecondaryCurrency &&
{ feeInSecondaryCurrency }
} diff --git a/ui/app/components/app/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js b/ui/app/components/app/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js index 37840a8a54a9..85f53d08e993 100644 --- a/ui/app/components/app/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js +++ b/ui/app/components/app/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js @@ -156,15 +156,15 @@ describe('GasPriceButtonGroup Component', function () { }) describe('renderButtonContent', () => { - it('should render a label if passed a labelKey', () => { + it('should render a label if passed a gasEstimateType', () => { const renderButtonContentResult = wrapper.instance().renderButtonContent({ - labelKey: 'mockLabelKey', + gasEstimateType: 'SLOW', }, { className: 'someClass', }) const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) - assert.equal(wrappedRenderButtonContentResult.find('.someClass__label').text(), 'mockLabelKey') + assert.equal(wrappedRenderButtonContentResult.find('.someClass__label').text(), 'slow') }) it('should render a feeInPrimaryCurrency if passed a feeInPrimaryCurrency', () => { @@ -211,7 +211,7 @@ describe('GasPriceButtonGroup Component', function () { it('should render all elements if all args passed', () => { const renderButtonContentResult = wrapper.instance().renderButtonContent({ - labelKey: 'mockLabel', + gasEstimateType: 'SLOW', feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', timeEstimate: 'mockTimeEstimate', diff --git a/ui/app/components/app/gas-customization/gas-slider/gas-slider.component.js b/ui/app/components/app/gas-customization/gas-slider/gas-slider.component.js index 5836e7dfca2d..8233dedb5adc 100644 --- a/ui/app/components/app/gas-customization/gas-slider/gas-slider.component.js +++ b/ui/app/components/app/gas-customization/gas-slider/gas-slider.component.js @@ -1,7 +1,7 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -export default class AdvancedTabContent extends Component { +export default class GasSlider extends Component { static propTypes = { onChange: PropTypes.func, lowLabel: PropTypes.string, diff --git a/ui/app/helpers/constants/common.js b/ui/app/helpers/constants/common.js index a0d6e65b3ffa..5055f88a7e0d 100644 --- a/ui/app/helpers/constants/common.js +++ b/ui/app/helpers/constants/common.js @@ -12,3 +12,9 @@ export const NETWORK_TYPES = { ROPSTEN: 'ropsten', GOERLI: 'goerli', } + +export const GAS_ESTIMATE_TYPES = { + SLOW: 'SLOW', + AVERAGE: 'AVERAGE', + FAST: 'FAST', +} diff --git a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js index 5ad1ff7d306c..ea8aa2dbd4f1 100644 --- a/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/app/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -14,6 +14,7 @@ import { import { CONFIRMED_STATUS, DROPPED_STATUS } from '../../helpers/constants/transactions' import UserPreferencedCurrencyDisplay from '../../components/app/user-preferenced-currency-display' import { PRIMARY, SECONDARY } from '../../helpers/constants/common' +import { hexToDecimal } from '../../helpers/utils/conversions.util' import AdvancedGasInputs from '../../components/app/gas-customization/advanced-gas-inputs' import TextField from '../../components/ui/text-field' @@ -171,7 +172,7 @@ export default class ConfirmTransactionBase extends Component { } } - if (customGas.gasLimit < 21000) { + if (hexToDecimal(customGas.gasLimit) < 21000) { return { valid: false, errorKey: GAS_LIMIT_TOO_LOW_ERROR_KEY, diff --git a/ui/app/pages/routes/index.js b/ui/app/pages/routes/index.js index 79438174e67f..7cb2918707c3 100644 --- a/ui/app/pages/routes/index.js +++ b/ui/app/pages/routes/index.js @@ -12,7 +12,7 @@ import classnames from 'classnames' // init import FirstTimeFlow from '../first-time-flow' // accounts -const SendTransactionScreen = require('../send/send.container') +import SendTransactionScreen from '../send' const ConfirmTransaction = require('../confirm-transaction') // slideout menu diff --git a/ui/app/pages/send/README.md b/ui/app/pages/send/README.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/ui/app/pages/send/account-list-item/account-list-item-README.md b/ui/app/pages/send/account-list-item/account-list-item-README.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/ui/app/pages/send/send-content/send-amount-row/README.md b/ui/app/pages/send/send-content/send-amount-row/README.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/ui/app/pages/send/send-content/send-gas-row/README.md b/ui/app/pages/send/send-content/send-gas-row/README.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message-README.md b/ui/app/pages/send/send-content/send-row-wrapper/send-row-error-message/send-row-error-message-README.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/ui/app/pages/send/send-content/send-row-wrapper/send-row-wrapper-README.md b/ui/app/pages/send/send-content/send-row-wrapper/send-row-wrapper-README.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/ui/app/pages/send/send-footer/README.md b/ui/app/pages/send/send-footer/README.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/ui/app/pages/send/send-footer/send-footer.component.js b/ui/app/pages/send/send-footer/send-footer.component.js index 16a8fdde2be9..f637fb8c7674 100644 --- a/ui/app/pages/send/send-footer/send-footer.component.js +++ b/ui/app/pages/send/send-footer/send-footer.component.js @@ -27,7 +27,7 @@ export default class SendFooter extends Component { unapprovedTxs: PropTypes.object, update: PropTypes.func, sendErrors: PropTypes.object, - gasChangedLabel: PropTypes.string, + gasEstimateType: PropTypes.string, } static contextTypes = { @@ -58,7 +58,7 @@ export default class SendFooter extends Component { update, toAccounts, history, - gasChangedLabel, + gasEstimateType, } = this.props const { metricsEvent } = this.context @@ -94,7 +94,7 @@ export default class SendFooter extends Component { name: 'Complete', }, customVariables: { - gasChanged: gasChangedLabel, + gasChanged: gasEstimateType, }, }) history.push(CONFIRM_TRANSACTION_ROUTE) @@ -102,9 +102,10 @@ export default class SendFooter extends Component { } formShouldBeDisabled () { - const { data, inError, selectedToken, tokenBalance, gasTotal, to } = this.props + const { data, inError, selectedToken, tokenBalance, gasTotal, to, gasLimit } = this.props const missingTokenBalance = selectedToken && !tokenBalance - const shouldBeDisabled = inError || !gasTotal || missingTokenBalance || !(data || to) + const gasLimitTooLow = gasLimit < 5208 // 5208 is hex value of 21000, minimum gas limit + const shouldBeDisabled = inError || !gasTotal || missingTokenBalance || !(data || to) || gasLimitTooLow return shouldBeDisabled } diff --git a/ui/app/pages/send/send-footer/send-footer.container.js b/ui/app/pages/send/send-footer/send-footer.container.js index 68f4dc7c3cba..42c12f2d5ff0 100644 --- a/ui/app/pages/send/send-footer/send-footer.container.js +++ b/ui/app/pages/send/send-footer/send-footer.container.js @@ -42,8 +42,8 @@ function mapStateToProps (state) { const gasButtonInfo = getRenderableEstimateDataForSmallButtonsFromGWEI(state) const gasPrice = getGasPrice(state) const activeButtonIndex = getDefaultActiveButtonIndex(gasButtonInfo, gasPrice) - const gasChangedLabel = activeButtonIndex >= 0 - ? gasButtonInfo[activeButtonIndex].labelKey + const gasEstimateType = activeButtonIndex >= 0 + ? gasButtonInfo[activeButtonIndex].gasEstimateType : 'custom' return { @@ -61,7 +61,7 @@ function mapStateToProps (state) { tokenBalance: getTokenBalance(state), unapprovedTxs: getUnapprovedTxs(state), sendErrors: getSendErrors(state), - gasChangedLabel, + gasEstimateType, } } diff --git a/ui/app/pages/send/send-footer/tests/send-footer-container.test.js b/ui/app/pages/send/send-footer/tests/send-footer-container.test.js index 11b4adb3ef2f..b8af1901785a 100644 --- a/ui/app/pages/send/send-footer/tests/send-footer-container.test.js +++ b/ui/app/pages/send/send-footer/tests/send-footer-container.test.js @@ -48,7 +48,7 @@ proxyquire('../send-footer.container.js', { './send-footer.selectors': { isSendFormInError: (s) => `mockInError:${s}` }, './send-footer.utils': utilsStubs, '../../../selectors/custom-gas': { - getRenderableEstimateDataForSmallButtonsFromGWEI: (s) => ([{ labelKey: `mockLabel:${s}` }]), + getRenderableEstimateDataForSmallButtonsFromGWEI: (s) => ([{ gasEstimateType: `mockGasEstimateType:${s}` }]), getDefaultActiveButtonIndex: () => 0, }, }) @@ -73,7 +73,7 @@ describe('send-footer container', () => { tokenBalance: 'mockTokenBalance:mockState', unapprovedTxs: 'mockUnapprovedTxs:mockState', sendErrors: 'mockSendErrors:mockState', - gasChangedLabel: 'mockLabel:mockState', + gasEstimateType: 'mockGasEstimateType:mockState', }) }) diff --git a/ui/app/pages/send/send-header/README.md b/ui/app/pages/send/send-header/README.md deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/ui/app/pages/send/send.container.js b/ui/app/pages/send/send.container.js index 0863c60d462c..2350712f3e5f 100644 --- a/ui/app/pages/send/send.container.js +++ b/ui/app/pages/send/send.container.js @@ -62,11 +62,6 @@ import { SEND_ROUTE, } from '../../helpers/constants/routes' -module.exports = compose( - withRouter, - connect(mapStateToProps, mapDispatchToProps) -)(SendEther) - function mapStateToProps (state) { return { amount: getSendAmount(state), @@ -140,3 +135,8 @@ function mapDispatchToProps (dispatch) { }, } } + +export default compose( + withRouter, + connect(mapStateToProps, mapDispatchToProps) +)(SendEther) diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index 79dd0b8f4f65..95fe80e9b90a 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -21,6 +21,8 @@ import { } from '../pages/send/send.utils' import { addHexPrefix } from 'ethereumjs-util' +import { GAS_ESTIMATE_TYPES } from '../helpers/constants/common' + const selectors = { formatTimeEstimate, getAveragePriceEstimateInHexWEI, @@ -250,7 +252,7 @@ function getRenderableBasicEstimateData (state, gasLimit) { return [ { - labelKey: 'slow', + gasEstimateType: GAS_ESTIMATE_TYPES.SLOW, feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit), feeInSecondaryCurrency: showFiat ? getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate) @@ -259,7 +261,7 @@ function getRenderableBasicEstimateData (state, gasLimit) { priceInHexWei: getGasPriceInHexWei(safeLow), }, { - labelKey: 'average', + gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, feeInPrimaryCurrency: getRenderableEthFee(average, gasLimit), feeInSecondaryCurrency: showFiat ? getRenderableConvertedCurrencyFee(average, gasLimit, currentCurrency, conversionRate) @@ -268,7 +270,7 @@ function getRenderableBasicEstimateData (state, gasLimit) { priceInHexWei: getGasPriceInHexWei(average), }, { - labelKey: 'fast', + gasEstimateType: GAS_ESTIMATE_TYPES.FAST, feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit), feeInSecondaryCurrency: showFiat ? getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate) @@ -302,7 +304,7 @@ function getRenderableEstimateDataForSmallButtonsFromGWEI (state) { return [ { - labelKey: 'slow', + gasEstimateType: GAS_ESTIMATE_TYPES.SLOW, feeInSecondaryCurrency: showFiat ? getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate) : '', @@ -310,7 +312,7 @@ function getRenderableEstimateDataForSmallButtonsFromGWEI (state) { priceInHexWei: getGasPriceInHexWei(safeLow, true), }, { - labelKey: 'average', + gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, feeInSecondaryCurrency: showFiat ? getRenderableConvertedCurrencyFee(average, gasLimit, currentCurrency, conversionRate) : '', @@ -318,7 +320,7 @@ function getRenderableEstimateDataForSmallButtonsFromGWEI (state) { priceInHexWei: getGasPriceInHexWei(average, true), }, { - labelKey: 'fast', + gasEstimateType: GAS_ESTIMATE_TYPES.FAST, feeInSecondaryCurrency: showFiat ? getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate) : '', diff --git a/ui/app/selectors/custom-gas.test.js b/ui/app/selectors/custom-gas.test.js index efdc9db482ce..16b30beddbd4 100644 --- a/ui/app/selectors/custom-gas.test.js +++ b/ui/app/selectors/custom-gas.test.js @@ -77,21 +77,21 @@ describe('custom-gas selectors', () => { { expectedResult: [ { - labelKey: 'slow', + gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.01', feeInPrimaryCurrency: '0.0000525 ETH', timeEstimate: '~6 min 36 sec', priceInHexWei: '0x9502f900', }, { - labelKey: 'average', + gasEstimateType: 'AVERAGE', feeInPrimaryCurrency: '0.000084 ETH', feeInSecondaryCurrency: '$0.02', priceInHexWei: '0xee6b2800', timeEstimate: '~5 min 18 sec', }, { - labelKey: 'fast', + gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.03', feeInPrimaryCurrency: '0.000105 ETH', timeEstimate: '~3 min 18 sec', @@ -127,7 +127,7 @@ describe('custom-gas selectors', () => { { expectedResult: [ { - labelKey: 'slow', + gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.27', feeInPrimaryCurrency: '0.000105 ETH', timeEstimate: '~13 min 12 sec', @@ -136,12 +136,12 @@ describe('custom-gas selectors', () => { { feeInPrimaryCurrency: '0.000147 ETH', feeInSecondaryCurrency: '$0.38', - labelKey: 'average', + gasEstimateType: 'AVERAGE', priceInHexWei: '0x1a13b8600', timeEstimate: '~10 min 6 sec', }, { - labelKey: 'fast', + gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.54', feeInPrimaryCurrency: '0.00021 ETH', timeEstimate: '~6 min 36 sec', @@ -180,21 +180,21 @@ describe('custom-gas selectors', () => { { expectedResult: [ { - labelKey: 'slow', + gasEstimateType: 'SLOW', feeInSecondaryCurrency: '', feeInPrimaryCurrency: '0.000105 ETH', timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, { - labelKey: 'average', + gasEstimateType: 'AVERAGE', feeInPrimaryCurrency: '0.000147 ETH', feeInSecondaryCurrency: '', timeEstimate: '~10 min 6 sec', priceInHexWei: '0x1a13b8600', }, { - labelKey: 'fast', + gasEstimateType: 'FAST', feeInSecondaryCurrency: '', feeInPrimaryCurrency: '0.00021 ETH', timeEstimate: '~6 min 36 sec', @@ -233,21 +233,21 @@ describe('custom-gas selectors', () => { { expectedResult: [ { - labelKey: 'slow', + gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.27', feeInPrimaryCurrency: '0.000105 ETH', timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, { - labelKey: 'average', + gasEstimateType: 'AVERAGE', feeInPrimaryCurrency: '0.000147 ETH', feeInSecondaryCurrency: '$0.38', priceInHexWei: '0x1a13b8600', timeEstimate: '~10 min 6 sec', }, { - labelKey: 'fast', + gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.54', feeInPrimaryCurrency: '0.00021 ETH', timeEstimate: '~6 min 36 sec', @@ -286,21 +286,21 @@ describe('custom-gas selectors', () => { { expectedResult: [ { - labelKey: 'slow', + gasEstimateType: 'SLOW', feeInSecondaryCurrency: '$0.27', feeInPrimaryCurrency: '0.000105 ETH', timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, { - labelKey: 'average', + gasEstimateType: 'AVERAGE', feeInPrimaryCurrency: '0.000147 ETH', feeInSecondaryCurrency: '$0.38', priceInHexWei: '0x1a13b8600', timeEstimate: '~10 min 6 sec', }, { - labelKey: 'fast', + gasEstimateType: 'FAST', feeInSecondaryCurrency: '$0.54', feeInPrimaryCurrency: '0.00021 ETH', timeEstimate: '~6 min 36 sec', @@ -355,19 +355,19 @@ describe('custom-gas selectors', () => { { feeInSecondaryCurrency: '$0.13', feeInPrimaryCurrency: '0.00052 ETH', - labelKey: 'slow', + gasEstimateType: 'SLOW', priceInHexWei: '0x5d21dba00', }, { feeInSecondaryCurrency: '$0.16', feeInPrimaryCurrency: '0.00063 ETH', - labelKey: 'average', + gasEstimateType: 'AVERAGE', priceInHexWei: '0x6fc23ac00', }, { feeInSecondaryCurrency: '$0.27', feeInPrimaryCurrency: '0.00105 ETH', - labelKey: 'fast', + gasEstimateType: 'FAST', priceInHexWei: '0xba43b7400', }, ], @@ -405,19 +405,19 @@ describe('custom-gas selectors', () => { { feeInSecondaryCurrency: '$2.68', feeInPrimaryCurrency: '0.00105 ETH', - labelKey: 'slow', + gasEstimateType: 'SLOW', priceInHexWei: '0xba43b7400', }, { feeInSecondaryCurrency: '$4.03', feeInPrimaryCurrency: '0.00157 ETH', - labelKey: 'average', + gasEstimateType: 'AVERAGE', priceInHexWei: '0x1176592e00', }, { feeInSecondaryCurrency: '$5.37', feeInPrimaryCurrency: '0.0021 ETH', - labelKey: 'fast', + gasEstimateType: 'FAST', priceInHexWei: '0x174876e800', }, ], @@ -455,19 +455,19 @@ describe('custom-gas selectors', () => { { feeInSecondaryCurrency: '', feeInPrimaryCurrency: '0.00105 ETH', - labelKey: 'slow', + gasEstimateType: 'SLOW', priceInHexWei: '0xba43b7400', }, { feeInSecondaryCurrency: '', feeInPrimaryCurrency: '0.00157 ETH', - labelKey: 'average', + gasEstimateType: 'AVERAGE', priceInHexWei: '0x1176592e00', }, { feeInSecondaryCurrency: '', feeInPrimaryCurrency: '0.0021 ETH', - labelKey: 'fast', + gasEstimateType: 'FAST', priceInHexWei: '0x174876e800', }, ], @@ -505,19 +505,19 @@ describe('custom-gas selectors', () => { { feeInSecondaryCurrency: '$2.68', feeInPrimaryCurrency: '0.00105 ETH', - labelKey: 'slow', + gasEstimateType: 'SLOW', priceInHexWei: '0xba43b7400', }, { feeInSecondaryCurrency: '$4.03', feeInPrimaryCurrency: '0.00157 ETH', - labelKey: 'average', + gasEstimateType: 'AVERAGE', priceInHexWei: '0x1176592e00', }, { feeInSecondaryCurrency: '$5.37', feeInPrimaryCurrency: '0.0021 ETH', - labelKey: 'fast', + gasEstimateType: 'FAST', priceInHexWei: '0x174876e800', }, ], @@ -555,19 +555,19 @@ describe('custom-gas selectors', () => { { feeInSecondaryCurrency: '$2.68', feeInPrimaryCurrency: '0.00105 ETH', - labelKey: 'slow', + gasEstimateType: 'SLOW', priceInHexWei: '0xba43b7400', }, { feeInSecondaryCurrency: '$4.03', feeInPrimaryCurrency: '0.00157 ETH', - labelKey: 'average', + gasEstimateType: 'AVERAGE', priceInHexWei: '0x1176592e00', }, { feeInSecondaryCurrency: '$5.37', feeInPrimaryCurrency: '0.0021 ETH', - labelKey: 'fast', + gasEstimateType: 'FAST', priceInHexWei: '0x174876e800', }, ],