From 25bcdfcac82740a655b9ee3b02f0b7cedaaab3be Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Wed, 5 Feb 2020 09:45:46 -0330 Subject: [PATCH] Fix SendAmountRow tests (#7968) * Rewrite SendAmountRow tests to avoid flakiness * Use sinon@5.0.1 * Dedupe supports-color versions --- .../tests/send-amount-row-component.test.js | 226 +++++++++--------- yarn.lock | 44 ++-- 2 files changed, 127 insertions(+), 143 deletions(-) diff --git a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js index 41474acf2..f1ef75bc9 100644 --- a/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js +++ b/ui/app/pages/send/send-content/send-amount-row/tests/send-amount-row-component.test.js @@ -8,100 +8,55 @@ import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component' import AmountMaxButton from '../amount-max-button/amount-max-button.container' import UserPreferencedTokenInput from '../../../../../components/app/user-preferenced-token-input' -import timeout from '../../../../../../lib/test-timeout' - -const propsMethodSpies = { - setMaxModeTo: sinon.spy(), - updateSendAmount: sinon.spy(), - updateSendAmountError: sinon.spy(), - updateGas: sinon.spy(), - updateGasFeeError: sinon.spy(), -} - -sinon.spy(SendAmountRow.prototype, 'updateAmount') -sinon.spy(SendAmountRow.prototype, 'validateAmount') -sinon.spy(SendAmountRow.prototype, 'updateGas') - describe('SendAmountRow Component', function () { - let wrapper - let instance - - beforeEach(() => { - wrapper = shallow(( - - ), { context: { t: str => str + '_t' } }) - instance = wrapper.instance() - }) - - afterEach(() => { - propsMethodSpies.setMaxModeTo.resetHistory() - propsMethodSpies.updateSendAmount.resetHistory() - propsMethodSpies.updateSendAmountError.resetHistory() - propsMethodSpies.updateGasFeeError.resetHistory() - SendAmountRow.prototype.validateAmount.resetHistory() - SendAmountRow.prototype.updateAmount.resetHistory() - }) - describe('validateAmount', () => { - it('should call updateSendAmountError with the correct params', () => { - assert.equal(propsMethodSpies.updateSendAmountError.callCount, 0) + const { instance, propsMethodSpies: { updateSendAmountError } } = shallowRenderSendAmountRow() + + assert.equal(updateSendAmountError.callCount, 0) + instance.validateAmount('someAmount') - assert.equal(propsMethodSpies.updateSendAmountError.callCount, 1) - assert.deepEqual( - propsMethodSpies.updateSendAmountError.getCall(0).args, - [{ - amount: 'someAmount', - amountConversionRate: 'mockAmountConversionRate', - balance: 'mockBalance', - conversionRate: 7, - gasTotal: 'mockGasTotal', - primaryCurrency: 'mockPrimaryCurrency', - selectedToken: { address: 'mockTokenAddress' }, - tokenBalance: 'mockTokenBalance', - }] - ) + + assert.ok(updateSendAmountError.calledOnceWithExactly({ + amount: 'someAmount', + amountConversionRate: 'mockAmountConversionRate', + balance: 'mockBalance', + conversionRate: 7, + gasTotal: 'mockGasTotal', + primaryCurrency: 'mockPrimaryCurrency', + selectedToken: { address: 'mockTokenAddress' }, + tokenBalance: 'mockTokenBalance', + })) }) it('should call updateGasFeeError if selectedToken is truthy', () => { - assert.equal(propsMethodSpies.updateGasFeeError.callCount, 0) + const { instance, propsMethodSpies: { updateGasFeeError } } = shallowRenderSendAmountRow() + + assert.equal(updateGasFeeError.callCount, 0) + instance.validateAmount('someAmount') - assert.equal(propsMethodSpies.updateGasFeeError.callCount, 1) - assert.deepEqual( - propsMethodSpies.updateGasFeeError.getCall(0).args, - [{ - amountConversionRate: 'mockAmountConversionRate', - balance: 'mockBalance', - conversionRate: 7, - gasTotal: 'mockGasTotal', - primaryCurrency: 'mockPrimaryCurrency', - selectedToken: { address: 'mockTokenAddress' }, - tokenBalance: 'mockTokenBalance', - }] - ) + + assert.ok(updateGasFeeError.calledOnceWithExactly({ + amountConversionRate: 'mockAmountConversionRate', + balance: 'mockBalance', + conversionRate: 7, + gasTotal: 'mockGasTotal', + primaryCurrency: 'mockPrimaryCurrency', + selectedToken: { address: 'mockTokenAddress' }, + tokenBalance: 'mockTokenBalance', + })) }) it('should call not updateGasFeeError if selectedToken is falsey', () => { + const { wrapper, instance, propsMethodSpies: { updateGasFeeError } } = shallowRenderSendAmountRow() + wrapper.setProps({ selectedToken: null }) - assert.equal(propsMethodSpies.updateGasFeeError.callCount, 0) + + assert.equal(updateGasFeeError.callCount, 0) + instance.validateAmount('someAmount') - assert.equal(propsMethodSpies.updateGasFeeError.callCount, 0) + + assert.equal(updateGasFeeError.callCount, 0) }) }) @@ -109,33 +64,36 @@ describe('SendAmountRow Component', function () { describe('updateAmount', () => { it('should call setMaxModeTo', () => { - assert.equal(propsMethodSpies.setMaxModeTo.callCount, 0) + const { instance, propsMethodSpies: { setMaxModeTo } } = shallowRenderSendAmountRow() + + assert.equal(setMaxModeTo.callCount, 0) + instance.updateAmount('someAmount') - assert.equal(propsMethodSpies.setMaxModeTo.callCount, 1) - assert.deepEqual( - propsMethodSpies.setMaxModeTo.getCall(0).args, - [false] - ) + + assert.ok(setMaxModeTo.calledOnceWithExactly(false)) }) it('should call updateSendAmount', () => { - assert.equal(propsMethodSpies.updateSendAmount.callCount, 0) + const { instance, propsMethodSpies: { updateSendAmount } } = shallowRenderSendAmountRow() + + assert.equal(updateSendAmount.callCount, 0) + instance.updateAmount('someAmount') - assert.equal(propsMethodSpies.updateSendAmount.callCount, 1) - assert.deepEqual( - propsMethodSpies.updateSendAmount.getCall(0).args, - ['someAmount'] - ) + + assert.ok(updateSendAmount.calledOnceWithExactly('someAmount')) }) }) describe('render', () => { it('should render a SendRowWrapper component', () => { + const { wrapper } = shallowRenderSendAmountRow() + assert.equal(wrapper.find(SendRowWrapper).length, 1) }) it('should pass the correct props to SendRowWrapper', () => { + const { wrapper } = shallowRenderSendAmountRow() const { errorType, label, @@ -143,47 +101,87 @@ describe('SendAmountRow Component', function () { } = wrapper.find(SendRowWrapper).props() assert.equal(errorType, 'amount') - assert.equal(label, 'amount_t:') - assert.equal(showError, false) }) it('should render an AmountMaxButton as the first child of the SendRowWrapper', () => { + const { wrapper } = shallowRenderSendAmountRow() + assert(wrapper.find(SendRowWrapper).childAt(0).is(AmountMaxButton)) }) it('should render a UserPreferencedTokenInput as the second child of the SendRowWrapper', () => { + const { wrapper } = shallowRenderSendAmountRow() + assert(wrapper.find(SendRowWrapper).childAt(1).is(UserPreferencedTokenInput)) }) - it('should render the UserPreferencedTokenInput with the correct props', async () => { + it('should render the UserPreferencedTokenInput with the correct props', () => { + const { wrapper, instanceSpies: { updateGas, updateAmount, validateAmount } } = shallowRenderSendAmountRow() const { onChange, error, value, } = wrapper.find(SendRowWrapper).childAt(1).props() + assert.equal(error, false) assert.equal(value, 'mockAmount') - assert.equal(SendAmountRow.prototype.updateGas.callCount, 0) - assert.equal(SendAmountRow.prototype.updateAmount.callCount, 0) - assert.equal(SendAmountRow.prototype.validateAmount.callCount, 0) + assert.equal(updateGas.callCount, 0) + assert.equal(updateAmount.callCount, 0) + assert.equal(validateAmount.callCount, 0) + onChange('mockNewAmount') - await timeout(501) - assert.deepEqual( - SendAmountRow.prototype.updateGas.getCall(0).args, - ['mockNewAmount'] - ) - assert.equal(SendAmountRow.prototype.updateAmount.callCount, 1) - assert.deepEqual( - SendAmountRow.prototype.updateAmount.getCall(0).args, - ['mockNewAmount'] - ) - assert.equal(SendAmountRow.prototype.validateAmount.callCount, 1) - assert.deepEqual( - SendAmountRow.prototype.validateAmount.getCall(0).args, - ['mockNewAmount'] - ) + + assert.ok(updateGas.calledOnceWithExactly('mockNewAmount')) + assert.ok(updateAmount.calledOnceWithExactly('mockNewAmount')) + assert.ok(validateAmount.calledOnceWithExactly('mockNewAmount')) }) }) }) + +function shallowRenderSendAmountRow () { + const setMaxModeTo = sinon.spy() + const updateGasFeeError = sinon.spy() + const updateSendAmount = sinon.spy() + const updateSendAmountError = sinon.spy() + const wrapper = shallow(( + {}} + /> + ), { context: { t: str => str + '_t' } }) + const instance = wrapper.instance() + const updateAmount = sinon.spy(instance, 'updateAmount') + const updateGas = sinon.spy(instance, 'updateGas') + const validateAmount = sinon.spy(instance, 'validateAmount') + + return { + instance, + wrapper, + propsMethodSpies: { + setMaxModeTo, + updateGasFeeError, + updateSendAmount, + updateSendAmountError, + }, + instanceSpies: { + updateAmount, + updateGas, + validateAmount, + }, + } +} diff --git a/yarn.lock b/yarn.lock index 9e47248d2..98a8ee2ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2301,6 +2301,13 @@ dependencies: type-detect "4.0.8" +"@sinonjs/formatio@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2" + integrity sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg== + dependencies: + samsam "1.3.0" + "@sinonjs/formatio@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.1.0.tgz#6ac9d1eb1821984d84c4996726e45d1646d8cce5" @@ -12425,13 +12432,6 @@ format@^0.2.2: resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" integrity sha1-1hcBB+nv3E7TDJ3DkBbflCtctYs= -formatio@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb" - integrity sha1-87IWfZBoxGmKjVH092CjmlTYGOs= - dependencies: - samsam "1.x" - formidable@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.1.tgz#70fb7ca0290ee6ff961090415f4b3df3d2082659" @@ -24976,7 +24976,7 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -samsam@1.x: +samsam@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" integrity sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg== @@ -25663,16 +25663,16 @@ single-line-log@^1.1.2: string-width "^1.0.1" sinon@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-5.0.0.tgz#e6de3b3f7fed338b470f8779dc4bab9fca058894" - integrity sha512-dMX7ZB2E1iQ5DOEOePoNJQp03uyhdMfb+kLXlNPbquv2FwfezD+0GbbHSgCw4MFhpSSS9NMoYJfOPMjCMJtXWA== + version "5.0.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-5.0.1.tgz#e399e00b30df53abf816f16cfc8f3aa0a480ada2" + integrity sha512-xhPMTWl8dusKsa/4Px+K0FCHsAhcpxjMurofDzPr6BF1I5C2G6r4JLIaHKSOcMnXkt7X4Md0OZgJuuIqlw9ieA== dependencies: + "@sinonjs/formatio" "^2.0.0" diff "^3.1.0" - formatio "1.2.0" lodash.get "^4.4.2" lolex "^2.2.0" nise "^1.2.0" - supports-color "^4.4.0" + supports-color "^5.1.0" type-detect "^4.0.5" sisteransi@^1.0.3: @@ -26933,34 +26933,20 @@ supports-color@^2.0.0: resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= -supports-color@^4.0.0, supports-color@^4.4.0, supports-color@^4.5.0: +supports-color@^4.0.0, supports-color@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" integrity sha1-vnoN5ITexcXN34s9WRJQRJEvY1s= dependencies: has-flag "^2.0.0" -supports-color@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.3.0.tgz#5b24ac15db80fa927cf5227a4a33fd3c4c7676c0" - integrity sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg== - dependencies: - has-flag "^3.0.0" - -supports-color@^5.3.0: +supports-color@^5.1.0, supports-color@^5.2.0, supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" -supports-color@^5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== - dependencies: - has-flag "^3.0.0" - supports-color@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"