diff options
author | Chi Kei Chan <chikeichan@gmail.com> | 2019-04-18 03:15:13 +0800 |
---|---|---|
committer | Dan J Miller <danjm.com@gmail.com> | 2019-04-18 03:15:13 +0800 |
commit | 931aaeb7003f175374a06eb949cd47a12ebc8bbf (patch) | |
tree | fe67bd73faf453f5f06ebae1987da5a2338f2e41 /ui/app/pages/send/send-header | |
parent | a844eb20da700b832003f63b83fc42ba74392d6c (diff) | |
download | tangerine-wallet-browser-931aaeb7003f175374a06eb949cd47a12ebc8bbf.tar tangerine-wallet-browser-931aaeb7003f175374a06eb949cd47a12ebc8bbf.tar.gz tangerine-wallet-browser-931aaeb7003f175374a06eb949cd47a12ebc8bbf.tar.bz2 tangerine-wallet-browser-931aaeb7003f175374a06eb949cd47a12ebc8bbf.tar.lz tangerine-wallet-browser-931aaeb7003f175374a06eb949cd47a12ebc8bbf.tar.xz tangerine-wallet-browser-931aaeb7003f175374a06eb949cd47a12ebc8bbf.tar.zst tangerine-wallet-browser-931aaeb7003f175374a06eb949cd47a12ebc8bbf.zip |
Add token selection to the send screen (#6445)
* Move send to pages/
* Fix unit tests
* Finish UI
* Integrate asset dropdown to send actions
* Remove console.log
* Hide asset change during edit
* Enable switch from send token to seand eth
* Enable switching from token to eth when editing
* Fix linter
* Fixing test
* Fix unit tests
* Fix linter
* Fix react warning; remove console.log
* fix flat test
* Add metrics
* Address code review comments
* Consistent spacing between send screen form rows.
* Reduce height of gas buttons on send screen.
* Make send screen gas button height dependent on size of contents.
Diffstat (limited to 'ui/app/pages/send/send-header')
8 files changed, 267 insertions, 0 deletions
diff --git a/ui/app/pages/send/send-header/README.md b/ui/app/pages/send/send-header/README.md new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/ui/app/pages/send/send-header/README.md diff --git a/ui/app/pages/send/send-header/index.js b/ui/app/pages/send/send-header/index.js new file mode 100644 index 000000000..0b17f0b7d --- /dev/null +++ b/ui/app/pages/send/send-header/index.js @@ -0,0 +1 @@ +export { default } from './send-header.container' diff --git a/ui/app/pages/send/send-header/send-header.component.js b/ui/app/pages/send/send-header/send-header.component.js new file mode 100644 index 000000000..02bda383e --- /dev/null +++ b/ui/app/pages/send/send-header/send-header.component.js @@ -0,0 +1,34 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import PageContainerHeader from '../../../components/ui/page-container/page-container-header' +import { DEFAULT_ROUTE } from '../../../helpers/constants/routes' + +export default class SendHeader extends Component { + + static propTypes = { + clearSend: PropTypes.func, + history: PropTypes.object, + titleKey: PropTypes.string, + subtitleParams: PropTypes.array, + }; + + static contextTypes = { + t: PropTypes.func, + }; + + onClose () { + this.props.clearSend() + this.props.history.push(DEFAULT_ROUTE) + } + + render () { + return ( + <PageContainerHeader + onClose={() => this.onClose()} + subtitle={this.context.t(...this.props.subtitleParams)} + title={this.context.t(this.props.titleKey)} + /> + ) + } + +} diff --git a/ui/app/pages/send/send-header/send-header.container.js b/ui/app/pages/send/send-header/send-header.container.js new file mode 100644 index 000000000..1a9c5e9c0 --- /dev/null +++ b/ui/app/pages/send/send-header/send-header.container.js @@ -0,0 +1,19 @@ +import { connect } from 'react-redux' +import { clearSend } from '../../../store/actions' +import SendHeader from './send-header.component' +import { getSubtitleParams, getTitleKey } from './send-header.selectors' + +export default connect(mapStateToProps, mapDispatchToProps)(SendHeader) + +function mapStateToProps (state) { + return { + titleKey: getTitleKey(state), + subtitleParams: getSubtitleParams(state), + } +} + +function mapDispatchToProps (dispatch) { + return { + clearSend: () => dispatch(clearSend()), + } +} diff --git a/ui/app/pages/send/send-header/send-header.selectors.js b/ui/app/pages/send/send-header/send-header.selectors.js new file mode 100644 index 000000000..d7c9d3766 --- /dev/null +++ b/ui/app/pages/send/send-header/send-header.selectors.js @@ -0,0 +1,37 @@ +const { + getSelectedToken, + getSendEditingTransactionId, +} = require('../send.selectors.js') + +const selectors = { + getTitleKey, + getSubtitleParams, +} + +module.exports = selectors + +function getTitleKey (state) { + const isEditing = Boolean(getSendEditingTransactionId(state)) + const isToken = Boolean(getSelectedToken(state)) + + if (isEditing) { + return 'edit' + } else if (isToken) { + return 'sendTokens' + } else { + return 'sendETH' + } +} + +function getSubtitleParams (state) { + const isEditing = Boolean(getSendEditingTransactionId(state)) + const token = getSelectedToken(state) + + if (isEditing) { + return [ 'editingTransaction' ] + } else if (token) { + return [ 'onlySendTokensToAccountAddress', [ token.symbol ] ] + } else { + return [ 'onlySendToEtherAddress' ] + } +} diff --git a/ui/app/pages/send/send-header/tests/send-header-component.test.js b/ui/app/pages/send/send-header/tests/send-header-component.test.js new file mode 100644 index 000000000..4a5575e9f --- /dev/null +++ b/ui/app/pages/send/send-header/tests/send-header-component.test.js @@ -0,0 +1,70 @@ +import React from 'react' +import assert from 'assert' +import { shallow } from 'enzyme' +import sinon from 'sinon' +import { DEFAULT_ROUTE } from '../../../../helpers/constants/routes' +import SendHeader from '../send-header.component.js' + +import PageContainerHeader from '../../../../components/ui/page-container/page-container-header' + +const propsMethodSpies = { + clearSend: sinon.spy(), +} +const historySpies = { + push: sinon.spy(), +} + +sinon.spy(SendHeader.prototype, 'onClose') + +describe('SendHeader Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow(<SendHeader + clearSend={propsMethodSpies.clearSend} + history={historySpies} + titleKey={'mockTitleKey'} + subtitleParams={[ 'mockSubtitleKey', 'mockVal']} + />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) + }) + + afterEach(() => { + propsMethodSpies.clearSend.resetHistory() + historySpies.push.resetHistory() + SendHeader.prototype.onClose.resetHistory() + }) + + describe('onClose', () => { + it('should call clearSend', () => { + assert.equal(propsMethodSpies.clearSend.callCount, 0) + wrapper.instance().onClose() + assert.equal(propsMethodSpies.clearSend.callCount, 1) + }) + + it('should call history.push', () => { + assert.equal(historySpies.push.callCount, 0) + wrapper.instance().onClose() + assert.equal(historySpies.push.callCount, 1) + assert.equal(historySpies.push.getCall(0).args[0], DEFAULT_ROUTE) + }) + }) + + describe('render', () => { + it('should render a PageContainerHeader compenent', () => { + assert.equal(wrapper.find(PageContainerHeader).length, 1) + }) + + it('should pass the correct props to PageContainerHeader', () => { + const { + onClose, + subtitle, + title, + } = wrapper.find(PageContainerHeader).props() + assert.equal(subtitle, 'mockSubtitleKeymockVal') + assert.equal(title, 'mockTitleKey') + assert.equal(SendHeader.prototype.onClose.callCount, 0) + onClose() + assert.equal(SendHeader.prototype.onClose.callCount, 1) + }) + }) +}) diff --git a/ui/app/pages/send/send-header/tests/send-header-container.test.js b/ui/app/pages/send/send-header/tests/send-header-container.test.js new file mode 100644 index 000000000..fdad8aab3 --- /dev/null +++ b/ui/app/pages/send/send-header/tests/send-header-container.test.js @@ -0,0 +1,59 @@ +import assert from 'assert' +import proxyquire from 'proxyquire' +import sinon from 'sinon' + +let mapStateToProps +let mapDispatchToProps + +const actionSpies = { + clearSend: sinon.spy(), +} + +proxyquire('../send-header.container.js', { + 'react-redux': { + connect: (ms, md) => { + mapStateToProps = ms + mapDispatchToProps = md + return () => ({}) + }, + }, + '../../../store/actions': actionSpies, + './send-header.selectors': { + getTitleKey: (s) => `mockTitleKey:${s}`, + getSubtitleParams: (s) => `mockSubtitleParams:${s}`, + }, +}) + +describe('send-header container', () => { + + describe('mapStateToProps()', () => { + + it('should map the correct properties to props', () => { + assert.deepEqual(mapStateToProps('mockState'), { + titleKey: 'mockTitleKey:mockState', + subtitleParams: 'mockSubtitleParams:mockState', + }) + }) + + }) + + describe('mapDispatchToProps()', () => { + let dispatchSpy + let mapDispatchToPropsObject + + beforeEach(() => { + dispatchSpy = sinon.spy() + mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) + }) + + describe('clearSend()', () => { + it('should dispatch an action', () => { + mapDispatchToPropsObject.clearSend() + assert(dispatchSpy.calledOnce) + assert(actionSpies.clearSend.calledOnce) + }) + }) + + }) + +}) diff --git a/ui/app/pages/send/send-header/tests/send-header-selectors.test.js b/ui/app/pages/send/send-header/tests/send-header-selectors.test.js new file mode 100644 index 000000000..e0c6a3ab3 --- /dev/null +++ b/ui/app/pages/send/send-header/tests/send-header-selectors.test.js @@ -0,0 +1,47 @@ +import assert from 'assert' +import proxyquire from 'proxyquire' + +const { + getTitleKey, + getSubtitleParams, +} = proxyquire('../send-header.selectors', { + '../send.selectors': { + getSelectedToken: (mockState) => mockState.t, + getSendEditingTransactionId: (mockState) => mockState.e, + }, +}) + +describe('send-header selectors', () => { + + describe('getTitleKey()', () => { + it('should return the correct key when getSendEditingTransactionId is truthy', () => { + assert.equal(getTitleKey({ e: 1, t: true }), 'edit') + }) + + it('should return the correct key when getSendEditingTransactionId is falsy and getSelectedToken is truthy', () => { + assert.equal(getTitleKey({ e: null, t: 'abc' }), 'sendTokens') + }) + + it('should return the correct key when getSendEditingTransactionId is falsy and getSelectedToken is falsy', () => { + assert.equal(getTitleKey({ e: null }), 'sendETH') + }) + }) + + describe('getSubtitleParams()', () => { + it('should return the correct params when getSendEditingTransactionId is truthy', () => { + assert.deepEqual(getSubtitleParams({ e: 1, t: true }), [ 'editingTransaction' ]) + }) + + it('should return the correct params when getSendEditingTransactionId is falsy and getSelectedToken is truthy', () => { + assert.deepEqual( + getSubtitleParams({ e: null, t: { symbol: 'ABC' } }), + [ 'onlySendTokensToAccountAddress', [ 'ABC' ] ] + ) + }) + + it('should return the correct params when getSendEditingTransactionId is falsy and getSelectedToken is falsy', () => { + assert.deepEqual(getSubtitleParams({ e: null }), [ 'onlySendToEtherAddress' ]) + }) + }) + +}) |