Skip to content

Commit d533a54

Browse files
authored
Merge pull request Expensify#68122 from DylanDylann/remove-onyx-connect-in-EmojiUtils-CardMessageUtils-2
Refactor src/libs/CardMessageUtils.ts to remove Onyx.connect() references - P2
2 parents e2e2e3b + d25c4b9 commit d533a54

4 files changed

Lines changed: 58 additions & 35 deletions

File tree

src/components/LHNOptionsList/OptionRowLHNData.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,11 @@ import {deepEqual} from 'fast-equals';
22
import React, {useMemo, useRef} from 'react';
33
import useCurrentReportID from '@hooks/useCurrentReportID';
44
import useGetExpensifyCardFromReportAction from '@hooks/useGetExpensifyCardFromReportAction';
5-
import useOnyx from '@hooks/useOnyx';
65
import {getSortedReportActions, shouldReportActionBeVisibleAsLastAction} from '@libs/ReportActionsUtils';
76
import {canUserPerformWriteAction as canUserPerformWriteActionUtil} from '@libs/ReportUtils';
87
import SidebarUtils from '@libs/SidebarUtils';
98
import CONST from '@src/CONST';
109
import type {OptionData} from '@src/libs/ReportUtils';
11-
import ONYXKEYS from '@src/ONYXKEYS';
1210
import OptionRowLHN from './OptionRowLHN';
1311
import type {OptionRowLHNDataProps} from './types';
1412

@@ -45,22 +43,20 @@ function OptionRowLHNData({
4543

4644
const optionItemRef = useRef<OptionData | undefined>(undefined);
4745

48-
const [reportActionsData] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {canBeMissing: true});
49-
5046
const lastAction = useMemo(() => {
51-
if (!reportActionsData || !fullReport) {
47+
if (!reportActions || !fullReport) {
5248
return undefined;
5349
}
5450

5551
const canUserPerformWriteAction = canUserPerformWriteActionUtil(fullReport);
56-
const actionsArray = getSortedReportActions(Object.values(reportActionsData));
52+
const actionsArray = getSortedReportActions(Object.values(reportActions));
5753

5854
const reportActionsForDisplay = actionsArray.filter(
5955
(reportAction) => shouldReportActionBeVisibleAsLastAction(reportAction, canUserPerformWriteAction) && reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.CREATED,
6056
);
6157

6258
return reportActionsForDisplay.at(-1);
63-
}, [reportActionsData, fullReport]);
59+
}, [reportActions, fullReport]);
6460

6561
const card = useGetExpensifyCardFromReportAction({reportAction: lastAction, policyID: fullReport?.policyID});
6662
const optionItem = useMemo(() => {

src/components/OnyxListItemProvider.tsx

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ const [SessionProvider, , useSession] = createOnyxContext(ONYXKEYS.SESSION);
1515
const [PolicyCategoriesProvider, , usePolicyCategories] = createOnyxContext(ONYXKEYS.COLLECTION.POLICY_CATEGORIES);
1616
const [PolicyTagsProvider, , usePolicyTags] = createOnyxContext(ONYXKEYS.COLLECTION.POLICY_TAGS);
1717
const [ReportTransactionsAndViolationsProvider, , useAllReportsTransactionsAndViolations] = createOnyxContext(ONYXKEYS.DERIVED.REPORT_TRANSACTIONS_AND_VIOLATIONS);
18+
const [CardListProvider, , useCardList] = createOnyxContext(ONYXKEYS.CARD_LIST);
19+
const [WorkspaceCardListProvider, , useWorkspaceCardList] = createOnyxContext(ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST);
1820

1921
type OnyxListItemProviderProps = {
2022
/** Rendered child component */
@@ -32,6 +34,8 @@ function OnyxListItemProvider(props: OnyxListItemProviderProps) {
3234
PolicyCategoriesProvider,
3335
PolicyTagsProvider,
3436
ReportTransactionsAndViolationsProvider,
37+
CardListProvider,
38+
WorkspaceCardListProvider,
3539
]}
3640
>
3741
{props.children}
@@ -43,4 +47,16 @@ OnyxListItemProvider.displayName = 'OnyxListItemProvider';
4347

4448
export default OnyxListItemProvider;
4549

46-
export {usePersonalDetails, BetasContext, useBetas, PersonalDetailsContext, useBlockedFromConcierge, useSession, usePolicyCategories, usePolicyTags, useAllReportsTransactionsAndViolations};
50+
export {
51+
usePersonalDetails,
52+
BetasContext,
53+
useBetas,
54+
PersonalDetailsContext,
55+
useBlockedFromConcierge,
56+
useSession,
57+
usePolicyCategories,
58+
usePolicyTags,
59+
useAllReportsTransactionsAndViolations,
60+
useCardList,
61+
useWorkspaceCardList,
62+
};
Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
1+
import {useCardList, useWorkspaceCardList} from '@components/OnyxListItemProvider';
12
import {getPolicy, getWorkspaceAccountID, isPolicyAdmin} from '@libs/PolicyUtils';
23
import {getOriginalMessage, isCardIssuedAction} from '@libs/ReportActionsUtils';
34
import CONST from '@src/CONST';
45
import ONYXKEYS from '@src/ONYXKEYS';
56
import type {Card, ReportAction} from '@src/types/onyx';
6-
import useOnyx from './useOnyx';
77

88
function useGetExpensifyCardFromReportAction({reportAction, policyID}: {reportAction?: ReportAction; policyID?: string}): Card | undefined {
9-
const [allUserCards] = useOnyx(ONYXKEYS.CARD_LIST, {canBeMissing: true});
10-
const [allExpensifyCards] = useOnyx(ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST, {
11-
selector: (val) => {
12-
const workspaceAccountID = getWorkspaceAccountID(policyID);
13-
return val?.[`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`] ?? {};
14-
},
15-
canBeMissing: true,
16-
});
9+
const allUserCards = useCardList();
10+
const workspaceAccountID = getWorkspaceAccountID(policyID);
11+
const allExpensifyCards = useWorkspaceCardList();
12+
const expensifyCards = allExpensifyCards?.[`${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}${workspaceAccountID}_${CONST.EXPENSIFY_CARD.BANK}`] ?? {};
13+
1714
const cardIssuedActionOriginalMessage = isCardIssuedAction(reportAction) ? getOriginalMessage(reportAction) : undefined;
1815

1916
const cardID = cardIssuedActionOriginalMessage?.cardID ?? CONST.DEFAULT_NUMBER_ID;
2017
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
2118
// eslint-disable-next-line deprecation/deprecation
22-
return isPolicyAdmin(getPolicy(policyID)) ? allExpensifyCards?.[cardID] : allUserCards?.[cardID];
19+
return isPolicyAdmin(getPolicy(policyID)) ? expensifyCards?.[cardID] : allUserCards?.[cardID];
2320
}
2421

2522
export default useGetExpensifyCardFromReportAction;

tests/unit/useGetExpensifyCardFromReportActionTest.ts

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {renderHook} from '@testing-library/react-native';
22
import Onyx from 'react-native-onyx';
3+
import {useCardList, useWorkspaceCardList} from '@components/OnyxListItemProvider';
34
import {getPolicy, getWorkspaceAccountID, isPolicyAdmin} from '@libs/PolicyUtils';
45
import {getOriginalMessage, isCardIssuedAction} from '@libs/ReportActionsUtils';
56
import CONST from '@src/CONST';
@@ -12,6 +13,10 @@ import waitForBatchedUpdatesWithAct from '../utils/waitForBatchedUpdatesWithAct'
1213
// Mock the dependencies
1314
jest.mock('@libs/PolicyUtils');
1415
jest.mock('@libs/ReportActionsUtils');
16+
jest.mock('@components/OnyxListItemProvider', () => ({
17+
useCardList: jest.fn(),
18+
useWorkspaceCardList: jest.fn(),
19+
}));
1520

1621
// This will be fixed as part of https://github.com/Expensify/Expensify/issues/507850
1722
// eslint-disable-next-line deprecation/deprecation
@@ -20,6 +25,8 @@ const mockGetWorkspaceAccountID = getWorkspaceAccountID as jest.MockedFunction<t
2025
const mockIsPolicyAdmin = isPolicyAdmin as jest.MockedFunction<typeof isPolicyAdmin>;
2126
const mockGetOriginalMessage = getOriginalMessage as jest.MockedFunction<typeof getOriginalMessage>;
2227
const mockIsCardIssuedAction = isCardIssuedAction as jest.MockedFunction<typeof isCardIssuedAction>;
28+
const mockUseCardList = useCardList as jest.MockedFunction<typeof useCardList>;
29+
const mockUseWorkspaceCardList = useWorkspaceCardList as jest.MockedFunction<typeof useWorkspaceCardList>;
2330

2431
describe('useGetExpensifyCardFromReportAction', () => {
2532
const mockCard: Card = {
@@ -76,6 +83,8 @@ describe('useGetExpensifyCardFromReportAction', () => {
7683
mockIsPolicyAdmin.mockReturnValue(false);
7784
mockGetOriginalMessage.mockReturnValue({cardID: 123, assigneeAccountID: 1});
7885
mockIsCardIssuedAction.mockReturnValue(true);
86+
mockUseCardList.mockReturnValue({});
87+
mockUseWorkspaceCardList.mockReturnValue({});
7988
});
8089

8190
describe('when reportAction is not a card issued action', () => {
@@ -102,8 +111,7 @@ describe('useGetExpensifyCardFromReportAction', () => {
102111

103112
it('returns card from allUserCards when card exists', async () => {
104113
// eslint-disable-next-line @typescript-eslint/naming-convention
105-
Onyx.set(ONYXKEYS.CARD_LIST, {'123': mockCard});
106-
await waitForBatchedUpdatesWithAct();
114+
mockUseCardList.mockReturnValue({'123': mockCard});
107115

108116
const {result} = renderHook(() => useGetExpensifyCardFromReportAction({reportAction: createMockReportAction(), policyID: 'policy123'}));
109117
await waitForBatchedUpdatesWithAct();
@@ -112,8 +120,7 @@ describe('useGetExpensifyCardFromReportAction', () => {
112120
});
113121

114122
it('returns undefined when card does not exist in allUserCards', async () => {
115-
Onyx.set(ONYXKEYS.CARD_LIST, {});
116-
await waitForBatchedUpdatesWithAct();
123+
mockUseCardList.mockReturnValue({});
117124

118125
const {result} = renderHook(() => useGetExpensifyCardFromReportAction({reportAction: createMockReportAction(), policyID: 'policy123'}));
119126
await waitForBatchedUpdatesWithAct();
@@ -143,8 +150,7 @@ describe('useGetExpensifyCardFromReportAction', () => {
143150
it('returns card from allExpensifyCards when card exists', async () => {
144151
const workspaceCardsKey = `${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}123_${CONST.EXPENSIFY_CARD.BANK}` as OnyxKey;
145152
// eslint-disable-next-line @typescript-eslint/naming-convention
146-
Onyx.set(workspaceCardsKey, {123: mockCard});
147-
await waitForBatchedUpdatesWithAct();
153+
mockUseWorkspaceCardList.mockReturnValue({[workspaceCardsKey]: {123: mockCard}});
148154

149155
const {result} = renderHook(() => useGetExpensifyCardFromReportAction({reportAction: createMockReportAction(), policyID: 'policy123'}));
150156
await waitForBatchedUpdatesWithAct();
@@ -155,8 +161,7 @@ describe('useGetExpensifyCardFromReportAction', () => {
155161
it('returns undefined when card does not exist in allExpensifyCards', async () => {
156162
const workspaceCardsKey = `${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}123_${CONST.EXPENSIFY_CARD.BANK}` as OnyxKey;
157163
// eslint-disable-next-line @typescript-eslint/naming-convention
158-
Onyx.set(ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST, {[workspaceCardsKey]: {}});
159-
await waitForBatchedUpdatesWithAct();
164+
mockUseWorkspaceCardList.mockReturnValue({[workspaceCardsKey]: {}});
160165

161166
const {result} = renderHook(() => useGetExpensifyCardFromReportAction({reportAction: createMockReportAction(), policyID: 'policy123'}));
162167
await waitForBatchedUpdatesWithAct();
@@ -168,16 +173,22 @@ describe('useGetExpensifyCardFromReportAction', () => {
168173

169174
describe('reactivity to Onyx changes', () => {
170175
it('updates when allUserCards changes', async () => {
176+
mockUseCardList.mockReturnValue({});
177+
mockUseWorkspaceCardList.mockReturnValue({});
178+
171179
const {result} = renderHook(() => useGetExpensifyCardFromReportAction({reportAction: createMockReportAction(), policyID: 'policy123'}));
172180
await waitForBatchedUpdatesWithAct();
173181

174182
expect(result.current).toBeUndefined();
175183

176184
// eslint-disable-next-line @typescript-eslint/naming-convention
177-
Onyx.set(ONYXKEYS.CARD_LIST, {'123': mockCard});
185+
mockUseCardList.mockReturnValue({'123': mockCard});
186+
187+
// Re-render the hook to get the updated result
188+
const {result: updatedResult} = renderHook(() => useGetExpensifyCardFromReportAction({reportAction: createMockReportAction(), policyID: 'policy123'}));
178189
await waitForBatchedUpdatesWithAct();
179190

180-
expect(result.current).toEqual(mockCard);
191+
expect(updatedResult.current).toEqual(mockCard);
181192
});
182193

183194
it('updates when allExpensifyCards changes for policy admin', async () => {
@@ -193,26 +204,30 @@ describe('useGetExpensifyCardFromReportAction', () => {
193204
isPolicyExpenseChatEnabled: false,
194205
workspaceAccountID: 123,
195206
});
207+
208+
// Set initial state
209+
mockUseCardList.mockReturnValue({});
210+
mockUseWorkspaceCardList.mockReturnValue({});
211+
196212
const {result} = renderHook(() => useGetExpensifyCardFromReportAction({reportAction: createMockReportAction(), policyID: 'policy123'}));
197213
await waitForBatchedUpdatesWithAct();
198214

199215
expect(result.current).toBeUndefined();
200216

201-
// eslint-disable-next-line @typescript-eslint/naming-convention
202217
const workspaceCardsKey = `${ONYXKEYS.COLLECTION.WORKSPACE_CARDS_LIST}123_${CONST.EXPENSIFY_CARD.BANK}` as OnyxKey;
203218
// eslint-disable-next-line @typescript-eslint/naming-convention
204-
Onyx.set(workspaceCardsKey, {123: mockCard});
219+
mockUseWorkspaceCardList.mockReturnValue({[workspaceCardsKey]: {123: mockCard}});
220+
const {result: updatedResult} = renderHook(() => useGetExpensifyCardFromReportAction({reportAction: createMockReportAction(), policyID: 'policy123'}));
205221
await waitForBatchedUpdatesWithAct();
206222

207-
expect(result.current).toEqual(mockCard);
223+
expect(updatedResult.current).toEqual(mockCard);
208224
});
209225
});
210226

211227
describe('workspace account ID generation', () => {
212228
it('calls getWorkspaceAccountID with correct policyID', async () => {
213229
// eslint-disable-next-line @typescript-eslint/naming-convention
214-
Onyx.set(ONYXKEYS.CARD_LIST, {'123': mockCard});
215-
await waitForBatchedUpdatesWithAct();
230+
mockUseCardList.mockReturnValue({'123': mockCard});
216231

217232
const {result} = renderHook(() => useGetExpensifyCardFromReportAction({reportAction: createMockReportAction(), policyID: 'test-policy-123'}));
218233
await waitForBatchedUpdatesWithAct();
@@ -238,8 +253,7 @@ describe('useGetExpensifyCardFromReportAction', () => {
238253
mockGetPolicy.mockReturnValue(testPolicy);
239254

240255
// eslint-disable-next-line @typescript-eslint/naming-convention
241-
Onyx.set(ONYXKEYS.CARD_LIST, {'123': mockCard});
242-
await waitForBatchedUpdatesWithAct();
256+
mockUseCardList.mockReturnValue({'123': mockCard});
243257

244258
const {result} = renderHook(() => useGetExpensifyCardFromReportAction({reportAction: createMockReportAction(), policyID: 'policy123'}));
245259
await waitForBatchedUpdatesWithAct();

0 commit comments

Comments
 (0)