From 112d18e316df312a648b8c8ac17c201314fc9ed6 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 9 Aug 2018 13:44:03 -0230 Subject: Adds basic tab content to gas customizer, with styled button group (static, for now). --- ui/app/components/button/button.component.js | 6 +- .../basic-tab-content.component.js | 22 ++ .../basic-tab-content/index.js | 1 + .../basic-tab-content/index.scss | 11 + .../tests/basic-tab-content-component.test.js | 71 ++++++ .../gas-modal-page-container.component.js | 10 +- .../gas-modal-page-container.container.js | 29 +++ .../gas-modal-page-container/index.scss | 7 +- .../gas-modal-page-container-component.test.js | 47 +++- .../gas-modal-page-container-container.test.js | 39 +++- .../gas-price-button-group.component.js | 85 ++++++++ .../gas-price-button-group/index.js | 1 + .../gas-price-button-group/index.scss | 60 ++++++ .../tests/gas-price-button-group-component.test.js | 238 +++++++++++++++++++++ ui/app/components/index.scss | 2 + 15 files changed, 614 insertions(+), 15 deletions(-) create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js create mode 100644 ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js create mode 100644 ui/app/components/gas-customization/gas-price-button-group/index.js create mode 100644 ui/app/components/gas-customization/gas-price-button-group/index.scss create mode 100644 ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js (limited to 'ui/app/components') diff --git a/ui/app/components/button/button.component.js b/ui/app/components/button/button.component.js index 4a06333e7..5c617585d 100644 --- a/ui/app/components/button/button.component.js +++ b/ui/app/components/button/button.component.js @@ -22,7 +22,11 @@ export default class Button extends Component { type: PropTypes.string, large: PropTypes.bool, className: PropTypes.string, - children: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), + children: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.array, + PropTypes.element, + ]), } render () { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js new file mode 100644 index 000000000..751042871 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js @@ -0,0 +1,22 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import GasPriceButtonGroup from '../../gas-price-button-group' + +export default class BasicTabContent extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + gasPriceButtonGroupProps: PropTypes.object, + } + + render () { + return ( +
+
Suggest gas fee increases
+ +
+ ) + } +} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js new file mode 100644 index 000000000..078d50fce --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js @@ -0,0 +1 @@ +export { default } from './basic-tab-content.component' diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss new file mode 100644 index 000000000..ba665716c --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss @@ -0,0 +1,11 @@ +.basic-tab-content { + display: flex; + flex-direction: column; + align-items: center; + + &__title { + margin-top: 19px; + font-size: 20px; + color: $scorpion; + } +} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js new file mode 100644 index 000000000..0c9c6ac63 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js @@ -0,0 +1,71 @@ +import React from 'react' +import assert from 'assert' +import { shallow } from 'enzyme' +import BasicTabContent from '../basic-tab-content.component' + +import GasPriceButtonGroup from '../../../gas-price-button-group/' + +const mockGasPriceButtonGroupProps = { + buttonDataLoading: false, + className: 'gas-price-button-group', + gasButtonInfo: [ + { + feeInPrimaryCurrency: '$0.52', + feeInSecondaryCurrency: '0.0048 ETH', + timeEstimate: '~ 1 min 0 sec', + priceInHexWei: '0xa1b2c3f', + }, + { + feeInPrimaryCurrency: '$0.39', + feeInSecondaryCurrency: '0.004 ETH', + timeEstimate: '~ 1 min 30 sec', + priceInHexWei: '0xa1b2c39', + }, + { + feeInPrimaryCurrency: '$0.30', + feeInSecondaryCurrency: '0.00354 ETH', + timeEstimate: '~ 2 min 1 sec', + priceInHexWei: '0xa1b2c30', + }, + ], + handleGasPriceSelection: newPrice => console.log('NewPrice: ', newPrice), + noButtonActiveByDefault: true, + showCheck: true, +} + +describe('BasicTabContent Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow() + }) + + describe('render', () => { + it('should have a title', () => { + assert(wrapper.find('.basic-tab-content').childAt(0).hasClass('basic-tab-content__title')) + }) + + it('should render a GasPriceButtonGroup compenent', () => { + assert.equal(wrapper.find(GasPriceButtonGroup).length, 1) + }) + + it('should pass correct props to GasPriceButtonGroup', () => { + const { + buttonDataLoading, + className, + gasButtonInfo, + handleGasPriceSelection, + noButtonActiveByDefault, + showCheck, + } = wrapper.find(GasPriceButtonGroup).props() + assert.equal(buttonDataLoading, mockGasPriceButtonGroupProps.buttonDataLoading) + assert.equal(className, mockGasPriceButtonGroupProps.className) + assert.equal(noButtonActiveByDefault, mockGasPriceButtonGroupProps.noButtonActiveByDefault) + assert.equal(showCheck, mockGasPriceButtonGroupProps.showCheck) + assert.deepEqual(gasButtonInfo, mockGasPriceButtonGroupProps.gasButtonInfo) + assert.equal(JSON.stringify(handleGasPriceSelection), JSON.stringify(mockGasPriceButtonGroupProps.handleGasPriceSelection)) + }) + }) +}) 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 e47ebaf65..9a0070b2a 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 @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import PageContainer from '../../page-container' import { Tabs, Tab } from '../../tabs' import AdvancedTabContent from './advanced-tab-content' +import BasicTabContent from './basic-tab-content' export default class GasModalPageContainer extends Component { static contextTypes = { @@ -15,13 +16,14 @@ export default class GasModalPageContainer extends Component { updateCustomGasLimit: PropTypes.func, customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, + gasPriceButtonGroupProps: PropTypes.object, } state = {} renderBasicTabContent () { return ( -
+ ) } @@ -63,7 +65,7 @@ export default class GasModalPageContainer extends Component { renderTabContent (mainTabContent) { return (
- { mainTabContent() } + { mainTabContent } { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') } { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') }
@@ -74,10 +76,10 @@ export default class GasModalPageContainer extends Component { return ( - { this.renderTabContent(this.renderBasicTabContent) } + { this.renderTabContent(this.renderBasicTabContent()) } - { this.renderTabContent(this.renderAdvancedTabContent) } + { this.renderTabContent(this.renderAdvancedTabContent()) } ) 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 f7ac91a38..2354d578c 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 @@ -10,10 +10,39 @@ import { getCustomGasLimit, } from '../../../selectors/custom-gas' +const mockGasPriceButtonGroupProps = { + buttonDataLoading: false, + className: 'gas-price-button-group', + gasButtonInfo: [ + { + feeInPrimaryCurrency: '$0.52', + feeInSecondaryCurrency: '0.0048 ETH', + timeEstimate: '~ 1 min 0 sec', + priceInHexWei: '0xa1b2c3f', + }, + { + feeInPrimaryCurrency: '$0.39', + feeInSecondaryCurrency: '0.004 ETH', + timeEstimate: '~ 1 min 30 sec', + priceInHexWei: '0xa1b2c39', + }, + { + feeInPrimaryCurrency: '$0.30', + feeInSecondaryCurrency: '0.00354 ETH', + timeEstimate: '~ 2 min 1 sec', + priceInHexWei: '0xa1b2c30', + }, + ], + handleGasPriceSelection: newPrice => console.log('NewPrice: ', newPrice), + noButtonActiveByDefault: true, + showCheck: true, +} + const mapStateToProps = state => { return { customGasPrice: getCustomGasPrice(state), customGasLimit: getCustomGasLimit(state), + gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, } } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss index ff512537e..427b58888 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -1,4 +1,5 @@ @import './advanced-tab-content/index'; +@import './basic-tab-content/index'; .gas-modal-page-container { .page-container { @@ -12,7 +13,7 @@ } - .info-row, .info-row--fade { + &__info-row, &__info-row--fade { width: 100%; background: $polar; padding: 15px 21px; @@ -51,5 +52,7 @@ &__info-row--fade { background: white; color: $dusty-gray; + border-top: 1px solid $mischka; + margin-top: 22px; } -} \ No newline at end of file +} 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 8bf72647a..86286b615 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 @@ -5,12 +5,43 @@ import sinon from 'sinon' import GasModalPageContainer from '../gas-modal-page-container.component.js' import PageContainer from '../../../page-container' +import BasicTabContent from '../basic-tab-content' +import AdvancedTabContent from '../advanced-tab-content' + import { Tab } from '../../../tabs' const propsMethodSpies = { hideModal: sinon.spy(), } +const mockGasPriceButtonGroupProps = { + buttonDataLoading: false, + className: 'gas-price-button-group', + gasButtonInfo: [ + { + feeInPrimaryCurrency: '$0.52', + feeInSecondaryCurrency: '0.0048 ETH', + timeEstimate: '~ 1 min 0 sec', + priceInHexWei: '0xa1b2c3f', + }, + { + feeInPrimaryCurrency: '$0.39', + feeInSecondaryCurrency: '0.004 ETH', + timeEstimate: '~ 1 min 30 sec', + priceInHexWei: '0xa1b2c39', + }, + { + feeInPrimaryCurrency: '$0.30', + feeInSecondaryCurrency: '0.00354 ETH', + timeEstimate: '~ 2 min 1 sec', + priceInHexWei: '0xa1b2c30', + }, + ], + handleGasPriceSelection: 'mockSelectionFunction', + noButtonActiveByDefault: true, + showCheck: true, +} + describe('GasModalPageContainer Component', function () { let wrapper @@ -21,6 +52,7 @@ describe('GasModalPageContainer Component', function () { updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} customGasPrice={21} customGasLimit={54321} + gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) @@ -90,8 +122,8 @@ describe('GasModalPageContainer Component', function () { assert.equal(GP.renderTabContent.callCount, 2) - assert.deepEqual(GP.renderTabContent.firstCall.args, [wrapper.instance().renderBasicTabContent]) - assert.deepEqual(GP.renderTabContent.secondCall.args, [wrapper.instance().renderAdvancedTabContent]) + assert.equal(GP.renderTabContent.firstCall.args.type, BasicTabContent.type) + assert.equal(GP.renderTabContent.secondCall.args.type, AdvancedTabContent.type) GP.renderTabContent.restore() }) @@ -104,8 +136,8 @@ describe('GasModalPageContainer Component', function () { assert.equal(renderedTabContent.props().className, 'gas-modal-content') }) - it('should render the element returned by the passed func as its first child', () => { - const renderTabContentResult = wrapper.instance().renderTabContent(() => Mock content) + it('should render the passed element as its first child', () => { + const renderTabContentResult = wrapper.instance().renderTabContent(Mock content) const renderedTabContent = shallow(renderTabContentResult) assert(renderedTabContent.childAt(0).equals(Mock content)) }) @@ -145,8 +177,11 @@ describe('GasModalPageContainer Component', function () { describe('renderBasicTabContent', () => { it('should render', () => { const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent() - const renderedBasicTabContent = shallow(renderBasicTabContentResult) - assert.equal(renderedBasicTabContent.props().className, 'gas-modal-content__basic-tab') + + assert.deepEqual( + renderBasicTabContentResult.props.gasPriceButtonGroupProps, + mockGasPriceButtonGroupProps + ) }) }) 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 5b133fbe2..119ae640b 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 @@ -2,26 +2,45 @@ import assert from 'assert' import proxyquire from 'proxyquire' import sinon from 'sinon' -// let mapStateToProps +let mapStateToProps let mapDispatchToProps const actionSpies = { hideModal: sinon.spy(), } +const customGasActionSpies = { + setCustomGasPrice: sinon.spy(), + setCustomGasLimit: sinon.spy(), +} + proxyquire('../gas-modal-page-container.container.js', { 'react-redux': { connect: (ms, md) => { - // mapStateToProps = ms + mapStateToProps = ms mapDispatchToProps = md return () => ({}) }, }, + '../../../selectors/custom-gas': { + getCustomGasPrice: (s) => `mockGasPrice:${s}`, + getCustomGasLimit: (s) => `mockGasLimit:${s}`, + }, '../../../actions': actionSpies, + '../../../ducks/custom-gas': customGasActionSpies, }) describe('gas-modal-page-container container', () => { + describe('mapStateToProps()', () => { + + it('should map the correct properties to props', () => { + assert.equal(mapStateToProps('mockState').customGasPrice, 'mockGasPrice:mockState') + assert.equal(mapStateToProps('mockState').customGasLimit, 'mockGasLimit:mockState') + }) + + }) + describe('mapDispatchToProps()', () => { let dispatchSpy let mapDispatchToPropsObject @@ -39,6 +58,22 @@ describe('gas-modal-page-container container', () => { }) }) + describe('updateCustomGasPrice()', () => { + it('should dispatch a setCustomGasPrice action', () => { + mapDispatchToPropsObject.updateCustomGasPrice() + assert(dispatchSpy.calledOnce) + assert(customGasActionSpies.setCustomGasPrice.calledOnce) + }) + }) + + describe('updateCustomGasLimit()', () => { + it('should dispatch a setCustomGasLimit action', () => { + mapDispatchToPropsObject.updateCustomGasLimit() + assert(dispatchSpy.calledOnce) + assert(customGasActionSpies.setCustomGasLimit.calledOnce) + }) + }) + }) }) 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 new file mode 100644 index 000000000..3873f54bc --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js @@ -0,0 +1,85 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import ButtonGroup from '../../button-group' +import Button from '../../button' + +const GAS_OBJECT_PROPTYPES_SHAPE = { + label: PropTypes.string, + feeInPrimaryCurrency: PropTypes.string, + feeInSecondaryCurrency: PropTypes.string, + timeEstimate: PropTypes.string, + priceInHexWei: PropTypes.string, +} + +export default class GasPriceButtonGroup extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + buttonDataLoading: PropTypes.bool, + className: PropTypes.string, + defaultActiveButtonIndex: PropTypes.number, + gasButtonInfo: PropTypes.arrayOf(PropTypes.shape(GAS_OBJECT_PROPTYPES_SHAPE)), + handleGasPriceSelection: PropTypes.func, + noButtonActiveByDefault: PropTypes.bool, + showCheck: PropTypes.bool, + } + + renderButtonContent ({ + label, + feeInPrimaryCurrency, + feeInSecondaryCurrency, + timeEstimate, + }, { + className, + showCheck, + }) { + return (
+ { label &&
{ label }
} + { feeInPrimaryCurrency &&
{ feeInPrimaryCurrency }
} + { feeInSecondaryCurrency &&
{ feeInSecondaryCurrency }
} + { timeEstimate &&
{ timeEstimate }
} + { showCheck && } +
) + } + + renderButton ({ + priceInHexWei, + ...renderableGasInfo + }, { + buttonDataLoading, + handleGasPriceSelection, + ...buttonContentPropsAndFlags + }, index) { + return ( + + ) + } + + render () { + const { + gasButtonInfo, + defaultActiveButtonIndex = 1, + noButtonActiveByDefault = false, + ...buttonPropsAndFlags + } = this.props + + return ( + + { gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) } + + ) + } +} diff --git a/ui/app/components/gas-customization/gas-price-button-group/index.js b/ui/app/components/gas-customization/gas-price-button-group/index.js new file mode 100644 index 000000000..775648330 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-button-group/index.js @@ -0,0 +1 @@ +export { default } from './gas-price-button-group.component' diff --git a/ui/app/components/gas-customization/gas-price-button-group/index.scss b/ui/app/components/gas-customization/gas-price-button-group/index.scss new file mode 100644 index 000000000..e2670edd5 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-button-group/index.scss @@ -0,0 +1,60 @@ +.gas-price-button-group { + margin-top: 22px; + display: flex; + justify-content: space-evenly; + width: 100%; + padding-left: 20px; + padding-right: 20px; + + &__primary-currency { + font-size: 18px; + height: 20.5px; + margin-bottom: 7.5px; + } + + &__time-estimate { + margin-top: 5.5px; + color: $silver-chalice; + height: 15.4px; + } + + + .button-group__button, .button-group__button--active { + height: 130px; + max-width: 108px; + font-size: 12px; + flex-direction: column; + align-items: center; + display: flex; + padding-top: 17px; + border-radius: 4px; + border: 2px solid $spindle; + background: $white; + color: $scorpion; + + div { + display: flex; + flex-direction: column; + align-items: center; + } + + i { + &:last-child { + display: none; + } + } + } + + .button-group__button--active { + border: 2px solid $curious-blue; + color: $scorpion; + + i { + &:last-child { + display: flex; + color: $curious-blue; + margin-top: 8px + } + } + } +} 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 new file mode 100644 index 000000000..e1458188d --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js @@ -0,0 +1,238 @@ +import React from 'react' +import assert from 'assert' +import { shallow } from 'enzyme' +import sinon from 'sinon' +import GasPriceButtonGroup from '../gas-price-button-group.component' + +import ButtonGroup from '../../../button-group/' + +const mockGasPriceButtonGroupProps = { + buttonDataLoading: false, + className: 'gas-price-button-group', + gasButtonInfo: [ + { + feeInPrimaryCurrency: '$0.52', + feeInSecondaryCurrency: '0.0048 ETH', + timeEstimate: '~ 1 min 0 sec', + priceInHexWei: '0xa1b2c3f', + }, + { + feeInPrimaryCurrency: '$0.39', + feeInSecondaryCurrency: '0.004 ETH', + timeEstimate: '~ 1 min 30 sec', + priceInHexWei: '0xa1b2c39', + }, + { + feeInPrimaryCurrency: '$0.30', + feeInSecondaryCurrency: '0.00354 ETH', + timeEstimate: '~ 2 min 1 sec', + priceInHexWei: '0xa1b2c30', + }, + ], + handleGasPriceSelection: sinon.spy(), + noButtonActiveByDefault: true, + defaultActiveButtonIndex: 2, + showCheck: true, +} + +const mockButtonPropsAndFlags = Object.assign({}, { + buttonDataLoading: mockGasPriceButtonGroupProps.buttonDataLoading, + className: mockGasPriceButtonGroupProps.className, + handleGasPriceSelection: mockGasPriceButtonGroupProps.handleGasPriceSelection, + showCheck: mockGasPriceButtonGroupProps.showCheck, +}) + +sinon.spy(GasPriceButtonGroup.prototype, 'renderButton') +sinon.spy(GasPriceButtonGroup.prototype, 'renderButtonContent') + +describe('GasPriceButtonGroup Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow() + }) + + afterEach(() => { + GasPriceButtonGroup.prototype.renderButton.resetHistory() + GasPriceButtonGroup.prototype.renderButtonContent.resetHistory() + mockGasPriceButtonGroupProps.handleGasPriceSelection.resetHistory() + }) + + describe('render', () => { + it('should render a ButtonGroup', () => { + assert(wrapper.is(ButtonGroup)) + }) + + it('should render the correct props on the ButtonGroup', () => { + const { + className, + defaultActiveButtonIndex, + noButtonActiveByDefault, + } = wrapper.props() + assert.equal(className, 'gas-price-button-group') + assert.equal(defaultActiveButtonIndex, 2) + assert.equal(noButtonActiveByDefault, true) + }) + + function renderButtonArgsTest (i, mockButtonPropsAndFlags) { + assert.deepEqual( + GasPriceButtonGroup.prototype.renderButton.getCall(i).args, + [ + Object.assign({}, mockGasPriceButtonGroupProps.gasButtonInfo[i]), + mockButtonPropsAndFlags, + i, + ] + ) + } + + it('should called this.renderButton 3 times, with the correct args', () => { + assert.equal(GasPriceButtonGroup.prototype.renderButton.callCount, 3) + renderButtonArgsTest(0, mockButtonPropsAndFlags) + renderButtonArgsTest(1, mockButtonPropsAndFlags) + renderButtonArgsTest(2, mockButtonPropsAndFlags) + }) + }) + + describe('renderButton', () => { + let wrappedRenderButtonResult + + beforeEach(() => { + GasPriceButtonGroup.prototype.renderButtonContent.resetHistory() + const renderButtonResult = GasPriceButtonGroup.prototype.renderButton( + Object.assign({}, mockGasPriceButtonGroupProps.gasButtonInfo[0]), + mockButtonPropsAndFlags + ) + wrappedRenderButtonResult = shallow(renderButtonResult) + }) + + it('should render a button', () => { + assert.equal(wrappedRenderButtonResult.type(), 'button') + }) + + it('should call the correct method when clicked', () => { + assert.equal(mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, 0) + wrappedRenderButtonResult.props().onClick() + assert.equal(mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, 1) + assert.deepEqual( + mockGasPriceButtonGroupProps.handleGasPriceSelection.getCall(0).args, + [mockGasPriceButtonGroupProps.gasButtonInfo[0].priceInHexWei] + ) + }) + + it('should call this.renderButtonContent with the correct args', () => { + assert.equal(GasPriceButtonGroup.prototype.renderButtonContent.callCount, 1) + const { + feeInPrimaryCurrency, + feeInSecondaryCurrency, + timeEstimate, + } = mockGasPriceButtonGroupProps.gasButtonInfo[0] + const { + showCheck, + className, + } = mockGasPriceButtonGroupProps + assert.deepEqual( + GasPriceButtonGroup.prototype.renderButtonContent.getCall(0).args, + [ + { + feeInPrimaryCurrency, + feeInSecondaryCurrency, + timeEstimate, + }, + { + showCheck, + className, + }, + ] + ) + }) + + 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', + }, { + className: 'someClass', + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) + assert.equal(wrappedRenderButtonContentResult.find('.someClass__label').text(), 'mockLabel') + }) + + it('should render a feeInPrimaryCurrency if passed a feeInPrimaryCurrency', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ + feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', + }, { + className: 'someClass', + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) + assert.equal(wrappedRenderButtonContentResult.find('.someClass__primary-currency').text(), 'mockFeeInPrimaryCurrency') + }) + + it('should render a feeInSecondaryCurrency if passed a feeInSecondaryCurrency', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ + feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', + }, { + className: 'someClass', + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) + assert.equal(wrappedRenderButtonContentResult.find('.someClass__secondary-currency').text(), 'mockFeeInSecondaryCurrency') + }) + + it('should render a timeEstimate if passed a timeEstimate', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ + timeEstimate: 'mockTimeEstimate', + }, { + className: 'someClass', + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) + assert.equal(wrappedRenderButtonContentResult.find('.someClass__time-estimate').text(), 'mockTimeEstimate') + }) + + it('should render a check if showCheck is true', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({}, { + className: 'someClass', + showCheck: true, + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.find('.fa-check').length, 1) + }) + + it('should render all elements if all args passed', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ + label: 'mockLabel', + feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', + feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', + timeEstimate: 'mockTimeEstimate', + }, { + className: 'someClass', + showCheck: true, + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.children().length, 5) + }) + + + it('should render no elements if all args passed', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({}, {}) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.children().length, 0) + }) + }) +}) diff --git a/ui/app/components/index.scss b/ui/app/components/index.scss index 156b1b9f6..78c1216f7 100644 --- a/ui/app/components/index.scss +++ b/ui/app/components/index.scss @@ -71,3 +71,5 @@ @import './gas-customization/gas-modal-page-container/index'; @import './gas-customization/index'; + +@import './gas-customization/gas-price-button-group/index'; -- cgit