From 2d6dbbcb1872d3859abda5068b481b86bf73013c Mon Sep 17 00:00:00 2001 From: Danny Skubak Date: Sun, 21 Jan 2018 13:23:09 -0500 Subject: [PATCH] Cancel Requests on Wallet Switch (#873) * add cancellation to nonce * add cancellation to account/token balance updates * update tests --- common/sagas/transaction/network/nonce.ts | 14 ++++++++-- common/sagas/wallet/wallet.ts | 8 ++++-- spec/sagas/transaction/network/nonce.spec.ts | 28 +++++++++++++++++--- spec/sagas/wallet.spec.tsx | 18 ++++++++++--- 4 files changed, 58 insertions(+), 10 deletions(-) diff --git a/common/sagas/transaction/network/nonce.ts b/common/sagas/transaction/network/nonce.ts index 071af61c..2f3f7ead 100644 --- a/common/sagas/transaction/network/nonce.ts +++ b/common/sagas/transaction/network/nonce.ts @@ -1,6 +1,6 @@ import { getNonceSucceeded, getNonceFailed, TypeKeys as TK, inputNonce } from 'actions/transaction'; import { SagaIterator } from 'redux-saga'; -import { apply, put, select, takeEvery } from 'redux-saga/effects'; +import { apply, put, select, takeEvery, fork, cancel, take } from 'redux-saga/effects'; import { INode } from 'libs/nodes/INode'; import { AppState } from 'reducers'; import { getNodeLib, getOffline } from 'selectors/config'; @@ -33,5 +33,15 @@ export function* handleNonceRequest(): SagaIterator { } } +export function* handleNonceRequestWrapper(): SagaIterator { + const nonceRequest = yield fork(handleNonceRequest); + + yield take(WalletTK.WALLET_SET); + yield cancel(nonceRequest); +} + //leave get nonce requested for nonce refresh later on -export const nonce = takeEvery([TK.GET_NONCE_REQUESTED, WalletTK.WALLET_SET], handleNonceRequest); +export const nonce = takeEvery( + [TK.GET_NONCE_REQUESTED, WalletTK.WALLET_SET], + handleNonceRequestWrapper +); diff --git a/common/sagas/wallet/wallet.ts b/common/sagas/wallet/wallet.ts index 62c2dfa9..afff2ce5 100644 --- a/common/sagas/wallet/wallet.ts +++ b/common/sagas/wallet/wallet.ts @@ -163,8 +163,12 @@ export function* handleSetWalletTokens(action: SetWalletTokensAction): SagaItera } export function* updateBalances(): SagaIterator { - yield fork(updateAccountBalance); - yield fork(updateTokenBalances); + const updateAccount = yield fork(updateAccountBalance); + const updateToken = yield fork(updateTokenBalances); + + yield take(TypeKeys.WALLET_SET); + yield cancel(updateAccount); + yield cancel(updateToken); } export function* handleNewWallet(): SagaIterator { diff --git a/spec/sagas/transaction/network/nonce.spec.ts b/spec/sagas/transaction/network/nonce.spec.ts index 868ac7ed..596d6fc1 100644 --- a/spec/sagas/transaction/network/nonce.spec.ts +++ b/spec/sagas/transaction/network/nonce.spec.ts @@ -1,10 +1,11 @@ import { getNonceSucceeded, getNonceFailed, inputNonce } from 'actions/transaction'; -import { apply, put, select } from 'redux-saga/effects'; +import { apply, put, select, fork, take, cancel } from 'redux-saga/effects'; import { getNodeLib, getOffline } from 'selectors/config'; import { getWalletInst } from 'selectors/wallet'; import { showNotification } from 'actions/notifications'; -import { handleNonceRequest } from 'sagas/transaction/network/nonce'; -import { cloneableGenerator } from 'redux-saga/utils'; +import { handleNonceRequest, handleNonceRequestWrapper } from 'sagas/transaction/network/nonce'; +import { cloneableGenerator, createMockTask } from 'redux-saga/utils'; +import { TypeKeys as WalletTK } from 'actions/wallet'; import { Nonce } from 'libs/units'; describe('handleNonceRequest*', () => { @@ -77,3 +78,24 @@ describe('handleNonceRequest*', () => { expect(gens.gen.next().value).toEqual(put(getNonceSucceeded(retrievedNonce))); }); }); + +describe('handleNonceRequestWrapper*', () => { + const gen = handleNonceRequestWrapper(); + const nonceRequest = createMockTask(); + + it('should fork handleNonceRequest', () => { + expect(gen.next().value).toEqual(fork(handleNonceRequest)); + }); + + it('should take on WALLET_SET', () => { + expect(gen.next(nonceRequest).value).toEqual(take(WalletTK.WALLET_SET)); + }); + + it('should cancel nonceRequest', () => { + expect(gen.next().value).toEqual(cancel(nonceRequest)); + }); + + it('should be done', () => { + expect(gen.next().done).toEqual(true); + }); +}); diff --git a/spec/sagas/wallet.spec.tsx b/spec/sagas/wallet.spec.tsx index b6f8e3ae..6a330b83 100644 --- a/spec/sagas/wallet.spec.tsx +++ b/spec/sagas/wallet.spec.tsx @@ -8,13 +8,14 @@ import { unlockMnemonic as unlockMnemonicActionGen, setTokenBalancesFulfilled, setTokenBalancesPending, - setTokenBalancesRejected + setTokenBalancesRejected, + TypeKeys } from 'actions/wallet'; import { Wei } from 'libs/units'; import { changeNodeIntent, web3UnsetNode } from 'actions/config'; import { INode } from 'libs/nodes/INode'; import { initWeb3Node, Token, N_FACTOR } from 'config'; -import { apply, call, fork, put, select, take } from 'redux-saga/effects'; +import { apply, call, fork, put, select, take, cancel } from 'redux-saga/effects'; import { getNodeLib, getOffline } from 'selectors/config'; import { getWalletInst, getWalletConfigTokens } from 'selectors/wallet'; import { @@ -190,13 +191,24 @@ describe('updateTokenBalances*', () => { describe('updateBalances*', () => { const gen = updateBalances(); + const updateAccount = createMockTask(); + const updateToken = createMockTask(); it('should fork updateAccountBalance', () => { expect(gen.next().value).toEqual(fork(updateAccountBalance)); }); it('should fork updateTokenBalances', () => { - expect(gen.next().value).toEqual(fork(updateTokenBalances)); + expect(gen.next(updateAccount).value).toEqual(fork(updateTokenBalances)); + }); + + it('should take on WALLET_SET', () => { + expect(gen.next(updateToken).value).toEqual(take(TypeKeys.WALLET_SET)); + }); + + it('should cancel updates', () => { + expect(gen.next().value).toEqual(cancel(updateAccount)); + expect(gen.next().value).toEqual(cancel(updateToken)); }); it('should be done', () => {