Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/libs/actions/IOU/MoneyRequestBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,6 @@ function buildOnyxDataForMoneyRequest(moneyRequestParams: BuildOnyxDataForMoneyR
existingTransactionThreadReportID,
policyParams = {},
optimisticParams,
retryParams,
participant,
shouldGenerateTransactionThreadReport = true,
isASAPSubmitBetaEnabled,
Expand Down Expand Up @@ -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,
},
},
Expand All @@ -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),
},
},
},
Expand Down Expand Up @@ -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,
},
},
Expand All @@ -1011,15 +1010,15 @@ 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'),
},
}
: {
[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),
},
}),
},
Expand Down
9 changes: 4 additions & 5 deletions src/libs/actions/IOU/TrackExpense.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,6 @@ function buildOnyxDataForTrackExpense({
shouldCreateNewMoneyRequestReport,
existingTransactionThreadReportID,
actionableTrackExpenseWhisper,
retryParams,
participant,
isASAPSubmitBetaEnabled,
quickAction,
Expand Down Expand Up @@ -554,15 +553,15 @@ 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'),
},
}
: {
[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),
},
}),
},
Expand All @@ -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),
},
},
});
Expand Down Expand Up @@ -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,
},
},
Expand Down
137 changes: 0 additions & 137 deletions tests/actions/IOUTest/TrackExpenseTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
getDeleteTrackExpenseInformation,
getTrackExpenseInformation,
hasManualDistanceOverride,
requestMoney,
trackExpense,
} from '@libs/actions/IOU/TrackExpense';
import initOnyxDerivedValues from '@libs/actions/OnyxDerived';
Expand All @@ -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';

Expand Down Expand Up @@ -1754,58 +1752,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<Transaction>;
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<string, ReceiptError | undefined>;
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<string, unknown>;
const persistedExistingTransaction = parsedRetryParams.existingTransaction as Partial<Transaction> | 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 = {
Expand Down Expand Up @@ -2260,89 +2206,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<Transaction>;
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<string, ReceiptError | undefined>;
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<string, unknown>;
const persistedExistingTransaction = parsedRetryParams.existingTransaction as Partial<Transaction> | 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';
Expand Down
Loading