diff options
author | Dan Miller <danjm.com@gmail.com> | 2018-09-20 12:16:43 +0800 |
---|---|---|
committer | Dan Miller <danjm.com@gmail.com> | 2018-12-04 11:36:04 +0800 |
commit | 5354325fab9b9ab3091e3c49e6b940fa713d1799 (patch) | |
tree | 2d1855aa633614a5d786629e125770981efb265c | |
parent | b567c78bcae73e9c73b69040d22e096e4f876a2b (diff) | |
download | tangerine-wallet-browser-5354325fab9b9ab3091e3c49e6b940fa713d1799.tar.gz tangerine-wallet-browser-5354325fab9b9ab3091e3c49e6b940fa713d1799.tar.zst tangerine-wallet-browser-5354325fab9b9ab3091e3c49e6b940fa713d1799.zip |
Test updates and additions for button integration with send screen.
19 files changed, 465 insertions, 64 deletions
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 7a79da2bd..1fd4c8e1e 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -65,6 +65,9 @@ "address": { "message": "Address" }, + "advancedOptions": { + "message": "Advanced Options" + }, "addCustomToken": { "message": "Add custom token" }, diff --git a/ui/app/components/button-group/button-group.component.js b/ui/app/components/button-group/button-group.component.js index 723f9b526..17a281030 100644 --- a/ui/app/components/button-group/button-group.component.js +++ b/ui/app/components/button-group/button-group.component.js @@ -10,6 +10,7 @@ export default class ButtonGroup extends PureComponent { children: PropTypes.array, className: PropTypes.string, style: PropTypes.object, + newActiveButtonIndex: PropTypes.number, } static defaultProps = { @@ -23,9 +24,10 @@ export default class ButtonGroup extends PureComponent { : this.props.defaultActiveButtonIndex, } - componentDidUpdate (prevProps, prevState) { + componentDidUpdate (_, prevState) { + // Provides an API for dynamically updating the activeButtonIndex if (typeof this.props.newActiveButtonIndex === 'number' && prevState.activeButtonIndex !== this.props.newActiveButtonIndex) { - this.setState({ activeButtonIndex: prevProps.newActiveButtonIndex }) + this.setState({ activeButtonIndex: this.props.newActiveButtonIndex }) } } diff --git a/ui/app/components/button-group/tests/button-group-component.test.js b/ui/app/components/button-group/tests/button-group-component.test.js index f07bb97c8..0bece90d6 100644 --- a/ui/app/components/button-group/tests/button-group-component.test.js +++ b/ui/app/components/button-group/tests/button-group-component.test.js @@ -35,6 +35,20 @@ describe('ButtonGroup Component', function () { ButtonGroup.prototype.renderButtons.resetHistory() }) + describe('componentDidUpdate', () => { + it('should set the activeButtonIndex to the updated newActiveButtonIndex', () => { + assert.equal(wrapper.state('activeButtonIndex'), 1) + wrapper.setProps({ newActiveButtonIndex: 2 }) + assert.equal(wrapper.state('activeButtonIndex'), 2) + }) + + it('should not set the activeButtonIndex to an updated newActiveButtonIndex that is not a number', () => { + assert.equal(wrapper.state('activeButtonIndex'), 1) + wrapper.setProps({ newActiveButtonIndex: null }) + assert.equal(wrapper.state('activeButtonIndex'), 1) + }) + }) + describe('handleButtonClick', () => { it('should set the activeButtonIndex', () => { assert.equal(wrapper.state('activeButtonIndex'), 1) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index db730458d..41fe901fa 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -92,23 +92,24 @@ export default class GasModalPageContainer extends Component { hideBasic, ...advancedTabProps }) { + let tabsToRender = [ + { name: 'basic', content: this.renderBasicTabContent(gasPriceButtonGroupProps) }, + { name: 'advanced', content: this.renderAdvancedTabContent(advancedTabProps) }, + ] + + if (hideBasic) { + tabsToRender = tabsToRender.slice(1) + } + return ( <Tabs> - {hideBasic - ? null - : <Tab name={this.context.t('basic')}> + {tabsToRender.map(({ name, content }, i) => <Tab name={this.context.t(name)} key={`gas-modal-tab-${i}`}> <div className="gas-modal-content"> - { this.renderBasicTabContent(gasPriceButtonGroupProps) } + { content } { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } </div> </Tab> - } - <Tab name={this.context.t('advanced')}> - <div className="gas-modal-content"> - { this.renderAdvancedTabContent(advancedTabProps) } - { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } - </div> - </Tab> + )} </Tabs> ) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index a150e5009..f9ed1cebb 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -119,10 +119,12 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...stateProps, ...otherDispatchProps, ...ownProps, - onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : (newLimit, newPrice) => { - dispatchSetGasData(newLimit, newPrice) - dispatchHideGasButtonGroup() - }, + onSubmit: isConfirm + ? dispatchUpdateConfirmTxGasAndCalculate + : (newLimit, newPrice) => { + dispatchSetGasData(newLimit, newPrice) + dispatchHideGasButtonGroup() + }, gasPriceButtonGroupProps: { ...gasPriceButtonGroupProps, handleGasPriceSelection: dispatchUpdateCustomGasPrice, diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index c41adca83..fdd7709d9 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -161,6 +161,19 @@ describe('GasModalPageContainer Component', function () { assert.deepEqual(GP.renderInfoRows.getCall(0).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) assert.deepEqual(GP.renderInfoRows.getCall(1).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) }) + + it('should not render the basic tab if hideBasic is true', () => { + const renderTabsResult = wrapper.instance().renderTabs(mockInfoRowProps, { + gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, + otherProps: 'mockAdvancedTabProps', + hideBasic: true, + }) + + const renderedTabs = shallow(renderTabsResult) + const tabs = renderedTabs.find(Tab) + assert.equal(tabs.length, 1) + assert.equal(tabs.at(0).props().name, 'advanced') + }) }) describe('renderInfoRow', () => { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index e01fd3898..238f27ed6 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -4,6 +4,7 @@ import sinon from 'sinon' let mapStateToProps let mapDispatchToProps +let mergeProps const actionSpies = { hideModal: sinon.spy(), @@ -20,11 +21,16 @@ const confirmTransactionActionSpies = { updateGasAndCalculate: sinon.spy(), } +const sendActionSpies = { + hideGasButtonGroup: sinon.spy(), +} + proxyquire('../gas-modal-page-container.container.js', { 'react-redux': { - connect: (ms, md) => { + connect: (ms, md, mp) => { mapStateToProps = ms mapDispatchToProps = md + mergeProps = mp return () => ({}) }, }, @@ -36,6 +42,7 @@ proxyquire('../gas-modal-page-container.container.js', { '../../../actions': actionSpies, '../../../ducks/gas.duck': gasActionSpies, '../../../ducks/confirm-transaction.duck': confirmTransactionActionSpies, + '../../../ducks/send.duck': sendActionSpies, }) describe('gas-modal-page-container container', () => { @@ -44,6 +51,15 @@ describe('gas-modal-page-container container', () => { it('should map the correct properties to props', () => { const mockState2 = { + appState: { + modal: { + modalState: { + props: { + hideBasic: true, + }, + }, + }, + }, metamask: { send: { gasLimit: '16', @@ -80,10 +96,11 @@ describe('gas-modal-page-container container', () => { newTotalFiat: '637.41', gasPriceButtonGroupProps: { - buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:3', - defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:3ffffffff0x3200000', - gasButtonInfo: 'mockRenderableBasicEstimateData:3', + buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', + defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff0x3200000', + gasButtonInfo: 'mockRenderableBasicEstimateData:4', }, + hideBasic: true, infoRowProps: { originalTotalFiat: '22.58', originalTotalEth: '0.451569 ETH', @@ -110,6 +127,14 @@ describe('gas-modal-page-container container', () => { gasActionSpies.setCustomGasLimit.resetHistory() }) + describe('hideGasButtonGroup()', () => { + it('should dispatch a hideGasButtonGroup action', () => { + mapDispatchToPropsObject.hideGasButtonGroup() + assert(dispatchSpy.calledOnce) + assert(sendActionSpies.hideGasButtonGroup.calledOnce) + }) + }) + describe('hideModal()', () => { it('should dispatch a hideModal action', () => { mapDispatchToPropsObject.hideModal() @@ -168,4 +193,85 @@ describe('gas-modal-page-container container', () => { }) + describe('mergeProps', () => { + let stateProps + let dispatchProps + let ownProps + + beforeEach(() => { + stateProps = { + gasPriceButtonGroupProps: { + someGasPriceButtonGroupProp: 'foo', + anotherGasPriceButtonGroupProp: 'bar', + }, + isConfirm: true, + someOtherStateProp: 'baz', + } + dispatchProps = { + updateCustomGasPrice: sinon.spy(), + hideGasButtonGroup: sinon.spy(), + setGasData: sinon.spy(), + updateConfirmTxGasAndCalculate: sinon.spy(), + someOtherDispatchProp: sinon.spy(), + } + ownProps = { someOwnProp: 123 } + }) + it('should return the expected props when isConfirm is true', () => { + const result = mergeProps(stateProps, dispatchProps, ownProps) + + assert.equal(result.isConfirm, true) + assert.equal(result.someOtherStateProp, 'baz') + assert.equal(result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, 'foo') + assert.equal(result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, 'bar') + assert.equal(result.someOwnProp, 123) + + assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) + assert.equal(dispatchProps.setGasData.callCount, 0) + assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) + + result.onSubmit() + + assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 1) + assert.equal(dispatchProps.setGasData.callCount, 0) + assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) + + assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0) + result.gasPriceButtonGroupProps.handleGasPriceSelection() + assert.equal(dispatchProps.updateCustomGasPrice.callCount, 1) + + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 0) + result.someOtherDispatchProp() + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 1) + }) + + it('should return the expected props when isConfirm is false', () => { + const result = mergeProps(Object.assign({}, stateProps, { isConfirm: false }), dispatchProps, ownProps) + + assert.equal(result.isConfirm, false) + assert.equal(result.someOtherStateProp, 'baz') + assert.equal(result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, 'foo') + assert.equal(result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, 'bar') + assert.equal(result.someOwnProp, 123) + + assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) + assert.equal(dispatchProps.setGasData.callCount, 0) + assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) + + result.onSubmit('mockNewLimit', 'mockNewPrice') + + assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) + assert.equal(dispatchProps.setGasData.callCount, 1) + assert.deepEqual(dispatchProps.setGasData.getCall(0).args, ['mockNewLimit', 'mockNewPrice']) + assert.equal(dispatchProps.hideGasButtonGroup.callCount, 1) + + assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0) + result.gasPriceButtonGroupProps.handleGasPriceSelection() + assert.equal(dispatchProps.updateCustomGasPrice.callCount, 1) + + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 0) + result.someOtherDispatchProp() + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 1) + }) + }) + }) diff --git a/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js b/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js index 8d6675e18..62ebb512d 100644 --- a/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js +++ b/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js @@ -22,6 +22,7 @@ export default class GasPriceButtonGroup extends Component { defaultActiveButtonIndex: PropTypes.number, gasButtonInfo: PropTypes.arrayOf(PropTypes.shape(GAS_OBJECT_PROPTYPES_SHAPE)), handleGasPriceSelection: PropTypes.func, + newActiveButtonIndex: PropTypes.number, noButtonActiveByDefault: PropTypes.bool, showCheck: PropTypes.bool, } @@ -82,7 +83,7 @@ export default class GasPriceButtonGroup extends Component { > { gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) } </ButtonGroup> - : <div className={`${buttonPropsAndFlags.className}__loading-container`}>Loading...</div> + : <div className={`${buttonPropsAndFlags.className}__loading-container`}>{ this.context.t('loading') }</div> ) } } diff --git a/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js b/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js index e1458188d..79f74f8e4 100644 --- a/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js +++ b/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js @@ -1,6 +1,6 @@ import React from 'react' import assert from 'assert' -import { shallow } from 'enzyme' +import shallow from '../../../../../lib/shallow-with-context' import sinon from 'sinon' import GasPriceButtonGroup from '../gas-price-button-group.component' @@ -36,7 +36,6 @@ const mockGasPriceButtonGroupProps = { } const mockButtonPropsAndFlags = Object.assign({}, { - buttonDataLoading: mockGasPriceButtonGroupProps.buttonDataLoading, className: mockGasPriceButtonGroupProps.className, handleGasPriceSelection: mockGasPriceButtonGroupProps.handleGasPriceSelection, showCheck: mockGasPriceButtonGroupProps.showCheck, @@ -87,12 +86,19 @@ describe('GasPriceButtonGroup Component', function () { ) } - it('should called this.renderButton 3 times, with the correct args', () => { + it('should call this.renderButton 3 times, with the correct args', () => { assert.equal(GasPriceButtonGroup.prototype.renderButton.callCount, 3) renderButtonArgsTest(0, mockButtonPropsAndFlags) renderButtonArgsTest(1, mockButtonPropsAndFlags) renderButtonArgsTest(2, mockButtonPropsAndFlags) }) + + it('should show loading if buttonDataLoading', () => { + wrapper.setProps({ buttonDataLoading: true }) + assert(wrapper.is('div')) + assert(wrapper.hasClass('gas-price-button-group__loading-container')) + assert.equal(wrapper.text(), 'loading') + }) }) describe('renderButton', () => { @@ -147,29 +153,18 @@ describe('GasPriceButtonGroup Component', function () { ] ) }) - - it('should not call renderButtonContent if buttonDataLoading is true and should show a loading indicator', () => { - GasPriceButtonGroup.prototype.renderButtonContent.resetHistory() - const renderButtonResult = GasPriceButtonGroup.prototype.renderButton( - Object.assign({}, mockGasPriceButtonGroupProps.gasButtonInfo[0]), - Object.assign({}, mockButtonPropsAndFlags, {buttonDataLoading: true}) - ) - wrappedRenderButtonResult = shallow(renderButtonResult) - assert.equal(GasPriceButtonGroup.prototype.renderButtonContent.callCount, 0) - assert.equal(wrappedRenderButtonResult.childAt(0).text(), 'Loading...') - }) }) describe('renderButtonContent', () => { - it('should render a label if passed a label', () => { - const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ - label: 'mockLabel', + it('should render a label if passed a labelKey', () => { + const renderButtonContentResult = wrapper.instance().renderButtonContent({ + labelKey: 'mockLabelKey', }, { className: 'someClass', }) const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) - assert.equal(wrappedRenderButtonContentResult.find('.someClass__label').text(), 'mockLabel') + assert.equal(wrappedRenderButtonContentResult.find('.someClass__label').text(), 'mockLabelKey') }) it('should render a feeInPrimaryCurrency if passed a feeInPrimaryCurrency', () => { @@ -215,8 +210,8 @@ describe('GasPriceButtonGroup Component', function () { }) it('should render all elements if all args passed', () => { - const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ - label: 'mockLabel', + const renderButtonContentResult = wrapper.instance().renderButtonContent({ + labelKey: 'mockLabel', feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', timeEstimate: 'mockTimeEstimate', diff --git a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js index 9962f8028..40f8b1fe0 100644 --- a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js +++ b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js @@ -11,7 +11,7 @@ export default class GasFeeDisplay extends Component { convertedCurrency: PropTypes.string, gasLoadingError: PropTypes.bool, gasTotal: PropTypes.string, - onClick: PropTypes.func, + showGasButtonGroup: PropTypes.func, }; static contextTypes = { @@ -49,7 +49,7 @@ export default class GasFeeDisplay extends Component { className="gas-fee-reset" onClick={showGasButtonGroup} > - Reset + { this.context.t('reset') } </button> </div> ) diff --git a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js index 9ff01493a..c7ac175d9 100644 --- a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js +++ b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js @@ -17,9 +17,9 @@ describe('SendGasRow Component', function () { wrapper = shallow(<GasFeeDisplay conversionRate={20} gasTotal={'mockGasTotal'} - onClick={propsMethodSpies.showCustomizeGasModal} primaryCurrency={'mockPrimaryCurrency'} convertedCurrency={'mockConvertedCurrency'} + showGasButtonGroup={propsMethodSpies.showCustomizeGasModal} />, {context: {t: str => str + '_t'}}) }) @@ -41,13 +41,19 @@ describe('SendGasRow Component', function () { assert.equal(value, 'mockGasTotal') }) - it('should render the Button with the correct props', () => { + it('should render the reset button with the correct props', () => { const { onClick, + className, } = wrapper.find('button').props() + assert.equal(className, 'gas-fee-reset') assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 0) onClick() assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 1) }) + + it('should render the reset button with the correct text', () => { + assert.equal(wrapper.find('button').text(), 'reset_t') + }) }) }) diff --git a/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js b/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js index 64a5cd603..507407306 100644 --- a/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js +++ b/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js @@ -13,6 +13,9 @@ export default class SendGasRow extends Component { gasLoadingError: PropTypes.bool, gasTotal: PropTypes.string, showCustomizeGasModal: PropTypes.func, + gasPriceButtonGroupProps: PropTypes.object, + showGasButtonGroup: PropTypes.func, + gasButtonGroupShown: PropTypes.bool, } static contextTypes = { @@ -29,7 +32,7 @@ export default class SendGasRow extends Component { showCustomizeGasModal, gasPriceButtonGroupProps, gasButtonGroupShown, - showGasButtonGroup + showGasButtonGroup, } = this.props return ( @@ -43,10 +46,10 @@ export default class SendGasRow extends Component { <GasPriceButtonGroup className="gas-price-button-group--small" showCheck={false} - {...this.props.gasPriceButtonGroupProps} + {...gasPriceButtonGroupProps} /> <div className="advanced-gas-options-btn" onClick={() => showCustomizeGasModal()}> - Advanced Options + { this.context.t('advancedOptions') } </div> </div> : <GasFeeDisplay diff --git a/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js b/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js index 19e49b391..dd16559d0 100644 --- a/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js +++ b/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js @@ -5,13 +5,13 @@ import { getGasTotal, getGasPrice, } from '../../send.selectors.js' -import{ +import { getBasicGasEstimateLoadingStatus, getRenderableEstimateDataForSmallButtons, - getDefaultActiveButtonIndex + getDefaultActiveButtonIndex, } from '../../../../selectors/custom-gas' -import{ - showGasButtonGroup +import { + showGasButtonGroup, } from '../../../../ducks/send.duck' import { getGasLoadingError, gasFeeIsInError, getGasButtonGroupShown } from './send-gas-row.selectors.js' import { showModal, setGasPrice } from '../../../../actions' @@ -43,7 +43,7 @@ function mapDispatchToProps (dispatch) { return { showCustomizeGasModal: () => dispatch(showModal({ name: 'CUSTOMIZE_GAS', hideBasic: true })), setGasPrice: newPrice => dispatch(setGasPrice(newPrice)), - showGasButtonGroup: () => dispatch(showGasButtonGroup()) + showGasButtonGroup: () => dispatch(showGasButtonGroup()), } } @@ -63,4 +63,4 @@ function mergeProps (stateProps, dispatchProps, ownProps) { handleGasPriceSelection: dispatchSetGasPrice, }, } -}
\ No newline at end of file +} diff --git a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js index 54a92bd2d..171cd7bf6 100644 --- a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js +++ b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js @@ -6,6 +6,7 @@ import SendGasRow from '../send-gas-row.component.js' import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component' import GasFeeDisplay from '../gas-fee-display/gas-fee-display.component' +import GasPriceButtonGroup from '../../../../gas-customization/gas-price-button-group' const propsMethodSpies = { showCustomizeGasModal: sinon.spy(), @@ -21,7 +22,13 @@ describe('SendGasRow Component', function () { gasFeeError={'mockGasFeeError'} gasLoadingError={false} gasTotal={'mockGasTotal'} + showGasButtonGroup={'mockShowGasPriceButtonGroup'} + gasButtonGroupShown={false} showCustomizeGasModal={propsMethodSpies.showCustomizeGasModal} + gasPriceButtonGroupProps={{ + someGasPriceButtonGroupProp: 'foo', + anotherGasPriceButtonGroupProp: 'bar', + }} />, { context: { t: str => str + '_t' } }) }) @@ -41,7 +48,7 @@ describe('SendGasRow Component', function () { errorType, } = wrapper.find(SendRowWrapper).props() - assert.equal(label, 'gasFee_t:') + assert.equal(label, 'transactionFee_t:') assert.equal(showError, 'mockGasFeeError') assert.equal(errorType, 'gasFee') }) @@ -57,14 +64,42 @@ describe('SendGasRow Component', function () { gasLoadingError, gasTotal, onClick, + showGasButtonGroup, } = wrapper.find(SendRowWrapper).childAt(0).props() assert.equal(conversionRate, 20) assert.equal(convertedCurrency, 'mockConvertedCurrency') assert.equal(gasLoadingError, false) assert.equal(gasTotal, 'mockGasTotal') + assert.equal(showGasButtonGroup, 'mockShowGasPriceButtonGroup') assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 0) onClick() assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 1) }) + + it('should render the GasPriceButtonGroup if gasButtonGroupShown is true', () => { + wrapper.setProps({ gasButtonGroupShown: true }) + const rendered = wrapper.find(SendRowWrapper).childAt(0) + assert.equal(rendered.children().length, 2) + + const gasPriceButtonGroup = rendered.childAt(0) + assert(gasPriceButtonGroup.is(GasPriceButtonGroup)) + assert(gasPriceButtonGroup.hasClass('gas-price-button-group--small')) + assert.equal(gasPriceButtonGroup.props().showCheck, false) + assert.equal(gasPriceButtonGroup.props().someGasPriceButtonGroupProp, 'foo') + assert.equal(gasPriceButtonGroup.props().anotherGasPriceButtonGroupProp, 'bar') + }) + + it('should render an advanced options button if gasButtonGroupShown is true', () => { + wrapper.setProps({ gasButtonGroupShown: true }) + const rendered = wrapper.find(SendRowWrapper).childAt(0) + assert.equal(rendered.children().length, 2) + + const advancedOptionsButton = rendered.childAt(1) + assert.equal(advancedOptionsButton.text(), 'advancedOptions_t') + + assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 0) + advancedOptionsButton.props().onClick() + assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 1) + }) }) }) diff --git a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js index 2ce062505..1c385e216 100644 --- a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js +++ b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js @@ -4,16 +4,23 @@ import sinon from 'sinon' let mapStateToProps let mapDispatchToProps +let mergeProps const actionSpies = { showModal: sinon.spy(), + setGasPrice: sinon.spy(), +} + +const sendDuckSpies = { + showGasButtonGroup: sinon.spy(), } proxyquire('../send-gas-row.container.js', { 'react-redux': { - connect: (ms, md) => { + connect: (ms, md, mp) => { mapStateToProps = ms mapDispatchToProps = md + mergeProps = mp return () => ({}) }, }, @@ -21,12 +28,20 @@ proxyquire('../send-gas-row.container.js', { getConversionRate: (s) => `mockConversionRate:${s}`, getCurrentCurrency: (s) => `mockConvertedCurrency:${s}`, getGasTotal: (s) => `mockGasTotal:${s}`, + getGasPrice: (s) => `mockGasPrice:${s}`, }, './send-gas-row.selectors.js': { getGasLoadingError: (s) => `mockGasLoadingError:${s}`, gasFeeIsInError: (s) => `mockGasFeeError:${s}`, + getGasButtonGroupShown: (s) => `mockGetGasButtonGroupShown:${s}`, }, '../../../../actions': actionSpies, + '../../../../selectors/custom-gas': { + getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${s}`, + getRenderableEstimateDataForSmallButtons: (s) => `mockGasButtonInfo:${s}`, + getDefaultActiveButtonIndex: (gasButtonInfo, gasPrice) => gasButtonInfo.length + gasPrice.length, + }, + '../../../../ducks/send.duck': sendDuckSpies, }) describe('send-gas-row container', () => { @@ -40,6 +55,13 @@ describe('send-gas-row container', () => { gasTotal: 'mockGasTotal:mockState', gasFeeError: 'mockGasFeeError:mockState', gasLoadingError: 'mockGasLoadingError:mockState', + gasPriceButtonGroupProps: { + buttonDataLoading: `mockBasicGasEstimateLoadingStatus:mockState`, + defaultActiveButtonIndex: 1, + newActiveButtonIndex: 49, + gasButtonInfo: `mockGasButtonInfo:mockState`, + }, + gasButtonGroupShown: `mockGetGasButtonGroupShown:mockState`, }) }) @@ -60,11 +82,66 @@ describe('send-gas-row container', () => { assert(dispatchSpy.calledOnce) assert.deepEqual( actionSpies.showModal.getCall(0).args[0], - { name: 'CUSTOMIZE_GAS' } + { name: 'CUSTOMIZE_GAS', hideBasic: true } ) }) }) + describe('setGasPrice()', () => { + it('should dispatch an action', () => { + mapDispatchToPropsObject.setGasPrice('mockNewPrice') + assert(dispatchSpy.calledOnce) + assert(actionSpies.setGasPrice.calledOnce) + assert.equal(actionSpies.setGasPrice.getCall(0).args[0], 'mockNewPrice') + }) + }) + + describe('showGasButtonGroup()', () => { + it('should dispatch an action', () => { + mapDispatchToPropsObject.showGasButtonGroup() + assert(dispatchSpy.calledOnce) + assert(sendDuckSpies.showGasButtonGroup.calledOnce) + }) + }) + + }) + + describe('mergeProps', () => { + let stateProps + let dispatchProps + let ownProps + + beforeEach(() => { + stateProps = { + gasPriceButtonGroupProps: { + someGasPriceButtonGroupProp: 'foo', + anotherGasPriceButtonGroupProp: 'bar', + }, + someOtherStateProp: 'baz', + } + dispatchProps = { + setGasPrice: sinon.spy(), + someOtherDispatchProp: sinon.spy(), + } + ownProps = { someOwnProp: 123 } + }) + + it('should return the expected props when isConfirm is true', () => { + const result = mergeProps(stateProps, dispatchProps, ownProps) + + assert.equal(result.someOtherStateProp, 'baz') + assert.equal(result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, 'foo') + assert.equal(result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, 'bar') + assert.equal(result.someOwnProp, 123) + + assert.equal(dispatchProps.setGasPrice.callCount, 0) + result.gasPriceButtonGroupProps.handleGasPriceSelection() + assert.equal(dispatchProps.setGasPrice.callCount, 1) + + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 0) + result.someOtherDispatchProp() + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 1) + }) }) }) diff --git a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-selectors.test.js b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-selectors.test.js index d46dd9d8b..bd3c9a257 100644 --- a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-selectors.test.js +++ b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-selectors.test.js @@ -2,6 +2,7 @@ import assert from 'assert' import { gasFeeIsInError, getGasLoadingError, + getGasButtonGroupShown, } from '../send-gas-row.selectors.js' describe('send-gas-row selectors', () => { @@ -46,4 +47,16 @@ describe('send-gas-row selectors', () => { }) }) + describe('getGasButtonGroupShown()', () => { + it('should return send.gasButtonGroupShown', () => { + const state = { + send: { + gasButtonGroupShown: 'foobar', + }, + } + + assert.equal(getGasButtonGroupShown(state), 'foobar') + }) + }) + }) diff --git a/ui/app/ducks/tests/send-duck.test.js b/ui/app/ducks/tests/send-duck.test.js index c101132d9..196fe226c 100644 --- a/ui/app/ducks/tests/send-duck.test.js +++ b/ui/app/ducks/tests/send-duck.test.js @@ -6,6 +6,8 @@ import SendReducer, { openToDropdown, closeToDropdown, updateSendErrors, + showGasButtonGroup, + hideGasButtonGroup, } from '../send.duck.js' describe('Send Duck', () => { @@ -18,6 +20,7 @@ describe('Send Duck', () => { fromDropdownOpen: false, toDropdownOpen: false, errors: {}, + gasButtonGroupShown: true, } const OPEN_FROM_DROPDOWN = 'metamask/send/OPEN_FROM_DROPDOWN' const CLOSE_FROM_DROPDOWN = 'metamask/send/CLOSE_FROM_DROPDOWN' @@ -25,6 +28,8 @@ describe('Send Duck', () => { const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN' const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS' const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE' + const SHOW_GAS_BUTTON_GROUP = 'metamask/send/SHOW_GAS_BUTTON_GROUP' + const HIDE_GAS_BUTTON_GROUP = 'metamask/send/HIDE_GAS_BUTTON_GROUP' describe('SendReducer()', () => { it('should initialize state', () => { @@ -85,6 +90,24 @@ describe('Send Duck', () => { ) }) + it('should set gasButtonGroupShown to true when receiving a SHOW_GAS_BUTTON_GROUP action', () => { + assert.deepEqual( + SendReducer(Object.assign({}, mockState, { gasButtonGroupShown: false }), { + type: SHOW_GAS_BUTTON_GROUP, + }), + Object.assign({gasButtonGroupShown: true}, mockState.send) + ) + }) + + it('should set gasButtonGroupShown to false when receiving a HIDE_GAS_BUTTON_GROUP action', () => { + assert.deepEqual( + SendReducer(mockState, { + type: HIDE_GAS_BUTTON_GROUP, + }), + Object.assign({gasButtonGroupShown: false}, mockState.send) + ) + }) + it('should extend send.errors with the value of a UPDATE_SEND_ERRORS action', () => { const modifiedMockState = Object.assign({}, mockState, { send: { @@ -145,6 +168,20 @@ describe('Send Duck', () => { ) }) + describe('showGasButtonGroup', () => { + assert.deepEqual( + showGasButtonGroup(), + { type: SHOW_GAS_BUTTON_GROUP } + ) + }) + + describe('hideGasButtonGroup', () => { + assert.deepEqual( + hideGasButtonGroup(), + { type: HIDE_GAS_BUTTON_GROUP } + ) + }) + describe('updateSendErrors', () => { assert.deepEqual( updateSendErrors('mockErrorObject'), diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index f023b03b8..d5a3972df 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -63,9 +63,7 @@ function getAveragePriceEstimateInHexWEI (state) { } function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) { - console.log('gasButtonInfo', gasButtonInfo) return gasButtonInfo.findIndex(({ priceInHexWei }) => { - console.log('priceInHexWei', priceInHexWei, '|', customGasPriceInHex) return priceInHexWei === addHexPrefix(customGasPriceInHex || gasPrice) }) } @@ -208,10 +206,6 @@ function getRenderableEstimateDataForSmallButtons (state) { safeLow, average, fast, - blockTime, - safeLowWait, - avgWait, - fastWait, }, }, } = state diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js index d53c1ec98..5fde61c9b 100644 --- a/ui/app/selectors/tests/custom-gas.test.js +++ b/ui/app/selectors/tests/custom-gas.test.js @@ -7,6 +7,7 @@ const { getCustomGasPrice, getCustomGasTotal, getRenderableBasicEstimateData, + getRenderableEstimateDataForSmallButtons, } = proxyquire('../custom-gas', {}) describe('custom-gas selectors', () => { @@ -137,4 +138,102 @@ describe('custom-gas selectors', () => { }) + describe('getRenderableEstimateDataForSmallButtons()', () => { + const tests = [ + { + expectedResult: [ + { + feeInSecondaryCurrency: '$0.05', + feeInPrimaryCurrency: '0.00021 ETH', + labelKey: 'fast', + priceInHexWei: '0x2540be400', + }, + { + feeInSecondaryCurrency: '$0.03', + feeInPrimaryCurrency: '0.0001 ETH', + labelKey: 'average', + priceInHexWei: '0x12a05f200', + }, + { + feeInSecondaryCurrency: '$0.01', + feeInPrimaryCurrency: '0.00005 ETH', + labelKey: 'slow', + priceInHexWei: '0x9502f900', + }, + ], + mockState: { + metamask: { + conversionRate: 255.71, + currentCurrency: 'usd', + send: { + gasLimit: '0x5208', + }, + }, + gas: { + basicEstimates: { + blockTime: 14.16326530612245, + safeLow: 25, + safeLowWait: 6.6, + average: 50, + avgWait: 3.3, + fast: 100, + fastWait: 0.5, + }, + }, + }, + }, + { + expectedResult: [ + { + feeInSecondaryCurrency: '$1.07', + feeInPrimaryCurrency: '0.00042 ETH', + labelKey: 'fast', + priceInHexWei: '0x4a817c800', + }, + { + feeInSecondaryCurrency: '$0.54', + feeInPrimaryCurrency: '0.00021 ETH', + labelKey: 'average', + priceInHexWei: '0x2540be400', + }, + { + feeInSecondaryCurrency: '$0.27', + feeInPrimaryCurrency: '0.0001 ETH', + labelKey: 'slow', + priceInHexWei: '0x12a05f200', + }, + ], + mockState: { + metamask: { + conversionRate: 2557.1, + currentCurrency: 'usd', + send: { + gasLimit: '0x5208', + }, + }, + gas: { + basicEstimates: { + blockTime: 14.16326530612245, + safeLow: 50, + safeLowWait: 13.2, + average: 100, + avgWait: 6.6, + fast: 200, + fastWait: 1.0, + }, + }, + }, + }, + ] + it('should return renderable data about basic estimates appropriate for buttons with less info', () => { + tests.forEach(test => { + assert.deepEqual( + getRenderableEstimateDataForSmallButtons(test.mockState), + test.expectedResult + ) + }) + }) + + }) + }) |