Skip to content

Commit a7d994c

Browse files
authored
Merge pull request #75054 from callstack-internal/fix/1807/remove-createOpitonList-call-from-app-start
Remove createOptionList call from app start
2 parents f01d6a3 + fed7a03 commit a7d994c

2 files changed

Lines changed: 118 additions & 1 deletion

File tree

src/components/OptionListContextProvider.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ function OptionsListContextProvider({children}: OptionsListProviderProps) {
8080
* Since options might use report attributes, it's necessary to call this after report attributes are loaded with the new locale to make sure the options are generated in a proper language
8181
*/
8282
useEffect(() => {
83-
if (reportAttributes?.locale === prevReportAttributesLocale) {
83+
if (!areOptionsInitialized.current || reportAttributes?.locale === prevReportAttributesLocale) {
8484
return;
8585
}
8686

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import {act, renderHook} from '@testing-library/react-native';
2+
import React from 'react';
3+
import {usePersonalDetails} from '@components/OnyxListItemProvider';
4+
import OptionListContextProvider, {useOptionsList} from '@components/OptionListContextProvider';
5+
import useOnyx from '@hooks/useOnyx';
6+
import {createOptionList} from '@libs/OptionsListUtils';
7+
import ONYXKEYS from '@src/ONYXKEYS';
8+
9+
jest.mock('@libs/OptionsListUtils', () => {
10+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
11+
const actual = jest.requireActual('@libs/OptionsListUtils');
12+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
13+
return {
14+
...actual,
15+
createOptionList: jest.fn(),
16+
processReport: jest.fn(() => ({reportOption: null})),
17+
createOptionFromReport: jest.fn(),
18+
};
19+
});
20+
21+
jest.mock('@hooks/useOnyx', () => jest.fn());
22+
jest.mock('@components/OnyxListItemProvider', () => ({
23+
usePersonalDetails: jest.fn(),
24+
}));
25+
26+
const mockCreateOptionList = createOptionList as jest.MockedFunction<typeof createOptionList>;
27+
const mockUseOnyx = useOnyx as jest.MockedFunction<typeof useOnyx>;
28+
const mockUsePersonalDetails = usePersonalDetails as jest.MockedFunction<typeof usePersonalDetails>;
29+
30+
const wrapper: React.FC<{children: React.ReactNode}> = ({children}) => <OptionListContextProvider>{children}</OptionListContextProvider>;
31+
32+
describe('OptionListContextProvider', () => {
33+
let onyxState: Record<string, unknown>;
34+
let onyxSourceValues: Record<string, unknown>;
35+
36+
beforeEach(() => {
37+
jest.clearAllMocks();
38+
39+
onyxState = {
40+
[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES]: {locale: 'en'},
41+
[ONYXKEYS.COLLECTION.REPORT]: {},
42+
};
43+
44+
onyxSourceValues = {
45+
[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES]: onyxState[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES],
46+
[ONYXKEYS.COLLECTION.REPORT]: {},
47+
[ONYXKEYS.COLLECTION.REPORT_ACTIONS]: {},
48+
};
49+
50+
mockCreateOptionList.mockReturnValue({reports: [], personalDetails: []});
51+
mockUsePersonalDetails.mockReturnValue({});
52+
53+
mockUseOnyx.mockImplementation(((key: string) => {
54+
if (key === ONYXKEYS.DERIVED.REPORT_ATTRIBUTES) {
55+
return [onyxState[key], {sourceValue: onyxSourceValues[key]}];
56+
}
57+
58+
if (key === ONYXKEYS.COLLECTION.REPORT) {
59+
return [onyxState[key], {sourceValue: onyxSourceValues[key]}];
60+
}
61+
62+
if (key === ONYXKEYS.COLLECTION.REPORT_ACTIONS) {
63+
return [undefined, {sourceValue: onyxSourceValues[key]}];
64+
}
65+
66+
return [undefined];
67+
}) as typeof useOnyx);
68+
});
69+
70+
it('ignores locale changes before options are initialized', () => {
71+
const {rerender} = renderHook(({shouldInitialize}) => useOptionsList({shouldInitialize}), {
72+
initialProps: {shouldInitialize: false},
73+
wrapper,
74+
});
75+
76+
expect(mockCreateOptionList).not.toHaveBeenCalled();
77+
78+
onyxState = {
79+
...onyxState,
80+
[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES]: {locale: 'es'},
81+
};
82+
onyxSourceValues = {
83+
...onyxSourceValues,
84+
[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES]: onyxState[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES],
85+
};
86+
rerender({shouldInitialize: false});
87+
88+
expect(mockCreateOptionList).not.toHaveBeenCalled();
89+
});
90+
91+
it('refreshes options once after initialization when locale changes', () => {
92+
const {result, rerender} = renderHook(({shouldInitialize}) => useOptionsList({shouldInitialize}), {
93+
initialProps: {shouldInitialize: false},
94+
wrapper,
95+
});
96+
97+
act(() => {
98+
result.current.initializeOptions();
99+
});
100+
101+
expect(mockCreateOptionList).toHaveBeenCalledTimes(1);
102+
103+
mockCreateOptionList.mockClear();
104+
105+
onyxState = {
106+
...onyxState,
107+
[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES]: {locale: 'fr'},
108+
};
109+
onyxSourceValues = {
110+
...onyxSourceValues,
111+
[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES]: onyxState[ONYXKEYS.DERIVED.REPORT_ATTRIBUTES],
112+
};
113+
rerender({shouldInitialize: false});
114+
115+
expect(mockCreateOptionList).toHaveBeenCalledTimes(1);
116+
});
117+
});

0 commit comments

Comments
 (0)