diff --git a/lib/utils/reducers-utils.js b/lib/utils/reducers-utils.js new file mode 100644 --- /dev/null +++ b/lib/utils/reducers-utils.js @@ -0,0 +1,24 @@ +// @flow + +import type { BaseNavInfo } from '../types/nav-types.js'; +import type { BaseAppState } from '../types/redux-types.js'; + +function resetUserSpecificStateOnIdentityActions< + N: BaseNavInfo, + T: BaseAppState, +>( + state: T, + defaultState: T, + nonUserSpecificFields: $ReadOnlyArray<$Keys>, +): T { + let newState: T = { ...defaultState }; + for (const field of nonUserSpecificFields) { + newState = { + ...newState, + [(field: string)]: state[field], + }; + } + return newState; +} + +export { resetUserSpecificStateOnIdentityActions }; diff --git a/lib/utils/reducers-utils.test.js b/lib/utils/reducers-utils.test.js new file mode 100644 --- /dev/null +++ b/lib/utils/reducers-utils.test.js @@ -0,0 +1,122 @@ +// @flow + +import { defaultNotifPermissionAlertInfo } from './push-alerts.js'; +import { resetUserSpecificStateOnIdentityActions } from './reducers-utils.js'; +import { ashoatKeyserverID } from './validation-utils.js'; +import { defaultWebEnabledApps } from '../types/enabled-apps.js'; +import { defaultCalendarFilters } from '../types/filter-types.js'; +import { defaultKeyserverInfo } from '../types/keyserver-types.js'; +import { defaultGlobalThemeInfo } from '../types/theme-types.js'; + +describe('resetUserSpecificStateOnIdentityActions', () => { + let defaultState; + let state; + beforeAll(() => { + defaultState = { + navInfo: { + activeChatThreadID: null, + startDate: '', + endDate: '', + tab: 'chat', + }, + currentUserInfo: null, + draftStore: { drafts: {} }, + entryStore: { + entryInfos: {}, + daysToEntries: {}, + lastUserInteractionCalendar: 0, + }, + threadStore: { + threadInfos: {}, + }, + userStore: { + userInfos: {}, + }, + messageStore: { + messages: {}, + threads: {}, + local: {}, + currentAsOf: { [ashoatKeyserverID]: 0 }, + }, + windowActive: true, + pushApiPublicKey: null, + cryptoStore: null, + loadingStatuses: {}, + calendarFilters: defaultCalendarFilters, + dataLoaded: false, + notifPermissionAlertInfo: defaultNotifPermissionAlertInfo, + watchedThreadIDs: [], + lifecycleState: 'active', + enabledApps: defaultWebEnabledApps, + reportStore: { + enabledReports: { + crashReports: false, + inconsistencyReports: false, + mediaReports: false, + }, + queuedReports: [], + }, + nextLocalID: 0, + _persist: null, + userPolicies: {}, + commServicesAccessToken: null, + inviteLinksStore: { + links: {}, + }, + actualizedCalendarQuery: { + startDate: '', + endDate: '', + filters: defaultCalendarFilters, + }, + communityPickerStore: { chat: null, calendar: null }, + keyserverStore: { + keyserverInfos: { + [ashoatKeyserverID]: defaultKeyserverInfo('url'), + }, + }, + threadActivityStore: {}, + initialStateLoaded: false, + integrityStore: { threadHashes: {}, threadHashingStatus: 'starting' }, + globalThemeInfo: defaultGlobalThemeInfo, + customServer: null, + }; + state = { + ...defaultState, + globalThemeInfo: { + activeTheme: 'light', + preference: 'light', + systemTheme: null, + }, + communityPickerStore: { chat: '256|1', calendar: '256|1' }, + nextLocalID: 9, + navInfo: { + activeChatThreadID: null, + startDate: '2023-02-02', + endDate: '2023-03-02', + tab: 'calendar', + }, + }; + }); + it("doesn't reset fields named in nonUserSpecificFields", () => { + const nonUserSpecificFields = [ + 'globalThemeInfo', + 'communityPickerStore', + 'nextLocalID', + 'navInfo', + ]; + + expect( + resetUserSpecificStateOnIdentityActions( + state, + defaultState, + nonUserSpecificFields, + ), + ).toEqual(state); + }); + + it('resets fields not named in nonUserSpecificFields', () => { + expect( + resetUserSpecificStateOnIdentityActions(state, defaultState, []), + ).toEqual(defaultState); + }); +});