diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 14d13da15db1..999e44f8bdb6 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -10797,16 +10797,18 @@ function getNonHeldAndFullAmount(iouReport: OnyxEntry, shouldExcludeNonR * - The action is a whisper action and it's neither a report preview nor IOU action * - The action is the thread's first chat */ -function shouldDisableThread(reportAction: OnyxInputOrEntry, reportID: string, isThreadReportParentAction: boolean, isReportArchived = false): boolean { +function shouldDisableThread(reportAction: OnyxInputOrEntry, isThreadReportParentAction: boolean, isReportArchived = false): boolean { const isSplitBillAction = isSplitBillReportAction(reportAction); const isDeletedActionLocal = isDeletedAction(reportAction); const isReportPreviewActionLocal = isReportPreviewAction(reportAction); const isIOUAction = isMoneyRequestAction(reportAction); const isWhisperActionLocal = isWhisperAction(reportAction) || isActionableTrackExpense(reportAction); const isActionDisabled = CONST.REPORT.ACTIONS.THREAD_DISABLED.some((action: string) => action === reportAction?.actionName); + const isManagerMcTestOwner = reportAction?.actorAccountID === CONST.ACCOUNT_ID.MANAGER_MCTEST; return ( isActionDisabled || + isManagerMcTestOwner || isSplitBillAction || (isDeletedActionLocal && !reportAction?.childVisibleActionCount) || (isReportArchived && !reportAction?.childVisibleActionCount) || diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index 493ec6a7a90a..1b44c0d6d72f 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -346,7 +346,7 @@ const ContextMenuActions: ContextMenuAction[] = [ if (type !== CONST.CONTEXT_MENU_TYPES.REPORT_ACTION || !reportID) { return false; } - return !shouldDisableThread(reportAction, reportID, isThreadReportParentAction, isArchivedRoom); + return !shouldDisableThread(reportAction, isThreadReportParentAction, isArchivedRoom); }, onPress: (closePopover, {reportAction, reportID}) => { const originalReportID = getOriginalReportID(reportID, reportAction); @@ -486,6 +486,7 @@ const ContextMenuActions: ContextMenuAction[] = [ const isExpenseReportAction = isMoneyRequestAction(reportAction) || isReportPreviewActionReportActionsUtils(reportAction); const isTaskAction = isCreatedTaskReportAction(reportAction); const isHarvestCreatedExpenseReportAction = isHarvestReport && isCreatedAction(reportAction); + const shouldDisableJoinThread = shouldDisableThread(reportAction, isThreadReportParentAction, isArchivedRoom); return ( !subscribed && !isWhisperAction && @@ -493,6 +494,7 @@ const ContextMenuActions: ContextMenuAction[] = [ !isExpenseReportAction && !isThreadReportParentAction && !isHarvestCreatedExpenseReportAction && + !shouldDisableJoinThread && (shouldDisplayThreadReplies || (!isDeletedAction && !isArchivedRoom)) ); }, diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 0646035a2663..e7918e5c4307 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -3341,7 +3341,7 @@ describe('ReportUtils', () => { it('should disable on thread-disabled actions', () => { const reportAction = buildOptimisticCreatedReportAction('email1@test.com'); - expect(shouldDisableThread(reportAction, reportID, false)).toBeTruthy(); + expect(shouldDisableThread(reportAction, false)).toBeTruthy(); }); it('should disable thread on split expense actions', () => { @@ -3353,7 +3353,7 @@ describe('ReportUtils', () => { participants: [{login: 'email1@test.com'}, {login: 'email2@test.com'}], transactionID: NumberUtils.rand64(), }) as ReportAction; - expect(shouldDisableThread(reportAction, reportID, false)).toBeTruthy(); + expect(shouldDisableThread(reportAction, false)).toBeTruthy(); }); it("should disable on a whisper action and it's neither a report preview nor IOU action", () => { @@ -3363,14 +3363,37 @@ describe('ReportUtils', () => { whisperedTo: [123456], }, } as ReportAction; - expect(shouldDisableThread(reportAction, reportID, false)).toBeTruthy(); + expect(shouldDisableThread(reportAction, false)).toBeTruthy(); }); it('should disable on thread first chat', () => { const reportAction = { childReportID: reportID, } as ReportAction; - expect(shouldDisableThread(reportAction, reportID, true)).toBeTruthy(); + expect(shouldDisableThread(reportAction, true)).toBeTruthy(); + }); + + it('should disable thread for messages sent by MANAGER_MCTEST', () => { + // Given a report action from MANAGER_MCTEST + const reportAction = { + actorAccountID: CONST.ACCOUNT_ID.MANAGER_MCTEST, + message: [ + { + translationKey: '', + type: 'COMMENT', + html: 'Test message from Manager McTest', + text: 'Test message from Manager McTest', + }, + ], + actionName: CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT, + } as ReportAction; + + // When it's checked to see if the thread should be disabled + const isThreadDisabled = shouldDisableThread(reportAction, false); + + // Then the thread should be disabled + // This ensures "Reply in thread" and "Join thread" context menu options won't be shown + expect(isThreadDisabled).toBeTruthy(); }); describe('deleted threads', () => { @@ -3389,7 +3412,7 @@ describe('ReportUtils', () => { } as ReportAction; // When it's checked to see if the thread should be disabled - const isThreadDisabled = shouldDisableThread(reportAction, reportID, false); + const isThreadDisabled = shouldDisableThread(reportAction, false); // Then the thread should be enabled expect(isThreadDisabled).toBeFalsy(); @@ -3410,7 +3433,7 @@ describe('ReportUtils', () => { } as ReportAction; // When it's checked to see if the thread should be disabled - const isThreadDisabled = shouldDisableThread(reportAction, reportID, false); + const isThreadDisabled = shouldDisableThread(reportAction, false); // Then the thread should be enabled expect(isThreadDisabled).toBeFalsy(); @@ -3430,7 +3453,7 @@ describe('ReportUtils', () => { } as ReportAction; // When it's checked to see if the thread should be disabled - const isThreadDisabled = shouldDisableThread(reportAction, reportID, false); + const isThreadDisabled = shouldDisableThread(reportAction, false); // Then the thread should be enabled expect(isThreadDisabled).toBeFalsy(); @@ -3451,7 +3474,7 @@ describe('ReportUtils', () => { } as ReportAction; // When it's checked to see if the thread should be disabled - const isThreadDisabled = shouldDisableThread(reportAction, reportID, false); + const isThreadDisabled = shouldDisableThread(reportAction, false); // Then the thread should be disabled expect(isThreadDisabled).toBeTruthy(); @@ -3477,7 +3500,7 @@ describe('ReportUtils', () => { const isReportArchived = false; // When it's checked to see if the thread should be disabled - const isThreadDisabled = shouldDisableThread(reportAction, reportID, false, isReportArchived); + const isThreadDisabled = shouldDisableThread(reportAction, false, isReportArchived); // Then the thread should be enabled expect(isThreadDisabled).toBeFalsy(); @@ -3500,7 +3523,7 @@ describe('ReportUtils', () => { const isReportArchived = false; // When it's checked to see if the thread should be disabled - const isThreadDisabled = shouldDisableThread(reportAction, reportID, false, isReportArchived); + const isThreadDisabled = shouldDisableThread(reportAction, false, isReportArchived); // Then the thread should be enabled expect(isThreadDisabled).toBeFalsy(); @@ -3523,7 +3546,7 @@ describe('ReportUtils', () => { const isReportArchived = true; // When it's checked to see if the thread should be disabled - const isThreadDisabled = shouldDisableThread(reportAction, reportID, false, isReportArchived); + const isThreadDisabled = shouldDisableThread(reportAction, false, isReportArchived); // Then the thread should be enabled expect(isThreadDisabled).toBeFalsy(); @@ -3546,7 +3569,7 @@ describe('ReportUtils', () => { const isReportArchived = true; // When it's checked to see if the thread should be disabled - const isThreadDisabled = shouldDisableThread(reportAction, reportID, false, isReportArchived); + const isThreadDisabled = shouldDisableThread(reportAction, false, isReportArchived); // Then the thread should be disabled expect(isThreadDisabled).toBeTruthy();