Skip to content

Commit d4aa2df

Browse files
authored
Merge pull request Expensify#75779 from Expensify/lucien/add-rbr-test-copilot-held-expense
2 parents 29e1abf + 6d1b511 commit d4aa2df

1 file changed

Lines changed: 105 additions & 2 deletions

File tree

tests/unit/SidebarUtilsTest.ts

Lines changed: 105 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
/* eslint-disable @typescript-eslint/naming-convention */
22
import {act, renderHook} from '@testing-library/react-native';
3-
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
3+
import type {OnyxCollection, OnyxEntry, OnyxMultiSetInput} from 'react-native-onyx';
44
import Onyx from 'react-native-onyx';
55
import useReportIsArchived from '@hooks/useReportIsArchived';
6+
import {generateTransactionID} from '@libs/actions/Transaction';
67
import DateUtils from '@libs/DateUtils';
78
import {getLastActorDisplayName} from '@libs/OptionsListUtils';
89
// eslint-disable-next-line no-restricted-syntax
910
import type * as PolicyUtils from '@libs/PolicyUtils';
1011
import {getOriginalMessage, getReportActionMessageText} from '@libs/ReportActionsUtils';
11-
import {formatReportLastMessageText, getAllReportErrors, getReportPreviewMessage} from '@libs/ReportUtils';
12+
import {formatReportLastMessageText, generateReportID, getAllReportErrors, getReasonAndReportActionThatRequiresAttention, getReportPreviewMessage} from '@libs/ReportUtils';
1213
import SidebarUtils from '@libs/SidebarUtils';
1314
import initOnyxDerivedValues from '@userActions/OnyxDerived';
1415
import CONST from '@src/CONST';
@@ -23,6 +24,7 @@ import createRandomPolicy from '../utils/collections/policies';
2324
import createRandomReportAction from '../utils/collections/reportActions';
2425
import {createRandomReport} from '../utils/collections/reports';
2526
import {createSidebarReportsCollection, createSidebarTestData} from '../utils/collections/sidebarReports';
27+
import createRandomTransaction from '../utils/collections/transaction';
2628
import * as LHNTestUtils from '../utils/LHNTestUtils';
2729
import {localeCompare} from '../utils/TestHelper';
2830
import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
@@ -573,6 +575,107 @@ describe('SidebarUtils', () => {
573575
expect(result).toBe(true);
574576
});
575577

578+
it('returns true when submitter has held expenses even if outstanding tasks trigger GBR', async () => {
579+
const policyID = generateReportID();
580+
const expenseChatID = generateReportID();
581+
const expenseReportID = generateReportID();
582+
const holdReportActionID = generateReportID();
583+
584+
const policyExpenseChat: Report = {
585+
reportID: expenseChatID,
586+
chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT,
587+
type: CONST.REPORT.TYPE.CHAT,
588+
ownerAccountID: 12345,
589+
policyID,
590+
hasOutstandingChildRequest: true,
591+
stateNum: CONST.REPORT.STATE_NUM.OPEN,
592+
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
593+
};
594+
595+
const expenseReport: Report = {
596+
reportID: expenseReportID,
597+
chatReportID: expenseChatID,
598+
type: CONST.REPORT.TYPE.EXPENSE,
599+
ownerAccountID: 12345,
600+
managerID: 12345,
601+
policyID,
602+
stateNum: CONST.REPORT.STATE_NUM.OPEN,
603+
statusNum: CONST.REPORT.STATUS_NUM.OPEN,
604+
};
605+
606+
const baseTransaction = createRandomTransaction(700);
607+
const transactionID = generateTransactionID();
608+
const transaction: Transaction = {
609+
...baseTransaction,
610+
transactionID,
611+
reportID: expenseReport.reportID,
612+
amount: 12345,
613+
currency: CONST.CURRENCY.USD,
614+
status: CONST.TRANSACTION.STATUS.POSTED,
615+
comment: {
616+
...(baseTransaction.comment ?? {}),
617+
hold: holdReportActionID,
618+
},
619+
};
620+
621+
const transactionKey = `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}` as const;
622+
const transactionViolationsKey = `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}` as const;
623+
const transactionViolations: OnyxCollection<TransactionViolation[]> = {
624+
[transactionViolationsKey]: [
625+
{
626+
name: CONST.VIOLATIONS.HOLD,
627+
type: CONST.VIOLATION_TYPES.VIOLATION,
628+
showInReview: true,
629+
},
630+
],
631+
};
632+
633+
await act(async () => {
634+
await Onyx.multiSet({
635+
[ONYXKEYS.SESSION]: {
636+
accountID: 12345,
637+
},
638+
[`${ONYXKEYS.COLLECTION.REPORT}${policyExpenseChat.reportID}`]: policyExpenseChat,
639+
[`${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`]: expenseReport,
640+
[transactionKey]: transaction,
641+
[transactionViolationsKey]: transactionViolations[transactionViolationsKey],
642+
} as unknown as OnyxMultiSetInput);
643+
});
644+
645+
await waitForBatchedUpdatesWithAct();
646+
647+
const requiresAttention = getReasonAndReportActionThatRequiresAttention(policyExpenseChat);
648+
expect(requiresAttention?.reason).toBe(CONST.REQUIRES_ATTENTION_REASONS.HAS_CHILD_REPORT_AWAITING_ACTION);
649+
650+
const {reason} =
651+
SidebarUtils.getReasonAndReportActionThatHasRedBrickRoad(
652+
policyExpenseChat,
653+
policyExpenseChat,
654+
{} as OnyxEntry<ReportActions>,
655+
true,
656+
{},
657+
{[transactionKey]: transaction},
658+
transactionViolations,
659+
false,
660+
) ?? {};
661+
662+
expect(reason).toBe(CONST.RBR_REASONS.HAS_TRANSACTION_THREAD_VIOLATIONS);
663+
664+
const {result: isReportArchived} = renderHook(() => useReportIsArchived(policyExpenseChat.reportID));
665+
const hasRedBrickRoad = SidebarUtils.shouldShowRedBrickRoad(
666+
policyExpenseChat,
667+
policyExpenseChat,
668+
{} as OnyxEntry<ReportActions>,
669+
true,
670+
{},
671+
{[transactionKey]: transaction},
672+
transactionViolations as OnyxCollection<TransactionViolations>,
673+
isReportArchived.current,
674+
);
675+
676+
expect(hasRedBrickRoad).toBe(true);
677+
});
678+
576679
it('returns true when report has errors', () => {
577680
const MOCK_REPORT: Report = {
578681
reportID: '1',

0 commit comments

Comments
 (0)