From 3260a15f4d0f3e6fb6f9b4c0f7a6dcdca3f4854b Mon Sep 17 00:00:00 2001 From: Qichen Zhu <57348009+QichenZhu@users.noreply.github.com> Date: Sat, 11 Jul 2026 01:34:38 +1200 Subject: [PATCH 1/3] Remove retryParams from buildOnyxDataForTrackExpense and buildOnyxDataForMoneyRequest --- src/libs/actions/IOU/MoneyRequestBuilder.ts | 11 +++++------ src/libs/actions/IOU/TrackExpense.ts | 9 ++++----- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/libs/actions/IOU/MoneyRequestBuilder.ts b/src/libs/actions/IOU/MoneyRequestBuilder.ts index 2cd5a8b197d2..4346a2250e92 100644 --- a/src/libs/actions/IOU/MoneyRequestBuilder.ts +++ b/src/libs/actions/IOU/MoneyRequestBuilder.ts @@ -423,7 +423,6 @@ function buildOnyxDataForMoneyRequest(moneyRequestParams: BuildOnyxDataForMoneyR existingTransactionThreadReportID, policyParams = {}, optimisticParams, - retryParams, participant, shouldGenerateTransactionThreadReport = true, isASAPSubmitBetaEnabled, @@ -951,7 +950,7 @@ function buildOnyxDataForMoneyRequest(moneyRequestParams: BuildOnyxDataForMoneyR onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, value: { - errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, errorKey, CONST.IOU.ACTION_PARAMS.MONEY_REQUEST, retryParams), + errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, errorKey, CONST.IOU.ACTION_PARAMS.MONEY_REQUEST), pendingFields: clearedPendingFields, }, }, @@ -960,7 +959,7 @@ function buildOnyxDataForMoneyRequest(moneyRequestParams: BuildOnyxDataForMoneyR key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${selfDMReportID}`, value: { [iou.action.reportActionID]: { - errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, errorKey, CONST.IOU.ACTION_PARAMS.MONEY_REQUEST, retryParams), + errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, errorKey, CONST.IOU.ACTION_PARAMS.MONEY_REQUEST), }, }, }, @@ -1000,7 +999,7 @@ function buildOnyxDataForMoneyRequest(moneyRequestParams: BuildOnyxDataForMoneyR onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, value: { - errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, errorKey, CONST.IOU.ACTION_PARAMS.MONEY_REQUEST, retryParams), + errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, errorKey, CONST.IOU.ACTION_PARAMS.MONEY_REQUEST), pendingFields: clearedPendingFields, }, }, @@ -1011,7 +1010,7 @@ function buildOnyxDataForMoneyRequest(moneyRequestParams: BuildOnyxDataForMoneyR ...(shouldCreateNewMoneyRequestReport ? { [iou.createdAction.reportActionID]: { - errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, errorKey, CONST.IOU.ACTION_PARAMS.MONEY_REQUEST, retryParams), + errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, errorKey, CONST.IOU.ACTION_PARAMS.MONEY_REQUEST), }, [iou.action.reportActionID]: { errors: getMicroSecondOnyxErrorWithTranslationKey('iou.error.genericCreateFailureMessage'), @@ -1019,7 +1018,7 @@ function buildOnyxDataForMoneyRequest(moneyRequestParams: BuildOnyxDataForMoneyR } : { [iou.action.reportActionID]: { - errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, errorKey, CONST.IOU.ACTION_PARAMS.MONEY_REQUEST, retryParams), + errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, errorKey, CONST.IOU.ACTION_PARAMS.MONEY_REQUEST), }, }), }, diff --git a/src/libs/actions/IOU/TrackExpense.ts b/src/libs/actions/IOU/TrackExpense.ts index 89be1887d1ab..398bddf4f3f3 100644 --- a/src/libs/actions/IOU/TrackExpense.ts +++ b/src/libs/actions/IOU/TrackExpense.ts @@ -241,7 +241,6 @@ function buildOnyxDataForTrackExpense({ shouldCreateNewMoneyRequestReport, existingTransactionThreadReportID, actionableTrackExpenseWhisper, - retryParams, participant, isASAPSubmitBetaEnabled, quickAction, @@ -554,7 +553,7 @@ function buildOnyxDataForTrackExpense({ ...(shouldCreateNewMoneyRequestReport ? { [iouCreatedAction.reportActionID]: { - errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, undefined, CONST.IOU.ACTION_PARAMS.TRACK_EXPENSE, retryParams), + errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, undefined, CONST.IOU.ACTION_PARAMS.TRACK_EXPENSE), }, [iouAction.reportActionID]: { errors: getMicroSecondOnyxErrorWithTranslationKey('iou.error.genericCreateFailureMessage'), @@ -562,7 +561,7 @@ function buildOnyxDataForTrackExpense({ } : { [iouAction.reportActionID]: { - errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, undefined, CONST.IOU.ACTION_PARAMS.TRACK_EXPENSE, retryParams), + errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, undefined, CONST.IOU.ACTION_PARAMS.TRACK_EXPENSE), }, }), }, @@ -574,7 +573,7 @@ function buildOnyxDataForTrackExpense({ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`, value: { [iouAction.reportActionID]: { - errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, undefined, CONST.IOU.ACTION_PARAMS.TRACK_EXPENSE, retryParams), + errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, undefined, CONST.IOU.ACTION_PARAMS.TRACK_EXPENSE), }, }, }); @@ -606,7 +605,7 @@ function buildOnyxDataForTrackExpense({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, value: { - errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, undefined, CONST.IOU.ACTION_PARAMS.TRACK_EXPENSE, retryParams), + errors: getReceiptError(transaction.receipt, transaction.receipt?.filename, isScanRequest, undefined, CONST.IOU.ACTION_PARAMS.TRACK_EXPENSE), pendingFields: clearedPendingFields, }, }, From 4a64a650c6ab9f6428bf6420acc44e1bc4ac14c1 Mon Sep 17 00:00:00 2001 From: Qichen Zhu <57348009+QichenZhu@users.noreply.github.com> Date: Sat, 11 Jul 2026 02:11:46 +1200 Subject: [PATCH 2/3] Remove outdated tests --- tests/actions/IOUTest/TrackExpenseTest.ts | 135 ---------------------- 1 file changed, 135 deletions(-) diff --git a/tests/actions/IOUTest/TrackExpenseTest.ts b/tests/actions/IOUTest/TrackExpenseTest.ts index 9f2482d85da2..b8fdc73c60de 100644 --- a/tests/actions/IOUTest/TrackExpenseTest.ts +++ b/tests/actions/IOUTest/TrackExpenseTest.ts @@ -1754,58 +1754,6 @@ describe('actions/IOU/TrackExpense', () => { mockFetch?.succeed?.(); }); - it('should preserve iouRequestType in retryParams without leaking the full existingTransaction', async () => { - // Given a selfDM report and an existing SCAN transaction (carrying state that would bloat the retry payload) - const selfDMReport: Report = { - ...createRandomReport(1, CONST.REPORT.CHAT_TYPE.SELF_DM), - reportID: 'selfDM-retry-leak', - }; - const existingTransaction: Transaction = { - ...createRandomTransaction(1), - iouRequestType: CONST.IOU.REQUEST_TYPE.SCAN, - comment: {comment: 'pre-existing comment'}, - receipt: {source: 'existing-receipt.jpg', state: CONST.IOU.RECEIPT_STATE.SCAN_READY}, - }; - - await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${selfDMReport.reportID}`, selfDMReport); - mockFetch?.fail?.(); - - // When trackExpense fails with a SCAN receipt - trackExpense({ - ...getDefaultTrackExpenseParams(selfDMReport, { - receipt: {source: 'new-receipt.jpg', name: 'new-receipt.jpg', state: CONST.IOU.RECEIPT_STATE.SCAN_READY}, - }), - existingTransaction, - delegateAccountID: undefined, - }); - await mockFetch?.resume?.(); - await waitForBatchedUpdates(); - - // Then the retryParams stored on the receipt error must preserve iouRequestType but not the bulky source state - let transactions: OnyxCollection; - await getOnyxData({ - key: ONYXKEYS.COLLECTION.TRANSACTION, - waitForCollectionCallback: true, - callback: (val) => { - transactions = val; - }, - }); - - const failedTransaction = Object.values(transactions ?? {}).find((t) => !!t?.errors); - expect(failedTransaction).toBeDefined(); - const errors = (failedTransaction?.errors ?? {}) as Record; - const receiptError = Object.values(errors).find((err) => err?.error === CONST.IOU.RECEIPT_ERROR); - expect(receiptError).toBeDefined(); - const parsedRetryParams = JSON.parse(receiptError?.retryParams as unknown as string) as Record; - const persistedExistingTransaction = parsedRetryParams.existingTransaction as Partial | undefined; - expect(persistedExistingTransaction?.iouRequestType).toBe(CONST.IOU.REQUEST_TYPE.SCAN); - expect(persistedExistingTransaction?.comment).toBeUndefined(); - expect(persistedExistingTransaction?.receipt).toBeUndefined(); - expect(persistedExistingTransaction?.cardNumber).toBeUndefined(); - - mockFetch?.succeed?.(); - }); - it('should handle category and tag together correctly', async () => { // Given a selfDM report with category and tag const selfDMReport: Report = { @@ -2260,89 +2208,6 @@ describe('actions/IOU/TrackExpense', () => { }); }); - describe('requestMoney', () => { - it('should preserve iouRequestType in retryParams without leaking the full existingTransaction', async () => { - // Given a 1:1 chat report and an existing SCAN transaction (carrying state that would bloat the retry payload) - const chatReport: Report = { - ...createRandomReport(2, undefined), - reportID: 'chat-retry-leak', - type: CONST.REPORT.TYPE.CHAT, - participants: { - [RORY_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, - [CARLOS_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS}, - }, - }; - const existingTransaction: Transaction = { - ...createRandomTransaction(2), - iouRequestType: CONST.IOU.REQUEST_TYPE.SCAN, - comment: {comment: 'pre-existing comment'}, - receipt: {source: 'existing-receipt.jpg', state: CONST.IOU.RECEIPT_STATE.SCAN_READY}, - }; - - await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, chatReport); - mockFetch?.fail?.(); - - // When requestMoney fails with a SCAN receipt - requestMoney({ - report: chatReport, - participantParams: { - payeeEmail: RORY_EMAIL, - payeeAccountID: RORY_ACCOUNT_ID, - participant: {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, - }, - transactionParams: { - amount: 10000, - attendees: [], - currency: CONST.CURRENCY.USD, - created: format(new Date(), CONST.DATE.FNS_FORMAT_STRING), - merchant: 'Failure Test', - comment: 'retry payload guard', - receipt: {source: 'new-receipt.jpg', name: 'new-receipt.jpg', state: CONST.IOU.RECEIPT_STATE.SCAN_READY}, - }, - shouldGenerateTransactionThreadReport: true, - isASAPSubmitBetaEnabled: false, - currentUserAccountIDParam: RORY_ACCOUNT_ID, - currentUserEmailParam: RORY_EMAIL, - transactionViolations: {}, - policyRecentlyUsedCurrencies: [], - existingTransactionDraft: undefined, - existingTransaction, - draftTransactionIDs: [], - isSelfTourViewed: false, - quickAction: undefined, - betas: [CONST.BETAS.ALL], - personalDetails: {}, - delegateAccountID: undefined, - }); - await mockFetch?.resume?.(); - await waitForBatchedUpdates(); - - // Then the retryParams stored on the receipt error must preserve iouRequestType but not the bulky source state - let transactions: OnyxCollection; - await getOnyxData({ - key: ONYXKEYS.COLLECTION.TRANSACTION, - waitForCollectionCallback: true, - callback: (val) => { - transactions = val; - }, - }); - - const failedTransaction = Object.values(transactions ?? {}).find((t) => !!t?.errors); - expect(failedTransaction).toBeDefined(); - const errors = (failedTransaction?.errors ?? {}) as Record; - const receiptError = Object.values(errors).find((err) => err?.error === CONST.IOU.RECEIPT_ERROR); - expect(receiptError).toBeDefined(); - const parsedRetryParams = JSON.parse(receiptError?.retryParams as unknown as string) as Record; - const persistedExistingTransaction = parsedRetryParams.existingTransaction as Partial | undefined; - expect(persistedExistingTransaction?.iouRequestType).toBe(CONST.IOU.REQUEST_TYPE.SCAN); - expect(persistedExistingTransaction?.comment).toBeUndefined(); - expect(persistedExistingTransaction?.receipt).toBeUndefined(); - expect(persistedExistingTransaction?.cardNumber).toBeUndefined(); - - mockFetch?.succeed?.(); - }); - }); - describe('getDeleteTrackExpenseInformation', () => { const amount = 10000; const comment = 'Send me money please'; From 1d5389c7cbf0684baccd006e86a0107a2fa9e095 Mon Sep 17 00:00:00 2001 From: Qichen Zhu <57348009+QichenZhu@users.noreply.github.com> Date: Sat, 11 Jul 2026 02:48:30 +1200 Subject: [PATCH 3/3] Remove unused imports --- tests/actions/IOUTest/TrackExpenseTest.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/actions/IOUTest/TrackExpenseTest.ts b/tests/actions/IOUTest/TrackExpenseTest.ts index b8fdc73c60de..7d6b59215cdf 100644 --- a/tests/actions/IOUTest/TrackExpenseTest.ts +++ b/tests/actions/IOUTest/TrackExpenseTest.ts @@ -7,7 +7,6 @@ import { getDeleteTrackExpenseInformation, getTrackExpenseInformation, hasManualDistanceOverride, - requestMoney, trackExpense, } from '@libs/actions/IOU/TrackExpense'; import initOnyxDerivedValues from '@libs/actions/OnyxDerived'; @@ -34,7 +33,6 @@ import type {Accountant} from '@src/types/onyx/IOU'; import type ReportAction from '@src/types/onyx/ReportAction'; import type {ReportActions} from '@src/types/onyx/ReportAction'; import type Transaction from '@src/types/onyx/Transaction'; -import type {ReceiptError} from '@src/types/onyx/Transaction'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';