diff --git a/src/payment/data/reducers.js b/src/payment/data/reducers.js index bca6a50bf..1771d5d93 100644 --- a/src/payment/data/reducers.js +++ b/src/payment/data/reducers.js @@ -196,17 +196,19 @@ const paymentState = (state = basketInitialState, action = null) => { }, }; - case pollPaymentState.RECEIVED: + case pollPaymentState.RECEIVED: { + const isHttpError = action.payload.state === PAYMENT_STATE.HTTP_ERROR; + const currErrorCount = (isHttpError ? state.paymentStatePolling.errorCount - 1 : maxErrors); return { ...state, paymentState: action.payload.state, paymentStatePolling: { ...state.paymentStatePolling, - keepPolling: shouldPoll(action.payload.state), - errorCount: (action.payload.state === PAYMENT_STATE.HTTP_ERROR - ? state.paymentStatePolling.errorCount - 1 : maxErrors), + keepPolling: currErrorCount > 0 && shouldPoll(action.payload.state), + errorCount: currErrorCount, }, }; + } default: } diff --git a/src/payment/data/redux.test.js b/src/payment/data/redux.test.js index b3b793926..d1c4953cd 100644 --- a/src/payment/data/redux.test.js +++ b/src/payment/data/redux.test.js @@ -231,9 +231,10 @@ describe('redux tests', () => { }); }); - describe('pollPaymentState actions', () => { - it('Round Trip', () => { - const triggerStore = createStore( + describe('pollPaymentState actions + reducers', () => { + let triggerStore; + beforeEach(() => { + triggerStore = createStore( combineReducers({ payment: reducer, }), @@ -252,7 +253,11 @@ describe('redux tests', () => { }, }, ); + }); + + afterEach(() => { triggerStore = undefined; }); + it('Round Trip (No Error)', () => { triggerStore.dispatch(pollPaymentState()); expect(triggerStore.getState().payment.basket.paymentStatePolling.keepPolling).toBe(true); expect(triggerStore.getState().payment.basket.paymentState).toBe(PAYMENT_STATE.PENDING); @@ -265,6 +270,41 @@ describe('redux tests', () => { expect(triggerStore.getState().payment.basket.paymentStatePolling.keepPolling).toBe(false); expect(triggerStore.getState().payment.basket.paymentState === PAYMENT_STATE.PENDING).toBe(false); }); + + it('Round Trip (Fatal Error)', () => { + triggerStore.dispatch(pollPaymentState()); + expect(triggerStore.getState().payment.basket.paymentStatePolling.keepPolling).toBe(true); + expect(triggerStore.getState().payment.basket.paymentState).toBe(PAYMENT_STATE.PENDING); + + triggerStore.dispatch(pollPaymentState.failure(Error('Something broke!'))); + expect(triggerStore.getState().payment.basket.paymentStatePolling.keepPolling).toBe(false); + expect(triggerStore.getState().payment.basket.paymentState).toBe(null); + }); + + it('Round Trip (Max HTTP Error)', () => { + const pollingMaxErrors = DEFAULT_PAYMENT_STATE_POLLING_MAX_ERRORS; + + triggerStore.dispatch(pollPaymentState()); + expect(triggerStore.getState().payment.basket.paymentStatePolling.keepPolling).toBe(true); + expect(triggerStore.getState().payment.basket.paymentState).toBe(PAYMENT_STATE.PENDING); + + for (let i = 0; pollingMaxErrors > i; i++) { + const expectedCount = pollingMaxErrors - 1 - i; + triggerStore.dispatch(pollPaymentState.received({ state: PAYMENT_STATE.HTTP_ERROR })); + expect(triggerStore.getState().payment.basket.paymentStatePolling.keepPolling) + .toBe(expectedCount > 0); + expect(triggerStore.getState().payment.basket.paymentStatePolling.errorCount) + .toBe(expectedCount); + } + + expect(triggerStore.getState().payment.basket.paymentStatePolling.keepPolling).toBe(false); + expect(triggerStore.getState().payment.basket.paymentStatePolling.errorCount) + .toBe(0); + + triggerStore.dispatch(pollPaymentState.failure(Error('Too many HTTP errors!'))); + expect(triggerStore.getState().payment.basket.paymentStatePolling.keepPolling).toBe(false); + expect(triggerStore.getState().payment.basket.paymentState).toBe(null); + }); }); }); });