diff --git a/src/libs/Parser.ts b/src/libs/Parser.ts index bea8c3eae10e8..8b25f7b5dd796 100644 --- a/src/libs/Parser.ts +++ b/src/libs/Parser.ts @@ -61,6 +61,10 @@ class ExpensiMarkWithContext extends ExpensiMark { }); } + isHTML(text: string): boolean { + return /<[^>]+>/.test(text) || /&[#\w]+;/.test(text); + } + truncateHTML(htmlString: string, limit: number, extras?: {ellipsis: string | undefined}): string { return super.truncateHTML(htmlString, limit, extras); } diff --git a/src/libs/ReportNameUtils.ts b/src/libs/ReportNameUtils.ts index ab2010c5bd442..c4b173831da9a 100644 --- a/src/libs/ReportNameUtils.ts +++ b/src/libs/ReportNameUtils.ts @@ -776,7 +776,9 @@ function computeReportName( } if (isTaskReport(report)) { - return Parser.htmlToText(report?.reportName ?? '').trim(); + const taskName = report?.reportName ?? ''; + + return Parser.isHTML(taskName) ? Parser.htmlToText(taskName).trim() : taskName.trim(); } const privateIsArchivedValue = privateIsArchived ?? allReportNameValuePairs?.[`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${report.reportID}`]?.private_isArchived; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index ff4539c970bc0..c710efe520f0f 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -5757,7 +5757,8 @@ function getReportName( } if (isTaskReport(report)) { - return Parser.htmlToText(report?.reportName ?? '').trim(); + const taskName = report?.reportName ?? ''; + return Parser.isHTML(taskName) ? Parser.htmlToText(taskName).trim() : taskName.trim(); } if (isChatThread(report)) { diff --git a/tests/unit/ParserTest.ts b/tests/unit/ParserTest.ts new file mode 100644 index 0000000000000..e7fc8501500d7 --- /dev/null +++ b/tests/unit/ParserTest.ts @@ -0,0 +1,27 @@ +import Parser from '@libs/Parser'; + +describe('Parser', () => { + describe('isHTML', () => { + test('returns true for strings containing HTML tags', () => { + expect(Parser.isHTML('bold')).toBe(true); + expect(Parser.isHTML('link')).toBe(true); + expect(Parser.isHTML('

heading

')).toBe(true); + expect(Parser.isHTML('text with emphasis inside')).toBe(true); + expect(Parser.isHTML('
')).toBe(true); + expect(Parser.isHTML('

paragraph

')).toBe(true); + }); + + test('returns false for plain text', () => { + expect(Parser.isHTML('just plain text')).toBe(false); + expect(Parser.isHTML('Fix the login bug')).toBe(false); + expect(Parser.isHTML('')).toBe(false); + expect(Parser.isHTML('100 > 50 and 20 < 30')).toBe(false); + }); + + test('returns false for strings with angle brackets that are not HTML', () => { + expect(Parser.isHTML('a > b')).toBe(false); + expect(Parser.isHTML('x < y')).toBe(false); + expect(Parser.isHTML('<>')).toBe(false); + }); + }); +}); diff --git a/tests/unit/ReportNameUtilsTest.ts b/tests/unit/ReportNameUtilsTest.ts index 0bfdb96e023b0..e13906a0b3e39 100644 --- a/tests/unit/ReportNameUtilsTest.ts +++ b/tests/unit/ReportNameUtilsTest.ts @@ -284,6 +284,64 @@ describe('ReportNameUtils', () => { ); expect(name).toBe('heading with link'); }); + + test('Returns plain text title without HTML conversion', () => { + const plainTaskTitle = 'Fix the login bug on Android'; + const report: Report = { + ...createRegularTaskReport(41, currentUserAccountID), + reportName: plainTaskTitle, + }; + + const name = computeReportName( + report, + emptyCollections.reports, + emptyCollections.policies, + undefined, + undefined, + participantsPersonalDetails, + emptyCollections.reportActions, + currentUserAccountID, + ); + expect(name).toBe('Fix the login bug on Android'); + }); + + test('Trims whitespace from plain text title', () => { + const report: Report = { + ...createRegularTaskReport(42, currentUserAccountID), + reportName: ' Expense report review ', + }; + + const name = computeReportName( + report, + emptyCollections.reports, + emptyCollections.policies, + undefined, + undefined, + participantsPersonalDetails, + emptyCollections.reportActions, + currentUserAccountID, + ); + expect(name).toBe('Expense report review'); + }); + + test('Returns empty string for undefined reportName', () => { + const report: Report = { + ...createRegularTaskReport(43, currentUserAccountID), + reportName: undefined, + }; + + const name = computeReportName( + report, + emptyCollections.reports, + emptyCollections.policies, + undefined, + undefined, + participantsPersonalDetails, + emptyCollections.reportActions, + currentUserAccountID, + ); + expect(name).toBe(''); + }); }); describe('computeReportName - Thread report action names', () => {