remove customize-gas modal and related code that is no longer used (#16004)
parent
8e736e39d8
commit
99808eb02c
@ -1,11 +1,11 @@ |
|||||||
import { connect } from 'react-redux'; |
import { connect } from 'react-redux'; |
||||||
import { decGWEIToHexWEI } from '../../../../helpers/utils/conversions.util'; |
import { decGWEIToHexWEI } from '../../../helpers/utils/conversions.util'; |
||||||
import { getNetworkSupportsSettingGasFees } from '../../../../selectors/selectors'; |
import { getNetworkSupportsSettingGasFees } from '../../../selectors/selectors'; |
||||||
import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'; |
import { MIN_GAS_LIMIT_DEC } from '../../../pages/send/send.constants'; |
||||||
import { |
import { |
||||||
decimalToHex, |
decimalToHex, |
||||||
hexWEIToDecGWEI, |
hexWEIToDecGWEI, |
||||||
} from '../../../../../shared/lib/transactions-controller-utils'; |
} from '../../../../shared/lib/transactions-controller-utils'; |
||||||
import AdvancedGasInputs from './advanced-gas-inputs.component'; |
import AdvancedGasInputs from './advanced-gas-inputs.component'; |
||||||
|
|
||||||
function convertGasPriceForInputs(gasPriceInHexWEI) { |
function convertGasPriceForInputs(gasPriceInHexWEI) { |
@ -1,7 +1,7 @@ |
|||||||
import React from 'react'; |
import React from 'react'; |
||||||
import sinon from 'sinon'; |
import sinon from 'sinon'; |
||||||
import { renderWithProvider, fireEvent } from '../../../../../test/jest'; |
import { renderWithProvider, fireEvent } from '../../../../test/jest'; |
||||||
import configureStore from '../../../../store/store'; |
import configureStore from '../../../store/store'; |
||||||
import AdvancedGasInputs from '.'; |
import AdvancedGasInputs from '.'; |
||||||
|
|
||||||
describe('AdvancedGasInputs', () => { |
describe('AdvancedGasInputs', () => { |
@ -1,91 +0,0 @@ |
|||||||
import React from 'react'; |
|
||||||
import sinon from 'sinon'; |
|
||||||
import { shallowWithContext } from '../../../../../../test/lib/render-helpers'; |
|
||||||
import AdvancedTabContent from './advanced-tab-content.component'; |
|
||||||
|
|
||||||
describe('AdvancedTabContent Component', () => { |
|
||||||
let wrapper; |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
const propsMethodSpies = { |
|
||||||
updateCustomGasPrice: sinon.spy(), |
|
||||||
updateCustomGasLimit: sinon.spy(), |
|
||||||
}; |
|
||||||
sinon.spy(AdvancedTabContent.prototype, 'renderDataSummary'); |
|
||||||
|
|
||||||
wrapper = shallowWithContext( |
|
||||||
<AdvancedTabContent |
|
||||||
updateCustomGasPrice={propsMethodSpies.updateCustomGasPrice} |
|
||||||
updateCustomGasLimit={propsMethodSpies.updateCustomGasLimit} |
|
||||||
customModalGasPriceInHex="11" |
|
||||||
customModalGasLimitInHex="23456" |
|
||||||
transactionFee="$0.25" |
|
||||||
insufficientBalance={false} |
|
||||||
customPriceIsSafe |
|
||||||
isSpeedUp={false} |
|
||||||
customPriceIsExcessive={false} |
|
||||||
/>, |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
afterEach(() => { |
|
||||||
sinon.restore(); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('render()', () => { |
|
||||||
it('should render the advanced-tab root node', () => { |
|
||||||
expect(wrapper.hasClass('advanced-tab')).toStrictEqual(true); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render the expected child of the advanced-tab div', () => { |
|
||||||
const advancedTabChildren = wrapper.children(); |
|
||||||
expect(advancedTabChildren).toHaveLength(2); |
|
||||||
|
|
||||||
expect( |
|
||||||
advancedTabChildren |
|
||||||
.at(0) |
|
||||||
.hasClass('advanced-tab__transaction-data-summary'), |
|
||||||
).toStrictEqual(true); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should call renderDataSummary with the expected params', () => { |
|
||||||
const renderDataSummaryArgs = |
|
||||||
AdvancedTabContent.prototype.renderDataSummary.getCall(0).args; |
|
||||||
expect(renderDataSummaryArgs).toStrictEqual(['$0.25']); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('renderDataSummary()', () => { |
|
||||||
let dataSummary; |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
dataSummary = shallowWithContext( |
|
||||||
wrapper.instance().renderDataSummary('mockTotalFee'), |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render the transaction-data-summary root node', () => { |
|
||||||
expect( |
|
||||||
dataSummary.hasClass('advanced-tab__transaction-data-summary'), |
|
||||||
).toStrictEqual(true); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render titles of the data', () => { |
|
||||||
const titlesNode = dataSummary.children().at(0); |
|
||||||
expect( |
|
||||||
titlesNode.hasClass('advanced-tab__transaction-data-summary__titles'), |
|
||||||
).toStrictEqual(true); |
|
||||||
expect(titlesNode.children().at(0).text()).toStrictEqual( |
|
||||||
'newTransactionFee', |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render the data', () => { |
|
||||||
const dataNode = dataSummary.children().at(1); |
|
||||||
expect( |
|
||||||
dataNode.hasClass('advanced-tab__transaction-data-summary__container'), |
|
||||||
).toStrictEqual(true); |
|
||||||
expect(dataNode.children().at(0).text()).toStrictEqual('mockTotalFee'); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,76 +0,0 @@ |
|||||||
import React, { Component } from 'react'; |
|
||||||
import PropTypes from 'prop-types'; |
|
||||||
import AdvancedGasInputs from '../../advanced-gas-inputs'; |
|
||||||
|
|
||||||
export default class AdvancedTabContent extends Component { |
|
||||||
static contextTypes = { |
|
||||||
t: PropTypes.func, |
|
||||||
}; |
|
||||||
|
|
||||||
static propTypes = { |
|
||||||
updateCustomGasPrice: PropTypes.func, |
|
||||||
updateCustomGasLimit: PropTypes.func, |
|
||||||
customModalGasPriceInHex: PropTypes.string, |
|
||||||
customModalGasLimitInHex: PropTypes.string, |
|
||||||
transactionFee: PropTypes.string, |
|
||||||
insufficientBalance: PropTypes.bool, |
|
||||||
customPriceIsSafe: PropTypes.bool, |
|
||||||
isSpeedUp: PropTypes.bool, |
|
||||||
customGasLimitMessage: PropTypes.string, |
|
||||||
minimumGasLimit: PropTypes.number, |
|
||||||
customPriceIsExcessive: PropTypes.bool.isRequired, |
|
||||||
}; |
|
||||||
|
|
||||||
renderDataSummary(transactionFee) { |
|
||||||
return ( |
|
||||||
<div className="advanced-tab__transaction-data-summary"> |
|
||||||
<div className="advanced-tab__transaction-data-summary__titles"> |
|
||||||
<span>{this.context.t('newTransactionFee')}</span> |
|
||||||
</div> |
|
||||||
<div className="advanced-tab__transaction-data-summary__container"> |
|
||||||
<div className="advanced-tab__transaction-data-summary__fee"> |
|
||||||
{transactionFee} |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
render() { |
|
||||||
const { |
|
||||||
updateCustomGasPrice, |
|
||||||
updateCustomGasLimit, |
|
||||||
customModalGasPriceInHex, |
|
||||||
customModalGasLimitInHex, |
|
||||||
insufficientBalance, |
|
||||||
customPriceIsSafe, |
|
||||||
isSpeedUp, |
|
||||||
transactionFee, |
|
||||||
customGasLimitMessage, |
|
||||||
minimumGasLimit, |
|
||||||
customPriceIsExcessive, |
|
||||||
} = this.props; |
|
||||||
|
|
||||||
return ( |
|
||||||
<div className="advanced-tab"> |
|
||||||
{this.renderDataSummary(transactionFee)} |
|
||||||
<div className="advanced-tab__fee-chart"> |
|
||||||
<div className="advanced-tab__gas-inputs"> |
|
||||||
<AdvancedGasInputs |
|
||||||
updateCustomGasPrice={updateCustomGasPrice} |
|
||||||
updateCustomGasLimit={updateCustomGasLimit} |
|
||||||
customGasPrice={customModalGasPriceInHex} |
|
||||||
customGasLimit={customModalGasLimitInHex} |
|
||||||
insufficientBalance={insufficientBalance} |
|
||||||
customPriceIsSafe={customPriceIsSafe} |
|
||||||
isSpeedUp={isSpeedUp} |
|
||||||
customGasLimitMessage={customGasLimitMessage} |
|
||||||
minimumGasLimit={minimumGasLimit} |
|
||||||
customPriceIsExcessive={customPriceIsExcessive} |
|
||||||
/> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
@ -1 +0,0 @@ |
|||||||
export { default } from './advanced-tab-content.component'; |
|
@ -1,112 +0,0 @@ |
|||||||
.advanced-tab { |
|
||||||
display: flex; |
|
||||||
flex-flow: column; |
|
||||||
|
|
||||||
&__transaction-data-summary { |
|
||||||
padding-left: 24px; |
|
||||||
padding-right: 24px; |
|
||||||
} |
|
||||||
|
|
||||||
&__transaction-data-summary { |
|
||||||
display: flex; |
|
||||||
flex-flow: column; |
|
||||||
color: var(--color-text-alternative); |
|
||||||
margin-top: 12px; |
|
||||||
padding-left: 18px; |
|
||||||
padding-right: 18px; |
|
||||||
|
|
||||||
&__titles, |
|
||||||
&__container { |
|
||||||
@include H7; |
|
||||||
|
|
||||||
display: flex; |
|
||||||
flex-flow: row; |
|
||||||
justify-content: space-between; |
|
||||||
color: var(--color-text-muted); |
|
||||||
} |
|
||||||
|
|
||||||
&__container { |
|
||||||
@include Paragraph; |
|
||||||
|
|
||||||
margin-top: 0; |
|
||||||
} |
|
||||||
|
|
||||||
&__fee { |
|
||||||
@include Paragraph; |
|
||||||
|
|
||||||
color: var(--color-text-alternative); |
|
||||||
} |
|
||||||
|
|
||||||
&__time-remaining { |
|
||||||
@include Paragraph; |
|
||||||
|
|
||||||
/*rtl:ignore*/ |
|
||||||
direction: ltr; |
|
||||||
color: var(--color-text-alternative); |
|
||||||
|
|
||||||
.minutes-num, |
|
||||||
.seconds-num { |
|
||||||
@include Paragraph; |
|
||||||
} |
|
||||||
|
|
||||||
.seconds-num { |
|
||||||
@include Paragraph; |
|
||||||
|
|
||||||
margin-left: 7px; |
|
||||||
} |
|
||||||
|
|
||||||
.minutes-label, |
|
||||||
.seconds-label { |
|
||||||
@include Paragraph; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&__fee-chart { |
|
||||||
margin-top: 8px; |
|
||||||
height: 265px; |
|
||||||
background: var(--color-background-alternative); |
|
||||||
border-bottom: 1px solid var(--color-border-muted); |
|
||||||
border-top: 1px solid var(--color-border-muted); |
|
||||||
position: relative; |
|
||||||
|
|
||||||
&__title { |
|
||||||
@include H7; |
|
||||||
|
|
||||||
color: var(--color-text-alternative); |
|
||||||
margin-left: 22px; |
|
||||||
} |
|
||||||
|
|
||||||
&__speed-buttons { |
|
||||||
@include H8; |
|
||||||
|
|
||||||
position: absolute; |
|
||||||
bottom: 13px; |
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
padding-left: 20px; |
|
||||||
padding-right: 19px; |
|
||||||
width: 100%; |
|
||||||
color: var(--color-text-alternative); |
|
||||||
} |
|
||||||
|
|
||||||
.loading-overlay { |
|
||||||
height: auto; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&__slider-container { |
|
||||||
padding-left: 27px; |
|
||||||
padding-right: 27px; |
|
||||||
} |
|
||||||
|
|
||||||
&__gas-inputs { |
|
||||||
display: flex; |
|
||||||
flex-flow: row; |
|
||||||
justify-content: space-between; |
|
||||||
margin-left: 20px; |
|
||||||
margin-right: 10px; |
|
||||||
margin-top: 10px; |
|
||||||
margin-bottom: 20px; |
|
||||||
} |
|
||||||
} |
|
@ -1,103 +0,0 @@ |
|||||||
import React from 'react'; |
|
||||||
import GasPriceButtonGroup from '../../gas-price-button-group'; |
|
||||||
import Loading from '../../../../ui/loading-screen'; |
|
||||||
import { GAS_ESTIMATE_TYPES } from '../../../../../helpers/constants/common'; |
|
||||||
import { shallowWithContext } from '../../../../../../test/lib/render-helpers'; |
|
||||||
import BasicTabContent from './basic-tab-content.component'; |
|
||||||
|
|
||||||
const mockGasPriceButtonGroupProps = { |
|
||||||
buttonDataLoading: false, |
|
||||||
className: 'gas-price-button-group', |
|
||||||
gasButtonInfo: [ |
|
||||||
{ |
|
||||||
feeInPrimaryCurrency: '$0.52', |
|
||||||
feeInSecondaryCurrency: '0.0048 ETH', |
|
||||||
timeEstimate: '~ 1 min 0 sec', |
|
||||||
priceInHexWei: '0xa1b2c3f', |
|
||||||
gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, |
|
||||||
}, |
|
||||||
{ |
|
||||||
feeInPrimaryCurrency: '$0.39', |
|
||||||
feeInSecondaryCurrency: '0.004 ETH', |
|
||||||
timeEstimate: '~ 1 min 30 sec', |
|
||||||
priceInHexWei: '0xa1b2c39', |
|
||||||
gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, |
|
||||||
}, |
|
||||||
{ |
|
||||||
feeInPrimaryCurrency: '$0.30', |
|
||||||
feeInSecondaryCurrency: '0.00354 ETH', |
|
||||||
timeEstimate: '~ 2 min 1 sec', |
|
||||||
priceInHexWei: '0xa1b2c30', |
|
||||||
gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, |
|
||||||
}, |
|
||||||
], |
|
||||||
handleGasPriceSelection: ({ gasPrice }) => |
|
||||||
console.log('NewPrice: ', gasPrice), |
|
||||||
noButtonActiveByDefault: true, |
|
||||||
showCheck: true, |
|
||||||
}; |
|
||||||
|
|
||||||
describe('BasicTabContent Component', () => { |
|
||||||
describe('render', () => { |
|
||||||
let wrapper; |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
wrapper = shallowWithContext( |
|
||||||
<BasicTabContent |
|
||||||
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} |
|
||||||
/>, |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should have a title', () => { |
|
||||||
expect( |
|
||||||
wrapper |
|
||||||
.find('.basic-tab-content') |
|
||||||
.childAt(0) |
|
||||||
.hasClass('basic-tab-content__title'), |
|
||||||
).toStrictEqual(true); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render a GasPriceButtonGroup compenent', () => { |
|
||||||
expect(wrapper.find(GasPriceButtonGroup)).toHaveLength(1); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should pass correct props to GasPriceButtonGroup', () => { |
|
||||||
const { |
|
||||||
buttonDataLoading, |
|
||||||
className, |
|
||||||
gasButtonInfo, |
|
||||||
handleGasPriceSelection, |
|
||||||
noButtonActiveByDefault, |
|
||||||
showCheck, |
|
||||||
} = wrapper.find(GasPriceButtonGroup).props(); |
|
||||||
expect(wrapper.find(GasPriceButtonGroup)).toHaveLength(1); |
|
||||||
expect(buttonDataLoading).toStrictEqual( |
|
||||||
mockGasPriceButtonGroupProps.buttonDataLoading, |
|
||||||
); |
|
||||||
expect(className).toStrictEqual(mockGasPriceButtonGroupProps.className); |
|
||||||
expect(noButtonActiveByDefault).toStrictEqual( |
|
||||||
mockGasPriceButtonGroupProps.noButtonActiveByDefault, |
|
||||||
); |
|
||||||
expect(showCheck).toStrictEqual(mockGasPriceButtonGroupProps.showCheck); |
|
||||||
expect(gasButtonInfo).toStrictEqual( |
|
||||||
mockGasPriceButtonGroupProps.gasButtonInfo, |
|
||||||
); |
|
||||||
expect(handleGasPriceSelection).toStrictEqual( |
|
||||||
mockGasPriceButtonGroupProps.handleGasPriceSelection, |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render a loading component instead of the GasPriceButtonGroup if gasPriceButtonGroupProps.loading is true', () => { |
|
||||||
wrapper.setProps({ |
|
||||||
gasPriceButtonGroupProps: { |
|
||||||
...mockGasPriceButtonGroupProps, |
|
||||||
loading: true, |
|
||||||
}, |
|
||||||
}); |
|
||||||
|
|
||||||
expect(wrapper.find(GasPriceButtonGroup)).toHaveLength(0); |
|
||||||
expect(wrapper.find(Loading)).toHaveLength(1); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,42 +0,0 @@ |
|||||||
import React, { Component } from 'react'; |
|
||||||
import PropTypes from 'prop-types'; |
|
||||||
import Loading from '../../../../ui/loading-screen'; |
|
||||||
import GasPriceButtonGroup from '../../gas-price-button-group'; |
|
||||||
|
|
||||||
export default class BasicTabContent extends Component { |
|
||||||
static contextTypes = { |
|
||||||
t: PropTypes.func, |
|
||||||
}; |
|
||||||
|
|
||||||
static propTypes = { |
|
||||||
gasPriceButtonGroupProps: PropTypes.object, |
|
||||||
}; |
|
||||||
|
|
||||||
render() { |
|
||||||
const { t } = this.context; |
|
||||||
const { gasPriceButtonGroupProps } = this.props; |
|
||||||
|
|
||||||
return ( |
|
||||||
<div className="basic-tab-content"> |
|
||||||
<div className="basic-tab-content__title"> |
|
||||||
{t('estimatedProcessingTimes')} |
|
||||||
</div> |
|
||||||
<div className="basic-tab-content__blurb"> |
|
||||||
{t('selectAHigherGasFee')} |
|
||||||
</div> |
|
||||||
{gasPriceButtonGroupProps.loading ? ( |
|
||||||
<Loading /> |
|
||||||
) : ( |
|
||||||
<GasPriceButtonGroup |
|
||||||
className="gas-price-button-group--alt" |
|
||||||
showCheck |
|
||||||
{...gasPriceButtonGroupProps} |
|
||||||
/> |
|
||||||
)} |
|
||||||
<div className="basic-tab-content__footer-blurb"> |
|
||||||
{t('acceleratingATransaction')} |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
@ -1 +0,0 @@ |
|||||||
export { default } from './basic-tab-content.component'; |
|
@ -1,33 +0,0 @@ |
|||||||
.basic-tab-content { |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
align-items: flex-start; |
|
||||||
padding-left: 21px; |
|
||||||
height: 324px; |
|
||||||
background: var(--color-background-alternative); |
|
||||||
border-bottom: 1px solid var(--color-border-default); |
|
||||||
|
|
||||||
&__title { |
|
||||||
@include Paragraph; |
|
||||||
|
|
||||||
margin-top: 19px; |
|
||||||
color: var(--color-text-default); |
|
||||||
} |
|
||||||
|
|
||||||
&__blurb { |
|
||||||
@include H7; |
|
||||||
|
|
||||||
width: 95%; |
|
||||||
color: var(--color-text-default); |
|
||||||
margin-top: 5px; |
|
||||||
margin-bottom: 15px; |
|
||||||
} |
|
||||||
|
|
||||||
&__footer-blurb { |
|
||||||
@include H7; |
|
||||||
|
|
||||||
width: 95%; |
|
||||||
color: var(--color-text-alternative); |
|
||||||
margin-top: 15px; |
|
||||||
} |
|
||||||
} |
|
@ -1,272 +0,0 @@ |
|||||||
import React from 'react'; |
|
||||||
import sinon from 'sinon'; |
|
||||||
import { shallowWithContext } from '../../../../../test/lib/render-helpers'; |
|
||||||
import { getGasFeeEstimatesAndStartPolling } from '../../../../store/actions'; |
|
||||||
|
|
||||||
import PageContainer from '../../../ui/page-container'; |
|
||||||
|
|
||||||
import { Tab } from '../../../ui/tabs'; |
|
||||||
import GasModalPageContainer from './gas-modal-page-container.component'; |
|
||||||
|
|
||||||
jest.mock('../../../../store/actions', () => ({ |
|
||||||
disconnectGasFeeEstimatePoller: jest.fn(), |
|
||||||
getGasFeeEstimatesAndStartPolling: jest |
|
||||||
.fn() |
|
||||||
.mockImplementation(() => Promise.resolve()), |
|
||||||
addPollingTokenToAppState: jest.fn(), |
|
||||||
})); |
|
||||||
|
|
||||||
const propsMethodSpies = { |
|
||||||
cancelAndClose: sinon.spy(), |
|
||||||
onSubmit: 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, |
|
||||||
newTotalFiat: 'mockNewTotalFiat', |
|
||||||
newTotalEth: 'mockNewTotalEth', |
|
||||||
}; |
|
||||||
const mockInfoRowProps = { |
|
||||||
originalTotalFiat: 'mockOriginalTotalFiat', |
|
||||||
originalTotalEth: 'mockOriginalTotalEth', |
|
||||||
newTotalFiat: 'mockNewTotalFiat', |
|
||||||
newTotalEth: 'mockNewTotalEth', |
|
||||||
sendAmount: 'mockSendAmount', |
|
||||||
transactionFee: 'mockTransactionFee', |
|
||||||
extraInfoRow: { label: 'mockLabel', value: 'mockValue' }, |
|
||||||
}; |
|
||||||
|
|
||||||
const GP = GasModalPageContainer.prototype; |
|
||||||
describe('GasModalPageContainer Component', () => { |
|
||||||
let wrapper; |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
wrapper = shallowWithContext( |
|
||||||
<GasModalPageContainer |
|
||||||
cancelAndClose={propsMethodSpies.cancelAndClose} |
|
||||||
onSubmit={propsMethodSpies.onSubmit} |
|
||||||
updateCustomGasPrice={() => 'mockupdateCustomGasPrice'} |
|
||||||
updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} |
|
||||||
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} |
|
||||||
infoRowProps={mockInfoRowProps} |
|
||||||
customGasPriceInHex="mockCustomGasPriceInHex" |
|
||||||
customGasLimitInHex="mockCustomGasLimitInHex" |
|
||||||
insufficientBalance={false} |
|
||||||
disableSave={false} |
|
||||||
customPriceIsExcessive={false} |
|
||||||
/>, |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
afterEach(() => { |
|
||||||
propsMethodSpies.cancelAndClose.resetHistory(); |
|
||||||
jest.clearAllMocks(); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('componentDidMount', () => { |
|
||||||
it('should call getGasFeeEstimatesAndStartPolling', () => { |
|
||||||
jest.clearAllMocks(); |
|
||||||
expect(getGasFeeEstimatesAndStartPolling).not.toHaveBeenCalled(); |
|
||||||
wrapper.instance().componentDidMount(); |
|
||||||
expect(getGasFeeEstimatesAndStartPolling).toHaveBeenCalled(); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('render', () => { |
|
||||||
it('should render a PageContainer compenent', () => { |
|
||||||
expect(wrapper.find(PageContainer)).toHaveLength(1); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should pass correct props to PageContainer', () => { |
|
||||||
const { title, subtitle, disabled } = wrapper.find(PageContainer).props(); |
|
||||||
expect(title).toStrictEqual('customGas'); |
|
||||||
expect(subtitle).toStrictEqual('customGasSubTitle'); |
|
||||||
expect(disabled).toStrictEqual(false); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should pass the correct onCancel and onClose methods to PageContainer', () => { |
|
||||||
const { onCancel, onClose } = wrapper.find(PageContainer).props(); |
|
||||||
expect(propsMethodSpies.cancelAndClose.callCount).toStrictEqual(0); |
|
||||||
onCancel(); |
|
||||||
expect(propsMethodSpies.cancelAndClose.callCount).toStrictEqual(1); |
|
||||||
onClose(); |
|
||||||
expect(propsMethodSpies.cancelAndClose.callCount).toStrictEqual(2); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should pass the correct renderTabs property to PageContainer', () => { |
|
||||||
jest |
|
||||||
.spyOn(GasModalPageContainer.prototype, 'renderTabs') |
|
||||||
.mockImplementation(() => 'mockTabs'); |
|
||||||
const renderTabsWrapperTester = shallowWithContext( |
|
||||||
<GasModalPageContainer customPriceIsExcessive={false} />, |
|
||||||
{ context: { t: (str1, str2) => (str2 ? str1 + str2 : str1) } }, |
|
||||||
); |
|
||||||
const { tabsComponent } = renderTabsWrapperTester |
|
||||||
.find(PageContainer) |
|
||||||
.props(); |
|
||||||
expect(tabsComponent).toStrictEqual('mockTabs'); |
|
||||||
GasModalPageContainer.prototype.renderTabs.mockClear(); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('renderTabs', () => { |
|
||||||
beforeEach(() => { |
|
||||||
sinon.spy(GP, 'renderBasicTabContent'); |
|
||||||
sinon.spy(GP, 'renderAdvancedTabContent'); |
|
||||||
sinon.spy(GP, 'renderInfoRows'); |
|
||||||
}); |
|
||||||
|
|
||||||
afterEach(() => { |
|
||||||
GP.renderBasicTabContent.restore(); |
|
||||||
GP.renderAdvancedTabContent.restore(); |
|
||||||
GP.renderInfoRows.restore(); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render a Tabs component with "Basic" and "Advanced" tabs', () => { |
|
||||||
const renderTabsResult = wrapper.instance().renderTabs(); |
|
||||||
const renderedTabs = shallowWithContext(renderTabsResult); |
|
||||||
expect(renderedTabs.props().className).toStrictEqual('tabs'); |
|
||||||
|
|
||||||
const tabs = renderedTabs.find(Tab); |
|
||||||
expect(tabs).toHaveLength(2); |
|
||||||
|
|
||||||
expect(tabs.at(0).props().name).toStrictEqual('basic'); |
|
||||||
expect(tabs.at(1).props().name).toStrictEqual('advanced'); |
|
||||||
|
|
||||||
expect(tabs.at(0).childAt(0).props().className).toStrictEqual( |
|
||||||
'gas-modal-content', |
|
||||||
); |
|
||||||
expect(tabs.at(1).childAt(0).props().className).toStrictEqual( |
|
||||||
'gas-modal-content', |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should call renderInfoRows with the expected props', () => { |
|
||||||
expect(GP.renderInfoRows.callCount).toStrictEqual(0); |
|
||||||
|
|
||||||
wrapper.instance().renderTabs(); |
|
||||||
|
|
||||||
expect(GP.renderInfoRows.callCount).toStrictEqual(2); |
|
||||||
|
|
||||||
expect(GP.renderInfoRows.getCall(0).args).toStrictEqual([ |
|
||||||
'mockNewTotalFiat', |
|
||||||
'mockNewTotalEth', |
|
||||||
'mockSendAmount', |
|
||||||
'mockTransactionFee', |
|
||||||
]); |
|
||||||
expect(GP.renderInfoRows.getCall(1).args).toStrictEqual([ |
|
||||||
'mockNewTotalFiat', |
|
||||||
'mockNewTotalEth', |
|
||||||
'mockSendAmount', |
|
||||||
'mockTransactionFee', |
|
||||||
]); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should not render the basic tab if hideBasic is true', () => { |
|
||||||
wrapper = shallowWithContext( |
|
||||||
<GasModalPageContainer |
|
||||||
cancelAndClose={propsMethodSpies.cancelAndClose} |
|
||||||
onSubmit={propsMethodSpies.onSubmit} |
|
||||||
updateCustomGasPrice={() => 'mockupdateCustomGasPrice'} |
|
||||||
updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} |
|
||||||
gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} |
|
||||||
infoRowProps={mockInfoRowProps} |
|
||||||
customGasPriceInHex="mockCustomGasPriceInHex" |
|
||||||
customGasLimitInHex="mockCustomGasLimitInHex" |
|
||||||
insufficientBalance={false} |
|
||||||
disableSave={false} |
|
||||||
customPriceIsExcessive={false} |
|
||||||
hideBasic |
|
||||||
/>, |
|
||||||
); |
|
||||||
const renderTabsResult = wrapper.instance().renderTabs(); |
|
||||||
|
|
||||||
const renderedTabs = shallowWithContext(renderTabsResult); |
|
||||||
const tabs = renderedTabs.find(Tab); |
|
||||||
expect(tabs).toHaveLength(1); |
|
||||||
expect(tabs.at(0).props().name).toStrictEqual('advanced'); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('renderBasicTabContent', () => { |
|
||||||
it('should render', () => { |
|
||||||
const renderBasicTabContentResult = wrapper |
|
||||||
.instance() |
|
||||||
.renderBasicTabContent(mockGasPriceButtonGroupProps); |
|
||||||
|
|
||||||
expect( |
|
||||||
renderBasicTabContentResult.props.gasPriceButtonGroupProps, |
|
||||||
).toStrictEqual(mockGasPriceButtonGroupProps); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('renderInfoRows', () => { |
|
||||||
it('should render the info rows with the passed data', () => { |
|
||||||
const baseClassName = 'gas-modal-content__info-row'; |
|
||||||
const renderedInfoRowsContainer = shallowWithContext( |
|
||||||
wrapper |
|
||||||
.instance() |
|
||||||
.renderInfoRows( |
|
||||||
'mockNewTotalFiat', |
|
||||||
' mockNewTotalEth', |
|
||||||
' mockSendAmount', |
|
||||||
' mockTransactionFee', |
|
||||||
), |
|
||||||
); |
|
||||||
|
|
||||||
expect( |
|
||||||
renderedInfoRowsContainer.childAt(0).hasClass(baseClassName), |
|
||||||
).toStrictEqual(true); |
|
||||||
|
|
||||||
const renderedInfoRows = renderedInfoRowsContainer.childAt(0).children(); |
|
||||||
expect(renderedInfoRows).toHaveLength(4); |
|
||||||
expect( |
|
||||||
renderedInfoRows.at(0).hasClass(`${baseClassName}__send-info`), |
|
||||||
).toStrictEqual(true); |
|
||||||
expect( |
|
||||||
renderedInfoRows.at(1).hasClass(`${baseClassName}__transaction-info`), |
|
||||||
).toStrictEqual(true); |
|
||||||
expect( |
|
||||||
renderedInfoRows.at(2).hasClass(`${baseClassName}__total-info`), |
|
||||||
).toStrictEqual(true); |
|
||||||
expect( |
|
||||||
renderedInfoRows.at(3).hasClass(`${baseClassName}__fiat-total-info`), |
|
||||||
).toStrictEqual(true); |
|
||||||
|
|
||||||
expect(renderedInfoRows.at(0).text()).toStrictEqual( |
|
||||||
'sendAmount mockSendAmount', |
|
||||||
); |
|
||||||
expect(renderedInfoRows.at(1).text()).toStrictEqual( |
|
||||||
'transactionFee mockTransactionFee', |
|
||||||
); |
|
||||||
expect(renderedInfoRows.at(2).text()).toStrictEqual( |
|
||||||
'newTotal mockNewTotalEth', |
|
||||||
); |
|
||||||
expect(renderedInfoRows.at(3).text()).toStrictEqual('mockNewTotalFiat'); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,274 +0,0 @@ |
|||||||
import sinon from 'sinon'; |
|
||||||
|
|
||||||
import { hideModal } from '../../../../store/actions'; |
|
||||||
|
|
||||||
import { |
|
||||||
setCustomGasPrice, |
|
||||||
setCustomGasLimit, |
|
||||||
resetCustomData, |
|
||||||
} from '../../../../ducks/gas/gas.duck'; |
|
||||||
|
|
||||||
import { |
|
||||||
useCustomGas, |
|
||||||
updateGasLimit, |
|
||||||
updateGasPrice, |
|
||||||
} from '../../../../ducks/send'; |
|
||||||
|
|
||||||
let mapDispatchToProps; |
|
||||||
let mergeProps; |
|
||||||
|
|
||||||
jest.mock('react-redux', () => ({ |
|
||||||
connect: (_, md, mp) => { |
|
||||||
mapDispatchToProps = md; |
|
||||||
mergeProps = mp; |
|
||||||
return () => ({}); |
|
||||||
}, |
|
||||||
})); |
|
||||||
|
|
||||||
jest.mock('../../../../selectors', () => ({ |
|
||||||
getBasicGasEstimateLoadingStatus: (s) => |
|
||||||
`mockBasicGasEstimateLoadingStatus:${Object.keys(s).length}`, |
|
||||||
getRenderableBasicEstimateData: (s) => |
|
||||||
`mockRenderableBasicEstimateData:${Object.keys(s).length}`, |
|
||||||
getDefaultActiveButtonIndex: (a, b) => a + b, |
|
||||||
getCurrentEthBalance: (state) => state.metamask.balance || '0x0', |
|
||||||
getCustomGasPrice: (state) => state.gas.customData.price || '0x0', |
|
||||||
getCustomGasLimit: (state) => state.gas.customData.limit || '0x0', |
|
||||||
getCurrentCurrency: jest.fn().mockReturnValue('usd'), |
|
||||||
conversionRateSelector: jest.fn().mockReturnValue(50), |
|
||||||
getSendMaxModeState: jest.fn().mockReturnValue(false), |
|
||||||
getPreferences: jest.fn(() => ({ |
|
||||||
showFiatInTestnets: false, |
|
||||||
})), |
|
||||||
getIsMainnet: jest.fn().mockReturnValue(false), |
|
||||||
isCustomPriceSafe: jest.fn().mockReturnValue(true), |
|
||||||
})); |
|
||||||
|
|
||||||
jest.mock('../../../../store/actions', () => ({ |
|
||||||
hideModal: jest.fn(), |
|
||||||
updateTransaction: jest.fn(), |
|
||||||
})); |
|
||||||
|
|
||||||
jest.mock('../../../../ducks/metamask/metamask.js', () => ({ |
|
||||||
updateTransactionGasFees: jest.fn(), |
|
||||||
})); |
|
||||||
|
|
||||||
jest.mock('../../../../ducks/gas/gas.duck', () => ({ |
|
||||||
setCustomGasPrice: jest.fn(), |
|
||||||
setCustomGasLimit: jest.fn(), |
|
||||||
resetCustomData: jest.fn(), |
|
||||||
})); |
|
||||||
|
|
||||||
jest.mock('../../../../ducks/send', () => { |
|
||||||
const { ASSET_TYPES } = jest.requireActual( |
|
||||||
'../../../../../shared/constants/transaction', |
|
||||||
); |
|
||||||
return { |
|
||||||
useCustomGas: jest.fn(), |
|
||||||
updateGasLimit: jest.fn(), |
|
||||||
updateGasPrice: jest.fn(), |
|
||||||
getSendAsset: jest.fn(() => ({ type: ASSET_TYPES.NATIVE })), |
|
||||||
}; |
|
||||||
}); |
|
||||||
|
|
||||||
require('./gas-modal-page-container.container'); |
|
||||||
|
|
||||||
describe('gas-modal-page-container container', () => { |
|
||||||
describe('mapDispatchToProps()', () => { |
|
||||||
let dispatchSpy; |
|
||||||
let mapDispatchToPropsObject; |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
dispatchSpy = sinon.spy(); |
|
||||||
mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy); |
|
||||||
}); |
|
||||||
|
|
||||||
afterEach(() => { |
|
||||||
dispatchSpy.resetHistory(); |
|
||||||
jest.clearAllMocks(); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('useCustomGas()', () => { |
|
||||||
it('should dispatch a useCustomGas action', () => { |
|
||||||
mapDispatchToPropsObject.useCustomGas(); |
|
||||||
expect(dispatchSpy.calledOnce).toStrictEqual(true); |
|
||||||
expect(useCustomGas).toHaveBeenCalled(); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('cancelAndClose()', () => { |
|
||||||
it('should dispatch a hideModal action', () => { |
|
||||||
mapDispatchToPropsObject.cancelAndClose(); |
|
||||||
expect(dispatchSpy.calledTwice).toStrictEqual(true); |
|
||||||
expect(hideModal).toHaveBeenCalled(); |
|
||||||
expect(resetCustomData).toHaveBeenCalled(); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('updateCustomGasPrice()', () => { |
|
||||||
it('should dispatch a setCustomGasPrice action with the arg passed to updateCustomGasPrice hex prefixed', () => { |
|
||||||
mapDispatchToPropsObject.updateCustomGasPrice('ffff'); |
|
||||||
expect(dispatchSpy.calledOnce).toStrictEqual(true); |
|
||||||
expect(setCustomGasPrice).toHaveBeenCalled(); |
|
||||||
expect(setCustomGasPrice).toHaveBeenCalledWith('0xffff'); |
|
||||||
// expect(
|
|
||||||
// setCustomGasPrice.getCall(0).args[0],
|
|
||||||
// '0xffff',
|
|
||||||
// );
|
|
||||||
}); |
|
||||||
|
|
||||||
it('should dispatch a setCustomGasPrice action', () => { |
|
||||||
mapDispatchToPropsObject.updateCustomGasPrice('0xffff'); |
|
||||||
expect(dispatchSpy.calledOnce).toStrictEqual(true); |
|
||||||
expect(setCustomGasPrice).toHaveBeenCalled(); |
|
||||||
expect(setCustomGasPrice).toHaveBeenCalledWith('0xffff'); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('updateCustomGasLimit()', () => { |
|
||||||
it('should dispatch a setCustomGasLimit action', () => { |
|
||||||
mapDispatchToPropsObject.updateCustomGasLimit('0x10'); |
|
||||||
expect(dispatchSpy.calledOnce).toStrictEqual(true); |
|
||||||
expect(setCustomGasLimit).toHaveBeenCalled(); |
|
||||||
expect(setCustomGasLimit).toHaveBeenCalledWith('0x10'); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('setGasData()', () => { |
|
||||||
it('should dispatch a updateGasPrice and updateGasLimit action with the correct props', () => { |
|
||||||
mapDispatchToPropsObject.setGasData('ffff', 'aaaa'); |
|
||||||
expect(dispatchSpy.calledTwice).toStrictEqual(true); |
|
||||||
expect(updateGasPrice).toHaveBeenCalled(); |
|
||||||
expect(updateGasLimit).toHaveBeenCalled(); |
|
||||||
expect(updateGasLimit).toHaveBeenCalledWith('ffff'); |
|
||||||
expect(updateGasPrice).toHaveBeenCalledWith('aaaa'); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('mergeProps', () => { |
|
||||||
let stateProps; |
|
||||||
let dispatchProps; |
|
||||||
let ownProps; |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
stateProps = { |
|
||||||
gasPriceButtonGroupProps: { |
|
||||||
someGasPriceButtonGroupProp: 'foo', |
|
||||||
anotherGasPriceButtonGroupProp: 'bar', |
|
||||||
}, |
|
||||||
isConfirm: true, |
|
||||||
someOtherStateProp: 'baz', |
|
||||||
transaction: {}, |
|
||||||
}; |
|
||||||
dispatchProps = { |
|
||||||
updateCustomGasPrice: sinon.spy(), |
|
||||||
useCustomGas: sinon.spy(), |
|
||||||
setGasData: sinon.spy(), |
|
||||||
updateTransactionGasFees: sinon.spy(), |
|
||||||
someOtherDispatchProp: sinon.spy(), |
|
||||||
createSpeedUpTransaction: sinon.spy(), |
|
||||||
hideModal: sinon.spy(), |
|
||||||
cancelAndClose: sinon.spy(), |
|
||||||
}; |
|
||||||
ownProps = { someOwnProp: 123 }; |
|
||||||
}); |
|
||||||
|
|
||||||
it('should return the expected props when isConfirm is true', () => { |
|
||||||
const result = mergeProps(stateProps, dispatchProps, ownProps); |
|
||||||
|
|
||||||
expect(result.isConfirm).toStrictEqual(true); |
|
||||||
expect(result.someOtherStateProp).toStrictEqual('baz'); |
|
||||||
expect( |
|
||||||
result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, |
|
||||||
).toStrictEqual('foo'); |
|
||||||
expect( |
|
||||||
result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, |
|
||||||
).toStrictEqual('bar'); |
|
||||||
expect(result.someOwnProp).toStrictEqual(123); |
|
||||||
|
|
||||||
expect(dispatchProps.updateTransactionGasFees.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.setGasData.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.useCustomGas.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.hideModal.callCount).toStrictEqual(0); |
|
||||||
|
|
||||||
result.onSubmit(); |
|
||||||
|
|
||||||
expect(dispatchProps.updateTransactionGasFees.callCount).toStrictEqual(1); |
|
||||||
expect(dispatchProps.setGasData.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.useCustomGas.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.hideModal.callCount).toStrictEqual(1); |
|
||||||
|
|
||||||
expect(dispatchProps.updateCustomGasPrice.callCount).toStrictEqual(0); |
|
||||||
result.gasPriceButtonGroupProps.handleGasPriceSelection({ |
|
||||||
gasPrice: '0x0', |
|
||||||
}); |
|
||||||
expect(dispatchProps.updateCustomGasPrice.callCount).toStrictEqual(1); |
|
||||||
|
|
||||||
expect(dispatchProps.someOtherDispatchProp.callCount).toStrictEqual(0); |
|
||||||
result.someOtherDispatchProp(); |
|
||||||
expect(dispatchProps.someOtherDispatchProp.callCount).toStrictEqual(1); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should return the expected props when isConfirm is false', () => { |
|
||||||
const result = mergeProps( |
|
||||||
{ ...stateProps, isConfirm: false }, |
|
||||||
dispatchProps, |
|
||||||
ownProps, |
|
||||||
); |
|
||||||
|
|
||||||
expect(result.isConfirm).toStrictEqual(false); |
|
||||||
expect(result.someOtherStateProp).toStrictEqual('baz'); |
|
||||||
expect( |
|
||||||
result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, |
|
||||||
).toStrictEqual('foo'); |
|
||||||
expect( |
|
||||||
result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, |
|
||||||
).toStrictEqual('bar'); |
|
||||||
expect(result.someOwnProp).toStrictEqual(123); |
|
||||||
|
|
||||||
expect(dispatchProps.updateTransactionGasFees.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.setGasData.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.useCustomGas.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.cancelAndClose.callCount).toStrictEqual(0); |
|
||||||
|
|
||||||
result.onSubmit('mockNewLimit', 'mockNewPrice'); |
|
||||||
|
|
||||||
expect(dispatchProps.updateTransactionGasFees.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.setGasData.callCount).toStrictEqual(1); |
|
||||||
expect(dispatchProps.setGasData.getCall(0).args).toStrictEqual([ |
|
||||||
'mockNewLimit', |
|
||||||
'mockNewPrice', |
|
||||||
]); |
|
||||||
expect(dispatchProps.useCustomGas.callCount).toStrictEqual(1); |
|
||||||
expect(dispatchProps.cancelAndClose.callCount).toStrictEqual(1); |
|
||||||
|
|
||||||
expect(dispatchProps.updateCustomGasPrice.callCount).toStrictEqual(0); |
|
||||||
result.gasPriceButtonGroupProps.handleGasPriceSelection({ |
|
||||||
gasPrice: '0x0', |
|
||||||
}); |
|
||||||
expect(dispatchProps.updateCustomGasPrice.callCount).toStrictEqual(1); |
|
||||||
|
|
||||||
expect(dispatchProps.someOtherDispatchProp.callCount).toStrictEqual(0); |
|
||||||
result.someOtherDispatchProp(); |
|
||||||
expect(dispatchProps.someOtherDispatchProp.callCount).toStrictEqual(1); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should dispatch the expected actions from obSubmit when isConfirm is false and isSpeedUp is true', () => { |
|
||||||
const result = mergeProps( |
|
||||||
{ ...stateProps, isSpeedUp: true, isConfirm: false }, |
|
||||||
dispatchProps, |
|
||||||
ownProps, |
|
||||||
); |
|
||||||
|
|
||||||
result.onSubmit(); |
|
||||||
|
|
||||||
expect(dispatchProps.updateTransactionGasFees.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.setGasData.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.useCustomGas.callCount).toStrictEqual(0); |
|
||||||
expect(dispatchProps.cancelAndClose.callCount).toStrictEqual(1); |
|
||||||
|
|
||||||
expect(dispatchProps.createSpeedUpTransaction.callCount).toStrictEqual(1); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,240 +0,0 @@ |
|||||||
import React, { Component } from 'react'; |
|
||||||
import PropTypes from 'prop-types'; |
|
||||||
import PageContainer from '../../../ui/page-container'; |
|
||||||
import { Tabs, Tab } from '../../../ui/tabs'; |
|
||||||
import { |
|
||||||
disconnectGasFeeEstimatePoller, |
|
||||||
getGasFeeEstimatesAndStartPolling, |
|
||||||
addPollingTokenToAppState, |
|
||||||
removePollingTokenFromAppState, |
|
||||||
} from '../../../../store/actions'; |
|
||||||
import { EVENT } from '../../../../../shared/constants/metametrics'; |
|
||||||
import AdvancedTabContent from './advanced-tab-content'; |
|
||||||
import BasicTabContent from './basic-tab-content'; |
|
||||||
|
|
||||||
export default class GasModalPageContainer extends Component { |
|
||||||
static contextTypes = { |
|
||||||
t: PropTypes.func, |
|
||||||
trackEvent: PropTypes.func, |
|
||||||
}; |
|
||||||
|
|
||||||
static propTypes = { |
|
||||||
hideBasic: PropTypes.bool, |
|
||||||
updateCustomGasPrice: PropTypes.func, |
|
||||||
updateCustomGasLimit: PropTypes.func, |
|
||||||
insufficientBalance: PropTypes.bool, |
|
||||||
gasPriceButtonGroupProps: PropTypes.object, |
|
||||||
infoRowProps: PropTypes.shape({ |
|
||||||
originalTotalFiat: PropTypes.string, |
|
||||||
originalTotalEth: PropTypes.string, |
|
||||||
newTotalFiat: PropTypes.string, |
|
||||||
newTotalEth: PropTypes.string, |
|
||||||
sendAmount: PropTypes.string, |
|
||||||
transactionFee: PropTypes.string, |
|
||||||
}), |
|
||||||
onSubmit: PropTypes.func, |
|
||||||
customModalGasPriceInHex: PropTypes.string, |
|
||||||
customModalGasLimitInHex: PropTypes.string, |
|
||||||
cancelAndClose: PropTypes.func, |
|
||||||
customPriceIsSafe: PropTypes.bool, |
|
||||||
isSpeedUp: PropTypes.bool, |
|
||||||
isRetry: PropTypes.bool, |
|
||||||
disableSave: PropTypes.bool, |
|
||||||
customPriceIsExcessive: PropTypes.bool.isRequired, |
|
||||||
}; |
|
||||||
|
|
||||||
constructor(props) { |
|
||||||
super(props); |
|
||||||
this.state = { |
|
||||||
pollingToken: undefined, |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
componentDidMount() { |
|
||||||
this._isMounted = true; |
|
||||||
getGasFeeEstimatesAndStartPolling().then((pollingToken) => { |
|
||||||
if (this._isMounted) { |
|
||||||
addPollingTokenToAppState(pollingToken); |
|
||||||
this.setState({ pollingToken }); |
|
||||||
} else { |
|
||||||
disconnectGasFeeEstimatePoller(pollingToken); |
|
||||||
removePollingTokenFromAppState(pollingToken); |
|
||||||
} |
|
||||||
}); |
|
||||||
window.addEventListener('beforeunload', this._beforeUnload); |
|
||||||
} |
|
||||||
|
|
||||||
_beforeUnload = () => { |
|
||||||
this._isMounted = false; |
|
||||||
if (this.state.pollingToken) { |
|
||||||
disconnectGasFeeEstimatePoller(this.state.pollingToken); |
|
||||||
removePollingTokenFromAppState(this.state.pollingToken); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
componentWillUnmount() { |
|
||||||
this._beforeUnload(); |
|
||||||
window.removeEventListener('beforeunload', this._beforeUnload); |
|
||||||
} |
|
||||||
|
|
||||||
renderBasicTabContent(gasPriceButtonGroupProps) { |
|
||||||
return ( |
|
||||||
<BasicTabContent gasPriceButtonGroupProps={gasPriceButtonGroupProps} /> |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
renderAdvancedTabContent() { |
|
||||||
const { |
|
||||||
updateCustomGasPrice, |
|
||||||
updateCustomGasLimit, |
|
||||||
customModalGasPriceInHex, |
|
||||||
customModalGasLimitInHex, |
|
||||||
insufficientBalance, |
|
||||||
customPriceIsSafe, |
|
||||||
isSpeedUp, |
|
||||||
isRetry, |
|
||||||
customPriceIsExcessive, |
|
||||||
infoRowProps: { transactionFee }, |
|
||||||
} = this.props; |
|
||||||
|
|
||||||
return ( |
|
||||||
<AdvancedTabContent |
|
||||||
updateCustomGasPrice={updateCustomGasPrice} |
|
||||||
updateCustomGasLimit={updateCustomGasLimit} |
|
||||||
customModalGasPriceInHex={customModalGasPriceInHex} |
|
||||||
customModalGasLimitInHex={customModalGasLimitInHex} |
|
||||||
transactionFee={transactionFee} |
|
||||||
insufficientBalance={insufficientBalance} |
|
||||||
customPriceIsSafe={customPriceIsSafe} |
|
||||||
isSpeedUp={isSpeedUp} |
|
||||||
isRetry={isRetry} |
|
||||||
customPriceIsExcessive={customPriceIsExcessive} |
|
||||||
/> |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
renderInfoRows(newTotalFiat, newTotalEth, sendAmount, transactionFee) { |
|
||||||
return ( |
|
||||||
<div className="gas-modal-content__info-row-wrapper"> |
|
||||||
<div className="gas-modal-content__info-row"> |
|
||||||
<div className="gas-modal-content__info-row__send-info"> |
|
||||||
<span className="gas-modal-content__info-row__send-info__label"> |
|
||||||
{this.context.t('sendAmount')} |
|
||||||
</span> |
|
||||||
<span className="gas-modal-content__info-row__send-info__value"> |
|
||||||
{sendAmount} |
|
||||||
</span> |
|
||||||
</div> |
|
||||||
<div className="gas-modal-content__info-row__transaction-info"> |
|
||||||
<span className="gas-modal-content__info-row__transaction-info__label"> |
|
||||||
{this.context.t('transactionFee')} |
|
||||||
</span> |
|
||||||
<span className="gas-modal-content__info-row__transaction-info__value"> |
|
||||||
{transactionFee} |
|
||||||
</span> |
|
||||||
</div> |
|
||||||
<div className="gas-modal-content__info-row__total-info"> |
|
||||||
<span className="gas-modal-content__info-row__total-info__label"> |
|
||||||
{this.context.t('newTotal')} |
|
||||||
</span> |
|
||||||
<span className="gas-modal-content__info-row__total-info__value"> |
|
||||||
{newTotalEth} |
|
||||||
</span> |
|
||||||
</div> |
|
||||||
<div className="gas-modal-content__info-row__fiat-total-info"> |
|
||||||
<span className="gas-modal-content__info-row__fiat-total-info__value"> |
|
||||||
{newTotalFiat} |
|
||||||
</span> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
renderTabs() { |
|
||||||
const { |
|
||||||
gasPriceButtonGroupProps, |
|
||||||
hideBasic, |
|
||||||
infoRowProps: { newTotalFiat, newTotalEth, sendAmount, transactionFee }, |
|
||||||
} = this.props; |
|
||||||
|
|
||||||
let tabsToRender; |
|
||||||
if (hideBasic) { |
|
||||||
tabsToRender = [ |
|
||||||
{ |
|
||||||
name: this.context.t('advanced'), |
|
||||||
content: this.renderAdvancedTabContent(), |
|
||||||
}, |
|
||||||
]; |
|
||||||
} else { |
|
||||||
tabsToRender = [ |
|
||||||
{ |
|
||||||
name: this.context.t('basic'), |
|
||||||
content: this.renderBasicTabContent(gasPriceButtonGroupProps), |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: this.context.t('advanced'), |
|
||||||
content: this.renderAdvancedTabContent(), |
|
||||||
}, |
|
||||||
]; |
|
||||||
} |
|
||||||
|
|
||||||
return ( |
|
||||||
<Tabs> |
|
||||||
{tabsToRender.map(({ name, content }, i) => ( |
|
||||||
<Tab name={name} key={`gas-modal-tab-${i}`}> |
|
||||||
<div className="gas-modal-content"> |
|
||||||
{content} |
|
||||||
{this.renderInfoRows( |
|
||||||
newTotalFiat, |
|
||||||
newTotalEth, |
|
||||||
sendAmount, |
|
||||||
transactionFee, |
|
||||||
)} |
|
||||||
</div> |
|
||||||
</Tab> |
|
||||||
))} |
|
||||||
</Tabs> |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
render() { |
|
||||||
const { |
|
||||||
cancelAndClose, |
|
||||||
onSubmit, |
|
||||||
customModalGasPriceInHex, |
|
||||||
customModalGasLimitInHex, |
|
||||||
disableSave, |
|
||||||
isSpeedUp, |
|
||||||
} = this.props; |
|
||||||
|
|
||||||
return ( |
|
||||||
<div className="gas-modal-page-container"> |
|
||||||
<PageContainer |
|
||||||
title={this.context.t('customGas')} |
|
||||||
subtitle={this.context.t('customGasSubTitle')} |
|
||||||
tabsComponent={this.renderTabs()} |
|
||||||
disabled={disableSave} |
|
||||||
onCancel={() => cancelAndClose()} |
|
||||||
onClose={() => cancelAndClose()} |
|
||||||
onSubmit={() => { |
|
||||||
if (isSpeedUp) { |
|
||||||
this.context.trackEvent({ |
|
||||||
category: EVENT.CATEGORIES.NAVIGATION, |
|
||||||
event: 'Saved "Speed Up"', |
|
||||||
properties: { |
|
||||||
action: 'Activity Log', |
|
||||||
legacy_event: true, |
|
||||||
}, |
|
||||||
}); |
|
||||||
} |
|
||||||
onSubmit(customModalGasLimitInHex, customModalGasPriceInHex); |
|
||||||
}} |
|
||||||
submitText={this.context.t('save')} |
|
||||||
headerCloseText={this.context.t('close')} |
|
||||||
hideCancel |
|
||||||
/> |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
@ -1,330 +0,0 @@ |
|||||||
import { connect } from 'react-redux'; |
|
||||||
import { addHexPrefix } from '../../../../../app/scripts/lib/util'; |
|
||||||
import { |
|
||||||
hideModal, |
|
||||||
createRetryTransaction, |
|
||||||
createSpeedUpTransaction, |
|
||||||
} from '../../../../store/actions'; |
|
||||||
import { |
|
||||||
setCustomGasPrice, |
|
||||||
setCustomGasLimit, |
|
||||||
resetCustomData, |
|
||||||
} from '../../../../ducks/gas/gas.duck'; |
|
||||||
import { |
|
||||||
getSendMaxModeState, |
|
||||||
getGasLimit, |
|
||||||
getGasPrice, |
|
||||||
getSendAmount, |
|
||||||
updateGasLimit, |
|
||||||
updateGasPrice, |
|
||||||
useCustomGas, |
|
||||||
getSendAsset, |
|
||||||
} from '../../../../ducks/send'; |
|
||||||
import { |
|
||||||
conversionRateSelector as getConversionRate, |
|
||||||
getCurrentCurrency, |
|
||||||
getCurrentEthBalance, |
|
||||||
getIsMainnet, |
|
||||||
getIsTestnet, |
|
||||||
getBasicGasEstimateLoadingStatus, |
|
||||||
getCustomGasLimit, |
|
||||||
getCustomGasPrice, |
|
||||||
getDefaultActiveButtonIndex, |
|
||||||
getRenderableBasicEstimateData, |
|
||||||
isCustomPriceSafe, |
|
||||||
isCustomPriceSafeForCustomNetwork, |
|
||||||
getAveragePriceEstimateInHexWEI, |
|
||||||
isCustomPriceExcessive, |
|
||||||
getIsGasEstimatesFetched, |
|
||||||
getShouldShowFiat, |
|
||||||
getIsCustomNetworkGasPriceFetched, |
|
||||||
} from '../../../../selectors'; |
|
||||||
|
|
||||||
import { |
|
||||||
addHexes, |
|
||||||
subtractHexWEIsToDec, |
|
||||||
getValueFromWeiHex, |
|
||||||
sumHexWEIsToRenderableFiat, |
|
||||||
} from '../../../../helpers/utils/conversions.util'; |
|
||||||
import { formatETHFee } from '../../../../helpers/utils/formatters'; |
|
||||||
import { isBalanceSufficient } from '../../../../pages/send/send.utils'; |
|
||||||
import { MIN_GAS_LIMIT_DEC } from '../../../../pages/send/send.constants'; |
|
||||||
import { |
|
||||||
ASSET_TYPES, |
|
||||||
TRANSACTION_STATUSES, |
|
||||||
} from '../../../../../shared/constants/transaction'; |
|
||||||
import { GAS_LIMITS } from '../../../../../shared/constants/gas'; |
|
||||||
import { updateGasFees } from '../../../../ducks/metamask/metamask'; |
|
||||||
import { |
|
||||||
calcGasTotal, |
|
||||||
hexWEIToDecGWEI, |
|
||||||
} from '../../../../../shared/lib/transactions-controller-utils'; |
|
||||||
import GasModalPageContainer from './gas-modal-page-container.component'; |
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => { |
|
||||||
const gasLimit = getGasLimit(state); |
|
||||||
const gasPrice = getGasPrice(state); |
|
||||||
const amount = getSendAmount(state); |
|
||||||
const { currentNetworkTxList } = state.metamask; |
|
||||||
const { modalState: { props: modalProps } = {} } = state.appState.modal || {}; |
|
||||||
const { txData = {} } = modalProps || {}; |
|
||||||
const { transaction = {}, onSubmit } = ownProps; |
|
||||||
const selectedTransaction = currentNetworkTxList.find( |
|
||||||
({ id }) => id === (transaction.id || txData.id), |
|
||||||
); |
|
||||||
const buttonDataLoading = getBasicGasEstimateLoadingStatus(state); |
|
||||||
const asset = getSendAsset(state); |
|
||||||
|
|
||||||
// a "default" txParams is used during the send flow, since the transaction doesn't exist yet in that case
|
|
||||||
const txParams = selectedTransaction?.txParams |
|
||||||
? selectedTransaction.txParams |
|
||||||
: { |
|
||||||
gas: gasLimit || GAS_LIMITS.SIMPLE, |
|
||||||
gasPrice: gasPrice || getAveragePriceEstimateInHexWEI(state, true), |
|
||||||
value: asset.type === ASSET_TYPES.TOKEN ? '0x0' : amount, |
|
||||||
}; |
|
||||||
|
|
||||||
const { gasPrice: currentGasPrice, gas: currentGasLimit } = txParams; |
|
||||||
const value = ownProps.transaction?.txParams?.value || txParams.value; |
|
||||||
const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice; |
|
||||||
const customModalGasLimitInHex = |
|
||||||
getCustomGasLimit(state) || currentGasLimit || GAS_LIMITS.SIMPLE; |
|
||||||
const customGasTotal = calcGasTotal( |
|
||||||
customModalGasLimitInHex, |
|
||||||
customModalGasPriceInHex, |
|
||||||
); |
|
||||||
|
|
||||||
const gasButtonInfo = getRenderableBasicEstimateData( |
|
||||||
state, |
|
||||||
customModalGasLimitInHex, |
|
||||||
); |
|
||||||
|
|
||||||
const currentCurrency = getCurrentCurrency(state); |
|
||||||
const conversionRate = getConversionRate(state); |
|
||||||
const newTotalFiat = sumHexWEIsToRenderableFiat( |
|
||||||
[value, customGasTotal], |
|
||||||
currentCurrency, |
|
||||||
conversionRate, |
|
||||||
); |
|
||||||
|
|
||||||
const { hideBasic } = state.appState.modal.modalState.props; |
|
||||||
|
|
||||||
const customGasPrice = calcCustomGasPrice(customModalGasPriceInHex); |
|
||||||
|
|
||||||
const maxModeOn = getSendMaxModeState(state); |
|
||||||
|
|
||||||
const balance = getCurrentEthBalance(state); |
|
||||||
|
|
||||||
const isMainnet = getIsMainnet(state); |
|
||||||
const isTestnet = getIsTestnet(state); |
|
||||||
const showFiat = getShouldShowFiat(state); |
|
||||||
|
|
||||||
const newTotalEth = |
|
||||||
maxModeOn && asset.type === ASSET_TYPES.NATIVE |
|
||||||
? sumHexWEIsToRenderableEth([balance, '0x0']) |
|
||||||
: sumHexWEIsToRenderableEth([value, customGasTotal]); |
|
||||||
|
|
||||||
const sendAmount = |
|
||||||
maxModeOn && asset.type === ASSET_TYPES.NATIVE |
|
||||||
? subtractHexWEIsFromRenderableEth(balance, customGasTotal) |
|
||||||
: sumHexWEIsToRenderableEth([value, '0x0']); |
|
||||||
|
|
||||||
const insufficientBalance = maxModeOn |
|
||||||
? false |
|
||||||
: !isBalanceSufficient({ |
|
||||||
amount: value, |
|
||||||
gasTotal: customGasTotal, |
|
||||||
balance, |
|
||||||
conversionRate, |
|
||||||
}); |
|
||||||
const isGasEstimate = getIsGasEstimatesFetched(state); |
|
||||||
const customNetworkEstimateWasFetched = |
|
||||||
getIsCustomNetworkGasPriceFetched(state); |
|
||||||
|
|
||||||
let customPriceIsSafe = true; |
|
||||||
if ((isMainnet || process.env.IN_TEST) && isGasEstimate) { |
|
||||||
customPriceIsSafe = isCustomPriceSafe(state); |
|
||||||
} else if ( |
|
||||||
!(isMainnet || process.env.IN_TEST || isTestnet) && |
|
||||||
customNetworkEstimateWasFetched |
|
||||||
) { |
|
||||||
customPriceIsSafe = isCustomPriceSafeForCustomNetwork(state); |
|
||||||
} |
|
||||||
|
|
||||||
return { |
|
||||||
hideBasic, |
|
||||||
isConfirm: isConfirm(state), |
|
||||||
customModalGasPriceInHex, |
|
||||||
customModalGasLimitInHex, |
|
||||||
customGasPrice, |
|
||||||
customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), |
|
||||||
customGasTotal, |
|
||||||
newTotalFiat, |
|
||||||
customPriceIsSafe, |
|
||||||
customPriceIsExcessive: isCustomPriceExcessive(state), |
|
||||||
maxModeOn, |
|
||||||
gasPriceButtonGroupProps: { |
|
||||||
buttonDataLoading, |
|
||||||
defaultActiveButtonIndex: getDefaultActiveButtonIndex( |
|
||||||
gasButtonInfo, |
|
||||||
customModalGasPriceInHex, |
|
||||||
), |
|
||||||
gasButtonInfo, |
|
||||||
}, |
|
||||||
infoRowProps: { |
|
||||||
originalTotalFiat: sumHexWEIsToRenderableFiat( |
|
||||||
[value, customGasTotal], |
|
||||||
currentCurrency, |
|
||||||
conversionRate, |
|
||||||
), |
|
||||||
originalTotalEth: sumHexWEIsToRenderableEth([value, customGasTotal]), |
|
||||||
newTotalFiat: showFiat ? newTotalFiat : '', |
|
||||||
newTotalEth, |
|
||||||
transactionFee: sumHexWEIsToRenderableEth(['0x0', customGasTotal]), |
|
||||||
sendAmount, |
|
||||||
}, |
|
||||||
transaction: txData || transaction, |
|
||||||
isSpeedUp: transaction.status === TRANSACTION_STATUSES.SUBMITTED, |
|
||||||
isRetry: transaction.status === TRANSACTION_STATUSES.FAILED, |
|
||||||
txId: transaction.id, |
|
||||||
insufficientBalance, |
|
||||||
isMainnet, |
|
||||||
balance, |
|
||||||
conversionRate, |
|
||||||
value, |
|
||||||
onSubmit, |
|
||||||
}; |
|
||||||
}; |
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => { |
|
||||||
const updateCustomGasPrice = (newPrice) => |
|
||||||
dispatch(setCustomGasPrice(addHexPrefix(newPrice))); |
|
||||||
|
|
||||||
return { |
|
||||||
cancelAndClose: () => { |
|
||||||
dispatch(resetCustomData()); |
|
||||||
dispatch(hideModal()); |
|
||||||
}, |
|
||||||
hideModal: () => dispatch(hideModal()), |
|
||||||
useCustomGas: () => dispatch(useCustomGas()), |
|
||||||
updateTransactionGasFees: (gasFees) => { |
|
||||||
dispatch(updateGasFees({ ...gasFees, expectHexWei: true })); |
|
||||||
}, |
|
||||||
updateCustomGasPrice, |
|
||||||
updateCustomGasLimit: (newLimit) => |
|
||||||
dispatch(setCustomGasLimit(addHexPrefix(newLimit))), |
|
||||||
setGasData: (newLimit, newPrice) => { |
|
||||||
dispatch(updateGasLimit(newLimit)); |
|
||||||
dispatch(updateGasPrice(newPrice)); |
|
||||||
}, |
|
||||||
createRetryTransaction: (txId, customGasSettings) => { |
|
||||||
return dispatch(createRetryTransaction(txId, customGasSettings)); |
|
||||||
}, |
|
||||||
createSpeedUpTransaction: (txId, customGasSettings) => { |
|
||||||
return dispatch(createSpeedUpTransaction(txId, customGasSettings)); |
|
||||||
}, |
|
||||||
}; |
|
||||||
}; |
|
||||||
|
|
||||||
const mergeProps = (stateProps, dispatchProps, ownProps) => { |
|
||||||
const { |
|
||||||
gasPriceButtonGroupProps, |
|
||||||
// eslint-disable-next-line no-shadow
|
|
||||||
isConfirm, |
|
||||||
txId, |
|
||||||
isSpeedUp, |
|
||||||
isRetry, |
|
||||||
insufficientBalance, |
|
||||||
customGasPrice, |
|
||||||
customGasLimit, |
|
||||||
transaction, |
|
||||||
} = stateProps; |
|
||||||
const { |
|
||||||
useCustomGas: dispatchUseCustomGas, |
|
||||||
setGasData: dispatchSetGasData, |
|
||||||
createSpeedUpTransaction: dispatchCreateSpeedUpTransaction, |
|
||||||
createRetryTransaction: dispatchCreateRetryTransaction, |
|
||||||
updateTransactionGasFees: dispatchUpdateTransactionGasFees, |
|
||||||
cancelAndClose: dispatchCancelAndClose, |
|
||||||
hideModal: dispatchHideModal, |
|
||||||
...otherDispatchProps |
|
||||||
} = dispatchProps; |
|
||||||
|
|
||||||
return { |
|
||||||
...stateProps, |
|
||||||
...otherDispatchProps, |
|
||||||
...ownProps, |
|
||||||
onSubmit: (gasLimit, gasPrice) => { |
|
||||||
if (ownProps.onSubmit) { |
|
||||||
dispatchCancelAndClose(); |
|
||||||
ownProps.onSubmit({ gasLimit, gasPrice }); |
|
||||||
return; |
|
||||||
} |
|
||||||
if (isConfirm) { |
|
||||||
dispatchUpdateTransactionGasFees({ |
|
||||||
gasLimit, |
|
||||||
gasPrice, |
|
||||||
transaction, |
|
||||||
isModal: true, |
|
||||||
}); |
|
||||||
dispatchHideModal(); |
|
||||||
dispatchCancelAndClose(); |
|
||||||
} else if (isSpeedUp) { |
|
||||||
dispatchCreateSpeedUpTransaction(txId, { gasPrice, gasLimit }); |
|
||||||
dispatchCancelAndClose(); |
|
||||||
} else if (isRetry) { |
|
||||||
dispatchCreateRetryTransaction(txId, { gasPrice, gasLimit }); |
|
||||||
dispatchCancelAndClose(); |
|
||||||
} else { |
|
||||||
dispatchSetGasData(gasLimit, gasPrice); |
|
||||||
dispatchUseCustomGas(); |
|
||||||
dispatchCancelAndClose(); |
|
||||||
} |
|
||||||
}, |
|
||||||
gasPriceButtonGroupProps: { |
|
||||||
...gasPriceButtonGroupProps, |
|
||||||
handleGasPriceSelection: ({ gasPrice }) => |
|
||||||
otherDispatchProps.updateCustomGasPrice(gasPrice), |
|
||||||
}, |
|
||||||
cancelAndClose: () => { |
|
||||||
dispatchCancelAndClose(); |
|
||||||
}, |
|
||||||
disableSave: |
|
||||||
insufficientBalance || |
|
||||||
(isSpeedUp && customGasPrice === 0) || |
|
||||||
customGasLimit < Number(MIN_GAS_LIMIT_DEC), |
|
||||||
}; |
|
||||||
}; |
|
||||||
|
|
||||||
export default connect( |
|
||||||
mapStateToProps, |
|
||||||
mapDispatchToProps, |
|
||||||
mergeProps, |
|
||||||
)(GasModalPageContainer); |
|
||||||
|
|
||||||
function isConfirm(state) { |
|
||||||
return Boolean(Object.keys(state.confirmTransaction.txData).length); |
|
||||||
} |
|
||||||
|
|
||||||
function calcCustomGasPrice(customGasPriceInHex) { |
|
||||||
return Number(hexWEIToDecGWEI(customGasPriceInHex)); |
|
||||||
} |
|
||||||
|
|
||||||
function calcCustomGasLimit(customGasLimitInHex) { |
|
||||||
return parseInt(customGasLimitInHex, 16); |
|
||||||
} |
|
||||||
|
|
||||||
function sumHexWEIsToRenderableEth(hexWEIs) { |
|
||||||
const hexWEIsSum = hexWEIs.filter(Boolean).reduce(addHexes); |
|
||||||
return formatETHFee( |
|
||||||
getValueFromWeiHex({ |
|
||||||
value: hexWEIsSum, |
|
||||||
toCurrency: 'ETH', |
|
||||||
numberOfDecimals: 6, |
|
||||||
}), |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
function subtractHexWEIsFromRenderableEth(aHexWEI, bHexWEI) { |
|
||||||
return formatETHFee(subtractHexWEIsToDec(aHexWEI, bHexWEI)); |
|
||||||
} |
|
@ -1 +0,0 @@ |
|||||||
export { default } from './gas-modal-page-container.container'; |
|
@ -1,160 +0,0 @@ |
|||||||
@import './advanced-tab-content/index'; |
|
||||||
@import './basic-tab-content/index'; |
|
||||||
|
|
||||||
.gas-modal-page-container { |
|
||||||
.page-container { |
|
||||||
max-width: 391px; |
|
||||||
min-height: 585px; |
|
||||||
overflow-y: initial; |
|
||||||
|
|
||||||
@include screen-sm-max { |
|
||||||
&__content { |
|
||||||
display: flex; |
|
||||||
overflow-y: initial; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&__header { |
|
||||||
padding: 0; |
|
||||||
padding-top: 16px; |
|
||||||
|
|
||||||
&--no-padding-bottom { |
|
||||||
padding-bottom: 0; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&__footer { |
|
||||||
footer { |
|
||||||
padding-top: 12px; |
|
||||||
padding-bottom: 12px; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&__header-close-text { |
|
||||||
@include H6; |
|
||||||
|
|
||||||
color: var(--color-primary-default); |
|
||||||
position: absolute; |
|
||||||
font-size: 0.75rem; |
|
||||||
top: 8px; |
|
||||||
right: 16px; |
|
||||||
cursor: pointer; |
|
||||||
overflow: hidden; |
|
||||||
width: min-content; |
|
||||||
} |
|
||||||
|
|
||||||
&__title { |
|
||||||
@include H5; |
|
||||||
|
|
||||||
color: var(--color-text-default); |
|
||||||
font-weight: 500; |
|
||||||
display: flex; |
|
||||||
justify-content: center; |
|
||||||
align-items: flex-start; |
|
||||||
margin-right: 0; |
|
||||||
} |
|
||||||
|
|
||||||
&__subtitle { |
|
||||||
display: none; |
|
||||||
} |
|
||||||
|
|
||||||
&__tab { |
|
||||||
margin-right: 0; |
|
||||||
} |
|
||||||
|
|
||||||
&__tabs { |
|
||||||
margin-top: 0; |
|
||||||
} |
|
||||||
|
|
||||||
&__tab { |
|
||||||
@include H6; |
|
||||||
|
|
||||||
width: 100%; |
|
||||||
|
|
||||||
&:last-of-type { |
|
||||||
margin-right: 0; |
|
||||||
} |
|
||||||
|
|
||||||
& button { |
|
||||||
font-size: unset; |
|
||||||
} |
|
||||||
|
|
||||||
&.tab--active button { |
|
||||||
color: var(--color-primary-default); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.gas-modal-content { |
|
||||||
@include screen-sm-max { |
|
||||||
width: 100%; |
|
||||||
} |
|
||||||
|
|
||||||
&__basic-tab { |
|
||||||
height: 219px; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
&__info-row, |
|
||||||
&__info-row--fade { |
|
||||||
@include H7; |
|
||||||
|
|
||||||
width: 100%; |
|
||||||
background: var(--color-background-alternative); |
|
||||||
padding: 15px 21px; |
|
||||||
display: flex; |
|
||||||
flex-flow: column; |
|
||||||
color: var(--color-text-alternative); |
|
||||||
|
|
||||||
&__send-info, |
|
||||||
&__transaction-info, |
|
||||||
&__total-info, |
|
||||||
&__fiat-total-info { |
|
||||||
display: flex; |
|
||||||
flex-flow: row; |
|
||||||
justify-content: space-between; |
|
||||||
} |
|
||||||
|
|
||||||
&__fiat-total-info { |
|
||||||
justify-content: flex-end; |
|
||||||
} |
|
||||||
|
|
||||||
&__total-info { |
|
||||||
&__label { |
|
||||||
@include Paragraph; |
|
||||||
|
|
||||||
@include screen-sm-max { |
|
||||||
@include H6; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&__value { |
|
||||||
@include Paragraph; |
|
||||||
|
|
||||||
font-weight: bold; |
|
||||||
|
|
||||||
@include screen-sm-max { |
|
||||||
@include H6; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&__transaction-info, |
|
||||||
&__send-info { |
|
||||||
&__label { |
|
||||||
@include H7; |
|
||||||
} |
|
||||||
|
|
||||||
&__value { |
|
||||||
@include H6; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&__info-row--fade { |
|
||||||
background: var(--color-background-default); |
|
||||||
color: var(--color-text-muted); |
|
||||||
border-top: 1px solid var(--color-border-muted); |
|
||||||
} |
|
||||||
} |
|
@ -1,308 +0,0 @@ |
|||||||
import React from 'react'; |
|
||||||
import sinon from 'sinon'; |
|
||||||
import { shallowWithContext } from '../../../../../test/lib/render-helpers'; |
|
||||||
import { GAS_ESTIMATE_TYPES } from '../../../../helpers/constants/common'; |
|
||||||
|
|
||||||
import ButtonGroup from '../../../ui/button-group'; |
|
||||||
import GasPriceButtonGroup from './gas-price-button-group.component'; |
|
||||||
|
|
||||||
describe('GasPriceButtonGroup Component', () => { |
|
||||||
let mockButtonPropsAndFlags; |
|
||||||
let mockGasPriceButtonGroupProps; |
|
||||||
let wrapper; |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
mockGasPriceButtonGroupProps = { |
|
||||||
buttonDataLoading: false, |
|
||||||
className: 'gas-price-button-group', |
|
||||||
gasButtonInfo: [ |
|
||||||
{ |
|
||||||
gasEstimateType: GAS_ESTIMATE_TYPES.SLOW, |
|
||||||
feeInPrimaryCurrency: '$0.52', |
|
||||||
feeInSecondaryCurrency: '0.0048 ETH', |
|
||||||
timeEstimate: '~ 1 min 0 sec', |
|
||||||
priceInHexWei: '0xa1b2c3f', |
|
||||||
}, |
|
||||||
{ |
|
||||||
gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, |
|
||||||
feeInPrimaryCurrency: '$0.39', |
|
||||||
feeInSecondaryCurrency: '0.004 ETH', |
|
||||||
timeEstimate: '~ 1 min 30 sec', |
|
||||||
priceInHexWei: '0xa1b2c39', |
|
||||||
}, |
|
||||||
{ |
|
||||||
gasEstimateType: GAS_ESTIMATE_TYPES.FAST, |
|
||||||
feeInPrimaryCurrency: '$0.30', |
|
||||||
feeInSecondaryCurrency: '0.00354 ETH', |
|
||||||
timeEstimate: '~ 2 min 1 sec', |
|
||||||
priceInHexWei: '0xa1b2c30', |
|
||||||
}, |
|
||||||
], |
|
||||||
handleGasPriceSelection: sinon.spy(), |
|
||||||
noButtonActiveByDefault: true, |
|
||||||
defaultActiveButtonIndex: 2, |
|
||||||
showCheck: true, |
|
||||||
}; |
|
||||||
|
|
||||||
mockButtonPropsAndFlags = { |
|
||||||
className: mockGasPriceButtonGroupProps.className, |
|
||||||
handleGasPriceSelection: |
|
||||||
mockGasPriceButtonGroupProps.handleGasPriceSelection, |
|
||||||
showCheck: mockGasPriceButtonGroupProps.showCheck, |
|
||||||
}; |
|
||||||
|
|
||||||
sinon.spy(GasPriceButtonGroup.prototype, 'renderButton'); |
|
||||||
sinon.spy(GasPriceButtonGroup.prototype, 'renderButtonContent'); |
|
||||||
|
|
||||||
wrapper = shallowWithContext( |
|
||||||
<GasPriceButtonGroup {...mockGasPriceButtonGroupProps} />, |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
afterEach(() => { |
|
||||||
sinon.restore(); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('render', () => { |
|
||||||
it('should render a ButtonGroup', () => { |
|
||||||
expect(wrapper.is(ButtonGroup)).toStrictEqual(true); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render the correct props on the ButtonGroup', () => { |
|
||||||
const { className, defaultActiveButtonIndex, noButtonActiveByDefault } = |
|
||||||
wrapper.props(); |
|
||||||
expect(className).toStrictEqual('gas-price-button-group'); |
|
||||||
expect(defaultActiveButtonIndex).toStrictEqual(2); |
|
||||||
expect(noButtonActiveByDefault).toStrictEqual(true); |
|
||||||
}); |
|
||||||
|
|
||||||
function renderButtonArgsTest(i, mockPropsAndFlags) { |
|
||||||
expect( |
|
||||||
GasPriceButtonGroup.prototype.renderButton.getCall(i).args, |
|
||||||
).toStrictEqual([ |
|
||||||
{ ...mockGasPriceButtonGroupProps.gasButtonInfo[i] }, |
|
||||||
mockPropsAndFlags, |
|
||||||
i, |
|
||||||
]); |
|
||||||
} |
|
||||||
|
|
||||||
it('should call this.renderButton 3 times, with the correct args', () => { |
|
||||||
expect( |
|
||||||
GasPriceButtonGroup.prototype.renderButton.callCount, |
|
||||||
).toStrictEqual(3); |
|
||||||
renderButtonArgsTest(0, mockButtonPropsAndFlags); |
|
||||||
renderButtonArgsTest(1, mockButtonPropsAndFlags); |
|
||||||
renderButtonArgsTest(2, mockButtonPropsAndFlags); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should show loading if buttonDataLoading', () => { |
|
||||||
wrapper.setProps({ buttonDataLoading: true }); |
|
||||||
expect(wrapper.is('div')).toStrictEqual(true); |
|
||||||
expect( |
|
||||||
wrapper.hasClass('gas-price-button-group__loading-container'), |
|
||||||
).toStrictEqual(true); |
|
||||||
expect(wrapper.text()).toStrictEqual('loading'); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('renderButton', () => { |
|
||||||
let wrappedRenderButtonResult; |
|
||||||
|
|
||||||
beforeEach(() => { |
|
||||||
GasPriceButtonGroup.prototype.renderButtonContent.resetHistory(); |
|
||||||
const renderButtonResult = wrapper |
|
||||||
.instance() |
|
||||||
.renderButton( |
|
||||||
{ ...mockGasPriceButtonGroupProps.gasButtonInfo[0] }, |
|
||||||
mockButtonPropsAndFlags, |
|
||||||
); |
|
||||||
wrappedRenderButtonResult = shallowWithContext(renderButtonResult); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render a button', () => { |
|
||||||
expect(wrappedRenderButtonResult.type()).toStrictEqual('button'); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should call the correct method when clicked', () => { |
|
||||||
expect( |
|
||||||
mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, |
|
||||||
).toStrictEqual(0); |
|
||||||
wrappedRenderButtonResult.props().onClick(); |
|
||||||
expect( |
|
||||||
mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, |
|
||||||
).toStrictEqual(1); |
|
||||||
expect( |
|
||||||
mockGasPriceButtonGroupProps.handleGasPriceSelection.getCall(0).args, |
|
||||||
).toStrictEqual([ |
|
||||||
{ |
|
||||||
gasPrice: mockGasPriceButtonGroupProps.gasButtonInfo[0].priceInHexWei, |
|
||||||
gasEstimateType: |
|
||||||
mockGasPriceButtonGroupProps.gasButtonInfo[0].gasEstimateType, |
|
||||||
}, |
|
||||||
]); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should call this.renderButtonContent with the correct args', () => { |
|
||||||
expect( |
|
||||||
GasPriceButtonGroup.prototype.renderButtonContent.callCount, |
|
||||||
).toStrictEqual(1); |
|
||||||
const { |
|
||||||
feeInPrimaryCurrency, |
|
||||||
feeInSecondaryCurrency, |
|
||||||
timeEstimate, |
|
||||||
gasEstimateType, |
|
||||||
} = mockGasPriceButtonGroupProps.gasButtonInfo[0]; |
|
||||||
const { showCheck, className } = mockGasPriceButtonGroupProps; |
|
||||||
expect( |
|
||||||
GasPriceButtonGroup.prototype.renderButtonContent.getCall(0).args, |
|
||||||
).toStrictEqual([ |
|
||||||
{ |
|
||||||
gasEstimateType, |
|
||||||
feeInPrimaryCurrency, |
|
||||||
feeInSecondaryCurrency, |
|
||||||
timeEstimate, |
|
||||||
}, |
|
||||||
{ |
|
||||||
showCheck, |
|
||||||
className, |
|
||||||
}, |
|
||||||
]); |
|
||||||
}); |
|
||||||
}); |
|
||||||
|
|
||||||
describe('renderButtonContent', () => { |
|
||||||
it('should render a label if passed a gasEstimateType', () => { |
|
||||||
const renderButtonContentResult = wrapper.instance().renderButtonContent( |
|
||||||
{ |
|
||||||
gasEstimateType: 'SLOW', |
|
||||||
}, |
|
||||||
{ |
|
||||||
className: 'someClass', |
|
||||||
}, |
|
||||||
); |
|
||||||
const wrappedRenderButtonContentResult = shallowWithContext( |
|
||||||
renderButtonContentResult, |
|
||||||
); |
|
||||||
expect( |
|
||||||
wrappedRenderButtonContentResult.childAt(0).children(), |
|
||||||
).toHaveLength(1); |
|
||||||
expect( |
|
||||||
wrappedRenderButtonContentResult.find('.someClass__label').text(), |
|
||||||
).toStrictEqual('slow'); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render a feeInPrimaryCurrency if passed a feeInPrimaryCurrency', () => { |
|
||||||
const renderButtonContentResult = |
|
||||||
GasPriceButtonGroup.prototype.renderButtonContent( |
|
||||||
{ |
|
||||||
feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', |
|
||||||
}, |
|
||||||
{ |
|
||||||
className: 'someClass', |
|
||||||
}, |
|
||||||
); |
|
||||||
const wrappedRenderButtonContentResult = shallowWithContext( |
|
||||||
renderButtonContentResult, |
|
||||||
); |
|
||||||
expect( |
|
||||||
wrappedRenderButtonContentResult.childAt(0).children(), |
|
||||||
).toHaveLength(1); |
|
||||||
expect( |
|
||||||
wrappedRenderButtonContentResult |
|
||||||
.find('.someClass__primary-currency') |
|
||||||
.text(), |
|
||||||
).toStrictEqual('mockFeeInPrimaryCurrency'); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render a feeInSecondaryCurrency if passed a feeInSecondaryCurrency', () => { |
|
||||||
const renderButtonContentResult = |
|
||||||
GasPriceButtonGroup.prototype.renderButtonContent( |
|
||||||
{ |
|
||||||
feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', |
|
||||||
}, |
|
||||||
{ |
|
||||||
className: 'someClass', |
|
||||||
}, |
|
||||||
); |
|
||||||
const wrappedRenderButtonContentResult = shallowWithContext( |
|
||||||
renderButtonContentResult, |
|
||||||
); |
|
||||||
expect( |
|
||||||
wrappedRenderButtonContentResult.childAt(0).children(), |
|
||||||
).toHaveLength(1); |
|
||||||
expect( |
|
||||||
wrappedRenderButtonContentResult |
|
||||||
.find('.someClass__secondary-currency') |
|
||||||
.text(), |
|
||||||
).toStrictEqual('mockFeeInSecondaryCurrency'); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render a timeEstimate if passed a timeEstimate', () => { |
|
||||||
const renderButtonContentResult = |
|
||||||
GasPriceButtonGroup.prototype.renderButtonContent( |
|
||||||
{ |
|
||||||
timeEstimate: 'mockTimeEstimate', |
|
||||||
}, |
|
||||||
{ |
|
||||||
className: 'someClass', |
|
||||||
}, |
|
||||||
); |
|
||||||
const wrappedRenderButtonContentResult = shallowWithContext( |
|
||||||
renderButtonContentResult, |
|
||||||
); |
|
||||||
expect( |
|
||||||
wrappedRenderButtonContentResult.childAt(0).children(), |
|
||||||
).toHaveLength(1); |
|
||||||
expect( |
|
||||||
wrappedRenderButtonContentResult |
|
||||||
.find('.someClass__time-estimate') |
|
||||||
.text(), |
|
||||||
).toStrictEqual('mockTimeEstimate'); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render a check if showCheck is true', () => { |
|
||||||
const renderButtonContentResult = |
|
||||||
GasPriceButtonGroup.prototype.renderButtonContent( |
|
||||||
{}, |
|
||||||
{ |
|
||||||
className: 'someClass', |
|
||||||
showCheck: true, |
|
||||||
}, |
|
||||||
); |
|
||||||
const wrappedRenderButtonContentResult = shallowWithContext( |
|
||||||
renderButtonContentResult, |
|
||||||
); |
|
||||||
expect(wrappedRenderButtonContentResult.find('.fa-check')).toHaveLength( |
|
||||||
1, |
|
||||||
); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render all elements if all args passed', () => { |
|
||||||
const renderButtonContentResult = wrapper.instance().renderButtonContent( |
|
||||||
{ |
|
||||||
gasEstimateType: 'SLOW', |
|
||||||
feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', |
|
||||||
feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', |
|
||||||
timeEstimate: 'mockTimeEstimate', |
|
||||||
}, |
|
||||||
{ |
|
||||||
className: 'someClass', |
|
||||||
showCheck: true, |
|
||||||
}, |
|
||||||
); |
|
||||||
const wrappedRenderButtonContentResult = shallowWithContext( |
|
||||||
renderButtonContentResult, |
|
||||||
); |
|
||||||
expect(wrappedRenderButtonContentResult.children()).toHaveLength(5); |
|
||||||
}); |
|
||||||
|
|
||||||
it('should render no elements if all args passed', () => { |
|
||||||
const renderButtonContentResult = |
|
||||||
GasPriceButtonGroup.prototype.renderButtonContent({}, {}); |
|
||||||
const wrappedRenderButtonContentResult = shallowWithContext( |
|
||||||
renderButtonContentResult, |
|
||||||
); |
|
||||||
expect(wrappedRenderButtonContentResult.children()).toHaveLength(0); |
|
||||||
}); |
|
||||||
}); |
|
||||||
}); |
|
@ -1,139 +0,0 @@ |
|||||||
import React, { Component } from 'react'; |
|
||||||
import PropTypes from 'prop-types'; |
|
||||||
import ButtonGroup from '../../../ui/button-group'; |
|
||||||
import Button from '../../../ui/button'; |
|
||||||
import { GAS_ESTIMATE_TYPES } from '../../../../helpers/constants/common'; |
|
||||||
|
|
||||||
const GAS_OBJECT_PROPTYPES_SHAPE = { |
|
||||||
gasEstimateType: PropTypes.oneOf(Object.values(GAS_ESTIMATE_TYPES)) |
|
||||||
.isRequired, |
|
||||||
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, |
|
||||||
newActiveButtonIndex: PropTypes.number, |
|
||||||
noButtonActiveByDefault: PropTypes.bool, |
|
||||||
showCheck: PropTypes.bool, |
|
||||||
}; |
|
||||||
|
|
||||||
gasEstimateTypeLabel(gasEstimateType) { |
|
||||||
if (gasEstimateType === GAS_ESTIMATE_TYPES.SLOW) { |
|
||||||
return this.context.t('slow'); |
|
||||||
} else if (gasEstimateType === GAS_ESTIMATE_TYPES.AVERAGE) { |
|
||||||
return this.context.t('average'); |
|
||||||
} else if (gasEstimateType === GAS_ESTIMATE_TYPES.FAST) { |
|
||||||
return this.context.t('fast'); |
|
||||||
} else if (gasEstimateType === GAS_ESTIMATE_TYPES.FASTEST) { |
|
||||||
return this.context.t('fastest'); |
|
||||||
} |
|
||||||
throw new Error(`Unrecognized gas estimate type: ${gasEstimateType}`); |
|
||||||
} |
|
||||||
|
|
||||||
renderButtonContent( |
|
||||||
{ |
|
||||||
gasEstimateType, |
|
||||||
feeInPrimaryCurrency, |
|
||||||
feeInSecondaryCurrency, |
|
||||||
timeEstimate, |
|
||||||
}, |
|
||||||
{ className, showCheck }, |
|
||||||
) { |
|
||||||
return ( |
|
||||||
<div> |
|
||||||
{gasEstimateType && ( |
|
||||||
<div className={`${className}__label`}> |
|
||||||
{this.gasEstimateTypeLabel(gasEstimateType)} |
|
||||||
</div> |
|
||||||
)} |
|
||||||
{timeEstimate && ( |
|
||||||
<div className={`${className}__time-estimate`}>{timeEstimate}</div> |
|
||||||
)} |
|
||||||
{feeInPrimaryCurrency && ( |
|
||||||
<div className={`${className}__primary-currency`}> |
|
||||||
{feeInPrimaryCurrency} |
|
||||||
</div> |
|
||||||
)} |
|
||||||
{feeInSecondaryCurrency && ( |
|
||||||
<div className={`${className}__secondary-currency`}> |
|
||||||
{feeInSecondaryCurrency} |
|
||||||
</div> |
|
||||||
)} |
|
||||||
{showCheck && ( |
|
||||||
<div className="button-check-wrapper"> |
|
||||||
<i className="fa fa-check fa-sm" /> |
|
||||||
</div> |
|
||||||
)} |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
renderButton( |
|
||||||
{ priceInHexWei, ...renderableGasInfo }, |
|
||||||
{ |
|
||||||
buttonDataLoading: _, |
|
||||||
handleGasPriceSelection, |
|
||||||
...buttonContentPropsAndFlags |
|
||||||
}, |
|
||||||
index, |
|
||||||
) { |
|
||||||
return ( |
|
||||||
<Button |
|
||||||
onClick={() => |
|
||||||
handleGasPriceSelection({ |
|
||||||
gasPrice: priceInHexWei, |
|
||||||
gasEstimateType: renderableGasInfo.gasEstimateType, |
|
||||||
}) |
|
||||||
} |
|
||||||
key={`gas-price-button-${index}`} |
|
||||||
> |
|
||||||
{this.renderButtonContent( |
|
||||||
renderableGasInfo, |
|
||||||
buttonContentPropsAndFlags, |
|
||||||
)} |
|
||||||
</Button> |
|
||||||
); |
|
||||||
} |
|
||||||
|
|
||||||
render() { |
|
||||||
const { |
|
||||||
gasButtonInfo, |
|
||||||
defaultActiveButtonIndex = 1, |
|
||||||
newActiveButtonIndex, |
|
||||||
noButtonActiveByDefault = false, |
|
||||||
buttonDataLoading, |
|
||||||
...buttonPropsAndFlags |
|
||||||
} = this.props; |
|
||||||
|
|
||||||
return buttonDataLoading ? ( |
|
||||||
<div className={`${buttonPropsAndFlags.className}__loading-container`}> |
|
||||||
{this.context.t('loading')} |
|
||||||
</div> |
|
||||||
) : ( |
|
||||||
<ButtonGroup |
|
||||||
className={buttonPropsAndFlags.className} |
|
||||||
defaultActiveButtonIndex={defaultActiveButtonIndex} |
|
||||||
newActiveButtonIndex={newActiveButtonIndex} |
|
||||||
noButtonActiveByDefault={noButtonActiveByDefault} |
|
||||||
> |
|
||||||
{gasButtonInfo.map((obj, index) => |
|
||||||
this.renderButton(obj, buttonPropsAndFlags, index), |
|
||||||
)} |
|
||||||
</ButtonGroup> |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
@ -1,47 +0,0 @@ |
|||||||
import React from 'react'; |
|
||||||
import { GAS_ESTIMATE_TYPES } from '../../../../helpers/constants/common'; |
|
||||||
import GasPriceButtonGroup from '.'; |
|
||||||
|
|
||||||
export default { |
|
||||||
title: 'Components/App/GasCustomization/GasPriceButtonGroup', |
|
||||||
id: __filename, |
|
||||||
argTypes: { |
|
||||||
handleGasPriceSelection: { |
|
||||||
action: 'handleGasPriceSelection', |
|
||||||
}, |
|
||||||
}, |
|
||||||
args: { |
|
||||||
buttonDataLoading: false, |
|
||||||
className: 'gas-price-button-group', |
|
||||||
gasButtonInfo: [ |
|
||||||
{ |
|
||||||
gasEstimateType: GAS_ESTIMATE_TYPES.SLOW, |
|
||||||
feeInPrimaryCurrency: '$0.52', |
|
||||||
feeInSecondaryCurrency: '0.0048 ETH', |
|
||||||
timeEstimate: '~ 1 min 0 sec', |
|
||||||
priceInHexWei: '0xa1b2c3f', |
|
||||||
}, |
|
||||||
{ |
|
||||||
gasEstimateType: GAS_ESTIMATE_TYPES.AVERAGE, |
|
||||||
feeInPrimaryCurrency: '$0.39', |
|
||||||
feeInSecondaryCurrency: '0.004 ETH', |
|
||||||
timeEstimate: '~ 1 min 30 sec', |
|
||||||
priceInHexWei: '0xa1b2c39', |
|
||||||
}, |
|
||||||
{ |
|
||||||
gasEstimateType: GAS_ESTIMATE_TYPES.FAST, |
|
||||||
feeInPrimaryCurrency: '$0.30', |
|
||||||
feeInSecondaryCurrency: '0.00354 ETH', |
|
||||||
timeEstimate: '~ 2 min 1 sec', |
|
||||||
priceInHexWei: '0xa1b2c30', |
|
||||||
}, |
|
||||||
], |
|
||||||
noButtonActiveByDefault: true, |
|
||||||
defaultActiveButtonIndex: 2, |
|
||||||
showCheck: true, |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
export const DefaultStory = (args) => <GasPriceButtonGroup {...args} />; |
|
||||||
|
|
||||||
DefaultStory.storyName = 'Default'; |
|
@ -1 +0,0 @@ |
|||||||
export { default } from './gas-price-button-group.component'; |
|
@ -1,251 +0,0 @@ |
|||||||
.gas-price-button-group { |
|
||||||
margin-top: 22px; |
|
||||||
display: flex; |
|
||||||
justify-content: space-evenly; |
|
||||||
width: 100%; |
|
||||||
padding-left: 20px; |
|
||||||
padding-right: 20px; |
|
||||||
|
|
||||||
&__primary-currency { |
|
||||||
@include H4; |
|
||||||
|
|
||||||
height: 20.5px; |
|
||||||
margin-bottom: 7.5px; |
|
||||||
} |
|
||||||
|
|
||||||
&__time-estimate { |
|
||||||
margin-top: 5.5px; |
|
||||||
color: var(--color-text-alternative); |
|
||||||
height: 15.4px; |
|
||||||
} |
|
||||||
|
|
||||||
&__loading-container { |
|
||||||
height: 130px; |
|
||||||
} |
|
||||||
|
|
||||||
.button-group__button, |
|
||||||
.button-group__button--active { |
|
||||||
@include H7; |
|
||||||
|
|
||||||
height: 130px; |
|
||||||
max-width: 108px; |
|
||||||
flex-direction: column; |
|
||||||
align-items: center; |
|
||||||
display: flex; |
|
||||||
padding-top: 17px; |
|
||||||
border-radius: 4px; |
|
||||||
border-color: var(--color-primary-muted); |
|
||||||
background: var(--color-background-default); |
|
||||||
color: var(--color-text-alternative); |
|
||||||
|
|
||||||
div { |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
|
|
||||||
i { |
|
||||||
&:last-child { |
|
||||||
display: none; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.button-group__button--active { |
|
||||||
border-color: var(--color-primary-default); |
|
||||||
color: var(--color-text-alternative); |
|
||||||
|
|
||||||
i { |
|
||||||
&:last-child { |
|
||||||
display: flex; |
|
||||||
color: var(--color-primary-default); |
|
||||||
margin-top: 8px; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.gas-price-button-group--small { |
|
||||||
display: flex; |
|
||||||
justify-content: stretch; |
|
||||||
min-height: 54px; |
|
||||||
|
|
||||||
@include screen-sm-max { |
|
||||||
max-width: 260px; |
|
||||||
} |
|
||||||
|
|
||||||
&__button-fiat-price { |
|
||||||
@include H6; |
|
||||||
} |
|
||||||
|
|
||||||
&__button-label { |
|
||||||
@include Paragraph; |
|
||||||
} |
|
||||||
|
|
||||||
&__label { |
|
||||||
font-weight: 500; |
|
||||||
line-height: 16px; |
|
||||||
padding-bottom: 4px; |
|
||||||
} |
|
||||||
|
|
||||||
&__primary-currency { |
|
||||||
@include H7; |
|
||||||
|
|
||||||
padding-bottom: 2px; |
|
||||||
|
|
||||||
@include screen-sm-max { |
|
||||||
@include H8; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&__secondary-currency { |
|
||||||
@include H7; |
|
||||||
|
|
||||||
padding-bottom: 2px; |
|
||||||
|
|
||||||
@include screen-sm-max { |
|
||||||
@include H8; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&__loading-container { |
|
||||||
height: 54px; |
|
||||||
} |
|
||||||
|
|
||||||
.button-group__button, |
|
||||||
.button-group__button--active { |
|
||||||
background: var(--color-background-default); |
|
||||||
color: var(--color-text-alternative); |
|
||||||
padding: 4px; |
|
||||||
|
|
||||||
div { |
|
||||||
display: flex; |
|
||||||
flex-flow: column; |
|
||||||
align-items: flex-start; |
|
||||||
justify-content: flex-start; |
|
||||||
} |
|
||||||
|
|
||||||
i { |
|
||||||
&:last-child { |
|
||||||
display: none; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.button-group__button--active { |
|
||||||
color: var(--color-background-default); |
|
||||||
background: var(--color-primary-muted); |
|
||||||
|
|
||||||
i { |
|
||||||
&:last-child { |
|
||||||
display: flex; |
|
||||||
color: var(--color-primary-default); |
|
||||||
margin-top: 10px; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.gas-price-button-group--alt { |
|
||||||
display: flex; |
|
||||||
justify-content: stretch; |
|
||||||
width: 95%; |
|
||||||
|
|
||||||
&__button-fiat-price { |
|
||||||
@include H6; |
|
||||||
} |
|
||||||
|
|
||||||
&__button-label { |
|
||||||
@include Paragraph; |
|
||||||
} |
|
||||||
|
|
||||||
&__label { |
|
||||||
@include H8; |
|
||||||
|
|
||||||
font-weight: 500; |
|
||||||
text-transform: capitalize; |
|
||||||
} |
|
||||||
|
|
||||||
&__primary-currency { |
|
||||||
@include H7; |
|
||||||
|
|
||||||
margin-top: 3px; |
|
||||||
} |
|
||||||
|
|
||||||
&__secondary-currency { |
|
||||||
@include H7; |
|
||||||
} |
|
||||||
|
|
||||||
&__loading-container { |
|
||||||
height: 78px; |
|
||||||
} |
|
||||||
|
|
||||||
&__time-estimate { |
|
||||||
@include H7; |
|
||||||
|
|
||||||
font-weight: 500; |
|
||||||
margin-top: 4px; |
|
||||||
color: var(--color-text-default); |
|
||||||
} |
|
||||||
|
|
||||||
.button-group__button, |
|
||||||
.button-group__button--active { |
|
||||||
height: 78px; |
|
||||||
background: var(--color-background-default); |
|
||||||
color: var(--color-text-default); |
|
||||||
width: 108px; |
|
||||||
height: 97px; |
|
||||||
box-shadow: var(--shadow-size-sm) var(--color-shadow-default); |
|
||||||
border-radius: 6px; |
|
||||||
border: none; |
|
||||||
|
|
||||||
div { |
|
||||||
display: flex; |
|
||||||
flex-flow: column; |
|
||||||
align-items: flex-start; |
|
||||||
justify-content: flex-start; |
|
||||||
position: relative; |
|
||||||
} |
|
||||||
|
|
||||||
.button-check-wrapper { |
|
||||||
display: none; |
|
||||||
} |
|
||||||
|
|
||||||
&:first-child { |
|
||||||
margin-right: 6px; |
|
||||||
} |
|
||||||
|
|
||||||
&:last-child { |
|
||||||
margin-left: 6px; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.button-group__button--active { |
|
||||||
background: var(--color-background-alternative); |
|
||||||
border-color: var(--color-primary-default); |
|
||||||
|
|
||||||
&:first-child { |
|
||||||
border-color: var(--color-primary-default); |
|
||||||
} |
|
||||||
|
|
||||||
.button-check-wrapper { |
|
||||||
height: 16px; |
|
||||||
width: 16px; |
|
||||||
border-radius: 8px; |
|
||||||
position: absolute; |
|
||||||
top: -11px; |
|
||||||
right: -10px; |
|
||||||
background: var(--color-background-alternative); |
|
||||||
display: flex; |
|
||||||
flex-flow: row; |
|
||||||
justify-content: center; |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
|
|
||||||
i { |
|
||||||
display: flex; |
|
||||||
color: var(--color-primary-default); |
|
||||||
font-weight: 900; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,40 +0,0 @@ |
|||||||
import React, { Component } from 'react'; |
|
||||||
import PropTypes from 'prop-types'; |
|
||||||
|
|
||||||
export default class GasSlider extends Component { |
|
||||||
static propTypes = { |
|
||||||
onChange: PropTypes.func, |
|
||||||
lowLabel: PropTypes.string, |
|
||||||
highLabel: PropTypes.string, |
|
||||||
value: PropTypes.number, |
|
||||||
step: PropTypes.number, |
|
||||||
max: PropTypes.number, |
|
||||||
min: PropTypes.number, |
|
||||||
}; |
|
||||||
|
|
||||||
render() { |
|
||||||
const { onChange, lowLabel, highLabel, value, step, max, min } = this.props; |
|
||||||
|
|
||||||
return ( |
|
||||||
<div className="gas-slider"> |
|
||||||
<input |
|
||||||
className="gas-slider__input" |
|
||||||
type="range" |
|
||||||
step={step} |
|
||||||
max={max} |
|
||||||
min={min} |
|
||||||
value={value} |
|
||||||
id="gasSlider" |
|
||||||
onChange={(event) => onChange(event.target.value)} |
|
||||||
/> |
|
||||||
<div className="gas-slider__bar"> |
|
||||||
<div className="gas-slider__colored" /> |
|
||||||
</div> |
|
||||||
<div className="gas-slider__labels"> |
|
||||||
<span>{lowLabel}</span> |
|
||||||
<span>{highLabel}</span> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
); |
|
||||||
} |
|
||||||
} |
|
@ -1,34 +0,0 @@ |
|||||||
import React from 'react'; |
|
||||||
import GasSlider from '.'; |
|
||||||
|
|
||||||
export default { |
|
||||||
title: 'Components/App/GasCustomization/GasSlider', |
|
||||||
id: __filename, |
|
||||||
argTypes: { |
|
||||||
onChange: { |
|
||||||
action: 'onChange', |
|
||||||
}, |
|
||||||
lowLabel: { |
|
||||||
control: 'text', |
|
||||||
}, |
|
||||||
highLabel: { |
|
||||||
control: 'text', |
|
||||||
}, |
|
||||||
value: { |
|
||||||
control: 'number', |
|
||||||
}, |
|
||||||
step: { |
|
||||||
control: 'number', |
|
||||||
}, |
|
||||||
max: { |
|
||||||
control: 'number', |
|
||||||
}, |
|
||||||
min: { |
|
||||||
control: 'number', |
|
||||||
}, |
|
||||||
}, |
|
||||||
}; |
|
||||||
|
|
||||||
export const DefaultStory = () => <GasSlider />; |
|
||||||
|
|
||||||
DefaultStory.storyName = 'Default'; |
|
@ -1 +0,0 @@ |
|||||||
export { default } from './gas-slider.component'; |
|
@ -1,54 +0,0 @@ |
|||||||
.gas-slider { |
|
||||||
position: relative; |
|
||||||
width: 322px; |
|
||||||
|
|
||||||
&__input { |
|
||||||
width: 322px; |
|
||||||
margin-left: -2px; |
|
||||||
z-index: 2; |
|
||||||
} |
|
||||||
|
|
||||||
input[type=range] { |
|
||||||
-webkit-appearance: none !important; |
|
||||||
} |
|
||||||
|
|
||||||
input[type=range]::-webkit-slider-thumb { |
|
||||||
-webkit-appearance: none !important; |
|
||||||
height: 34px; |
|
||||||
width: 34px; |
|
||||||
background-color: var(--color-primary-default); |
|
||||||
border-radius: 50%; |
|
||||||
position: relative; |
|
||||||
z-index: 10; |
|
||||||
} |
|
||||||
|
|
||||||
&__bar { |
|
||||||
height: 6px; |
|
||||||
width: 322px; |
|
||||||
background: var(--color-background-alternative); |
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
position: absolute; |
|
||||||
top: 16px; |
|
||||||
z-index: 0; |
|
||||||
border-radius: 4px; |
|
||||||
} |
|
||||||
|
|
||||||
&__colored { |
|
||||||
height: 6px; |
|
||||||
border-radius: 4px; |
|
||||||
margin-left: 102px; |
|
||||||
width: 322px; |
|
||||||
z-index: 1; |
|
||||||
background-color: var(--color-primary-muted); |
|
||||||
} |
|
||||||
|
|
||||||
&__labels { |
|
||||||
@include H7; |
|
||||||
|
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
margin-top: -6px; |
|
||||||
color: var(--color-text-alternative); |
|
||||||
} |
|
||||||
} |
|
@ -1,3 +0,0 @@ |
|||||||
@import './gas-slider/index'; |
|
||||||
@import './gas-modal-page-container/index'; |
|
||||||
@import './advanced-gas-inputs/index'; |
|
Loading…
Reference in new issue