From 8d76d6b712271c16178f410dffaf8b6843890c52 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 17 Dec 2024 09:32:36 -0700 Subject: [PATCH] Merge pull request #54249 from Expensify/revert-53374-fix/store-accountid-when-importing-state Revert "fix: display all LHN options in Import state mode" (cherry picked from commit 5ebb12b1a5f262225576f689fb7b216478f91fcb) (CP triggered by luacmartins) --- src/ONYXKEYS.ts | 4 - .../ImportOnyxState/index.native.tsx | 17 ++-- src/components/ImportOnyxState/index.tsx | 26 +++--- src/components/ImportOnyxState/types.ts | 1 + src/components/ImportOnyxState/utils.ts | 2 +- src/libs/actions/App.ts | 19 ---- .../Troubleshoot/TroubleshootPage.tsx | 5 +- tests/unit/ImportOnyxStateTest.ts | 93 ------------------- 8 files changed, 31 insertions(+), 136 deletions(-) delete mode 100644 tests/unit/ImportOnyxStateTest.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index e19aa71cce52..2e65b5f372b4 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -452,9 +452,6 @@ const ONYXKEYS = { /** The user's Concierge reportID */ CONCIERGE_REPORT_ID: 'conciergeReportID', - /** The user's session that will be preserved when using imported state */ - PRESERVED_USER_SESSION: 'preservedUserSession', - /** Collection Keys */ COLLECTION: { DOWNLOAD: 'download_', @@ -1017,7 +1014,6 @@ type OnyxValuesMapping = { [ONYXKEYS.IS_USING_IMPORTED_STATE]: boolean; [ONYXKEYS.NVP_EXPENSIFY_COMPANY_CARDS_CUSTOM_NAMES]: Record; [ONYXKEYS.CONCIERGE_REPORT_ID]: string; - [ONYXKEYS.PRESERVED_USER_SESSION]: OnyxTypes.Session; [ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING]: OnyxTypes.DismissedProductTraining; }; type OnyxValues = OnyxValuesMapping & OnyxCollectionValuesMapping & OnyxFormValuesMapping & OnyxFormDraftValuesMapping; diff --git a/src/components/ImportOnyxState/index.native.tsx b/src/components/ImportOnyxState/index.native.tsx index bdd805241c55..2258da4c8f6c 100644 --- a/src/components/ImportOnyxState/index.native.tsx +++ b/src/components/ImportOnyxState/index.native.tsx @@ -1,12 +1,11 @@ import React, {useState} from 'react'; import ReactNativeBlobUtil from 'react-native-blob-util'; -import Onyx, {useOnyx} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import type {FileObject} from '@components/AttachmentModal'; -import {KEYS_TO_PRESERVE, setIsUsingImportedState, setPreservedUserSession} from '@libs/actions/App'; +import {KEYS_TO_PRESERVE, setIsUsingImportedState} from '@libs/actions/App'; import {setShouldForceOffline} from '@libs/actions/Network'; import Navigation from '@libs/Navigation/Navigation'; import type {OnyxValues} from '@src/ONYXKEYS'; -import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import BaseImportOnyxState from './BaseImportOnyxState'; import type ImportOnyxStateProps from './types'; @@ -46,9 +45,8 @@ function applyStateInChunks(state: OnyxValues) { return promise; } -export default function ImportOnyxState({setIsLoading}: ImportOnyxStateProps) { +export default function ImportOnyxState({setIsLoading, isLoading}: ImportOnyxStateProps) { const [isErrorModalVisible, setIsErrorModalVisible] = useState(false); - const [session] = useOnyx(ONYXKEYS.SESSION); const handleFileRead = (file: FileObject) => { if (!file.uri) { @@ -59,8 +57,6 @@ export default function ImportOnyxState({setIsLoading}: ImportOnyxStateProps) { readOnyxFile(file.uri) .then((fileContent: string) => { const transformedState = cleanAndTransformState(fileContent); - const currentUserSessionCopy = {...session}; - setPreservedUserSession(currentUserSessionCopy); setShouldForceOffline(true); Onyx.clear(KEYS_TO_PRESERVE).then(() => { applyStateInChunks(transformedState).then(() => { @@ -71,7 +67,14 @@ export default function ImportOnyxState({setIsLoading}: ImportOnyxStateProps) { }) .catch(() => { setIsErrorModalVisible(true); + }) + .finally(() => { + setIsLoading(false); }); + + if (isLoading) { + setIsLoading(false); + } }; return ( diff --git a/src/components/ImportOnyxState/index.tsx b/src/components/ImportOnyxState/index.tsx index 2f9a2b70b65b..8add2d9172fd 100644 --- a/src/components/ImportOnyxState/index.tsx +++ b/src/components/ImportOnyxState/index.tsx @@ -1,19 +1,17 @@ import React, {useState} from 'react'; -import Onyx, {useOnyx} from 'react-native-onyx'; +import Onyx from 'react-native-onyx'; import type {FileObject} from '@components/AttachmentModal'; -import {KEYS_TO_PRESERVE, setIsUsingImportedState, setPreservedUserSession} from '@libs/actions/App'; +import {KEYS_TO_PRESERVE, setIsUsingImportedState} from '@libs/actions/App'; import {setShouldForceOffline} from '@libs/actions/Network'; import Navigation from '@libs/Navigation/Navigation'; import type {OnyxValues} from '@src/ONYXKEYS'; -import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import BaseImportOnyxState from './BaseImportOnyxState'; import type ImportOnyxStateProps from './types'; import {cleanAndTransformState} from './utils'; -export default function ImportOnyxState({setIsLoading}: ImportOnyxStateProps) { +export default function ImportOnyxState({setIsLoading, isLoading}: ImportOnyxStateProps) { const [isErrorModalVisible, setIsErrorModalVisible] = useState(false); - const [session] = useOnyx(ONYXKEYS.SESSION); const handleFileRead = (file: FileObject) => { if (!file.uri) { @@ -29,20 +27,26 @@ export default function ImportOnyxState({setIsLoading}: ImportOnyxStateProps) { .then((text) => { const fileContent = text; const transformedState = cleanAndTransformState(fileContent); - const currentUserSessionCopy = {...session}; - setPreservedUserSession(currentUserSessionCopy); setShouldForceOffline(true); Onyx.clear(KEYS_TO_PRESERVE).then(() => { - Onyx.multiSet(transformedState).then(() => { - setIsUsingImportedState(true); - Navigation.navigate(ROUTES.HOME); - }); + Onyx.multiSet(transformedState) + .then(() => { + setIsUsingImportedState(true); + Navigation.navigate(ROUTES.HOME); + }) + .finally(() => { + setIsLoading(false); + }); }); }) .catch(() => { setIsErrorModalVisible(true); setIsLoading(false); }); + + if (isLoading) { + setIsLoading(false); + } }; return ( diff --git a/src/components/ImportOnyxState/types.ts b/src/components/ImportOnyxState/types.ts index 2b4b56a3b20c..8e504c493529 100644 --- a/src/components/ImportOnyxState/types.ts +++ b/src/components/ImportOnyxState/types.ts @@ -1,4 +1,5 @@ type ImportOnyxStateProps = { + isLoading: boolean; setIsLoading: (isLoading: boolean) => void; }; diff --git a/src/components/ImportOnyxState/utils.ts b/src/components/ImportOnyxState/utils.ts index 94779868384d..a5f24fa80714 100644 --- a/src/components/ImportOnyxState/utils.ts +++ b/src/components/ImportOnyxState/utils.ts @@ -3,7 +3,7 @@ import type {UnknownRecord} from 'type-fest'; import ONYXKEYS from '@src/ONYXKEYS'; // List of Onyx keys from the .txt file we want to keep for the local override -const keysToOmit = [ONYXKEYS.ACTIVE_CLIENTS, ONYXKEYS.FREQUENTLY_USED_EMOJIS, ONYXKEYS.NETWORK, ONYXKEYS.CREDENTIALS, ONYXKEYS.PREFERRED_THEME]; +const keysToOmit = [ONYXKEYS.ACTIVE_CLIENTS, ONYXKEYS.FREQUENTLY_USED_EMOJIS, ONYXKEYS.NETWORK, ONYXKEYS.CREDENTIALS, ONYXKEYS.SESSION, ONYXKEYS.PREFERRED_THEME]; function isRecord(value: unknown): value is Record { return typeof value === 'object' && !Array.isArray(value) && value !== null; diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts index 931f9e226995..61ce04655ae5 100644 --- a/src/libs/actions/App.ts +++ b/src/libs/actions/App.ts @@ -89,14 +89,6 @@ Onyx.connect({ }, }); -let preservedUserSession: OnyxTypes.Session | undefined; -Onyx.connect({ - key: ONYXKEYS.PRESERVED_USER_SESSION, - callback: (value) => { - preservedUserSession = value; - }, -}); - const KEYS_TO_PRESERVE: OnyxKey[] = [ ONYXKEYS.ACCOUNT, ONYXKEYS.IS_CHECKING_PUBLIC_ROOM, @@ -110,7 +102,6 @@ const KEYS_TO_PRESERVE: OnyxKey[] = [ ONYXKEYS.PREFERRED_THEME, ONYXKEYS.NVP_PREFERRED_LOCALE, ONYXKEYS.CREDENTIALS, - ONYXKEYS.PRESERVED_USER_SESSION, ]; Onyx.connect({ @@ -533,10 +524,6 @@ function setIsUsingImportedState(usingImportedState: boolean) { Onyx.set(ONYXKEYS.IS_USING_IMPORTED_STATE, usingImportedState); } -function setPreservedUserSession(session: OnyxTypes.Session) { - Onyx.set(ONYXKEYS.PRESERVED_USER_SESSION, session); -} - function clearOnyxAndResetApp(shouldNavigateToHomepage?: boolean) { // The value of isUsingImportedState will be lost once Onyx is cleared, so we need to store it const isStateImported = isUsingImportedState; @@ -551,11 +538,6 @@ function clearOnyxAndResetApp(shouldNavigateToHomepage?: boolean) { Navigation.navigate(ROUTES.HOME); } - if (preservedUserSession) { - Onyx.set(ONYXKEYS.SESSION, preservedUserSession); - Onyx.set(ONYXKEYS.PRESERVED_USER_SESSION, null); - } - // Requests in a sequential queue should be called even if the Onyx state is reset, so we do not lose any pending data. // However, the OpenApp request must be called before any other request in a queue to ensure data consistency. // To do that, sequential queue is cleared together with other keys, and then it's restored once the OpenApp request is resolved. @@ -592,6 +574,5 @@ export { updateLastRoute, setIsUsingImportedState, clearOnyxAndResetApp, - setPreservedUserSession, KEYS_TO_PRESERVE, }; diff --git a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx index defc5eb941ac..bd0ce596c733 100644 --- a/src/pages/settings/Troubleshoot/TroubleshootPage.tsx +++ b/src/pages/settings/Troubleshoot/TroubleshootPage.tsx @@ -144,7 +144,10 @@ function TroubleshootPage() { /> - + { - it('converts object with numeric keys to array', () => { - const input = {'0': 'a', '1': 'b', '2': 'c'}; - expect(transformNumericKeysToArray(input)).toEqual(['a', 'b', 'c']); - }); - - it('handles nested numeric objects', () => { - const input = { - '0': {'0': 'a', '1': 'b'}, - '1': {'0': 'c', '1': 'd'}, - }; - expect(transformNumericKeysToArray(input)).toEqual([ - ['a', 'b'], - ['c', 'd'], - ]); - }); - - it('preserves non-numeric keys', () => { - const input = {foo: 'bar', baz: {'0': 'qux'}}; - expect(transformNumericKeysToArray(input)).toEqual({foo: 'bar', baz: ['qux']}); - }); - - it('handles empty objects', () => { - expect(transformNumericKeysToArray({})).toEqual({}); - }); - - it('handles non-sequential numeric keys', () => { - const input = {'0': 'a', '2': 'b', '5': 'c'}; - expect(transformNumericKeysToArray(input)).toEqual({'0': 'a', '2': 'b', '5': 'c'}); - }); -}); - -describe('cleanAndTransformState', () => { - it('removes omitted keys and transforms numeric objects', () => { - const input = JSON.stringify({ - [ONYXKEYS.NETWORK]: 'should be removed', - someKey: {'0': 'a', '1': 'b'}, - otherKey: 'value', - }); - - expect(cleanAndTransformState(input)).toEqual({ - someKey: ['a', 'b'], - otherKey: 'value', - }); - }); - - it('handles empty state', () => { - expect(cleanAndTransformState('{}')).toEqual({}); - }); - - it('removes keys that start with omitted keys', () => { - const input = JSON.stringify({ - [`${ONYXKEYS.NETWORK}_something`]: 'should be removed', - validKey: 'keep this', - }); - - expect(cleanAndTransformState(input)).toEqual({ - validKey: 'keep this', - }); - }); - - it('throws on invalid JSON', () => { - expect(() => cleanAndTransformState('invalid json')).toThrow(); - }); - - it('removes all specified ONYXKEYS', () => { - const input = JSON.stringify({ - [ONYXKEYS.ACTIVE_CLIENTS]: 'remove1', - [ONYXKEYS.FREQUENTLY_USED_EMOJIS]: 'remove2', - [ONYXKEYS.NETWORK]: 'remove3', - [ONYXKEYS.CREDENTIALS]: 'remove4', - [ONYXKEYS.PREFERRED_THEME]: 'remove5', - keepThis: 'value', - }); - - const result = cleanAndTransformState(input); - - expect(result).toEqual({ - keepThis: 'value', - }); - - // Verify each key is removed - expect(result).not.toHaveProperty(ONYXKEYS.ACTIVE_CLIENTS); - expect(result).not.toHaveProperty(ONYXKEYS.FREQUENTLY_USED_EMOJIS); - expect(result).not.toHaveProperty(ONYXKEYS.NETWORK); - expect(result).not.toHaveProperty(ONYXKEYS.CREDENTIALS); - expect(result).not.toHaveProperty(ONYXKEYS.PREFERRED_THEME); - }); -});