From e872f192ee9c8345b91a95ef11b1830aa0bfc713 Mon Sep 17 00:00:00 2001 From: Trace Harris Date: Thu, 29 Jan 2026 23:54:00 -0800 Subject: [PATCH 1/4] initial commit for issue #75979 --- src/pages/ReportDetailsPage.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index e682160de7db1..20d6fd66ea496 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -350,10 +350,11 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail const shouldShowLeaveButton = canLeaveChat(report, policy, !!reportNameValuePairs?.private_isArchived); const shouldShowGoToWorkspace = shouldShowPolicy(policy, false, currentUserPersonalDetails?.email) && !policy?.isJoinRequestPending; + const reportForHeader = useMemo(() => getReportForHeader(report), [report]); - const reportName = isGroupChat - ? getReportNameFromReportNameUtils(reportForHeader, reportAttributes) - : Parser.htmlToText(getReportNameFromReportNameUtils(reportForHeader, reportAttributes)); + const shouldParseFullTitle = parentReportAction?.actionName !== + CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT && !isGroupChat; + const reportName = shouldParseFullTitle ? Parser.htmlToText(getReportNameFromReportNameUtils(report, reportAttributes)) : getReportNameFromReportNameUtils(report, reportAttributes); const additionalRoomDetails = (isPolicyExpenseChat && !!report?.isOwnPolicyExpenseChat) || isExpenseReportUtil(report) || isPolicyExpenseChat || isInvoiceRoom ? chatRoomSubtitle From 6cfa0fd97377ba8ffd8e1fef584df2165d26109d Mon Sep 17 00:00:00 2001 From: Trace Harris Date: Fri, 30 Jan 2026 21:26:51 -0800 Subject: [PATCH 2/4] including unit tests for dev#75979 --- .../reportDetails/ReportDetailsPageTest.tsx | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 tests/unit/components/reportDetails/ReportDetailsPageTest.tsx diff --git a/tests/unit/components/reportDetails/ReportDetailsPageTest.tsx b/tests/unit/components/reportDetails/ReportDetailsPageTest.tsx new file mode 100644 index 0000000000000..f040f72274190 --- /dev/null +++ b/tests/unit/components/reportDetails/ReportDetailsPageTest.tsx @@ -0,0 +1,94 @@ +import {act, render} from '@testing-library/react-native'; +import React from 'react'; +import Onyx from 'react-native-onyx'; +import {LocaleContextProvider} from '@components/LocaleContextProvider'; +import OnyxListItemProvider from '@components/OnyxListItemProvider'; +import type Navigation from '@libs/Navigation/Navigation'; +import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types'; +import type {ReportDetailsNavigatorParamList} from '@libs/Navigation/types'; +import Parser from '@libs/Parser'; +import ReportDetailsPage from '@pages/ReportDetailsPage'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type SCREENS from '@src/SCREENS'; +import type {Report, ReportAction} from '@src/types/onyx'; +import createRandomReportAction from '../../../utils/collections/reportActions'; +import {createRandomReport} from '../../../utils/collections/reports'; +import waitForBatchedUpdatesWithAct from '../../../utils/waitForBatchedUpdatesWithAct'; + +jest.mock('@src/components/ConfirmedRoute.tsx'); + +jest.mock('@react-navigation/native', () => { + const actualNav = jest.requireActual('@react-navigation/native'); + return { + ...actualNav, + useIsFocused: jest.fn(), + useRoute: jest.fn(), + usePreventRemove: jest.fn(), + }; +}); + +const mockHtmlToText = jest.spyOn(Parser, 'htmlToText'); + +describe('ReportDetailsPage', () => { + beforeAll(() => { + Onyx.init({ + keys: ONYXKEYS, + evictableKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], + }); + }); + + beforeEach(() => { + mockHtmlToText.mockClear(); + }); + + afterEach(async () => { + await act(async () => { + await Onyx.clear(); + }); + }); + + it('should not call Parser.htmlToText when parentReportAction is ADD_COMMENT', async () => { + const reportID = '10'; + const parentReportID = '20'; + const parentActionID = '100'; + + const parentReportAction = { + ...createRandomReportAction(Number(parentActionID)), + actionName: CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT, + } as ReportAction; + + const report: Report = { + ...createRandomReport(Number(reportID), undefined), + parentReportID, + parentReportActionID: parentActionID, + }; + + await act(async () => { + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${parentReportID}`, createRandomReport(Number(parentReportID), undefined)); + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReportID}`, { + [parentActionID]: parentReportAction, + }); + }); + + render( + + + ['navigation']} + policy={undefined} + report={report} + reportMetadata={undefined} + route={{params: {reportID}} as PlatformStackScreenProps['route']} + /> + + , + ); + + await waitForBatchedUpdatesWithAct(); + + expect(mockHtmlToText).not.toHaveBeenCalled(); + }); +}); From ac6ad0f4c75d4d4cde4a1208519c57a747620be9 Mon Sep 17 00:00:00 2001 From: Trace Harris Date: Fri, 30 Jan 2026 21:53:42 -0800 Subject: [PATCH 3/4] cleaned up related flaky tests that to verify no breaking functionality --- tests/ui/GroupChatNameTests.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/ui/GroupChatNameTests.tsx b/tests/ui/GroupChatNameTests.tsx index 2e529a904ef09..338b2c91ff51a 100644 --- a/tests/ui/GroupChatNameTests.tsx +++ b/tests/ui/GroupChatNameTests.tsx @@ -1,7 +1,7 @@ /* eslint-disable testing-library/no-node-access */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import {act, render, screen, waitFor} from '@testing-library/react-native'; +import {act, cleanup, render, screen, waitFor} from '@testing-library/react-native'; import React from 'react'; import Onyx from 'react-native-onyx'; import {setSidebarLoaded} from '@userActions/App'; @@ -241,6 +241,10 @@ describe('Tests for group chat name', () => { return Onyx.clear().then(waitForBatchedUpdates); }); + afterEach(() => { + cleanup(); + }); + const participantAccountIDs4 = [USER_A_ACCOUNT_ID, USER_B_ACCOUNT_ID, USER_C_ACCOUNT_ID, USER_D_ACCOUNT_ID]; const participantAccountIDs8 = [...participantAccountIDs4, USER_E_ACCOUNT_ID, USER_F_ACCOUNT_ID, USER_G_ACCOUNT_ID, USER_H_ACCOUNT_ID]; From 864e426d67977706b663f48b45fedca4e3f55deb Mon Sep 17 00:00:00 2001 From: Trace Harris Date: Sat, 31 Jan 2026 21:01:41 -0800 Subject: [PATCH 4/4] refactored code to be inline with recommendations with automatic review per git actions revised lint error src/pgs/reportDetails.tsx line 749 included a sentrylabel per lint requirements clean lint at chnges and ran prettier --- src/pages/ReportDetailsPage.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 20d6fd66ea496..55e80e2a5b994 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -352,9 +352,9 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail const shouldShowGoToWorkspace = shouldShowPolicy(policy, false, currentUserPersonalDetails?.email) && !policy?.isJoinRequestPending; const reportForHeader = useMemo(() => getReportForHeader(report), [report]); - const shouldParseFullTitle = parentReportAction?.actionName !== - CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT && !isGroupChat; - const reportName = shouldParseFullTitle ? Parser.htmlToText(getReportNameFromReportNameUtils(report, reportAttributes)) : getReportNameFromReportNameUtils(report, reportAttributes); + const shouldParseFullTitle = parentReportAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT && !isGroupChat; + const rawReportName = getReportNameFromReportNameUtils(reportForHeader, reportAttributes); + const reportName = shouldParseFullTitle ? Parser.htmlToText(rawReportName) : rawReportName; const additionalRoomDetails = (isPolicyExpenseChat && !!report?.isOwnPolicyExpenseChat) || isExpenseReportUtil(report) || isPolicyExpenseChat || isInvoiceRoom ? chatRoomSubtitle @@ -746,6 +746,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail {isPolicyAdmin ? (