From eb793915ec47376e2b359503d84382b8727478aa Mon Sep 17 00:00:00 2001 From: "Yuwen Memon (via MelvinBot)" Date: Fri, 24 Jul 2026 19:01:30 +0000 Subject: [PATCH 1/4] Guard task htmlToText against undefined reportName/description Co-authored-by: Yuwen Memon --- src/libs/SearchUIUtils.ts | 4 +-- tests/unit/Search/SearchUIUtilsTest.ts | 42 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/libs/SearchUIUtils.ts b/src/libs/SearchUIUtils.ts index e1e6c25d7569..81ca21cad7a2 100644 --- a/src/libs/SearchUIUtils.ts +++ b/src/libs/SearchUIUtils.ts @@ -2590,8 +2590,8 @@ function getTaskSections( const report = getReportOrDraftReport(taskItem.reportID) ?? taskItem; const parentReport = getReportOrDraftReport(taskItem.parentReportID) ?? data[`${ONYXKEYS.COLLECTION.REPORT}${taskItem.parentReportID}`]; - const reportName = StringUtils.lineBreaksToSpaces(Parser.htmlToText(taskItem.reportName)); - const description = StringUtils.lineBreaksToSpaces(Parser.htmlToText(taskItem.description)); + const reportName = StringUtils.lineBreaksToSpaces(Parser.htmlToText(taskItem.reportName ?? '')); + const description = StringUtils.lineBreaksToSpaces(Parser.htmlToText(taskItem.description ?? '')); const result: TaskListItemType = { ...taskItem, diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index fa39006076e2..69b8893051ed 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -2674,6 +2674,48 @@ describe('SearchUIUtils', () => { expect(allReportActionsLength).toBe(6); }); + it('should not crash when a task has no description or reportName (type TASK)', () => { + const taskReportID = '987654321'; + const taskData = { + [`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`]: { + type: CONST.REPORT.TYPE.TASK, + accountID: adminAccountID, + managerID: adminAccountID, + created: '2024-01-01 00:00:00', + parentReportID: '123456789', + reportID: taskReportID, + stateNum: CONST.REPORT.STATE_NUM.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, + // description and reportName intentionally omitted: a task created without a description + // has `description === undefined`, which used to crash htmlToText. + } as unknown as SearchTask, + } as unknown as OnyxTypes.SearchResults['data']; + + const getTaskSectionsResult = () => + getSectionsByType( + SearchUIUtils.getSections({ + type: CONST.SEARCH.DATA_TYPES.TASK, + data: taskData, + currentAccountID: adminAccountID, + currentUserEmail: adminEmail, + translate: translateLocal, + formatPhoneNumber, + bankAccountList: {}, + conciergeReportID: undefined, + convertToDisplayString, + reportAttributesDerivedValue: {}, + }), + SearchUIUtils.isTaskListItemType, + )[0]; + + expect(getTaskSectionsResult).not.toThrow(); + + const [task] = getTaskSectionsResult(); + expect(task.reportID).toBe(taskReportID); + expect(task.description).toBe(''); + expect(task.reportName).toBe(''); + }); + it('should return getTransactionsSections result when groupBy is undefined', () => { expect( SearchUIUtils.getSections({ From d04af91b2b26974b94a45ce7ae322a2dc128e6f7 Mon Sep 17 00:00:00 2001 From: "Yuwen Memon (via MelvinBot)" Date: Fri, 24 Jul 2026 19:23:31 +0000 Subject: [PATCH 2/4] Fix ESLint no-unsafe-type-assertion in task filter test Replace the as unknown as double-casts with the createMock<> helper used by the other task tests in this file, which isolates the assertion and keeps description/reportName undefined for the crash-regression case. Co-authored-by: Yuwen Memon --- tests/unit/Search/SearchUIUtilsTest.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index 69b8893051ed..df7fb9a25d23 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -2676,8 +2676,8 @@ describe('SearchUIUtils', () => { it('should not crash when a task has no description or reportName (type TASK)', () => { const taskReportID = '987654321'; - const taskData = { - [`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`]: { + const taskData = createMock({ + [`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`]: createMock({ type: CONST.REPORT.TYPE.TASK, accountID: adminAccountID, managerID: adminAccountID, @@ -2688,8 +2688,8 @@ describe('SearchUIUtils', () => { statusNum: CONST.REPORT.STATUS_NUM.OPEN, // description and reportName intentionally omitted: a task created without a description // has `description === undefined`, which used to crash htmlToText. - } as unknown as SearchTask, - } as unknown as OnyxTypes.SearchResults['data']; + }), + }); const getTaskSectionsResult = () => getSectionsByType( From 4e87029181cd6f04d48cf535e7d45709f5c2d3aa Mon Sep 17 00:00:00 2001 From: "Yuwen Memon (via MelvinBot)" Date: Fri, 24 Jul 2026 19:36:01 +0000 Subject: [PATCH 3/4] Fix typecheck: avoid index-signature collapse in task filter test A sole computed report key made TS widen taskData to a bare index signature. Mirror the sibling task tests: extract taskReport and add a concrete personalDetailsList key so the object matches SearchResults data. Co-authored-by: Yuwen Memon --- tests/unit/Search/SearchUIUtilsTest.ts | 33 ++++++++++++++++---------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index df7fb9a25d23..7ac69c8c5fc9 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -2676,19 +2676,28 @@ describe('SearchUIUtils', () => { it('should not crash when a task has no description or reportName (type TASK)', () => { const taskReportID = '987654321'; + const taskReport = createMock({ + type: CONST.REPORT.TYPE.TASK, + accountID: adminAccountID, + managerID: adminAccountID, + created: '2024-01-01 00:00:00', + parentReportID: '123456789', + reportID: taskReportID, + stateNum: CONST.REPORT.STATE_NUM.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, + // description and reportName intentionally omitted: a task created without a description + // has `description === undefined`, which used to crash htmlToText. + }); const taskData = createMock({ - [`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`]: createMock({ - type: CONST.REPORT.TYPE.TASK, - accountID: adminAccountID, - managerID: adminAccountID, - created: '2024-01-01 00:00:00', - parentReportID: '123456789', - reportID: taskReportID, - stateNum: CONST.REPORT.STATE_NUM.OPEN, - statusNum: CONST.REPORT.STATUS_NUM.OPEN, - // description and reportName intentionally omitted: a task created without a description - // has `description === undefined`, which used to crash htmlToText. - }), + personalDetailsList: { + [adminAccountID]: { + accountID: adminAccountID, + avatar: '', + displayName: 'Task Admin', + login: adminEmail, + }, + }, + [`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`]: taskReport, }); const getTaskSectionsResult = () => From 7b60834104e74a4e8c15974e4e1264e0bd0d44b9 Mon Sep 17 00:00:00 2001 From: "Yuwen Memon (via MelvinBot)" Date: Fri, 24 Jul 2026 19:47:10 +0000 Subject: [PATCH 4/4] Fix typecheck: use literal report_ key prefix in task filter test Interpolating ONYXKEYS.COLLECTION.REPORT (typed as string) widened the key to a plain string index signature. Use the literal report_ prefix like the sibling task tests so the key matches the report_ PrefixedRecord. Co-authored-by: Yuwen Memon --- tests/unit/Search/SearchUIUtilsTest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/Search/SearchUIUtilsTest.ts b/tests/unit/Search/SearchUIUtilsTest.ts index 7ac69c8c5fc9..882cd0cd9c5d 100644 --- a/tests/unit/Search/SearchUIUtilsTest.ts +++ b/tests/unit/Search/SearchUIUtilsTest.ts @@ -2697,7 +2697,7 @@ describe('SearchUIUtils', () => { login: adminEmail, }, }, - [`${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`]: taskReport, + [`report_${taskReportID}`]: taskReport, }); const getTaskSectionsResult = () =>