From cb03e6a4dcccf49681c14480242d276de0fbac6b Mon Sep 17 00:00:00 2001 From: FitseTLT Date: Mon, 12 May 2025 22:36:11 +0300 Subject: [PATCH] enable unhold for held duplicate transaction --- src/libs/ReportUtils.ts | 3 +- tests/unit/ReportUtilsTest.ts | 62 +++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 99d8a4efe0fa..f2d297e324e9 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -235,7 +235,6 @@ import { hasWarningTypeViolation, isCardTransaction as isCardTransactionTransactionUtils, isDistanceRequest, - isDuplicate, isExpensifyCardTransaction, isFetchingWaypointsFromServer, isOnHold as isOnHoldTransactionUtils, @@ -3972,7 +3971,7 @@ function canHoldUnholdReportAction(reportAction: OnyxInputOrEntry) const canHoldOrUnholdRequest = !isRequestSettled && !isApproved && !isDeletedParentActionLocal && !isClosed && !isDeletedParentAction(reportAction); const canHoldRequest = canHoldOrUnholdRequest && !isOnHold && (isRequestIOU || canModifyStatus) && !isScanning; - const canUnholdRequest = !!(canHoldOrUnholdRequest && isOnHold && !isDuplicate(transaction.transactionID, true) && (isRequestIOU ? isHoldActionCreator : canModifyUnholdStatus)); + const canUnholdRequest = !!(canHoldOrUnholdRequest && isOnHold && (isRequestIOU ? isHoldActionCreator : canModifyUnholdStatus)); return {canHoldRequest, canUnholdRequest}; } diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 0516bd60f7fc..1a6515889d5e 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -5,6 +5,7 @@ import {addDays, format as formatDate} from 'date-fns'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import useReportIsArchived from '@hooks/useReportIsArchived'; +import {putOnHold} from '@libs/actions/IOU'; import DateUtils from '@libs/DateUtils'; import {translateLocal} from '@libs/Localize'; import {getOriginalMessage} from '@libs/ReportActionsUtils'; @@ -13,11 +14,13 @@ import { buildOptimisticCreatedReportAction, buildOptimisticExpenseReport, buildOptimisticIOUReportAction, + buildOptimisticReportPreview, buildParticipantsFromAccountIDs, buildReportNameFromParticipantNames, buildTransactionThread, canDeleteReportAction, canEditWriteCapability, + canHoldUnholdReportAction, findLastAccessedReport, getAllAncestorReportActions, getApprovalChain, @@ -1386,6 +1389,65 @@ describe('ReportUtils', () => { }); }); + describe('canHoldUnholdReportAction', () => { + it.only('should return canUnholdRequest as true for a held duplicate transaction', async () => { + const chatReport: Report = {reportID: '1'}; + const reportPreviewReportActionID = '8'; + const expenseReport = buildOptimisticExpenseReport(chatReport.reportID, '123', currentUserAccountID, 122, 'USD', undefined, reportPreviewReportActionID); + const expenseTransaction = buildOptimisticTransaction({ + transactionParams: { + amount: 100, + currency: 'USD', + reportID: expenseReport.reportID, + }, + }); + const reportPreview = buildOptimisticReportPreview(chatReport, expenseReport, '', expenseTransaction, expenseReport.reportID, reportPreviewReportActionID); + const expenseCreatedAction = buildOptimisticIOUReportAction({ + type: 'create', + amount: 100, + currency: 'USD', + comment: '', + participants: [], + transactionID: expenseTransaction.transactionID, + iouReportID: expenseReport.reportID, + }); + const transactionThreadReport = buildTransactionThread(expenseCreatedAction, expenseReport); + expenseCreatedAction.childReportID = transactionThreadReport.reportID; + + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, { + currentUserAccountID: { + accountID: currentUserAccountID, + displayName: currentUserEmail, + login: currentUserEmail, + }, + }); + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION}${expenseTransaction.transactionID}`, {...expenseTransaction}); + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, expenseReport); + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport.reportID}`, transactionThreadReport); + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`, { + [expenseCreatedAction.reportActionID]: expenseCreatedAction, + }); + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, { + [reportPreview.reportActionID]: reportPreview, + }); + // Given a transaction with duplicate transaction violation + await Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${expenseTransaction.transactionID}`, [ + { + name: CONST.VIOLATIONS.DUPLICATED_TRANSACTION, + type: CONST.VIOLATION_TYPES.WARNING, + }, + ]); + + expect(canHoldUnholdReportAction(expenseCreatedAction)).toEqual({canHoldRequest: true, canUnholdRequest: false}); + + putOnHold(expenseTransaction.transactionID, 'hold', transactionThreadReport.reportID); + await waitForBatchedUpdates(); + + // canUnholdRequest should be true after the transaction is held. + expect(canHoldUnholdReportAction(expenseCreatedAction)).toEqual({canHoldRequest: false, canUnholdRequest: true}); + }); + }); + describe('getQuickActionDetails', () => { it('if the report is archived, the quick action will hide the subtitle and avatar', () => { // Create a fake archived report as quick action report