diff --git a/src/libs/ModifiedExpenseMessage.ts b/src/libs/ModifiedExpenseMessage.ts index 2bfb5d2e1461..11ec215363b5 100644 --- a/src/libs/ModifiedExpenseMessage.ts +++ b/src/libs/ModifiedExpenseMessage.ts @@ -69,24 +69,21 @@ function buildMessageFragmentForValue( shouldConvertToLowercase = true, ) { const newValueToDisplay = valueInQuotes ? `"${newValue}"` : newValue; + const oldValueToDisplay = valueInQuotes ? `"${oldValue}"` : oldValue; - // If the valueName is category and the old value was Uncategorized, show it in lowercase without quotes - let oldValueToDisplay; - if (valueName.includes(translate('common.category').toLowerCase()) && isCategoryMissing(oldValue)) { - oldValueToDisplay = oldValue.toLowerCase(); - } else if (valueInQuotes) { - oldValueToDisplay = `"${oldValue}"`; - } else { - oldValueToDisplay = oldValue; - } + // eslint-disable-next-line @typescript-eslint/no-deprecated + const isCategoryField = valueName.includes(translateLocal('common.category').toLowerCase()); const displayValueName = shouldConvertToLowercase ? valueName.toLowerCase() : valueName; const isOldValuePartialMerchant = valueName === translate('common.merchant') && oldValue === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT; + const isOldCategoryMissing = isCategoryField && isCategoryMissing(oldValue); + const isNewCategoryMissing = isCategoryField && isCategoryMissing(newValue); - // In case of a partial merchant value, we want to avoid user seeing the "(none)" value in the message. - if (!oldValue || isOldValuePartialMerchant) { - const fragment = translate('iou.setTheRequest', {valueName: displayValueName, newValueToDisplay}); - setFragments.push(fragment); + if (!oldValue || isOldValuePartialMerchant || isOldCategoryMissing) { + if (!(isOldCategoryMissing && isNewCategoryMissing)) { + const fragment = translate('iou.setTheRequest', {valueName: displayValueName, newValueToDisplay}); + setFragments.push(fragment); + } } else if (!newValue || newValue === CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT) { const fragment = translate('iou.removedTheRequest', {valueName: displayValueName, oldValueToDisplay}); removalFragments.push(fragment); diff --git a/tests/unit/ModifiedExpenseMessageTest.ts b/tests/unit/ModifiedExpenseMessageTest.ts index b10b1b281a67..cf4446a6d305 100644 --- a/tests/unit/ModifiedExpenseMessageTest.ts +++ b/tests/unit/ModifiedExpenseMessageTest.ts @@ -739,6 +739,45 @@ describe('ModifiedExpenseMessage', () => { }); }); + describe('when the category is changed from Uncategorized with AI attribution', () => { + const reportAction = { + ...createRandomReportAction(1), + actionName: CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE, + originalMessage: { + category: '6403 Travel - Member Services', + oldCategory: 'Uncategorized', + source: CONST.CATEGORY_SOURCE.AI, + } as OriginalMessageModifiedExpense, + }; + + it('returns the correct text message without showing previously uncategorized', () => { + const expectedResult = `set the category based on past activity to "6403 Travel - Member Services"`; + + const result = getForReportAction({reportAction, policyID: report.policyID}); + + expect(result).toEqual(expectedResult); + }); + }); + + describe('when the category is cleared from Uncategorized (both missing)', () => { + const reportAction = { + ...createRandomReportAction(1), + actionName: CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE, + originalMessage: { + category: '', + oldCategory: 'Uncategorized', + } as OriginalMessageModifiedExpense, + }; + + it('returns the generic changed expense message since no meaningful change occurred', () => { + const expectedResult = `changed the expense`; + + const result = getForReportAction({reportAction, policyID: report.policyID}); + + expect(result).toEqual(expectedResult); + }); + }); + describe('when the category is removed with AI attribution', () => { const reportAction = { ...createRandomReportAction(1),