diff --git a/lib/reducers/db-ops-reducer.js b/lib/reducers/db-ops-reducer.js new file mode 100644 --- /dev/null +++ b/lib/reducers/db-ops-reducer.js @@ -0,0 +1,21 @@ +// @flow + +import { opsProcessingFinishedActionType } from '../actions/db-ops-actions.js'; +import type { DBOpsStore } from '../types/db-ops-types.js'; +import type { BaseAction } from '../types/redux-types.js'; + +function reduceDBOpsStore(store: DBOpsStore, action: BaseAction): DBOpsStore { + if (action.type === opsProcessingFinishedActionType) { + const ids = new Set(action.payload.actionIDs); + return { + ...store, + queuedOps: store.queuedOps.filter( + ops => ops.opsID !== action.payload.opsID, + ), + noOpsActions: store.noOpsActions.filter(id => !ids.has(id)), + }; + } + return store; +} + +export { reduceDBOpsStore }; diff --git a/lib/reducers/db-ops-reducer.test.js b/lib/reducers/db-ops-reducer.test.js new file mode 100644 --- /dev/null +++ b/lib/reducers/db-ops-reducer.test.js @@ -0,0 +1,73 @@ +// @flow + +import { reduceDBOpsStore } from './db-ops-reducer.js'; +import { opsProcessingFinishedActionType } from '../actions/db-ops-actions.js'; +import type { DBOpsStore } from '../types/db-ops-types.js'; + +const emptyOps = { + draftStoreOperations: [], + threadStoreOperations: [], + messageStoreOperations: [], + reportStoreOperations: [], + userStoreOperations: [], + keyserverStoreOperations: [], + communityStoreOperations: [], +}; + +describe('DB ops reducer', () => { + const store: DBOpsStore = { + queuedOps: [ + { opsID: '1', ops: emptyOps, actionID: '5' }, + { opsID: '4', ops: emptyOps, actionID: '6' }, + { opsID: '5', ops: emptyOps, actionID: '7' }, + ], + noOpsActions: ['3', '6', '8'], + }; + + it('should filter ops', () => { + const newState = reduceDBOpsStore(store, { + type: opsProcessingFinishedActionType, + payload: { actionIDs: [], opsID: '4' }, + }); + expect(newState.queuedOps.length).toEqual(2); + expect(newState.queuedOps[0].opsID).toEqual('1'); + expect(newState.queuedOps[1].opsID).toEqual('5'); + }); + + it('should filter actions without ops', () => { + const newState = reduceDBOpsStore(store, { + type: opsProcessingFinishedActionType, + payload: { actionIDs: ['3', '6'] }, + }); + expect(newState.noOpsActions.length).toEqual(1); + expect(newState.noOpsActions[0]).toEqual('8'); + }); + + it('should filter both queues', () => { + const newState = reduceDBOpsStore(store, { + type: opsProcessingFinishedActionType, + payload: { actionIDs: ['6'], opsID: '1' }, + }); + expect(newState.noOpsActions.length).toEqual(2); + expect(newState.queuedOps.length).toEqual(2); + }); + + it("shouldn't filter ops when ids aren't present", () => { + const newState = reduceDBOpsStore(store, { + type: opsProcessingFinishedActionType, + payload: { actionIDs: ['10'] }, + }); + expect(newState.noOpsActions.length).toEqual(3); + expect(newState.queuedOps.length).toEqual(3); + }); + + it("shouldn't change queue order", () => { + const newState = reduceDBOpsStore(store, { + type: opsProcessingFinishedActionType, + payload: { opsID: '4', actionIDs: [] }, + }); + expect(newState.queuedOps.length).toEqual(2); + expect(newState.queuedOps[0].actionID).toEqual('5'); + expect(newState.queuedOps[1].actionID).toEqual('7'); + }); +}); diff --git a/lib/reducers/master-reducer.js b/lib/reducers/master-reducer.js --- a/lib/reducers/master-reducer.js +++ b/lib/reducers/master-reducer.js @@ -4,6 +4,7 @@ import { reduceCommunityStore } from './community-reducer.js'; import reduceCustomerServer from './custom-server-reducer.js'; import reduceDataLoaded from './data-loaded-reducer.js'; +import { reduceDBOpsStore } from './db-ops-reducer.js'; import { reduceDraftStore } from './draft-reducer.js'; import reduceEnabledApps from './enabled-apps-reducer.js'; import { reduceEntryInfos } from './entry-reducer.js'; @@ -206,6 +207,7 @@ globalThemeInfo: reduceGlobalThemeInfo(state.globalThemeInfo, action), customServer: reduceCustomerServer(state.customServer, action), communityStore, + dbOpsStore: reduceDBOpsStore(state.dbOpsStore, action), }, storeOperations: { draftStoreOperations,