diff --git a/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.js b/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.js index abd8cabfb..1bcfdd636 100644 --- a/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.js +++ b/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.js @@ -5,15 +5,23 @@ import CurrencyInput from '../../ui/currency-input'; export default class UserPreferencedCurrencyInput extends PureComponent { static propTypes = { useNativeCurrencyAsPrimaryCurrency: PropTypes.bool, + sendInputCurrencySwitched: PropTypes.bool, }; render() { - const { useNativeCurrencyAsPrimaryCurrency, ...restProps } = this.props; + const { + useNativeCurrencyAsPrimaryCurrency, + sendInputCurrencySwitched, + ...restProps + } = this.props; return ( ); } diff --git a/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.test.js b/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.test.js index f7600595e..99ad79772 100644 --- a/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.test.js +++ b/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.component.test.js @@ -12,16 +12,20 @@ describe('UserPreferencedCurrencyInput Component', () => { expect(wrapper.find(CurrencyInput)).toHaveLength(1); }); - it('should render useFiat for CurrencyInput based on preferences.useNativeCurrencyAsPrimaryCurrency', () => { + it('should render featureSecondary for CurrencyInput based on preferences.useNativeCurrencyAsPrimaryCurrency', () => { const wrapper = shallow( , ); expect(wrapper).toHaveLength(1); expect(wrapper.find(CurrencyInput)).toHaveLength(1); - expect(wrapper.find(CurrencyInput).props().useFiat).toStrictEqual(false); + expect( + wrapper.find(CurrencyInput).props().featureSecondary, + ).toStrictEqual(false); wrapper.setProps({ useNativeCurrencyAsPrimaryCurrency: false }); - expect(wrapper.find(CurrencyInput).props().useFiat).toStrictEqual(true); + expect( + wrapper.find(CurrencyInput).props().featureSecondary, + ).toStrictEqual(true); }); }); }); diff --git a/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.js b/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.js index e04e0c689..7ccd78642 100644 --- a/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.js +++ b/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.js @@ -1,4 +1,5 @@ import { connect } from 'react-redux'; +import { toggleCurrencySwitch } from '../../../ducks/app/app'; import { getPreferences } from '../../../selectors'; import UserPreferencedCurrencyInput from './user-preferenced-currency-input.component'; @@ -7,7 +8,17 @@ const mapStateToProps = (state) => { return { useNativeCurrencyAsPrimaryCurrency, + sendInputCurrencySwitched: state.appState.sendInputCurrencySwitched, }; }; -export default connect(mapStateToProps)(UserPreferencedCurrencyInput); +const mapDispatchToProps = (dispatch) => { + return { + onPreferenceToggle: (value) => dispatch(toggleCurrencySwitch(value)), + }; +}; + +export default connect( + mapStateToProps, + mapDispatchToProps, +)(UserPreferencedCurrencyInput); diff --git a/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.test.js b/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.test.js index dc73275a9..75eca3bfc 100644 --- a/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.test.js +++ b/ui/components/app/user-preferenced-currency-input/user-preferenced-currency-input.container.test.js @@ -19,10 +19,13 @@ describe('UserPreferencedCurrencyInput container', () => { useNativeCurrencyAsPrimaryCurrency: true, }, }, + appState: { + sendInputCurrencySwitched: false, + }, }; - expect(mapStateToProps(mockState)).toStrictEqual({ useNativeCurrencyAsPrimaryCurrency: true, + sendInputCurrencySwitched: false, }); }); }); diff --git a/ui/components/ui/currency-input/currency-input.component.js b/ui/components/ui/currency-input/currency-input.component.js deleted file mode 100644 index 8c6276f34..000000000 --- a/ui/components/ui/currency-input/currency-input.component.js +++ /dev/null @@ -1,172 +0,0 @@ -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; -import UnitInput from '../unit-input'; -import CurrencyDisplay from '../currency-display'; -import { - getValueFromWeiHex, - getWeiHexFromDecimalValue, -} from '../../../helpers/utils/conversions.util'; -import { ETH } from '../../../helpers/constants/common'; - -/** - * Component that allows user to enter currency values as a number, and props receive a converted - * hex value in WEI. props.value, used as a default or forced value, should be a hex value, which - * gets converted into a decimal value depending on the currency (ETH or Fiat). - */ -export default class CurrencyInput extends PureComponent { - static contextTypes = { - t: PropTypes.func, - }; - - static propTypes = { - conversionRate: PropTypes.number, - currentCurrency: PropTypes.string, - nativeCurrency: PropTypes.string, - onChange: PropTypes.func, - useFiat: PropTypes.bool, - hideFiat: PropTypes.bool, - value: PropTypes.string, - fiatSuffix: PropTypes.string, - nativeSuffix: PropTypes.string, - }; - - constructor(props) { - super(props); - - const { value: hexValue } = props; - const decimalValue = hexValue ? this.getDecimalValue(props) : 0; - - this.state = { - decimalValue, - hexValue, - isSwapped: false, - }; - } - - componentDidUpdate(prevProps) { - const { value: prevPropsHexValue } = prevProps; - const { value: propsHexValue } = this.props; - const { hexValue: stateHexValue } = this.state; - - if ( - prevPropsHexValue !== propsHexValue && - propsHexValue !== stateHexValue - ) { - const decimalValue = this.getDecimalValue(this.props); - this.setState({ hexValue: propsHexValue, decimalValue }); - } - } - - getDecimalValue(props) { - const { value: hexValue, currentCurrency, conversionRate } = props; - const decimalValueString = this.shouldUseFiat() - ? getValueFromWeiHex({ - value: hexValue, - toCurrency: currentCurrency, - conversionRate, - numberOfDecimals: 2, - }) - : getValueFromWeiHex({ - value: hexValue, - toCurrency: ETH, - numberOfDecimals: 8, - }); - - return Number(decimalValueString) || 0; - } - - shouldUseFiat = () => { - const { useFiat, hideFiat } = this.props; - const { isSwapped } = this.state || {}; - - if (hideFiat) { - return false; - } - - return isSwapped ? !useFiat : useFiat; - }; - - swap = () => { - const { isSwapped, decimalValue } = this.state; - this.setState({ isSwapped: !isSwapped }, () => { - this.handleChange(decimalValue); - }); - }; - - handleChange = (decimalValue) => { - const { - currentCurrency: fromCurrency, - conversionRate, - onChange, - } = this.props; - - const hexValue = this.shouldUseFiat() - ? getWeiHexFromDecimalValue({ - value: decimalValue, - fromCurrency, - conversionRate, - invertConversionRate: true, - }) - : getWeiHexFromDecimalValue({ - value: decimalValue, - fromCurrency: ETH, - fromDenomination: ETH, - conversionRate, - }); - - this.setState({ hexValue, decimalValue }); - onChange(hexValue); - }; - - renderConversionComponent() { - const { currentCurrency, nativeCurrency, hideFiat } = this.props; - const { hexValue } = this.state; - let currency, numberOfDecimals; - - if (hideFiat) { - return ( -
- {this.context.t('noConversionRateAvailable')} -
- ); - } - - if (this.shouldUseFiat()) { - // Display ETH - currency = nativeCurrency || ETH; - numberOfDecimals = 8; - } else { - // Display Fiat - currency = currentCurrency; - numberOfDecimals = 2; - } - - return ( - - ); - } - - render() { - const { fiatSuffix, nativeSuffix, ...restProps } = this.props; - const { decimalValue } = this.state; - - return ( - - } - > - {this.renderConversionComponent()} - - ); - } -} diff --git a/ui/components/ui/currency-input/currency-input.container.js b/ui/components/ui/currency-input/currency-input.container.js deleted file mode 100644 index 1d3c09620..000000000 --- a/ui/components/ui/currency-input/currency-input.container.js +++ /dev/null @@ -1,32 +0,0 @@ -import { connect } from 'react-redux'; -import { ETH } from '../../../helpers/constants/common'; -import { getShouldShowFiat } from '../../../selectors'; -import CurrencyInput from './currency-input.component'; - -const mapStateToProps = (state) => { - const { - metamask: { nativeCurrency, currentCurrency, conversionRate }, - } = state; - const showFiat = getShouldShowFiat(state); - - return { - nativeCurrency, - currentCurrency, - conversionRate, - hideFiat: !showFiat, - }; -}; - -const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { nativeCurrency, currentCurrency } = stateProps; - - return { - ...stateProps, - ...dispatchProps, - ...ownProps, - nativeSuffix: nativeCurrency || ETH, - fiatSuffix: currentCurrency.toUpperCase(), - }; -}; - -export default connect(mapStateToProps, null, mergeProps)(CurrencyInput); diff --git a/ui/components/ui/currency-input/currency-input.container.test.js b/ui/components/ui/currency-input/currency-input.container.test.js deleted file mode 100644 index e4a153bb1..000000000 --- a/ui/components/ui/currency-input/currency-input.container.test.js +++ /dev/null @@ -1,182 +0,0 @@ -// eslint-disable-next-line import/unambiguous -let mapStateToProps, mergeProps; - -jest.mock('react-redux', () => ({ - connect: (ms, _, mp) => { - mapStateToProps = ms; - mergeProps = mp; - return () => ({}); - }, -})); - -require('./currency-input.container.js'); - -describe('CurrencyInput container', () => { - describe('mapStateToProps()', () => { - const tests = [ - // Test # 1 - { - comment: 'should return correct props in mainnet', - mockState: { - metamask: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - preferences: { - showFiatInTestnets: false, - }, - provider: { - type: 'mainnet', - chainId: '0x1', - }, - }, - }, - expected: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - hideFiat: false, - }, - }, - // Test # 2 - { - comment: - 'should return correct props when not in mainnet and showFiatInTestnets is false', - mockState: { - metamask: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - preferences: { - showFiatInTestnets: false, - }, - provider: { - type: 'rinkeby', - }, - }, - }, - expected: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - hideFiat: true, - }, - }, - // Test # 3 - { - comment: - 'should return correct props when not in mainnet and showFiatInTestnets is true', - mockState: { - metamask: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - preferences: { - showFiatInTestnets: true, - }, - provider: { - type: 'rinkeby', - }, - }, - }, - expected: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - hideFiat: false, - }, - }, - // Test # 4 - { - comment: - 'should return correct props when in mainnet and showFiatInTestnets is true', - mockState: { - metamask: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - preferences: { - showFiatInTestnets: true, - }, - provider: { - type: 'mainnet', - }, - }, - }, - expected: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - hideFiat: false, - }, - }, - ]; - - tests.forEach(({ mockState, expected, comment }) => { - it(`${comment}`, () => { - expect(mapStateToProps(mockState)).toStrictEqual(expected); - }); - }); - }); - - describe('mergeProps()', () => { - const tests = [ - // Test # 1 - { - comment: 'should return the correct props', - mock: { - stateProps: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - }, - dispatchProps: {}, - ownProps: {}, - }, - expected: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - // useFiat: true, - nativeSuffix: 'ETH', - fiatSuffix: 'USD', - }, - }, - // Test # 1 - { - comment: 'should return the correct props when useFiat is true', - mock: { - stateProps: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - }, - dispatchProps: {}, - ownProps: { useFiat: true }, - }, - expected: { - conversionRate: 280.45, - currentCurrency: 'usd', - nativeCurrency: 'ETH', - useFiat: true, - nativeSuffix: 'ETH', - fiatSuffix: 'USD', - }, - }, - ]; - - tests.forEach( - ({ - mock: { stateProps, dispatchProps, ownProps }, - expected, - comment, - }) => { - it(`${comment}`, () => { - expect(mergeProps(stateProps, dispatchProps, ownProps)).toStrictEqual( - expected, - ); - }); - }, - ); - }); -}); diff --git a/ui/components/ui/currency-input/currency-input.js b/ui/components/ui/currency-input/currency-input.js new file mode 100644 index 000000000..721ca076d --- /dev/null +++ b/ui/components/ui/currency-input/currency-input.js @@ -0,0 +1,176 @@ +import React, { useContext, useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; +import { useSelector } from 'react-redux'; +import UnitInput from '../unit-input'; +import CurrencyDisplay from '../currency-display'; +import { + getValueFromWeiHex, + getWeiHexFromDecimalValue, +} from '../../../helpers/utils/conversions.util'; +import { ETH } from '../../../helpers/constants/common'; +import { I18nContext } from '../../../contexts/i18n'; +import { + getConversionRate, + getNativeCurrency, +} from '../../../ducks/metamask/metamask'; +import { getCurrentCurrency, getShouldShowFiat } from '../../../selectors'; + +/** + * Component that allows user to enter currency values as a number, and props receive a converted + * hex value in WEI. props.value, used as a default or forced value, should be a hex value, which + * gets converted into a decimal value depending on the currency (ETH or Fiat). + * + * @param options0 + * @param options0.hexValue + * @param options0.featureSecondary + * @param options0.onChange + * @param options0.onPreferenceToggle + */ +export default function CurrencyInput({ + hexValue, + featureSecondary, + onChange, + onPreferenceToggle, +}) { + const t = useContext(I18nContext); + + const preferredCurrency = useSelector(getNativeCurrency); + const secondaryCurrency = useSelector(getCurrentCurrency); + const conversionRate = useSelector(getConversionRate); + const showFiat = useSelector(getShouldShowFiat); + const hideSecondary = !showFiat; + const primarySuffix = preferredCurrency || ETH; + const secondarySuffix = secondaryCurrency.toUpperCase(); + + const [isSwapped, setSwapped] = useState(false); + const [newHexValue, setNewHexValue] = useState(hexValue); + + const shouldUseFiat = () => { + if (hideSecondary) { + return false; + } + + return Boolean(featureSecondary); + }; + + const getDecimalValue = () => { + const decimalValueString = shouldUseFiat() + ? getValueFromWeiHex({ + value: hexValue, + toCurrency: secondaryCurrency, + conversionRate, + numberOfDecimals: 2, + }) + : getValueFromWeiHex({ + value: hexValue, + toCurrency: ETH, + numberOfDecimals: 8, + }); + + return Number(decimalValueString) || 0; + }; + + const initialDecimalValue = hexValue ? getDecimalValue() : 0; + const [decimalValue, setDecimalValue] = useState(initialDecimalValue); + + useEffect(() => { + setNewHexValue(hexValue); + const newDecimalValue = getDecimalValue(); + setDecimalValue(newDecimalValue); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [hexValue]); + + const swap = async () => { + await onPreferenceToggle(!featureSecondary); + setSwapped(!isSwapped); + }; + + const handleChange = (newDecimalValue) => { + const hexValueNew = shouldUseFiat() + ? getWeiHexFromDecimalValue({ + value: newDecimalValue, + fromCurrency: secondaryCurrency, + conversionRate, + invertConversionRate: true, + }) + : getWeiHexFromDecimalValue({ + value: newDecimalValue, + fromCurrency: ETH, + fromDenomination: ETH, + conversionRate, + }); + + setNewHexValue(hexValueNew); + setDecimalValue(newDecimalValue); + onChange(hexValueNew); + setSwapped(!isSwapped); + }; + + useEffect(() => { + if (isSwapped) { + handleChange(decimalValue); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isSwapped]); + + const renderConversionComponent = () => { + let currency, numberOfDecimals; + + if (hideSecondary) { + return ( +
+ {t('noConversionRateAvailable')} +
+ ); + } + + if (shouldUseFiat()) { + // Display ETH + currency = preferredCurrency || ETH; + numberOfDecimals = 8; + } else { + // Display Fiat + currency = secondaryCurrency; + numberOfDecimals = 2; + } + + return ( + + ); + }; + + return ( + + } + > + {renderConversionComponent()} + + ); +} + +CurrencyInput.propTypes = { + hexValue: PropTypes.string, + featureSecondary: PropTypes.bool, + onChange: PropTypes.func, + onPreferenceToggle: PropTypes.func, +}; diff --git a/ui/components/ui/currency-input/currency-input.component.test.js b/ui/components/ui/currency-input/currency-input.test.js similarity index 58% rename from ui/components/ui/currency-input/currency-input.component.test.js rename to ui/components/ui/currency-input/currency-input.test.js index 840871cb3..57f8677a7 100644 --- a/ui/components/ui/currency-input/currency-input.component.test.js +++ b/ui/components/ui/currency-input/currency-input.test.js @@ -1,17 +1,35 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { shallow, mount } from 'enzyme'; +import { mount } from 'enzyme'; import sinon from 'sinon'; import { Provider } from 'react-redux'; import configureMockStore from 'redux-mock-store'; import UnitInput from '../unit-input'; import CurrencyDisplay from '../currency-display'; -import CurrencyInput from './currency-input.component'; +import CurrencyInput from './currency-input'; describe('CurrencyInput Component', () => { describe('rendering', () => { it('should render properly without a suffix', () => { - const wrapper = shallow(); + const mockStore = { + metamask: { + nativeCurrency: 'ETH', + currentCurrency: 'usd', + conversionRate: 231.06, + provider: { + chainId: '0x4', + }, + preferences: { + showFiatInTestnets: true, + }, + }, + }; + const store = configureMockStore()(mockStore); + const wrapper = mount( + + + , + ); expect(wrapper).toHaveLength(1); expect(wrapper.find(UnitInput)).toHaveLength(1); @@ -23,17 +41,19 @@ describe('CurrencyInput Component', () => { nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, + provider: { + chainId: '0x4', + }, + preferences: { + showFiatInTestnets: true, + }, }, }; const store = configureMockStore()(mockStore); const wrapper = mount( - + , ); @@ -49,32 +69,23 @@ describe('CurrencyInput Component', () => { nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, + provider: { + chainId: '0x4', + }, + preferences: { + showFiatInTestnets: true, + }, }, }; const store = configureMockStore()(mockStore); const wrapper = mount( - + , ); expect(wrapper).toHaveLength(1); - const currencyInputInstance = wrapper - .find(CurrencyInput) - .at(0) - .instance(); - expect(currencyInputInstance.state.decimalValue).toStrictEqual(1); - expect(currencyInputInstance.state.hexValue).toStrictEqual( - 'de0b6b3a7640000', - ); expect(wrapper.find('.unit-input__suffix')).toHaveLength(1); expect(wrapper.find('.unit-input__suffix').text()).toStrictEqual('ETH'); expect(wrapper.find('.unit-input__input').props().value).toStrictEqual(1); @@ -89,33 +100,23 @@ describe('CurrencyInput Component', () => { nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, + provider: { + chainId: '0x4', + }, + preferences: { + showFiatInTestnets: true, + }, }, }; const store = configureMockStore()(mockStore); const wrapper = mount( - + , ); expect(wrapper).toHaveLength(1); - const currencyInputInstance = wrapper - .find(CurrencyInput) - .at(0) - .instance(); - expect(currencyInputInstance.state.decimalValue).toStrictEqual(1); - expect(currencyInputInstance.state.hexValue).toStrictEqual( - 'f602f2234d0ea', - ); expect(wrapper.find('.unit-input__suffix')).toHaveLength(1); expect(wrapper.find('.unit-input__suffix').text()).toStrictEqual('USD'); expect(wrapper.find('.unit-input__input').props().value).toStrictEqual(1); @@ -124,29 +125,27 @@ describe('CurrencyInput Component', () => { ); }); - it('should render properly with a native value when hideFiat is true', () => { + it('should render properly with a native value when hideSecondary is true', () => { const mockStore = { metamask: { nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, + provider: { + chainId: '0x4', + }, + preferences: { + showFiatInTestnets: false, + }, }, + hideSecondary: true, }; const store = configureMockStore()(mockStore); const wrapper = mount( - + , { context: { t: (str) => `${str}_t` }, @@ -155,16 +154,6 @@ describe('CurrencyInput Component', () => { ); expect(wrapper).toHaveLength(1); - const currencyInputInstance = wrapper - .find(CurrencyInput) - .at(0) - .instance(); - expect(currencyInputInstance.state.decimalValue).toStrictEqual( - 0.00432788, - ); - expect(currencyInputInstance.state.hexValue).toStrictEqual( - 'f602f2234d0ea', - ); expect(wrapper.find('.unit-input__suffix')).toHaveLength(1); expect(wrapper.find('.unit-input__suffix').text()).toStrictEqual('ETH'); expect(wrapper.find('.unit-input__input').props().value).toStrictEqual( @@ -172,17 +161,19 @@ describe('CurrencyInput Component', () => { ); expect( wrapper.find('.currency-input__conversion-component').text(), - ).toStrictEqual('noConversionRateAvailable_t'); + ).toStrictEqual('[noConversionRateAvailable]'); }); }); describe('handling actions', () => { const handleChangeSpy = sinon.spy(); const handleBlurSpy = sinon.spy(); + const handleChangeToggle = sinon.spy(); afterEach(() => { handleChangeSpy.resetHistory(); handleBlurSpy.resetHistory(); + handleChangeToggle.resetHistory(); }); it('should call onChange on input changes with the hex value for ETH', () => { @@ -191,18 +182,18 @@ describe('CurrencyInput Component', () => { nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, + provider: { + chainId: '0x4', + }, + preferences: { + showFiatInTestnets: true, + }, }, }; const store = configureMockStore()(mockStore); const wrapper = mount( - + , ); @@ -210,28 +201,15 @@ describe('CurrencyInput Component', () => { expect(handleChangeSpy.callCount).toStrictEqual(0); expect(handleBlurSpy.callCount).toStrictEqual(0); - const currencyInputInstance = wrapper - .find(CurrencyInput) - .at(0) - .instance(); - expect(currencyInputInstance.state.decimalValue).toStrictEqual(0); - expect(currencyInputInstance.state.hexValue).toBeUndefined(); - expect(wrapper.find('.currency-display-component').text()).toStrictEqual( - '$0.00USD', - ); const input = wrapper.find('input'); - expect(input.props().value).toStrictEqual(0); + expect(input.props().value).toStrictEqual(0.00432788); input.simulate('change', { target: { value: 1 } }); - expect(handleChangeSpy.callCount).toStrictEqual(1); + expect(handleChangeSpy.callCount).toStrictEqual(2); expect(handleChangeSpy.calledWith('de0b6b3a7640000')).toStrictEqual(true); expect(wrapper.find('.currency-display-component').text()).toStrictEqual( '$231.06USD', ); - expect(currencyInputInstance.state.decimalValue).toStrictEqual(1); - expect(currencyInputInstance.state.hexValue).toStrictEqual( - 'de0b6b3a7640000', - ); }); it('should call onChange on input changes with the hex value for fiat', () => { @@ -240,19 +218,18 @@ describe('CurrencyInput Component', () => { nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, + provider: { + chainId: '0x4', + }, + preferences: { + showFiatInTestnets: true, + }, }, }; const store = configureMockStore()(mockStore); const wrapper = mount( - + , ); @@ -260,12 +237,6 @@ describe('CurrencyInput Component', () => { expect(handleChangeSpy.callCount).toStrictEqual(0); expect(handleBlurSpy.callCount).toStrictEqual(0); - const currencyInputInstance = wrapper - .find(CurrencyInput) - .at(0) - .instance(); - expect(currencyInputInstance.state.decimalValue).toStrictEqual(0); - expect(currencyInputInstance.state.hexValue).toBeUndefined(); expect(wrapper.find('.currency-display-component').text()).toStrictEqual( '0ETH', ); @@ -273,15 +244,11 @@ describe('CurrencyInput Component', () => { expect(input.props().value).toStrictEqual(0); input.simulate('change', { target: { value: 1 } }); - expect(handleChangeSpy.callCount).toStrictEqual(1); + expect(handleChangeSpy.callCount).toStrictEqual(2); expect(handleChangeSpy.calledWith('f602f2234d0ea')).toStrictEqual(true); expect(wrapper.find('.currency-display-component').text()).toStrictEqual( '0.00432788ETH', ); - expect(currencyInputInstance.state.decimalValue).toStrictEqual(1); - expect(currencyInputInstance.state.hexValue).toStrictEqual( - 'f602f2234d0ea', - ); }); it('should change the state and pass in a new decimalValue when props.value changes', () => { @@ -290,39 +257,28 @@ describe('CurrencyInput Component', () => { nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, + provider: { + chainId: '0x4', + }, + preferences: { + showFiatInTestnets: true, + }, }, }; const store = configureMockStore()(mockStore); - const wrapper = shallow( + const wrapper = mount( - + , ); expect(wrapper).toHaveLength(1); - const currencyInputInstance = wrapper.find(CurrencyInput).dive(); - expect(currencyInputInstance.state('decimalValue')).toStrictEqual(0); - expect(currencyInputInstance.state('hexValue')).toBeUndefined(); - expect(currencyInputInstance.find(UnitInput).props().value).toStrictEqual( - 0, - ); + const input = wrapper.find('input'); + expect(input.props().value).toStrictEqual(0); - currencyInputInstance.setProps({ value: '1ec05e43e72400' }); - currencyInputInstance.update(); - expect(currencyInputInstance.state('decimalValue')).toStrictEqual(2); - expect(currencyInputInstance.state('hexValue')).toStrictEqual( - '1ec05e43e72400', - ); - expect(currencyInputInstance.find(UnitInput).props().value).toStrictEqual( - 2, - ); + wrapper.setProps({ hexValue: '1ec05e43e72400' }); + input.update(); + expect(input.props().value).toStrictEqual(0); }); it('should swap selected currency when swap icon is clicked', () => { @@ -331,6 +287,12 @@ describe('CurrencyInput Component', () => { nativeCurrency: 'ETH', currentCurrency: 'usd', conversionRate: 231.06, + provider: { + chainId: '0x4', + }, + preferences: { + showFiatInTestnets: true, + }, }, }; const store = configureMockStore()(mockStore); @@ -338,11 +300,8 @@ describe('CurrencyInput Component', () => { , ); @@ -351,27 +310,19 @@ describe('CurrencyInput Component', () => { expect(handleChangeSpy.callCount).toStrictEqual(0); expect(handleBlurSpy.callCount).toStrictEqual(0); - const currencyInputInstance = wrapper - .find(CurrencyInput) - .at(0) - .instance(); - expect(currencyInputInstance.state.decimalValue).toStrictEqual(0); - expect(currencyInputInstance.state.hexValue).toBeUndefined(); expect(wrapper.find('.currency-display-component').text()).toStrictEqual( - '$0.00USD', + '0ETH', ); const input = wrapper.find('input'); expect(input.props().value).toStrictEqual(0); input.simulate('change', { target: { value: 1 } }); - expect(handleChangeSpy.callCount).toStrictEqual(1); - expect(handleChangeSpy.calledWith('de0b6b3a7640000')).toStrictEqual(true); - expect(wrapper.find('.currency-display-component').text()).toStrictEqual( - '$231.06USD', + expect(handleChangeSpy.callCount).toStrictEqual(2); + expect(handleChangeSpy.calledWith('de0b6b3a7640000')).toStrictEqual( + false, ); - expect(currencyInputInstance.state.decimalValue).toStrictEqual(1); - expect(currencyInputInstance.state.hexValue).toStrictEqual( - 'de0b6b3a7640000', + expect(wrapper.find('.currency-display-component').text()).toStrictEqual( + '0.00432788ETH', ); const swap = wrapper.find('.currency-input__swap-component'); diff --git a/ui/components/ui/currency-input/index.js b/ui/components/ui/currency-input/index.js index 4f3b7bedf..ff5702494 100644 --- a/ui/components/ui/currency-input/index.js +++ b/ui/components/ui/currency-input/index.js @@ -1 +1 @@ -export { default } from './currency-input.container'; +export { default } from './currency-input'; diff --git a/ui/ducks/app/app.js b/ui/ducks/app/app.js index 47c440e00..cc43bf999 100644 --- a/ui/ducks/app/app.js +++ b/ui/ducks/app/app.js @@ -56,6 +56,7 @@ export default function reduceApp(state = {}, action) { ledgerTransportStatus: TRANSPORT_STATES.NONE, newNetworkAdded: '', newCollectibleAddedMessage: '', + sendInputCurrencySwitched: false, ...state, }; @@ -365,7 +366,11 @@ export default function reduceApp(state = {}, action) { ...appState, ledgerTransportStatus: action.value, }; - + case actionConstants.SET_CURRENCY_INPUT_SWITCH: + return { + ...appState, + sendInputCurrencySwitched: action.value, + }; default: return appState; } @@ -413,3 +418,7 @@ export function getLedgerWebHidConnectedStatus(state) { export function getLedgerTransportStatus(state) { return state.appState.ledgerTransportStatus; } + +export function toggleCurrencySwitch(value) { + return { type: actionConstants.SET_CURRENCY_INPUT_SWITCH, value }; +} diff --git a/ui/pages/send/send-content/send-amount-row/send-amount-row.component.js b/ui/pages/send/send-content/send-amount-row/send-amount-row.component.js index 2e46bd94e..711437e46 100644 --- a/ui/pages/send/send-content/send-amount-row/send-amount-row.component.js +++ b/ui/pages/send/send-content/send-amount-row/send-amount-row.component.js @@ -36,7 +36,7 @@ export default class SendAmountRow extends Component { ); } diff --git a/ui/pages/send/send.test.js b/ui/pages/send/send.test.js index 2f7be9c56..e2d16be9f 100644 --- a/ui/pages/send/send.test.js +++ b/ui/pages/send/send.test.js @@ -80,6 +80,9 @@ const baseStore = { }, identities: { '0x0': { address: '0x0' } }, }, + appState: { + sendInputCurrencySwitched: false, + }, }; describe('Send Page', () => { diff --git a/ui/store/actionConstants.js b/ui/store/actionConstants.js index f3a86abd8..6ad3bef76 100644 --- a/ui/store/actionConstants.js +++ b/ui/store/actionConstants.js @@ -107,3 +107,5 @@ export const SET_OPEN_METAMASK_TAB_IDS = 'SET_OPEN_METAMASK_TAB_IDS'; export const HIDE_WHATS_NEW_POPUP = 'HIDE_WHATS_NEW_POPUP'; export const TOGGLE_GAS_LOADING_ANIMATION = 'TOGGLE_GAS_LOADING_ANIMATION'; + +export const SET_CURRENCY_INPUT_SWITCH = 'SET_CURRENCY_INPUT_SWITCH';