Adds test for send, send-content, send-footer and send-header components.

This commit is contained in:
Dan 2018-05-07 08:03:20 -04:00
parent 7c49009854
commit 9ccc609e56
6 changed files with 516 additions and 16 deletions

View File

@ -0,0 +1,38 @@
import React from 'react'
import assert from 'assert'
import { shallow } from 'enzyme'
import SendContent from '../send-content.component.js'
import PageContainerContent from '../../../page-container/page-container-content.component'
import SendAmountRow from '../send-amount-row/send-amount-row.container'
import SendFromRow from '../send-from-row/send-from-row.container'
import SendGasRow from '../send-gas-row/send-gas-row.container'
import SendToRow from '../send-to-row/send-to-row.container'
describe('Send Component', function () {
let wrapper
beforeEach(() => {
wrapper = shallow(<SendContent />)
})
describe('render', () => {
it('should render a PageContainerContent component', () => {
assert.equal(wrapper.find(PageContainerContent).length, 1)
})
it('should render a div with a .send-v2__form class as a child of PageContainerContent', () => {
const PageContainerContentChild = wrapper.find(PageContainerContent).children()
PageContainerContentChild.is('div')
PageContainerContentChild.is('.send-v2__form')
})
it('should render the correct row components as grandchildren of the PageContainerContent component', () => {
const PageContainerContentChild = wrapper.find(PageContainerContent).children()
PageContainerContentChild.childAt(0).is(SendFromRow)
PageContainerContentChild.childAt(1).is(SendToRow)
PageContainerContentChild.childAt(2).is(SendAmountRow)
PageContainerContentChild.childAt(3).is(SendGasRow)
})
})
})

View File

@ -26,6 +26,11 @@ export default class SendFooter extends Component {
update: PropTypes.func,
};
onCancel () {
this.props.clearSend()
this.props.history.push(DEFAULT_ROUTE)
}
onSubmit (event) {
event.preventDefault()
const {
@ -44,7 +49,7 @@ export default class SendFooter extends Component {
toAccounts,
} = this.props
// Should not be needed because submit should be disabled if there are no errors.
// Should not be needed because submit should be disabled if there are errors.
// const noErrors = !amountError && toError === null
// if (!noErrors) {
@ -70,18 +75,12 @@ export default class SendFooter extends Component {
this.props.history.push(CONFIRM_TRANSACTION_ROUTE)
}
render () {
const { clearSend, disabled, history } = this.props
return (
<PageContainerFooter
onCancel={() => {
clearSend()
history.push(DEFAULT_ROUTE)
}}
onCancel={() => this.onCancel()}
onSubmit={e => this.onSubmit(e)}
disabled={disabled}
disabled={this.props.disabled}
/>
)
}

View File

@ -0,0 +1,159 @@
import React from 'react'
import assert from 'assert'
import { shallow } from 'enzyme'
import sinon from 'sinon'
import { CONFIRM_TRANSACTION_ROUTE, DEFAULT_ROUTE } from '../../../../routes'
import SendFooter from '../send-footer.component.js'
import PageContainerFooter from '../../../page-container/page-container-footer'
const propsMethodSpies = {
addToAddressBookIfNew: sinon.spy(),
clearSend: sinon.spy(),
sign: sinon.spy(),
update: sinon.spy(),
}
const historySpies = {
push: sinon.spy(),
}
const MOCK_EVENT = { preventDefault: () => {} }
sinon.spy(SendFooter.prototype, 'onCancel')
sinon.spy(SendFooter.prototype, 'onSubmit')
describe('Send Component', function () {
let wrapper
beforeEach(() => {
wrapper = shallow(<SendFooter
addToAddressBookIfNew={propsMethodSpies.addToAddressBookIfNew}
amount={'mockAmount'}
clearSend={propsMethodSpies.clearSend}
disabled={true}
editingTransactionId={'mockEditingTransactionId'}
errors={{}}
from={ { address: 'mockAddress', balance: 'mockBalance' } }
gasLimit={'mockGasLimit'}
gasPrice={'mockGasPrice'}
gasTotal={'mockGasTotal'}
history={historySpies}
selectedToken={{ mockProp: 'mockSelectedTokenProp' }}
sign={propsMethodSpies.sign}
to={'mockTo'}
toAccounts={['mockAccount']}
tokenBalance={'mockTokenBalance'}
unapprovedTxs={['mockTx']}
update={propsMethodSpies.update}
/>, { context: { t: str => str } })
instance = wrapper.instance()
})
afterEach(() => {
propsMethodSpies.clearSend.resetHistory()
propsMethodSpies.addToAddressBookIfNew.resetHistory()
propsMethodSpies.clearSend.resetHistory()
propsMethodSpies.sign.resetHistory()
propsMethodSpies.update.resetHistory()
historySpies.push.resetHistory()
SendFooter.prototype.onCancel.resetHistory()
SendFooter.prototype.onSubmit.resetHistory()
})
describe('onCancel', () => {
it('should call clearSend', () => {
assert.equal(propsMethodSpies.clearSend.callCount, 0)
wrapper.instance().onCancel()
assert.equal(propsMethodSpies.clearSend.callCount, 1)
})
it('should call history.push', () => {
assert.equal(historySpies.push.callCount, 0)
wrapper.instance().onCancel()
assert.equal(historySpies.push.callCount, 1)
assert.equal(historySpies.push.getCall(0).args[0], DEFAULT_ROUTE)
})
})
describe('onSubmit', () => {
it('should call addToAddressBookIfNew with the correct params', () => {
wrapper.instance().onSubmit(MOCK_EVENT)
assert(propsMethodSpies.addToAddressBookIfNew.calledOnce)
assert.deepEqual(
propsMethodSpies.addToAddressBookIfNew.getCall(0).args,
['mockTo', ['mockAccount']]
)
})
it('should call props.update if editingTransactionId is truthy', () => {
wrapper.instance().onSubmit(MOCK_EVENT)
assert(propsMethodSpies.update.calledOnce)
assert.deepEqual(
propsMethodSpies.update.getCall(0).args[0],
{
amount: 'mockAmount',
editingTransactionId: 'mockEditingTransactionId',
from: 'mockAddress',
gas: 'mockGasLimit',
gasPrice: 'mockGasPrice',
selectedToken: { mockProp: 'mockSelectedTokenProp' },
to: 'mockTo',
unapprovedTxs: ['mockTx'],
}
)
})
it('should not call props.sign if editingTransactionId is truthy', () => {
assert.equal(propsMethodSpies.sign.callCount, 0)
})
it('should call props.sign if editingTransactionId is falsy', () => {
wrapper.setProps({ editingTransactionId: null })
wrapper.instance().onSubmit(MOCK_EVENT)
assert(propsMethodSpies.sign.calledOnce)
assert.deepEqual(
propsMethodSpies.sign.getCall(0).args[0],
{
amount: 'mockAmount',
from: 'mockAddress',
gas: 'mockGasLimit',
gasPrice: 'mockGasPrice',
selectedToken: { mockProp: 'mockSelectedTokenProp' },
to: 'mockTo',
}
)
})
it('should not call props.update if editingTransactionId is falsy', () => {
assert.equal(propsMethodSpies.update.callCount, 0)
})
it('should call history.push', () => {
wrapper.instance().onSubmit(MOCK_EVENT)
assert.equal(historySpies.push.callCount, 1)
assert.equal(historySpies.push.getCall(0).args[0], CONFIRM_TRANSACTION_ROUTE)
})
})
describe('render', () => {
it('should render a PageContainerFooter component', () => {
assert.equal(wrapper.find(PageContainerFooter).length, 1)
})
it('should pass the correct props to PageContainerFooter', () => {
const {
onCancel,
onSubmit,
disabled,
} = wrapper.find(PageContainerFooter).props()
assert.equal(disabled, true)
assert.equal(SendFooter.prototype.onSubmit.callCount, 0)
onSubmit(MOCK_EVENT)
assert.equal(SendFooter.prototype.onSubmit.callCount, 1)
assert.equal(SendFooter.prototype.onCancel.callCount, 0)
onCancel()
assert.equal(SendFooter.prototype.onCancel.callCount, 1)
})
})
})

View File

@ -11,17 +11,17 @@ export default class SendHeader extends Component {
isToken: PropTypes.bool,
};
render () {
const { isToken, clearSend, history } = this.props
onClose () {
this.props.clearSend()
this.props.history.push(DEFAULT_ROUTE)
}
render () {
return (
<PageContainerHeader
onClose={() => {
clearSend()
history.push(DEFAULT_ROUTE)
}}
onClose={() => this.onClose()}
subtitle={this.context.t('onlySendToEtherAddress')}
title={isToken ? this.context.t('sendTokens') : this.context.t('sendETH')}
title={this.props.isToken ? this.context.t('sendTokens') : this.context.t('sendETH')}
/>
)
}

View File

@ -0,0 +1,70 @@
import React from 'react'
import assert from 'assert'
import { shallow } from 'enzyme'
import sinon from 'sinon'
import { DEFAULT_ROUTE } from '../../../../routes'
import SendHeader from '../send-header.component.js'
import PageContainerHeader from '../../../page-container/page-container-header'
const propsMethodSpies = {
clearSend: sinon.spy(),
}
const historySpies = {
push: sinon.spy(),
}
sinon.spy(SendHeader.prototype, 'onClose')
describe('Send Component', function () {
let wrapper
beforeEach(() => {
wrapper = shallow(<SendHeader
clearSend={propsMethodSpies.clearSend}
history={historySpies}
isToken={false}
/>, { context: { t: str => str } })
instance = wrapper.instance()
})
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, 'onlySendToEtherAddress')
assert.equal(title, 'sendETH')
assert.equal(SendHeader.prototype.onClose.callCount, 0)
onClose()
assert.equal(SendHeader.prototype.onClose.callCount, 1)
})
})
})

View File

@ -0,0 +1,234 @@
import React from 'react'
import assert from 'assert'
import proxyquire from 'proxyquire'
import { shallow } from 'enzyme'
import sinon from 'sinon'
import SendHeader from '../send-header/send-header.container'
import SendContent from '../send-content/send-content.component'
import SendFooter from '../send-footer/send-footer.container'
const propsMethodSpies = {
updateAndSetGasTotal: sinon.spy(),
updateSendErrors: sinon.spy(),
updateSendTokenBalance: sinon.spy(),
}
const utilsMethodStubs = {
getAmountErrorObject: sinon.stub().returns({ amount: 'mockAmountError' }),
doesAmountErrorRequireUpdate: sinon.stub().callsFake(obj => obj.balance !== obj.prevBalance),
}
const SendTransactionScreen = proxyquire('../send.component.js', {
'./send.utils': utilsMethodStubs,
}).default
sinon.spy(SendTransactionScreen.prototype, 'componentDidMount')
sinon.spy(SendTransactionScreen.prototype, 'updateGas')
describe('Send Component', function () {
let wrapper
beforeEach(() => {
wrapper = shallow(<SendTransactionScreen
amount={'mockAmount'}
amountConversionRate={'mockAmountConversionRate'}
conversionRate={10}
data={'mockData'}
editingTransactionId={'mockEditingTransactionId'}
from={ { address: 'mockAddress', balance: 'mockBalance' } }
gasLimit={'mockGasLimit'}
gasPrice={'mockGasPrice'}
gasTotal={'mockGasTotal'}
history={{ mockProp: 'history-abc'}}
network={'3'}
primaryCurrency={'mockPrimaryCurrency'}
selectedAddress={'mockSelectedAddress'}
selectedToken={'mockSelectedToken'}
tokenBalance={'mockTokenBalance'}
tokenContract={'mockTokenContract'}
updateAndSetGasTotal={propsMethodSpies.updateAndSetGasTotal}
updateSendErrors={propsMethodSpies.updateSendErrors}
updateSendTokenBalance={propsMethodSpies.updateSendTokenBalance}
/>)
instance = wrapper.instance()
})
afterEach(() => {
SendTransactionScreen.prototype.componentDidMount.resetHistory()
SendTransactionScreen.prototype.updateGas.resetHistory()
utilsMethodStubs.doesAmountErrorRequireUpdate.resetHistory()
utilsMethodStubs.getAmountErrorObject.resetHistory()
propsMethodSpies.updateAndSetGasTotal.resetHistory()
propsMethodSpies.updateSendErrors.resetHistory()
propsMethodSpies.updateSendTokenBalance.resetHistory()
})
it('should call componentDidMount', () => {
assert(SendTransactionScreen.prototype.componentDidMount.calledOnce)
})
describe('componentWillMount', () => {
it('should call this.updateGas', () => {
assert(SendTransactionScreen.prototype.updateGas.calledOnce)
wrapper.instance().componentWillMount()
assert(SendTransactionScreen.prototype.updateGas.calledTwice)
})
})
describe('componentDidUpdate', () => {
it('should call doesAmountErrorRequireUpdate with the expected params', () => {
wrapper.instance().componentDidUpdate({
from: {
balance: '',
},
})
assert(utilsMethodStubs.doesAmountErrorRequireUpdate.calledOnce)
assert.deepEqual(
utilsMethodStubs.doesAmountErrorRequireUpdate.getCall(0).args[0],
{
balance: 'mockBalance',
gasTotal: 'mockGasTotal',
prevBalance: '',
prevGasTotal: undefined,
prevTokenBalance: undefined,
selectedToken: 'mockSelectedToken',
tokenBalance: 'mockTokenBalance',
}
)
})
it('should not call getAmountErrorObject if doesAmountErrorRequireUpdate returns false', () => {
wrapper.instance().componentDidUpdate({
from: {
balance: 'mockBalance',
},
})
assert.equal(utilsMethodStubs.getAmountErrorObject.callCount, 0)
})
it('should call getAmountErrorObject if doesAmountErrorRequireUpdate returns true', () => {
wrapper.instance().componentDidUpdate({
from: {
balance: 'balanceChanged',
},
})
assert.equal(utilsMethodStubs.getAmountErrorObject.callCount, 1)
assert.deepEqual(
utilsMethodStubs.getAmountErrorObject.getCall(0).args[0],
{
amount: 'mockAmount',
amountConversionRate: 'mockAmountConversionRate',
balance: 'mockBalance',
conversionRate: 10,
gasTotal: 'mockGasTotal',
primaryCurrency: 'mockPrimaryCurrency',
selectedToken: 'mockSelectedToken',
tokenBalance: 'mockTokenBalance',
}
)
})
it('should call updateSendErrors with the expected params', () => {
wrapper.instance().componentDidUpdate({
from: {
balance: 'balanceChanged',
},
})
assert.equal(propsMethodSpies.updateSendErrors.callCount, 1)
assert.deepEqual(
propsMethodSpies.updateSendErrors.getCall(0).args[0],
{ amount: 'mockAmountError'}
)
})
it('should not call updateSendTokenBalance or this.updateGas if network === prevNetwork', () => {
SendTransactionScreen.prototype.updateGas.resetHistory()
wrapper.instance().componentDidUpdate({
from: {
balance: 'balanceChanged',
},
network: '3',
})
assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 0)
assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0)
})
it('should not call updateSendTokenBalance or this.updateGas if network === loading', () => {
wrapper.setProps({ network: 'loading' })
SendTransactionScreen.prototype.updateGas.resetHistory()
propsMethodSpies.updateSendTokenBalance.resetHistory()
wrapper.instance().componentDidUpdate({
from: {
balance: 'balanceChanged',
},
network: '3',
})
assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 0)
assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0)
})
it('should call updateSendTokenBalance and this.updateGas with the correct params', () => {
SendTransactionScreen.prototype.updateGas.resetHistory()
wrapper.instance().componentDidUpdate({
from: {
balance: 'balanceChanged',
},
network: '2',
})
assert.equal(propsMethodSpies.updateSendTokenBalance.callCount, 1)
assert.deepEqual(
propsMethodSpies.updateSendTokenBalance.getCall(0).args[0],
{
selectedToken: 'mockSelectedToken',
tokenContract: 'mockTokenContract',
address: 'mockAddress',
}
)
assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1)
assert.deepEqual(
SendTransactionScreen.prototype.updateGas.getCall(0).args,
[]
)
})
})
describe('updateGas', () => {
it('should call updateAndSetGasTotal with the correct params', () => {
propsMethodSpies.updateAndSetGasTotal.resetHistory()
wrapper.instance().updateGas()
assert.equal(propsMethodSpies.updateAndSetGasTotal.callCount, 1)
assert.deepEqual(
propsMethodSpies.updateAndSetGasTotal.getCall(0).args[0],
{
data: 'mockData',
editingTransactionId: 'mockEditingTransactionId',
gasLimit: 'mockGasLimit',
gasPrice: 'mockGasPrice',
selectedAddress: 'mockSelectedAddress',
selectedToken: 'mockSelectedToken',
}
)
})
})
describe('render', () => {
it('should render a page-container class', () => {
assert.equal(wrapper.find('.page-container').length, 1)
})
it('should render SendHeader, SendContent and SendFooter', () => {
assert.equal(wrapper.find(SendHeader).length, 1)
assert.equal(wrapper.find(SendContent).length, 1)
assert.equal(wrapper.find(SendFooter).length, 1)
})
it('should pass the history prop to SendHeader and SendFooter', () => {
assert.deepEqual(
wrapper.find(SendFooter).props(),
{
history: { mockProp: 'history-abc' },
}
)
})
})
})