From aa2729fdfe245756bc06bdf19bf0ab8c5784fde4 Mon Sep 17 00:00:00 2001 From: "Aimane Chnaif (via MelvinBot)" Date: Mon, 6 Apr 2026 13:17:50 +0000 Subject: [PATCH 1/5] Fix: Show Pay badge on LHN for negative expenses When a negative expense is approved, the expense preview correctly shows "Mark as paid" by calling canIOUBePaid with onlyShowPayElsewhere=true as a fallback. The LHN badge logic in getIOUReportActionWithBadge was missing this second call, so no Pay badge appeared for negative amounts. Co-authored-by: Aimane Chnaif --- src/libs/actions/IOU/index.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/IOU/index.ts b/src/libs/actions/IOU/index.ts index 26ab90d84dc61..f1f32bddcd8b3 100644 --- a/src/libs/actions/IOU/index.ts +++ b/src/libs/actions/IOU/index.ts @@ -7168,7 +7168,10 @@ function getIOUReportActionWithBadge( } const iouReport = getReportOrDraftReport(action.childReportID); // Only show to the actual payer, exclude admins with bank account access - if (canIOUBePaid(iouReport, chatReport, policy, undefined, undefined, undefined, undefined, invoiceReceiverPolicy)) { + if ( + canIOUBePaid(iouReport, chatReport, policy, undefined, undefined, undefined, undefined, invoiceReceiverPolicy) || + canIOUBePaid(iouReport, chatReport, policy, undefined, undefined, true, undefined, invoiceReceiverPolicy) + ) { actionBadge = CONST.REPORT.ACTION_BADGE.PAY; return true; } From 753fad974d769498872916664efad2f1197492a1 Mon Sep 17 00:00:00 2001 From: "Aimane Chnaif (via MelvinBot)" Date: Mon, 6 Apr 2026 14:02:34 +0000 Subject: [PATCH 2/5] Add unit test for getIOUReportActionWithBadge negative expense Pay badge Co-authored-by: Aimane Chnaif --- tests/unit/getIOUReportActionWithBadgeTest.ts | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 tests/unit/getIOUReportActionWithBadgeTest.ts diff --git a/tests/unit/getIOUReportActionWithBadgeTest.ts b/tests/unit/getIOUReportActionWithBadgeTest.ts new file mode 100644 index 0000000000000..ef111c45cbeee --- /dev/null +++ b/tests/unit/getIOUReportActionWithBadgeTest.ts @@ -0,0 +1,148 @@ +import Onyx from 'react-native-onyx'; +import {getIOUReportActionWithBadge} from '@userActions/IOU'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {Policy, Report, ReportAction, ReportActions} from '@src/types/onyx'; +import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; + +const CURRENT_USER_ACCOUNT_ID = 1; +const CURRENT_USER_EMAIL = 'admin@test.com'; +const POLICY_ID = 'policy1'; +const CHAT_REPORT_ID = '100'; +const EXPENSE_REPORT_ID = '200'; +const REPORT_ACTION_ID = '300'; + +function createPolicy(overrides: Partial = {}): Policy { + return { + id: POLICY_ID, + name: 'Test Policy', + type: CONST.POLICY.TYPE.TEAM, + role: CONST.POLICY.ROLE.ADMIN, + owner: CURRENT_USER_EMAIL, + ownerAccountID: CURRENT_USER_ACCOUNT_ID, + outputCurrency: CONST.CURRENCY.USD, + isPolicyExpenseChatEnabled: true, + reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL, + employeeList: { + [CURRENT_USER_EMAIL]: { + email: CURRENT_USER_EMAIL, + role: CONST.POLICY.ROLE.ADMIN, + }, + }, + ...overrides, + } as Policy; +} + +function createChatReport(): Report { + return { + reportID: CHAT_REPORT_ID, + chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, + type: CONST.REPORT.TYPE.CHAT, + policyID: POLICY_ID, + ownerAccountID: CURRENT_USER_ACCOUNT_ID, + isOwnPolicyExpenseChat: true, + reportName: 'Test Chat', + } as Report; +} + +function createExpenseReport(overrides: Partial = {}): Report { + return { + reportID: EXPENSE_REPORT_ID, + type: CONST.REPORT.TYPE.EXPENSE, + policyID: POLICY_ID, + ownerAccountID: 2, + managerID: CURRENT_USER_ACCOUNT_ID, + currency: CONST.CURRENCY.USD, + parentReportID: CHAT_REPORT_ID, + isWaitingOnBankAccount: false, + ...overrides, + } as Report; +} + +function createReportPreviewAction(): ReportAction { + return { + actionName: CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW, + reportActionID: REPORT_ACTION_ID, + childReportID: EXPENSE_REPORT_ID, + created: '2024-01-01 00:00:00', + message: [{text: 'Report preview', type: 'TEXT', html: 'Report preview'}], + } as ReportAction; +} + +async function setupOnyxData(expenseReportOverrides: Partial = {}, policyOverrides: Partial = {}) { + const reportActions: ReportActions = { + [REPORT_ACTION_ID]: createReportPreviewAction(), + }; + + await Onyx.multiSet({ + [ONYXKEYS.SESSION]: {email: CURRENT_USER_EMAIL, accountID: CURRENT_USER_ACCOUNT_ID}, + [`${ONYXKEYS.COLLECTION.REPORT}${CHAT_REPORT_ID}`]: createChatReport(), + [`${ONYXKEYS.COLLECTION.REPORT}${EXPENSE_REPORT_ID}`]: createExpenseReport(expenseReportOverrides), + [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${CHAT_REPORT_ID}`]: reportActions, + [`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`]: createPolicy(policyOverrides), + }); + + return waitForBatchedUpdates(); +} + +describe('getIOUReportActionWithBadge', () => { + beforeAll(() => { + Onyx.init({keys: ONYXKEYS}); + }); + + beforeEach(async () => { + await Onyx.clear(); + await waitForBatchedUpdates(); + }); + + it('should return PAY badge for approved expense report with positive reimbursable spend', async () => { + // total is negative for expense reports (convention: negative = owed to employee) + // getMoneyRequestSpendBreakdown flips sign for expense reports: reimbursableSpend = -total = 5000 + await setupOnyxData({ + total: -5000, + nonReimbursableTotal: 0, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.APPROVED, + }); + + const chatReport = createChatReport(); + const policy = createPolicy(); + const {actionBadge} = getIOUReportActionWithBadge(chatReport, policy, undefined, undefined); + + expect(actionBadge).toBe(CONST.REPORT.ACTION_BADGE.PAY); + }); + + it('should return PAY badge for negative expense (credit) via onlyShowPayElsewhere path', async () => { + // For a negative/credit expense, total is positive on expense reports + // getMoneyRequestSpendBreakdown flips sign: reimbursableSpend = -total = -5000 (negative) + // The first canIOUBePaid call (onlyShowPayElsewhere=false) returns false because reimbursableSpend < 0 + // The second canIOUBePaid call (onlyShowPayElsewhere=true) returns true via canShowMarkedAsPaidForNegativeAmount + await setupOnyxData({ + total: 5000, + nonReimbursableTotal: 0, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.APPROVED, + }); + + const chatReport = createChatReport(); + const policy = createPolicy(); + const {actionBadge} = getIOUReportActionWithBadge(chatReport, policy, undefined, undefined); + + expect(actionBadge).toBe(CONST.REPORT.ACTION_BADGE.PAY); + }); + + it('should not return PAY badge for settled expense report', async () => { + await setupOnyxData({ + total: -5000, + nonReimbursableTotal: 0, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, + }); + + const chatReport = createChatReport(); + const policy = createPolicy(); + const {actionBadge} = getIOUReportActionWithBadge(chatReport, policy, undefined, undefined); + + expect(actionBadge).toBeUndefined(); + }); +}); From ad14ecef5dc6593d0098827e54aca7080734390f Mon Sep 17 00:00:00 2001 From: "Aimane Chnaif (via MelvinBot)" Date: Mon, 6 Apr 2026 14:09:18 +0000 Subject: [PATCH 3/5] Migrate negative expense test into IOUTest.ts, remove standalone test file Move the negative expense (onlyShowPayElsewhere) test case into the existing getIOUReportActionWithBadge describe block in IOUTest.ts. The other two test cases (positive spend PAY badge, settled report) were already covered by existing tests. Delete the standalone test file. Co-authored-by: Aimane Chnaif --- tests/actions/IOUTest.ts | 67 ++++++++ tests/unit/getIOUReportActionWithBadgeTest.ts | 148 ------------------ 2 files changed, 67 insertions(+), 148 deletions(-) delete mode 100644 tests/unit/getIOUReportActionWithBadgeTest.ts diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index f1dd7dc36b294..48e99f134249f 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -13785,6 +13785,73 @@ describe('actions/IOU', () => { expect(result.actionBadge).toBe(CONST.REPORT.ACTION_BADGE.SUBMIT); }); + it('should return PAY badge for negative expense (credit) via onlyShowPayElsewhere path', async () => { + const chatReportID = '500'; + const iouReportID = '501'; + const policyID = '502'; + + const fakePolicy: Policy = { + ...createRandomPolicy(Number(policyID)), + id: policyID, + type: CONST.POLICY.TYPE.TEAM, + approvalMode: CONST.POLICY.APPROVAL_MODE.BASIC, + role: CONST.POLICY.ROLE.ADMIN, + reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL, + }; + + const fakeChatReport: Report = { + ...createRandomReport(Number(chatReportID), CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT), + reportID: chatReportID, + policyID, + }; + + // For a negative/credit expense, total is positive on expense reports + // getMoneyRequestSpendBreakdown flips sign: reimbursableSpend = -total = -5000 (negative) + // The first canIOUBePaid call (onlyShowPayElsewhere=false) returns false because reimbursableSpend < 0 + // The second canIOUBePaid call (onlyShowPayElsewhere=true) returns true via canShowMarkedAsPaidForNegativeAmount + const fakeIouReport: Report = { + ...createRandomReport(Number(iouReportID), CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT), + reportID: iouReportID, + type: CONST.REPORT.TYPE.EXPENSE, + policyID, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.APPROVED, + managerID: RORY_ACCOUNT_ID, + total: 5000, + nonReimbursableTotal: 0, + isWaitingOnBankAccount: false, + }; + + const fakeTransaction: Transaction = { + ...createRandomTransaction(0), + reportID: iouReportID, + amount: 100, + status: CONST.TRANSACTION.STATUS.POSTED, + bank: '', + }; + + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`, fakeChatReport); + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, fakeIouReport); + await Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${fakeTransaction.transactionID}`, fakeTransaction); + + const reportPreviewAction = { + reportActionID: iouReportID, + actionName: CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW, + created: '2024-08-08 19:00:00.000', + childReportID: iouReportID, + message: [{type: 'TEXT', text: 'Report preview'}], + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`, { + [reportPreviewAction.reportActionID]: reportPreviewAction, + }); + await waitForBatchedUpdates(); + + const result = getIOUReportActionWithBadge(fakeChatReport, fakePolicy, {}, undefined); + expect(result.reportAction).toMatchObject(reportPreviewAction); + expect(result.actionBadge).toBe(CONST.REPORT.ACTION_BADGE.PAY); + }); + it('should return undefined actionBadge when report is settled', async () => { const chatReportID = '400'; const iouReportID = '401'; diff --git a/tests/unit/getIOUReportActionWithBadgeTest.ts b/tests/unit/getIOUReportActionWithBadgeTest.ts deleted file mode 100644 index ef111c45cbeee..0000000000000 --- a/tests/unit/getIOUReportActionWithBadgeTest.ts +++ /dev/null @@ -1,148 +0,0 @@ -import Onyx from 'react-native-onyx'; -import {getIOUReportActionWithBadge} from '@userActions/IOU'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import type {Policy, Report, ReportAction, ReportActions} from '@src/types/onyx'; -import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; - -const CURRENT_USER_ACCOUNT_ID = 1; -const CURRENT_USER_EMAIL = 'admin@test.com'; -const POLICY_ID = 'policy1'; -const CHAT_REPORT_ID = '100'; -const EXPENSE_REPORT_ID = '200'; -const REPORT_ACTION_ID = '300'; - -function createPolicy(overrides: Partial = {}): Policy { - return { - id: POLICY_ID, - name: 'Test Policy', - type: CONST.POLICY.TYPE.TEAM, - role: CONST.POLICY.ROLE.ADMIN, - owner: CURRENT_USER_EMAIL, - ownerAccountID: CURRENT_USER_ACCOUNT_ID, - outputCurrency: CONST.CURRENCY.USD, - isPolicyExpenseChatEnabled: true, - reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL, - employeeList: { - [CURRENT_USER_EMAIL]: { - email: CURRENT_USER_EMAIL, - role: CONST.POLICY.ROLE.ADMIN, - }, - }, - ...overrides, - } as Policy; -} - -function createChatReport(): Report { - return { - reportID: CHAT_REPORT_ID, - chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, - type: CONST.REPORT.TYPE.CHAT, - policyID: POLICY_ID, - ownerAccountID: CURRENT_USER_ACCOUNT_ID, - isOwnPolicyExpenseChat: true, - reportName: 'Test Chat', - } as Report; -} - -function createExpenseReport(overrides: Partial = {}): Report { - return { - reportID: EXPENSE_REPORT_ID, - type: CONST.REPORT.TYPE.EXPENSE, - policyID: POLICY_ID, - ownerAccountID: 2, - managerID: CURRENT_USER_ACCOUNT_ID, - currency: CONST.CURRENCY.USD, - parentReportID: CHAT_REPORT_ID, - isWaitingOnBankAccount: false, - ...overrides, - } as Report; -} - -function createReportPreviewAction(): ReportAction { - return { - actionName: CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW, - reportActionID: REPORT_ACTION_ID, - childReportID: EXPENSE_REPORT_ID, - created: '2024-01-01 00:00:00', - message: [{text: 'Report preview', type: 'TEXT', html: 'Report preview'}], - } as ReportAction; -} - -async function setupOnyxData(expenseReportOverrides: Partial = {}, policyOverrides: Partial = {}) { - const reportActions: ReportActions = { - [REPORT_ACTION_ID]: createReportPreviewAction(), - }; - - await Onyx.multiSet({ - [ONYXKEYS.SESSION]: {email: CURRENT_USER_EMAIL, accountID: CURRENT_USER_ACCOUNT_ID}, - [`${ONYXKEYS.COLLECTION.REPORT}${CHAT_REPORT_ID}`]: createChatReport(), - [`${ONYXKEYS.COLLECTION.REPORT}${EXPENSE_REPORT_ID}`]: createExpenseReport(expenseReportOverrides), - [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${CHAT_REPORT_ID}`]: reportActions, - [`${ONYXKEYS.COLLECTION.POLICY}${POLICY_ID}`]: createPolicy(policyOverrides), - }); - - return waitForBatchedUpdates(); -} - -describe('getIOUReportActionWithBadge', () => { - beforeAll(() => { - Onyx.init({keys: ONYXKEYS}); - }); - - beforeEach(async () => { - await Onyx.clear(); - await waitForBatchedUpdates(); - }); - - it('should return PAY badge for approved expense report with positive reimbursable spend', async () => { - // total is negative for expense reports (convention: negative = owed to employee) - // getMoneyRequestSpendBreakdown flips sign for expense reports: reimbursableSpend = -total = 5000 - await setupOnyxData({ - total: -5000, - nonReimbursableTotal: 0, - stateNum: CONST.REPORT.STATE_NUM.APPROVED, - statusNum: CONST.REPORT.STATUS_NUM.APPROVED, - }); - - const chatReport = createChatReport(); - const policy = createPolicy(); - const {actionBadge} = getIOUReportActionWithBadge(chatReport, policy, undefined, undefined); - - expect(actionBadge).toBe(CONST.REPORT.ACTION_BADGE.PAY); - }); - - it('should return PAY badge for negative expense (credit) via onlyShowPayElsewhere path', async () => { - // For a negative/credit expense, total is positive on expense reports - // getMoneyRequestSpendBreakdown flips sign: reimbursableSpend = -total = -5000 (negative) - // The first canIOUBePaid call (onlyShowPayElsewhere=false) returns false because reimbursableSpend < 0 - // The second canIOUBePaid call (onlyShowPayElsewhere=true) returns true via canShowMarkedAsPaidForNegativeAmount - await setupOnyxData({ - total: 5000, - nonReimbursableTotal: 0, - stateNum: CONST.REPORT.STATE_NUM.APPROVED, - statusNum: CONST.REPORT.STATUS_NUM.APPROVED, - }); - - const chatReport = createChatReport(); - const policy = createPolicy(); - const {actionBadge} = getIOUReportActionWithBadge(chatReport, policy, undefined, undefined); - - expect(actionBadge).toBe(CONST.REPORT.ACTION_BADGE.PAY); - }); - - it('should not return PAY badge for settled expense report', async () => { - await setupOnyxData({ - total: -5000, - nonReimbursableTotal: 0, - stateNum: CONST.REPORT.STATE_NUM.APPROVED, - statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, - }); - - const chatReport = createChatReport(); - const policy = createPolicy(); - const {actionBadge} = getIOUReportActionWithBadge(chatReport, policy, undefined, undefined); - - expect(actionBadge).toBeUndefined(); - }); -}); From cf5ad94a8dd4337d476ef09dc64505d5e68541a6 Mon Sep 17 00:00:00 2001 From: "Aimane Chnaif (via MelvinBot)" Date: Mon, 6 Apr 2026 14:11:19 +0000 Subject: [PATCH 4/5] Update comment to reflect pay-elsewhere path for negative expenses Co-authored-by: Aimane Chnaif --- src/libs/actions/IOU/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU/index.ts b/src/libs/actions/IOU/index.ts index f1f32bddcd8b3..85fa9909c223c 100644 --- a/src/libs/actions/IOU/index.ts +++ b/src/libs/actions/IOU/index.ts @@ -7167,7 +7167,7 @@ function getIOUReportActionWithBadge( return false; } const iouReport = getReportOrDraftReport(action.childReportID); - // Only show to the actual payer, exclude admins with bank account access + // Show to the actual payer, or to policy admins via the pay-elsewhere path for negative expenses if ( canIOUBePaid(iouReport, chatReport, policy, undefined, undefined, undefined, undefined, invoiceReceiverPolicy) || canIOUBePaid(iouReport, chatReport, policy, undefined, undefined, true, undefined, invoiceReceiverPolicy) From 6a61b5696470e8f450e15517e19ed7688232f160 Mon Sep 17 00:00:00 2001 From: "Aimane Chnaif (via MelvinBot)" Date: Wed, 8 Apr 2026 14:31:01 +0000 Subject: [PATCH 5/5] Add unit test for REIMBURSEMENT_NO policy badge behavior MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Covers the scenario where a REIMBURSEMENT_NO policy with non-SUBMITTED status returns no PAY badge — both canIOUBePaid calls return false (first via the onlyShowPayElsewhere=false gate, second via the statusNum !== SUBMITTED check). Co-authored-by: Aimane Chnaif --- tests/actions/IOUTest.ts | 67 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 48e99f134249f..fb524f429b8fc 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -13852,6 +13852,73 @@ describe('actions/IOU', () => { expect(result.actionBadge).toBe(CONST.REPORT.ACTION_BADGE.PAY); }); + it('should return undefined actionBadge for REIMBURSEMENT_NO policy with non-SUBMITTED status', async () => { + const chatReportID = '600'; + const iouReportID = '601'; + const policyID = '602'; + + const fakePolicy: Policy = { + ...createRandomPolicy(Number(policyID)), + id: policyID, + type: CONST.POLICY.TYPE.TEAM, + approvalMode: CONST.POLICY.APPROVAL_MODE.BASIC, + role: CONST.POLICY.ROLE.ADMIN, + reimbursementChoice: CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_NO, + }; + + const fakeChatReport: Report = { + ...createRandomReport(Number(chatReportID), CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT), + reportID: chatReportID, + policyID, + }; + + // REIMBURSEMENT_NO + APPROVED (not SUBMITTED): + // First canIOUBePaid call (onlyShowPayElsewhere=false) returns false (early-exit for REIMBURSEMENT_NO) + // Second canIOUBePaid call (onlyShowPayElsewhere=true) also returns false (statusNum !== SUBMITTED) + // So no PAY badge is shown + const fakeIouReport: Report = { + ...createRandomReport(Number(iouReportID), CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT), + reportID: iouReportID, + type: CONST.REPORT.TYPE.EXPENSE, + policyID, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.APPROVED, + managerID: RORY_ACCOUNT_ID, + total: -5000, + nonReimbursableTotal: 0, + isWaitingOnBankAccount: false, + }; + + const fakeTransaction: Transaction = { + ...createRandomTransaction(0), + reportID: iouReportID, + amount: 100, + status: CONST.TRANSACTION.STATUS.POSTED, + bank: '', + }; + + await Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, fakePolicy); + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`, fakeChatReport); + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, fakeIouReport); + await Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${fakeTransaction.transactionID}`, fakeTransaction); + + const reportPreviewAction = { + reportActionID: iouReportID, + actionName: CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW, + created: '2024-08-08 19:00:00.000', + childReportID: iouReportID, + message: [{type: 'TEXT', text: 'Report preview'}], + }; + await Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`, { + [reportPreviewAction.reportActionID]: reportPreviewAction, + }); + await waitForBatchedUpdates(); + + const result = getIOUReportActionWithBadge(fakeChatReport, fakePolicy, {}, undefined); + expect(result.reportAction).toBeUndefined(); + expect(result.actionBadge).toBeUndefined(); + }); + it('should return undefined actionBadge when report is settled', async () => { const chatReportID = '400'; const iouReportID = '401';