Skip to content

Commit f1a4a92

Browse files
authored
Merge pull request #88716 from linhvovan29546/refactor/66418-remove-deprecatedReportsTransactions-in-getPolicyIDsWithEmptyReportsForAccount
refactor: remove deprecatedReportsTransactions in getPolicyIDsWithEmptyReportsForAccount
2 parents 6e87d5a + da37d08 commit f1a4a92

3 files changed

Lines changed: 175 additions & 12 deletions

File tree

src/libs/ReportUtils.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8976,8 +8976,8 @@ function hasEmptyReportsForPolicy(
89768976
*/
89778977
function getPolicyIDsWithEmptyReportsForAccount(
89788978
reports: OnyxCollection<Report> | undefined,
8979-
accountID?: number,
8980-
reportsTransactionsParam: Record<string, Transaction[]> = deprecatedReportsTransactions,
8979+
accountID: number | undefined,
8980+
reportsTransactionsParam: Record<string, Transaction[]>,
89818981
): Record<string, boolean> {
89828982
if (!accountID) {
89838983
return {};
@@ -9004,9 +9004,7 @@ function getPolicyIDsWithEmptyReportsForAccount(
90049004
}
90059005

90069006
// Ignore transactions that are already pending deletion so we treat the report as empty once the removal is queued.
9007-
const transactions = getReportTransactions(report.reportID, reportsTransactionsParam).filter(
9008-
(transaction) => transaction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE,
9009-
);
9007+
const transactions = (reportsTransactionsParam[report.reportID] ?? []).filter((transaction) => transaction.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE);
90109008
if (transactions.length === 0) {
90119009
policyLookup[report.policyID] = true;
90129010
}

src/pages/NewReportWorkspaceSelectionPage.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,15 +84,22 @@ function NewReportWorkspaceSelectionPage({route}: NewReportWorkspaceSelectionPag
8484

8585
const [allPolicyTags] = useOnyx(ONYXKEYS.COLLECTION.POLICY_TAGS);
8686

87-
const [policiesWithEmptyReports] = useOnyx(ONYXKEYS.COLLECTION.REPORT, {
88-
selector: (reports: OnyxCollection<OnyxTypes.Report>) => {
89-
if (!accountID) {
90-
return {};
91-
}
87+
const [todos] = useOnyx(ONYXKEYS.DERIVED.TODOS);
88+
const transactionsByReportID = todos?.transactionsByReportID;
89+
90+
const [policiesWithEmptyReports] = useOnyx(
91+
ONYXKEYS.COLLECTION.REPORT,
92+
{
93+
selector: (reports: OnyxCollection<OnyxTypes.Report>) => {
94+
if (!accountID) {
95+
return {};
96+
}
9297

93-
return getPolicyIDsWithEmptyReportsForAccount(reports, accountID);
98+
return getPolicyIDsWithEmptyReportsForAccount(reports, accountID, transactionsByReportID ?? {});
99+
},
94100
},
95-
});
101+
[accountID, transactionsByReportID],
102+
);
96103

97104
const navigateToNewReport = (optimisticReportID: string) => {
98105
if (isRHPOnReportInSearch) {
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import {PortalProvider} from '@gorhom/portal';
2+
import {NavigationContainer} from '@react-navigation/native';
3+
import {act, fireEvent, render, screen} from '@testing-library/react-native';
4+
import React from 'react';
5+
import Onyx from 'react-native-onyx';
6+
import ComposeProviders from '@components/ComposeProviders';
7+
import {LocaleContextProvider} from '@components/LocaleContextProvider';
8+
import OnyxListItemProvider from '@components/OnyxListItemProvider';
9+
import {createNewReport} from '@libs/actions/Report';
10+
import createPlatformStackNavigator from '@libs/Navigation/PlatformStackNavigation/createPlatformStackNavigator';
11+
import type {NewReportWorkspaceSelectionNavigatorParamList} from '@libs/Navigation/types';
12+
import NewReportWorkspaceSelectionPage from '@pages/NewReportWorkspaceSelectionPage';
13+
import CONST from '@src/CONST';
14+
import ONYXKEYS from '@src/ONYXKEYS';
15+
import SCREENS from '@src/SCREENS';
16+
import type {Policy, Report, TodosDerivedValue, Transaction} from '@src/types/onyx';
17+
import waitForBatchedUpdatesWithAct from '../utils/waitForBatchedUpdatesWithAct';
18+
19+
jest.mock('@libs/actions/Report', () => ({
20+
createNewReport: jest.fn(() => ({reportID: 'new-report-id'})),
21+
}));
22+
23+
const mockOpenCreateReportConfirmation = jest.fn();
24+
jest.mock('@hooks/useCreateEmptyReportConfirmation', () => jest.fn(() => ({openCreateReportConfirmation: mockOpenCreateReportConfirmation})));
25+
26+
jest.mock('@libs/Navigation/Navigation', () => ({
27+
navigate: jest.fn(),
28+
goBack: jest.fn(),
29+
dismissModal: jest.fn(),
30+
setNavigationActionToMicrotaskQueue: jest.fn((cb: () => void) => cb()),
31+
getActiveRoute: jest.fn(() => ''),
32+
isTopmostRouteModalScreen: jest.fn(() => false),
33+
}));
34+
35+
jest.mock('@libs/Navigation/helpers/isSearchTopmostFullScreenRoute', () => () => false);
36+
jest.mock('@navigation/helpers/isRHPOnSearchMoneyRequestReportPage', () => () => false);
37+
38+
const mockCreateNewReport = jest.mocked(createNewReport);
39+
40+
const ACCOUNT_ID = 12345;
41+
const EMAIL = 'test@example.com';
42+
const POLICY_ID = 'policy-1';
43+
const POLICY_NAME = 'Test Workspace';
44+
const REPORT_ID = 'report-1';
45+
46+
const BASE_TODOS: TodosDerivedValue = {
47+
reportsToSubmit: [],
48+
reportsToApprove: [],
49+
reportsToPay: [],
50+
reportsToExport: [],
51+
transactionsByReportID: {},
52+
};
53+
54+
const Stack = createPlatformStackNavigator<NewReportWorkspaceSelectionNavigatorParamList>();
55+
56+
function renderPage() {
57+
return render(
58+
<ComposeProviders components={[OnyxListItemProvider, LocaleContextProvider]}>
59+
<PortalProvider>
60+
<NavigationContainer>
61+
<Stack.Navigator>
62+
<Stack.Screen
63+
name={SCREENS.NEW_REPORT_WORKSPACE_SELECTION.ROOT}
64+
component={NewReportWorkspaceSelectionPage}
65+
initialParams={{}}
66+
/>
67+
</Stack.Navigator>
68+
</NavigationContainer>
69+
</PortalProvider>
70+
</ComposeProviders>,
71+
);
72+
}
73+
74+
async function seedBaseOnyx() {
75+
const policy: Partial<Policy> = {
76+
id: POLICY_ID,
77+
name: POLICY_NAME,
78+
role: CONST.POLICY.ROLE.ADMIN,
79+
type: CONST.POLICY.TYPE.TEAM,
80+
isPolicyExpenseChatEnabled: true,
81+
owner: EMAIL,
82+
employeeList: {[EMAIL]: {email: EMAIL, role: CONST.POLICY.ROLE.ADMIN}},
83+
pendingAction: null,
84+
};
85+
const report: Partial<Report> = {
86+
reportID: REPORT_ID,
87+
policyID: POLICY_ID,
88+
ownerAccountID: ACCOUNT_ID,
89+
type: CONST.REPORT.TYPE.EXPENSE,
90+
stateNum: CONST.REPORT.STATE_NUM.OPEN,
91+
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
92+
total: 0,
93+
nonReimbursableTotal: 0,
94+
pendingAction: null,
95+
};
96+
await Onyx.set(ONYXKEYS.SESSION, {accountID: ACCOUNT_ID, email: EMAIL});
97+
await Onyx.set(ONYXKEYS.PERSONAL_DETAILS_LIST, {
98+
[ACCOUNT_ID]: {login: EMAIL, accountID: ACCOUNT_ID, displayName: EMAIL},
99+
});
100+
await Onyx.set(ONYXKEYS.IS_LOADING_APP, false);
101+
await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`, policy);
102+
await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, report);
103+
}
104+
105+
describe('NewReportWorkspaceSelectionPage', () => {
106+
beforeAll(() => {
107+
Onyx.init({keys: ONYXKEYS});
108+
});
109+
110+
afterEach(async () => {
111+
await act(async () => {
112+
await Onyx.clear();
113+
});
114+
jest.clearAllMocks();
115+
});
116+
117+
it('opens the empty-report confirmation when TODOS has no transactions for the user report', async () => {
118+
await act(async () => {
119+
await seedBaseOnyx();
120+
await Onyx.set(ONYXKEYS.DERIVED.TODOS, BASE_TODOS);
121+
});
122+
await waitForBatchedUpdatesWithAct();
123+
124+
renderPage();
125+
await waitForBatchedUpdatesWithAct();
126+
127+
fireEvent.press(await screen.findByText(POLICY_NAME));
128+
await waitForBatchedUpdatesWithAct();
129+
130+
expect(mockOpenCreateReportConfirmation).toHaveBeenCalled();
131+
expect(mockCreateNewReport).not.toHaveBeenCalled();
132+
});
133+
134+
it('creates the report directly when TODOS has a live transaction for the user report', async () => {
135+
const transaction: Partial<Transaction> = {
136+
transactionID: 'txn-1',
137+
reportID: REPORT_ID,
138+
pendingAction: null,
139+
};
140+
await act(async () => {
141+
await seedBaseOnyx();
142+
await Onyx.set(ONYXKEYS.DERIVED.TODOS, {
143+
...BASE_TODOS,
144+
transactionsByReportID: {[REPORT_ID]: [transaction as Transaction]},
145+
});
146+
});
147+
await waitForBatchedUpdatesWithAct();
148+
149+
renderPage();
150+
await waitForBatchedUpdatesWithAct();
151+
152+
fireEvent.press(await screen.findByText(POLICY_NAME));
153+
await waitForBatchedUpdatesWithAct();
154+
155+
expect(mockCreateNewReport).toHaveBeenCalled();
156+
expect(mockOpenCreateReportConfirmation).not.toHaveBeenCalled();
157+
});
158+
});

0 commit comments

Comments
 (0)