From 389df9dd3773597ca576b03f6b59952c68f9f51e Mon Sep 17 00:00:00 2001
From: Brad Decker
Date: Thu, 21 May 2020 15:21:34 -0500
Subject: [PATCH] warn user when sending from different account (#8601)
---
app/_locales/en/messages.json | 3 +
...confirm-page-container-header.component.js | 71 ++--
ui/app/components/app/index.scss | 4 +
.../signature-request-header/index.scss | 21 +-
.../app/tests/signature-request.test.js | 10 +
.../account-mismatch-warning.component.js | 30 ++
.../ui/account-mismatch-warning/index.scss | 8 +
...cccount-mismatch-warning.component.test.js | 32 ++
ui/app/components/ui/icon/index.scss | 19 +
.../components/ui/icon/info-icon.component.js | 21 +
.../sender-to-recipient.component.js | 394 ++++++++++--------
ui/app/components/ui/tooltip-v2.js | 4 +
.../account-list-item.component.js | 181 ++++----
.../tests/account-list-item-component.test.js | 31 +-
14 files changed, 497 insertions(+), 332 deletions(-)
create mode 100644 ui/app/components/ui/account-mismatch-warning/account-mismatch-warning.component.js
create mode 100644 ui/app/components/ui/account-mismatch-warning/index.scss
create mode 100644 ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js
create mode 100644 ui/app/components/ui/icon/index.scss
create mode 100644 ui/app/components/ui/icon/info-icon.component.js
diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json
index 7ddaba250..2973b24ae 100644
--- a/app/_locales/en/messages.json
+++ b/app/_locales/en/messages.json
@@ -1030,6 +1030,9 @@
"noThanks": {
"message": "No Thanks"
},
+ "notCurrentAccount": {
+ "message": "Is this the correct account? It's different from the currently selected account in your wallet"
+ },
"notEnoughGas": {
"message": "Not Enough Gas"
},
diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js
index 620e54897..f1f10a797 100644
--- a/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js
+++ b/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js
@@ -1,4 +1,4 @@
-import React, { Component } from 'react'
+import React from 'react'
import PropTypes from 'prop-types'
import {
ENVIRONMENT_TYPE_POPUP,
@@ -8,31 +8,27 @@ import { getEnvironmentType } from '../../../../../../app/scripts/lib/util'
import NetworkDisplay from '../../network-display'
import Identicon from '../../../ui/identicon'
import { shortenAddress } from '../../../../helpers/utils/util'
+import AccountMismatchWarning from '../../../ui/account-mismatch-warning/account-mismatch-warning.component'
+import { useI18nContext } from '../../../../hooks/useI18nContext'
-export default class ConfirmPageContainerHeader extends Component {
- static contextTypes = {
- t: PropTypes.func,
+
+export default function ConfirmPageContainerHeader ({
+ onEdit,
+ showEdit,
+ accountAddress,
+ showAccountInHeader,
+ children,
+}) {
+ const t = useI18nContext()
+ const windowType = getEnvironmentType()
+ const isFullScreen = windowType !== ENVIRONMENT_TYPE_NOTIFICATION &&
+ windowType !== ENVIRONMENT_TYPE_POPUP
+
+ if (!showEdit && isFullScreen) {
+ return null
}
-
- static propTypes = {
- accountAddress: PropTypes.string,
- showAccountInHeader: PropTypes.bool,
- showEdit: PropTypes.bool,
- onEdit: PropTypes.func,
- children: PropTypes.node,
- }
-
- renderTop () {
- const { onEdit, showEdit, accountAddress, showAccountInHeader } = this.props
- const windowType = getEnvironmentType()
- const isFullScreen = windowType !== ENVIRONMENT_TYPE_NOTIFICATION &&
- windowType !== ENVIRONMENT_TYPE_POPUP
-
- if (!showEdit && isFullScreen) {
- return null
- }
-
- return (
+ return (
+
{ !showAccountInHeader
? (
@@ -49,7 +45,7 @@ export default class ConfirmPageContainerHeader extends Component {
className="confirm-page-container-header__back-button"
onClick={() => onEdit()}
>
- { this.context.t('edit') }
+ { t('edit') }
)
@@ -67,23 +63,22 @@ export default class ConfirmPageContainerHeader extends Component {
{ shortenAddress(accountAddress) }
+
)
: null
}
{ !isFullScreen && }
- )
- }
-
- render () {
- const { children } = this.props
-
- return (
-
- { this.renderTop() }
- { children }
-
- )
- }
+ { children }
+
+ )
+}
+
+ConfirmPageContainerHeader.propTypes = {
+ accountAddress: PropTypes.string,
+ showAccountInHeader: PropTypes.bool,
+ showEdit: PropTypes.bool,
+ onEdit: PropTypes.func,
+ children: PropTypes.node,
}
diff --git a/ui/app/components/app/index.scss b/ui/app/components/app/index.scss
index d633e7e05..227e9ce76 100644
--- a/ui/app/components/app/index.scss
+++ b/ui/app/components/app/index.scss
@@ -94,6 +94,8 @@
@import '../ui/icon-with-fallback/index';
+@import '../ui/icon/index';
+
@import '../ui/circle-icon/index';
@import '../ui/alert-circle-icon/index';
@@ -111,3 +113,5 @@
@import 'permissions-connect-footer/index';
@import 'wallet-overview/index';
+
+@import '../ui/account-mismatch-warning/index';
diff --git a/ui/app/components/app/signature-request/signature-request-header/index.scss b/ui/app/components/app/signature-request/signature-request-header/index.scss
index 7a33f85f2..1d32b4328 100644
--- a/ui/app/components/app/signature-request/signature-request-header/index.scss
+++ b/ui/app/components/app/signature-request/signature-request-header/index.scss
@@ -13,13 +13,20 @@
display: flex;
align-items: center;
- .account-list-item__account-name {
- font-size: 12px;
- font-weight: 500;
- }
+ .account-list-item {
+ &__top-row {
+ display: flex;
+ align-items: center;
+ }
- .account-list-item__top-row {
- margin: 0px;
+ &__account-name {
+ font-size: 12px;
+ font-weight: 500;
+ }
+
+ &__top-row {
+ margin: 0px;
+ }
}
}
-}
\ No newline at end of file
+}
diff --git a/ui/app/components/app/tests/signature-request.test.js b/ui/app/components/app/tests/signature-request.test.js
index e8054c4f9..493c31df1 100644
--- a/ui/app/components/app/tests/signature-request.test.js
+++ b/ui/app/components/app/tests/signature-request.test.js
@@ -14,6 +14,16 @@ describe('Signature Request', function () {
provider: {
type: 'test',
},
+ accounts: {
+ '0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5': {
+ address: '0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5',
+ balance: '0x03',
+ },
+ },
+ cachedBalances: {
+
+ },
+ selectedAddress: '0xd8f6a2ffb0fc5952d16c9768b71cfd35b6399aa5',
},
}
const store = configureMockStore()(mockStore)
diff --git a/ui/app/components/ui/account-mismatch-warning/account-mismatch-warning.component.js b/ui/app/components/ui/account-mismatch-warning/account-mismatch-warning.component.js
new file mode 100644
index 000000000..a2f3a0dd7
--- /dev/null
+++ b/ui/app/components/ui/account-mismatch-warning/account-mismatch-warning.component.js
@@ -0,0 +1,30 @@
+import React from 'react'
+import Tooltip from '../tooltip-v2'
+import { useSelector } from 'react-redux'
+import PropTypes from 'prop-types'
+import { getSelectedAccount } from '../../../selectors'
+import InfoIcon from '../icon/info-icon.component'
+import { useI18nContext } from '../../../hooks/useI18nContext'
+
+export default function AccountMismatchWarning ({ address }) {
+ const selectedAccount = useSelector(getSelectedAccount)
+ const t = useI18nContext()
+ if (selectedAccount.address === address) {
+ return null
+ }
+
+ return (
+ {t('notCurrentAccount')}
}
+ wrapperClassName="account-mismatch-warning__tooltip-wrapper"
+ containerClassName="account-mismatch-warning__tooltip-container"
+ >
+
+
+ )
+}
+
+AccountMismatchWarning.propTypes = {
+ address: PropTypes.string.isRequired,
+}
diff --git a/ui/app/components/ui/account-mismatch-warning/index.scss b/ui/app/components/ui/account-mismatch-warning/index.scss
new file mode 100644
index 000000000..751640871
--- /dev/null
+++ b/ui/app/components/ui/account-mismatch-warning/index.scss
@@ -0,0 +1,8 @@
+.account-mismatch-warning {
+ &__tooltip-container {
+ &-icon {
+ display: flex;
+ align-items: center;
+ }
+ }
+}
diff --git a/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js b/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js
new file mode 100644
index 000000000..eb71110b5
--- /dev/null
+++ b/ui/app/components/ui/account-mismatch-warning/tests/acccount-mismatch-warning.component.test.js
@@ -0,0 +1,32 @@
+import React from 'react'
+import * as reactRedux from 'react-redux'
+import assert from 'assert'
+import sinon from 'sinon'
+import { shallow } from 'enzyme'
+import InfoIcon from '../../icon/info-icon.component'
+import AccountMismatchWarning from '../account-mismatch-warning.component'
+import { getSelectedAccount } from '../../../../selectors'
+
+describe('AccountMismatchWarning', function () {
+ before(function () {
+ sinon.stub(reactRedux, 'useSelector').callsFake((selector) => {
+ if (selector === getSelectedAccount) {
+ return { address: 'mockedAddress' }
+ }
+ throw new Error(
+ `${selector.name} is not cared for in the AccountMismatchWarning test useSelector stub`
+ )
+ })
+ })
+ it('renders nothing when the addresses match', function () {
+ const wrapper = shallow()
+ assert.equal(wrapper.find(InfoIcon).length, 0)
+ })
+ it('renders a warning info icon when addresses do not match', function () {
+ const wrapper = shallow()
+ assert.equal(wrapper.find(InfoIcon).length, 1)
+ })
+ after(function () {
+ sinon.restore()
+ })
+})
diff --git a/ui/app/components/ui/icon/index.scss b/ui/app/components/ui/icon/index.scss
new file mode 100644
index 000000000..535b52acc
--- /dev/null
+++ b/ui/app/components/ui/icon/index.scss
@@ -0,0 +1,19 @@
+.info-icon {
+ margin: 4px;
+
+ &--success {
+ fill: $success-green;
+ }
+
+ &--info {
+ fill: $info-blue;
+ }
+
+ &--warning {
+ fill: $warning-yellow;
+ }
+
+ &--danger {
+ fill: $danger-red;
+ }
+}
diff --git a/ui/app/components/ui/icon/info-icon.component.js b/ui/app/components/ui/icon/info-icon.component.js
new file mode 100644
index 000000000..1df0ec5e7
--- /dev/null
+++ b/ui/app/components/ui/icon/info-icon.component.js
@@ -0,0 +1,21 @@
+import React from 'react'
+import classnames from 'classnames'
+import PropTypes from 'prop-types'
+
+export default function InfoIcon ({ severity }) {
+ const className = classnames('info-icon', {
+ 'info-icon--success': severity === 'success',
+ 'info-icon--warning': severity === 'warning',
+ 'info-icon--danger': severity === 'danger',
+ 'info-icon--info': severity === 'info',
+ })
+ return (
+
+ )
+}
+
+InfoIcon.propTypes = {
+ severity: PropTypes.oneOf(['success', 'info', 'warning', 'danger']),
+}
diff --git a/ui/app/components/ui/sender-to-recipient/sender-to-recipient.component.js b/ui/app/components/ui/sender-to-recipient/sender-to-recipient.component.js
index e1021e738..3055682b4 100644
--- a/ui/app/components/ui/sender-to-recipient/sender-to-recipient.component.js
+++ b/ui/app/components/ui/sender-to-recipient/sender-to-recipient.component.js
@@ -1,4 +1,4 @@
-import React, { PureComponent } from 'react'
+import React, { useState } from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import Identicon from '../identicon'
@@ -6,6 +6,9 @@ import Tooltip from '../tooltip-v2'
import copyToClipboard from 'copy-to-clipboard'
import { DEFAULT_VARIANT, CARDS_VARIANT, FLAT_VARIANT } from './sender-to-recipient.constants'
import { checksumAddress, shortenAddress } from '../../../helpers/utils/util'
+import AccountMismatchWarning from '../account-mismatch-warning/account-mismatch-warning.component'
+import { useI18nContext } from '../../../hooks/useI18nContext'
+
const variantHash = {
[DEFAULT_VARIANT]: 'sender-to-recipient--default',
@@ -13,67 +16,51 @@ const variantHash = {
[FLAT_VARIANT]: 'sender-to-recipient--flat',
}
-export default class SenderToRecipient extends PureComponent {
- static propTypes = {
- senderName: PropTypes.string,
- senderAddress: PropTypes.string,
- recipientName: PropTypes.string,
- recipientEns: PropTypes.string,
- recipientAddress: PropTypes.string,
- recipientNickname: PropTypes.string,
- variant: PropTypes.oneOf([DEFAULT_VARIANT, CARDS_VARIANT, FLAT_VARIANT]),
- addressOnly: PropTypes.bool,
- assetImage: PropTypes.string,
- onRecipientClick: PropTypes.func,
- onSenderClick: PropTypes.func,
+function SenderAddress ({
+ addressOnly,
+ checksummedSenderAddress,
+ senderName,
+ onSenderClick,
+ senderAddress,
+}) {
+ const t = useI18nContext()
+ const [addressCopied, setAddressCopied] = useState(false)
+ let tooltipHtml = {t('copiedExclamation')}
+ if (!addressCopied) {
+ tooltipHtml = addressOnly
+ ? {t('copyAddress')}
+ : (
+
+ {shortenAddress(checksummedSenderAddress)}
+ {t('copyAddress')}
+
+ )
}
-
- static defaultProps = {
- variant: DEFAULT_VARIANT,
- }
-
- static contextTypes = {
- t: PropTypes.func,
- }
-
- state = {
- senderAddressCopied: false,
- }
-
- renderSenderIdenticon () {
- return !this.props.addressOnly && (
-
-
-
- )
- }
-
- renderSenderAddress () {
- const { t } = this.context
- const { senderName, senderAddress, addressOnly } = this.props
- const checksummedSenderAddress = checksumAddress(senderAddress)
-
- return (
+ return (
+ {
+ setAddressCopied(true)
+ copyToClipboard(checksummedSenderAddress)
+ if (onSenderClick) {
+ onSenderClick()
+ }
+ }}
+ >
+ {!addressOnly && (
+
+
+
+ )}
{t('copiedExclamation')}
- : addressOnly
- ? {t('copyAddress')}
- : (
-
- {shortenAddress(checksummedSenderAddress)}
- {t('copyAddress')}
-
- )
- }
+ html={tooltipHtml}
wrapperClassName="sender-to-recipient__tooltip-wrapper"
containerClassName="sender-to-recipient__tooltip-container"
- onHidden={() => this.setState({ senderAddressCopied: false })}
+ onHidden={() => setAddressCopied(false)}
>
{
@@ -83,129 +70,184 @@ export default class SenderToRecipient extends PureComponent {
}
- )
+
+
+ )
+}
+
+SenderAddress.propTypes = {
+ senderName: PropTypes.string,
+ checksummedSenderAddress: PropTypes.string,
+ addressOnly: PropTypes.bool,
+ senderAddress: PropTypes.string,
+ onSenderClick: PropTypes.func,
+}
+
+function RecipientWithAddress ({
+ checksummedRecipientAddress,
+ assetImage,
+ onRecipientClick,
+ addressOnly,
+ recipientNickname,
+ recipientEns,
+ recipientName,
+}) {
+ const t = useI18nContext()
+ const [addressCopied, setAddressCopied] = useState(false)
+
+ let tooltipHtml = {t('copiedExclamation')}
+ if (!addressCopied) {
+ if (addressOnly && !recipientNickname && !recipientEns) {
+ tooltipHtml = {t('copyAddress')}
+ } else {
+ tooltipHtml = (
+
+ {shortenAddress(checksummedRecipientAddress)}
+ {t('copyAddress')}
+
+ )
+ }
}
+ return (
+ {
+ setAddressCopied(true)
+ copyToClipboard(checksummedRecipientAddress)
+ if (onRecipientClick) {
+ onRecipientClick()
+ }
+ }}
+ >
+ {!addressOnly && (
+
+
+
+ )}
+
setAddressCopied(false)}
+ >
+
+ { addressOnly ? `${t('to')}: ` : '' }
+ {
+ addressOnly
+ ? (recipientNickname || recipientEns || checksummedRecipientAddress)
+ : (recipientNickname || recipientEns || recipientName || t('newContract'))
+ }
+
+
+
+ )
+}
- renderRecipientIdenticon () {
- const { recipientAddress, assetImage } = this.props
- const checksummedRecipientAddress = checksumAddress(recipientAddress)
+RecipientWithAddress.propTypes = {
+ checksummedRecipientAddress: PropTypes.string,
+ recipientName: PropTypes.string,
+ recipientEns: PropTypes.string,
+ recipientNickname: PropTypes.string,
+ addressOnly: PropTypes.bool,
+ assetImage: PropTypes.string,
+ onRecipientClick: PropTypes.func,
+}
- return !this.props.addressOnly && (
-
-
+
+

+
+
+ ) : (
+
+
)
- }
-
- renderRecipientWithAddress () {
- const { t } = this.context
- const { recipientEns, recipientName, recipientAddress, recipientNickname, addressOnly, onRecipientClick } = this.props
- const checksummedRecipientAddress = checksumAddress(recipientAddress)
-
- return (
- {
- copyToClipboard(checksummedRecipientAddress)
- if (onRecipientClick) {
- onRecipientClick()
- }
- }}
- >
- { this.renderRecipientIdenticon() }
-
{t('copiedExclamation')}
- : (addressOnly && !recipientNickname && !recipientEns)
- ? {t('copyAddress')}
- : (
-
- {shortenAddress(checksummedRecipientAddress)}
- {t('copyAddress')}
-
- )
- }
- wrapperClassName="sender-to-recipient__tooltip-wrapper"
- containerClassName="sender-to-recipient__tooltip-container"
- >
-
- { addressOnly ? `${t('to')}: ` : '' }
- {
- addressOnly
- ? (recipientNickname || recipientEns || checksummedRecipientAddress)
- : (recipientNickname || recipientEns || recipientName || this.context.t('newContract'))
- }
-
-
-
- )
- }
-
- renderRecipientWithoutAddress () {
- return (
-
- { !this.props.addressOnly &&
}
-
- { this.context.t('newContract') }
-
-
- )
- }
-
- renderArrow () {
- return this.props.variant === DEFAULT_VARIANT
- ? (
-
-
-

-
-
- ) : (
-
-

-
- )
- }
-
- render () {
- const { senderAddress, recipientAddress, variant, onSenderClick } = this.props
- const checksummedSenderAddress = checksumAddress(senderAddress)
-
- return (
-
-
{
- this.setState({ senderAddressCopied: true })
- copyToClipboard(checksummedSenderAddress)
- if (onSenderClick) {
- onSenderClick()
- }
- }}
- >
- { this.renderSenderIdenticon() }
- { this.renderSenderAddress() }
-
- { this.renderArrow() }
- {
- recipientAddress
- ? this.renderRecipientWithAddress()
- : this.renderRecipientWithoutAddress()
- }
-
- )
- }
+}
+
+Arrow.propTypes = {
+ variant: PropTypes.oneOf([DEFAULT_VARIANT, CARDS_VARIANT, FLAT_VARIANT]),
+}
+
+export default function SenderToRecipient ({
+ senderAddress,
+ addressOnly,
+ assetImage,
+ senderName,
+ recipientNickname,
+ recipientName,
+ recipientEns,
+ onRecipientClick,
+ onSenderClick,
+ recipientAddress,
+ variant = DEFAULT_VARIANT,
+}) {
+ const t = useI18nContext()
+ const checksummedSenderAddress = checksumAddress(senderAddress)
+ const checksummedRecipientAddress = checksumAddress(recipientAddress)
+
+ return (
+
+
+
+ {recipientAddress
+ ? (
+
+ )
+ : (
+
+ { !addressOnly &&
}
+
+ {t('newContract') }
+
+
+ )
+ }
+
+ )
+}
+
+SenderToRecipient.propTypes = {
+ senderName: PropTypes.string,
+ senderAddress: PropTypes.string,
+ recipientName: PropTypes.string,
+ recipientEns: PropTypes.string,
+ recipientAddress: PropTypes.string,
+ recipientNickname: PropTypes.string,
+ variant: PropTypes.oneOf([DEFAULT_VARIANT, CARDS_VARIANT, FLAT_VARIANT]),
+ addressOnly: PropTypes.bool,
+ assetImage: PropTypes.string,
+ onRecipientClick: PropTypes.func,
+ onSenderClick: PropTypes.func,
}
diff --git a/ui/app/components/ui/tooltip-v2.js b/ui/app/components/ui/tooltip-v2.js
index 941ae1e55..8941aa1fd 100644
--- a/ui/app/components/ui/tooltip-v2.js
+++ b/ui/app/components/ui/tooltip-v2.js
@@ -11,6 +11,7 @@ export default class Tooltip extends PureComponent {
interactive: undefined,
onHidden: null,
position: 'left',
+ offset: 0,
size: 'small',
title: null,
trigger: 'mouseenter',
@@ -24,6 +25,7 @@ export default class Tooltip extends PureComponent {
disabled: PropTypes.bool,
html: PropTypes.node,
interactive: PropTypes.bool,
+ offset: PropTypes.number,
onHidden: PropTypes.func,
position: PropTypes.oneOf([
'top',
@@ -53,6 +55,7 @@ export default class Tooltip extends PureComponent {
title,
trigger,
onHidden,
+ offset,
wrapperClassName,
style,
} = this.props
@@ -77,6 +80,7 @@ export default class Tooltip extends PureComponent {
onHidden={onHidden}
position={position}
size={size}
+ offset={offset}
style={style}
title={title}
trigger={trigger}
diff --git a/ui/app/pages/send/account-list-item/account-list-item.component.js b/ui/app/pages/send/account-list-item/account-list-item.component.js
index 944bc35fb..58df336e5 100644
--- a/ui/app/pages/send/account-list-item/account-list-item.component.js
+++ b/ui/app/pages/send/account-list-item/account-list-item.component.js
@@ -1,4 +1,4 @@
-import React, { Component } from 'react'
+import React from 'react'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import { checksumAddress } from '../../../helpers/utils/util'
@@ -6,105 +6,96 @@ import Identicon from '../../../components/ui/identicon'
import UserPreferencedCurrencyDisplay from '../../../components/app/user-preferenced-currency-display'
import { PRIMARY, SECONDARY } from '../../../helpers/constants/common'
import Tooltip from '../../../components/ui/tooltip-v2'
+import AccountMismatchWarning from '../../../components/ui/account-mismatch-warning/account-mismatch-warning.component'
+import { useI18nContext } from '../../../hooks/useI18nContext'
-export default class AccountListItem extends Component {
+export default function AccountListItem ({
+ account,
+ className,
+ displayAddress = false,
+ displayBalance = true,
+ handleClick,
+ icon = null,
+ balanceIsCached,
+ showFiat = true,
+}) {
+ const t = useI18nContext()
+ const { name, address, balance } = account || {}
- static propTypes = {
- account: PropTypes.object,
- className: PropTypes.string,
- displayAddress: PropTypes.bool,
- displayBalance: PropTypes.bool,
- handleClick: PropTypes.func,
- icon: PropTypes.node,
- balanceIsCached: PropTypes.bool,
- showFiat: PropTypes.bool,
- }
+ return (
+ handleClick && handleClick({ name, address, balance })}
+ >
- static defaultProps = {
- showFiat: true,
- }
+
+
- static contextTypes = {
- t: PropTypes.func,
- }
+
{ name || address }
- render () {
- const {
- account,
- className,
- displayAddress = false,
- displayBalance = true,
- handleClick,
- icon = null,
- balanceIsCached,
- showFiat,
- } = this.props
-
- const { name, address, balance } = account || {}
-
- return (
-
handleClick && handleClick({ name, address, balance })}
- >
-
-
-
-
-
{ name || address }
-
- {icon &&
{ icon }
}
-
-
-
- {displayAddress && name && (
-
- { checksumAddress(address) }
-
- )}
-
- {displayBalance && (
-
-
-
-
- {
- balanceIsCached
- ? *
- : null
- }
-
- {showFiat && (
-
- )}
-
-
- )}
+ {icon &&
{ icon }
}
+
- )
- }
+
+ {displayAddress && name && (
+
+ { checksumAddress(address) }
+
+ )}
+
+ {displayBalance && (
+
+
+
+
+ {
+ balanceIsCached
+ ? *
+ : null
+ }
+
+ {showFiat && (
+
+ )}
+
+
+ )}
+
+
+ )
+}
+
+AccountListItem.propTypes = {
+ account: PropTypes.object,
+ className: PropTypes.string,
+ displayAddress: PropTypes.bool,
+ displayBalance: PropTypes.bool,
+ handleClick: PropTypes.func,
+ icon: PropTypes.node,
+ balanceIsCached: PropTypes.bool,
+ showFiat: PropTypes.bool,
}
diff --git a/ui/app/pages/send/account-list-item/tests/account-list-item-component.test.js b/ui/app/pages/send/account-list-item/tests/account-list-item-component.test.js
index e64a0e6f2..83c55e232 100644
--- a/ui/app/pages/send/account-list-item/tests/account-list-item-component.test.js
+++ b/ui/app/pages/send/account-list-item/tests/account-list-item-component.test.js
@@ -2,27 +2,21 @@ import React from 'react'
import assert from 'assert'
import { shallow } from 'enzyme'
import sinon from 'sinon'
-import proxyquire from 'proxyquire'
+import * as utils from '../../../../helpers/utils/util'
import Identicon from '../../../../components/ui/identicon'
import UserPreferencedCurrencyDisplay from '../../../../components/app/user-preferenced-currency-display'
-
-const utilsMethodStubs = {
- checksumAddress: sinon.stub().returns('mockCheckSumAddress'),
-}
-
-const AccountListItem = proxyquire('../account-list-item.component.js', {
- '../../../helpers/utils/util': utilsMethodStubs,
-}).default
-
-
-const propsMethodSpies = {
- handleClick: sinon.spy(),
-}
+import AccountListItem from '../account-list-item.component'
describe('AccountListItem Component', function () {
- let wrapper
+ let wrapper, propsMethodSpies, checksumAddressStub
describe('render', function () {
+ before(function () {
+ checksumAddressStub = sinon.stub(utils, 'checksumAddress').returns('mockCheckSumAddress')
+ propsMethodSpies = {
+ handleClick: sinon.spy(),
+ }
+ })
beforeEach(function () {
wrapper = shallow((