mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Adds basic tab content to gas customizer, with styled button group (static, for now).
This commit is contained in:
parent
57cd721800
commit
112d18e316
@ -22,7 +22,11 @@ export default class Button extends Component {
|
|||||||
type: PropTypes.string,
|
type: PropTypes.string,
|
||||||
large: PropTypes.bool,
|
large: PropTypes.bool,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
children: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
children: PropTypes.oneOfType([
|
||||||
|
PropTypes.string,
|
||||||
|
PropTypes.array,
|
||||||
|
PropTypes.element,
|
||||||
|
]),
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
@ -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 (
|
||||||
|
<div className="basic-tab-content">
|
||||||
|
<div className="basic-tab-content__title">Suggest gas fee increases</div>
|
||||||
|
<GasPriceButtonGroup {...this.props.gasPriceButtonGroupProps} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
export { default } from './basic-tab-content.component'
|
@ -0,0 +1,11 @@
|
|||||||
|
.basic-tab-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&__title {
|
||||||
|
margin-top: 19px;
|
||||||
|
font-size: 20px;
|
||||||
|
color: $scorpion;
|
||||||
|
}
|
||||||
|
}
|
@ -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(<BasicTabContent
|
||||||
|
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps}
|
||||||
|
/>)
|
||||||
|
})
|
||||||
|
|
||||||
|
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))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
|
|||||||
import PageContainer from '../../page-container'
|
import PageContainer from '../../page-container'
|
||||||
import { Tabs, Tab } from '../../tabs'
|
import { Tabs, Tab } from '../../tabs'
|
||||||
import AdvancedTabContent from './advanced-tab-content'
|
import AdvancedTabContent from './advanced-tab-content'
|
||||||
|
import BasicTabContent from './basic-tab-content'
|
||||||
|
|
||||||
export default class GasModalPageContainer extends Component {
|
export default class GasModalPageContainer extends Component {
|
||||||
static contextTypes = {
|
static contextTypes = {
|
||||||
@ -15,13 +16,14 @@ export default class GasModalPageContainer extends Component {
|
|||||||
updateCustomGasLimit: PropTypes.func,
|
updateCustomGasLimit: PropTypes.func,
|
||||||
customGasPrice: PropTypes.number,
|
customGasPrice: PropTypes.number,
|
||||||
customGasLimit: PropTypes.number,
|
customGasLimit: PropTypes.number,
|
||||||
|
gasPriceButtonGroupProps: PropTypes.object,
|
||||||
}
|
}
|
||||||
|
|
||||||
state = {}
|
state = {}
|
||||||
|
|
||||||
renderBasicTabContent () {
|
renderBasicTabContent () {
|
||||||
return (
|
return (
|
||||||
<div className="gas-modal-content__basic-tab"/>
|
<BasicTabContent gasPriceButtonGroupProps={this.props.gasPriceButtonGroupProps} />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +65,7 @@ export default class GasModalPageContainer extends Component {
|
|||||||
renderTabContent (mainTabContent) {
|
renderTabContent (mainTabContent) {
|
||||||
return (
|
return (
|
||||||
<div className="gas-modal-content">
|
<div className="gas-modal-content">
|
||||||
{ mainTabContent() }
|
{ mainTabContent }
|
||||||
{ this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') }
|
{ 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') }
|
{ this.renderInfoRow('gas-modal-content__info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') }
|
||||||
</div>
|
</div>
|
||||||
@ -74,10 +76,10 @@ export default class GasModalPageContainer extends Component {
|
|||||||
return (
|
return (
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<Tab name={this.context.t('basic')}>
|
<Tab name={this.context.t('basic')}>
|
||||||
{ this.renderTabContent(this.renderBasicTabContent) }
|
{ this.renderTabContent(this.renderBasicTabContent()) }
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab name={this.context.t('advanced')}>
|
<Tab name={this.context.t('advanced')}>
|
||||||
{ this.renderTabContent(this.renderAdvancedTabContent) }
|
{ this.renderTabContent(this.renderAdvancedTabContent()) }
|
||||||
</Tab>
|
</Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
)
|
)
|
||||||
|
@ -10,10 +10,39 @@ import {
|
|||||||
getCustomGasLimit,
|
getCustomGasLimit,
|
||||||
} from '../../../selectors/custom-gas'
|
} 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 => {
|
const mapStateToProps = state => {
|
||||||
return {
|
return {
|
||||||
customGasPrice: getCustomGasPrice(state),
|
customGasPrice: getCustomGasPrice(state),
|
||||||
customGasLimit: getCustomGasLimit(state),
|
customGasLimit: getCustomGasLimit(state),
|
||||||
|
gasPriceButtonGroupProps: mockGasPriceButtonGroupProps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
@import './advanced-tab-content/index';
|
@import './advanced-tab-content/index';
|
||||||
|
@import './basic-tab-content/index';
|
||||||
|
|
||||||
.gas-modal-page-container {
|
.gas-modal-page-container {
|
||||||
.page-container {
|
.page-container {
|
||||||
@ -12,7 +13,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.info-row, .info-row--fade {
|
&__info-row, &__info-row--fade {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: $polar;
|
background: $polar;
|
||||||
padding: 15px 21px;
|
padding: 15px 21px;
|
||||||
@ -51,5 +52,7 @@
|
|||||||
&__info-row--fade {
|
&__info-row--fade {
|
||||||
background: white;
|
background: white;
|
||||||
color: $dusty-gray;
|
color: $dusty-gray;
|
||||||
|
border-top: 1px solid $mischka;
|
||||||
|
margin-top: 22px;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,12 +5,43 @@ import sinon from 'sinon'
|
|||||||
import GasModalPageContainer from '../gas-modal-page-container.component.js'
|
import GasModalPageContainer from '../gas-modal-page-container.component.js'
|
||||||
|
|
||||||
import PageContainer from '../../../page-container'
|
import PageContainer from '../../../page-container'
|
||||||
|
import BasicTabContent from '../basic-tab-content'
|
||||||
|
import AdvancedTabContent from '../advanced-tab-content'
|
||||||
|
|
||||||
import { Tab } from '../../../tabs'
|
import { Tab } from '../../../tabs'
|
||||||
|
|
||||||
const propsMethodSpies = {
|
const propsMethodSpies = {
|
||||||
hideModal: sinon.spy(),
|
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 () {
|
describe('GasModalPageContainer Component', function () {
|
||||||
let wrapper
|
let wrapper
|
||||||
|
|
||||||
@ -21,6 +52,7 @@ describe('GasModalPageContainer Component', function () {
|
|||||||
updateCustomGasLimit={() => 'mockupdateCustomGasLimit'}
|
updateCustomGasLimit={() => 'mockupdateCustomGasLimit'}
|
||||||
customGasPrice={21}
|
customGasPrice={21}
|
||||||
customGasLimit={54321}
|
customGasLimit={54321}
|
||||||
|
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps}
|
||||||
/>, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } })
|
/>, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } })
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -90,8 +122,8 @@ describe('GasModalPageContainer Component', function () {
|
|||||||
|
|
||||||
assert.equal(GP.renderTabContent.callCount, 2)
|
assert.equal(GP.renderTabContent.callCount, 2)
|
||||||
|
|
||||||
assert.deepEqual(GP.renderTabContent.firstCall.args, [wrapper.instance().renderBasicTabContent])
|
assert.equal(GP.renderTabContent.firstCall.args.type, BasicTabContent.type)
|
||||||
assert.deepEqual(GP.renderTabContent.secondCall.args, [wrapper.instance().renderAdvancedTabContent])
|
assert.equal(GP.renderTabContent.secondCall.args.type, AdvancedTabContent.type)
|
||||||
|
|
||||||
GP.renderTabContent.restore()
|
GP.renderTabContent.restore()
|
||||||
})
|
})
|
||||||
@ -104,8 +136,8 @@ describe('GasModalPageContainer Component', function () {
|
|||||||
assert.equal(renderedTabContent.props().className, 'gas-modal-content')
|
assert.equal(renderedTabContent.props().className, 'gas-modal-content')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should render the element returned by the passed func as its first child', () => {
|
it('should render the passed element as its first child', () => {
|
||||||
const renderTabContentResult = wrapper.instance().renderTabContent(() => <span>Mock content</span>)
|
const renderTabContentResult = wrapper.instance().renderTabContent(<span>Mock content</span>)
|
||||||
const renderedTabContent = shallow(renderTabContentResult)
|
const renderedTabContent = shallow(renderTabContentResult)
|
||||||
assert(renderedTabContent.childAt(0).equals(<span>Mock content</span>))
|
assert(renderedTabContent.childAt(0).equals(<span>Mock content</span>))
|
||||||
})
|
})
|
||||||
@ -145,8 +177,11 @@ describe('GasModalPageContainer Component', function () {
|
|||||||
describe('renderBasicTabContent', () => {
|
describe('renderBasicTabContent', () => {
|
||||||
it('should render', () => {
|
it('should render', () => {
|
||||||
const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent()
|
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
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -2,26 +2,45 @@ import assert from 'assert'
|
|||||||
import proxyquire from 'proxyquire'
|
import proxyquire from 'proxyquire'
|
||||||
import sinon from 'sinon'
|
import sinon from 'sinon'
|
||||||
|
|
||||||
// let mapStateToProps
|
let mapStateToProps
|
||||||
let mapDispatchToProps
|
let mapDispatchToProps
|
||||||
|
|
||||||
const actionSpies = {
|
const actionSpies = {
|
||||||
hideModal: sinon.spy(),
|
hideModal: sinon.spy(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const customGasActionSpies = {
|
||||||
|
setCustomGasPrice: sinon.spy(),
|
||||||
|
setCustomGasLimit: sinon.spy(),
|
||||||
|
}
|
||||||
|
|
||||||
proxyquire('../gas-modal-page-container.container.js', {
|
proxyquire('../gas-modal-page-container.container.js', {
|
||||||
'react-redux': {
|
'react-redux': {
|
||||||
connect: (ms, md) => {
|
connect: (ms, md) => {
|
||||||
// mapStateToProps = ms
|
mapStateToProps = ms
|
||||||
mapDispatchToProps = md
|
mapDispatchToProps = md
|
||||||
return () => ({})
|
return () => ({})
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'../../../selectors/custom-gas': {
|
||||||
|
getCustomGasPrice: (s) => `mockGasPrice:${s}`,
|
||||||
|
getCustomGasLimit: (s) => `mockGasLimit:${s}`,
|
||||||
|
},
|
||||||
'../../../actions': actionSpies,
|
'../../../actions': actionSpies,
|
||||||
|
'../../../ducks/custom-gas': customGasActionSpies,
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('gas-modal-page-container container', () => {
|
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()', () => {
|
describe('mapDispatchToProps()', () => {
|
||||||
let dispatchSpy
|
let dispatchSpy
|
||||||
let mapDispatchToPropsObject
|
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)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -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 (<div>
|
||||||
|
{ label && <div className={`${className}__label`}>{ label }</div> }
|
||||||
|
{ feeInPrimaryCurrency && <div className={`${className}__primary-currency`}>{ feeInPrimaryCurrency }</div> }
|
||||||
|
{ feeInSecondaryCurrency && <div className={`${className}__secondary-currency`}>{ feeInSecondaryCurrency }</div> }
|
||||||
|
{ timeEstimate && <div className={`${className}__time-estimate`}>{ timeEstimate }</div> }
|
||||||
|
{ showCheck && <i className="fa fa-check fa-2x" /> }
|
||||||
|
</div>)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderButton ({
|
||||||
|
priceInHexWei,
|
||||||
|
...renderableGasInfo
|
||||||
|
}, {
|
||||||
|
buttonDataLoading,
|
||||||
|
handleGasPriceSelection,
|
||||||
|
...buttonContentPropsAndFlags
|
||||||
|
}, index) {
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
onClick={() => handleGasPriceSelection(priceInHexWei)}
|
||||||
|
key={`gas-price-button-${index}`}
|
||||||
|
>
|
||||||
|
{buttonDataLoading
|
||||||
|
? 'Loading...'
|
||||||
|
: this.renderButtonContent(renderableGasInfo, buttonContentPropsAndFlags)}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const {
|
||||||
|
gasButtonInfo,
|
||||||
|
defaultActiveButtonIndex = 1,
|
||||||
|
noButtonActiveByDefault = false,
|
||||||
|
...buttonPropsAndFlags
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ButtonGroup
|
||||||
|
className={buttonPropsAndFlags.className}
|
||||||
|
defaultActiveButtonIndex={defaultActiveButtonIndex}
|
||||||
|
noButtonActiveByDefault={noButtonActiveByDefault}
|
||||||
|
>
|
||||||
|
{ gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) }
|
||||||
|
</ButtonGroup>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
export { default } from './gas-price-button-group.component'
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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(<GasPriceButtonGroup
|
||||||
|
{...mockGasPriceButtonGroupProps}
|
||||||
|
/>)
|
||||||
|
})
|
||||||
|
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
@ -71,3 +71,5 @@
|
|||||||
@import './gas-customization/gas-modal-page-container/index';
|
@import './gas-customization/gas-modal-page-container/index';
|
||||||
|
|
||||||
@import './gas-customization/index';
|
@import './gas-customization/index';
|
||||||
|
|
||||||
|
@import './gas-customization/gas-price-button-group/index';
|
||||||
|
@ -58,6 +58,7 @@ $linen: #fdf4f4;
|
|||||||
$oslo-gray: #8C8E94;
|
$oslo-gray: #8C8E94;
|
||||||
$polar: #fafcfe;
|
$polar: #fafcfe;
|
||||||
$blizzard-blue: #bfdef3;
|
$blizzard-blue: #bfdef3;
|
||||||
|
$mischka: #dddee9;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Z-Indicies
|
Z-Indicies
|
||||||
|
Loading…
x
Reference in New Issue
Block a user