From 9eb3e68aad0344aa2a070a2f9ab2fba80cdd6ee5 Mon Sep 17 00:00:00 2001
From: Yauheni Pasiukevich <pasyukevich@live.com>
Date: Fri, 8 Mar 2024 17:53:11 +0100
Subject: [PATCH 1/5] [TS migration] Migrate 'IOUTest.js' test to TypeScript

---
 src/libs/ReportUtils.ts           |    6 +-
 src/libs/actions/ReportActions.ts |    5 +-
 tests/actions/IOUTest.js          | 2978 ---------------------------
 tests/actions/IOUTest.ts          | 3196 +++++++++++++++++++++++++++++
 4 files changed, 3202 insertions(+), 2983 deletions(-)
 delete mode 100644 tests/actions/IOUTest.js
 create mode 100644 tests/actions/IOUTest.ts

diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index 6c5b19704af4..15074227d0d1 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -3927,13 +3927,13 @@ function buildOptimisticTaskReport(
  * @param reportAction - the parent IOU report action from which to create the thread
  * @param moneyRequestReport - the report which the report action belongs to
  */
-function buildTransactionThread(reportAction: OnyxEntry<ReportAction | OptimisticIOUReportAction>, moneyRequestReport: Report): OptimisticChatReport {
+function buildTransactionThread(reportAction: OnyxEntry<ReportAction | OptimisticIOUReportAction>, moneyRequestReport: OnyxEntry<Report>): OptimisticChatReport {
     const participantAccountIDs = [...new Set([currentUserAccountID, Number(reportAction?.actorAccountID)])].filter(Boolean) as number[];
     return buildOptimisticChatReport(
         participantAccountIDs,
         getTransactionReportName(reportAction),
         undefined,
-        moneyRequestReport.policyID,
+        moneyRequestReport?.policyID,
         CONST.POLICY.OWNER_ACCOUNT_ID_FAKE,
         false,
         '',
@@ -3941,7 +3941,7 @@ function buildTransactionThread(reportAction: OnyxEntry<ReportAction | Optimisti
         undefined,
         CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
         reportAction?.reportActionID,
-        moneyRequestReport.reportID,
+        moneyRequestReport?.reportID,
     );
 }
 
diff --git a/src/libs/actions/ReportActions.ts b/src/libs/actions/ReportActions.ts
index aad6ae39810a..72d1fe9fe63d 100644
--- a/src/libs/actions/ReportActions.ts
+++ b/src/libs/actions/ReportActions.ts
@@ -1,4 +1,5 @@
 import Onyx from 'react-native-onyx';
+import type {OnyxEntry} from 'react-native-onyx';
 import * as ReportActionUtils from '@libs/ReportActionsUtils';
 import * as ReportUtils from '@libs/ReportUtils';
 import CONST from '@src/CONST';
@@ -6,10 +7,10 @@ import ONYXKEYS from '@src/ONYXKEYS';
 import type ReportAction from '@src/types/onyx/ReportAction';
 import * as Report from './Report';
 
-function clearReportActionErrors(reportID: string, reportAction: ReportAction) {
+function clearReportActionErrors(reportID: string, reportAction: OnyxEntry<ReportAction>) {
     const originalReportID = ReportUtils.getOriginalReportID(reportID, reportAction);
 
-    if (!reportAction.reportActionID) {
+    if (!reportAction?.reportActionID) {
         return;
     }
 
diff --git a/tests/actions/IOUTest.js b/tests/actions/IOUTest.js
deleted file mode 100644
index 64c8edb134b1..000000000000
--- a/tests/actions/IOUTest.js
+++ /dev/null
@@ -1,2978 +0,0 @@
-import Onyx from 'react-native-onyx';
-import _ from 'underscore';
-import CONST from '../../src/CONST';
-import * as IOU from '../../src/libs/actions/IOU';
-import OnyxUpdateManager from '../../src/libs/actions/OnyxUpdateManager';
-import * as PolicyActions from '../../src/libs/actions/Policy';
-import * as Report from '../../src/libs/actions/Report';
-import * as ReportActions from '../../src/libs/actions/ReportActions';
-import * as User from '../../src/libs/actions/User';
-import DateUtils from '../../src/libs/DateUtils';
-import Navigation from '../../src/libs/Navigation/Navigation';
-import * as NumberUtils from '../../src/libs/NumberUtils';
-import * as PersonalDetailsUtils from '../../src/libs/PersonalDetailsUtils';
-import * as ReportActionsUtils from '../../src/libs/ReportActionsUtils';
-import * as ReportUtils from '../../src/libs/ReportUtils';
-import ONYXKEYS from '../../src/ONYXKEYS';
-import ROUTES from '../../src/ROUTES';
-import PusherHelper from '../utils/PusherHelper';
-import * as TestHelper from '../utils/TestHelper';
-import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
-import waitForNetworkPromises from '../utils/waitForNetworkPromises';
-
-jest.mock('../../src/libs/Navigation/Navigation', () => ({
-    navigate: jest.fn(),
-    dismissModal: jest.fn(),
-    dismissModalWithReport: jest.fn(),
-    goBack: jest.fn(),
-}));
-
-const CARLOS_EMAIL = 'cmartins@expensifail.com';
-const CARLOS_ACCOUNT_ID = 1;
-const JULES_EMAIL = 'jules@expensifail.com';
-const JULES_ACCOUNT_ID = 2;
-const RORY_EMAIL = 'rory@expensifail.com';
-const RORY_ACCOUNT_ID = 3;
-const VIT_EMAIL = 'vit@expensifail.com';
-const VIT_ACCOUNT_ID = 4;
-
-OnyxUpdateManager();
-describe('actions/IOU', () => {
-    beforeAll(() => {
-        Onyx.init({
-            keys: ONYXKEYS,
-        });
-    });
-
-    beforeEach(() => {
-        global.fetch = TestHelper.getGlobalFetchMock();
-        return Onyx.clear().then(waitForBatchedUpdates);
-    });
-
-    describe('requestMoney', () => {
-        it('creates new chat if needed', () => {
-            const amount = 10000;
-            const comment = 'Giv money plz';
-            const merchant = 'KFC';
-            let iouReportID;
-            let createdAction;
-            let iouAction;
-            let transactionID;
-            let transactionThread;
-            let transactionThreadCreatedAction;
-            fetch.pause();
-            IOU.requestMoney({}, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment);
-            return waitForBatchedUpdates()
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    // A chat report, a transaction thread, and an iou report should be created
-                                    const chatReports = _.filter(allReports, (report) => report.type === CONST.REPORT.TYPE.CHAT);
-                                    const iouReports = _.filter(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-                                    expect(_.size(chatReports)).toBe(2);
-                                    expect(_.size(iouReports)).toBe(1);
-                                    const chatReport = chatReports[0];
-                                    const transactionThreadReport = chatReports[1];
-                                    const iouReport = iouReports[0];
-                                    iouReportID = iouReport.reportID;
-                                    transactionThread = transactionThreadReport;
-
-                                    expect(iouReport.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
-
-                                    // They should be linked together
-                                    expect(chatReport.participantAccountIDs).toEqual([CARLOS_ACCOUNT_ID]);
-                                    expect(chatReport.iouReportID).toBe(iouReport.reportID);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (reportActionsForIOUReport) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    // The IOU report should have a CREATED action and IOU action
-                                    expect(_.size(reportActionsForIOUReport)).toBe(2);
-                                    const createdActions = _.filter(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED);
-                                    const iouActions = _.filter(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                                    expect(_.size(createdActions)).toBe(1);
-                                    expect(_.size(iouActions)).toBe(1);
-                                    createdAction = createdActions[0];
-                                    iouAction = iouActions[0];
-
-                                    // The CREATED action should not be created after the IOU action
-                                    expect(Date.parse(createdAction.created)).toBeLessThan(Date.parse(iouAction.created));
-
-                                    // The IOUReportID should be correct
-                                    expect(iouAction.originalMessage.IOUReportID).toBe(iouReportID);
-
-                                    // The comment should be included in the IOU action
-                                    expect(iouAction.originalMessage.comment).toBe(comment);
-
-                                    // The amount in the IOU action should be correct
-                                    expect(iouAction.originalMessage.amount).toBe(amount);
-
-                                    // The IOU type should be correct
-                                    expect(iouAction.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
-
-                                    // Both actions should be pending
-                                    expect(createdAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                    expect(iouAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThread.reportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (reportActionsForTransactionThread) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    // The transaction thread should have a CREATED action
-                                    expect(_.size(reportActionsForTransactionThread)).toBe(1);
-                                    const createdActions = _.filter(reportActionsForTransactionThread, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED);
-                                    expect(_.size(createdActions)).toBe(1);
-                                    transactionThreadCreatedAction = createdActions[0];
-
-                                    expect(transactionThreadCreatedAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                waitForCollectionCallback: true,
-                                callback: (allTransactions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    // There should be one transaction
-                                    expect(_.size(allTransactions)).toBe(1);
-                                    const transaction = _.find(allTransactions, (t) => !_.isEmpty(t));
-                                    transactionID = transaction.transactionID;
-
-                                    // The transaction should be attached to the IOU report
-                                    expect(transaction.reportID).toBe(iouReportID);
-
-                                    // Its amount should match the amount of the request
-                                    expect(transaction.amount).toBe(amount);
-
-                                    // The comment should be correct
-                                    expect(transaction.comment.comment).toBe(comment);
-
-                                    // It should be pending
-                                    expect(transaction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-
-                                    // The transactionID on the iou action should match the one from the transactions collection
-                                    expect(iouAction.originalMessage.IOUTransactionID).toBe(transactionID);
-
-                                    expect(transaction.merchant).toBe(merchant);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(fetch.resume)
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (reportActionsForIOUReport) => {
-                                    Onyx.disconnect(connectionID);
-                                    expect(_.size(reportActionsForIOUReport)).toBe(2);
-                                    _.each(reportActionsForIOUReport, (reportAction) => expect(reportAction.pendingAction).toBeFalsy());
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
-                                waitForCollectionCallback: true,
-                                callback: (transaction) => {
-                                    Onyx.disconnect(connectionID);
-                                    expect(transaction.pendingAction).toBeFalsy();
-                                    resolve();
-                                },
-                            });
-                        }),
-                );
-        });
-
-        it('updates existing chat report if there is one', () => {
-            const amount = 10000;
-            const comment = 'Giv money plz';
-            let chatReport = {
-                reportID: 1234,
-                type: CONST.REPORT.TYPE.CHAT,
-                participantAccountIDs: [CARLOS_ACCOUNT_ID],
-            };
-            const createdAction = {
-                reportActionID: NumberUtils.rand64(),
-                actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
-                created: DateUtils.getDBTime(),
-            };
-            let iouReportID;
-            let iouAction;
-            let iouCreatedAction;
-            let transactionID;
-            fetch.pause();
-            return Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, chatReport)
-                .then(() =>
-                    Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, {
-                        [createdAction.reportActionID]: createdAction,
-                    }),
-                )
-                .then(() => {
-                    IOU.requestMoney(chatReport, amount, CONST.CURRENCY.USD, '', '', RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment);
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    // The same chat report should be reused, a transaction thread and an IOU report should be created
-                                    expect(_.size(allReports)).toBe(3);
-                                    expect(_.find(allReports, (report) => report.type === CONST.REPORT.TYPE.CHAT).reportID).toBe(chatReport.reportID);
-                                    chatReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.CHAT);
-                                    const iouReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-                                    iouReportID = iouReport.reportID;
-
-                                    expect(iouReport.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
-
-                                    // They should be linked together
-                                    expect(chatReport.iouReportID).toBe(iouReportID);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (allIOUReportActions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    // The chat report should have a CREATED and an IOU action
-                                    expect(_.size(allIOUReportActions)).toBe(2);
-                                    iouCreatedAction = _.find(allIOUReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED);
-                                    iouAction = _.find(allIOUReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-
-                                    // The CREATED action should not be created after the IOU action
-                                    expect(Date.parse(iouCreatedAction.created)).toBeLessThan(Date.parse(iouAction.created));
-
-                                    // The IOUReportID should be correct
-                                    expect(iouAction.originalMessage.IOUReportID).toBe(iouReportID);
-
-                                    // The comment should be included in the IOU action
-                                    expect(iouAction.originalMessage.comment).toBe(comment);
-
-                                    // The amount in the IOU action should be correct
-                                    expect(iouAction.originalMessage.amount).toBe(amount);
-
-                                    // The IOU action type should be correct
-                                    expect(iouAction.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
-
-                                    // The IOU action should be pending
-                                    expect(iouAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                waitForCollectionCallback: true,
-                                callback: (allTransactions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    // There should be one transaction
-                                    expect(_.size(allTransactions)).toBe(1);
-                                    const transaction = _.find(allTransactions, (t) => !_.isEmpty(t));
-                                    transactionID = transaction.transactionID;
-
-                                    // The transaction should be attached to the IOU report
-                                    expect(transaction.reportID).toBe(iouReportID);
-
-                                    // Its amount should match the amount of the request
-                                    expect(transaction.amount).toBe(amount);
-
-                                    // The comment should be correct
-                                    expect(transaction.comment.comment).toBe(comment);
-
-                                    expect(transaction.merchant).toBe(CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT);
-
-                                    // It should be pending
-                                    expect(transaction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-
-                                    // The transactionID on the iou action should match the one from the transactions collection
-                                    expect(iouAction.originalMessage.IOUTransactionID).toBe(transactionID);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(fetch.resume)
-                .then(waitForBatchedUpdates)
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (reportActionsForIOUReport) => {
-                                    Onyx.disconnect(connectionID);
-                                    expect(_.size(reportActionsForIOUReport)).toBe(2);
-                                    _.each(reportActionsForIOUReport, (reportAction) => expect(reportAction.pendingAction).toBeFalsy());
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
-                                waitForCollectionCallback: true,
-                                callback: (transaction) => {
-                                    Onyx.disconnect(connectionID);
-                                    expect(transaction.pendingAction).toBeFalsy();
-                                    resolve();
-                                },
-                            });
-                        }),
-                );
-        });
-
-        it('updates existing IOU report if there is one', () => {
-            const amount = 10000;
-            const comment = 'Giv money plz';
-            const chatReportID = 1234;
-            const iouReportID = 5678;
-            let chatReport = {
-                reportID: chatReportID,
-                type: CONST.REPORT.TYPE.CHAT,
-                iouReportID,
-                participantAccountIDs: [CARLOS_ACCOUNT_ID],
-            };
-            const createdAction = {
-                reportActionID: NumberUtils.rand64(),
-                actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
-                created: DateUtils.getDBTime(),
-            };
-            const existingTransaction = {
-                transactionID: NumberUtils.rand64(),
-                amount: 1000,
-                comment: '',
-                created: DateUtils.getDBTime(),
-            };
-            let iouReport = {
-                reportID: iouReportID,
-                chatReportID,
-                type: CONST.REPORT.TYPE.IOU,
-                ownerAccountID: RORY_ACCOUNT_ID,
-                managerID: CARLOS_ACCOUNT_ID,
-                currency: CONST.CURRENCY.USD,
-                total: existingTransaction.amount,
-            };
-            const iouAction = {
-                reportActionID: NumberUtils.rand64(),
-                actionName: CONST.REPORT.ACTIONS.TYPE.IOU,
-                actorAccountID: RORY_ACCOUNT_ID,
-                created: DateUtils.getDBTime(),
-                originalMessage: {
-                    IOUReportID: iouReportID,
-                    IOUTransactionID: existingTransaction.transactionID,
-                    amount: existingTransaction.amount,
-                    currency: CONST.CURRENCY.USD,
-                    type: CONST.IOU.REPORT_ACTION_TYPE.CREATE,
-                    participantAccountIDs: [RORY_ACCOUNT_ID, CARLOS_ACCOUNT_ID],
-                },
-            };
-            let newIOUAction;
-            let newTransaction;
-            fetch.pause();
-            return Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`, chatReport)
-                .then(() => Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, iouReport))
-                .then(() =>
-                    Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, {
-                        [createdAction.reportActionID]: createdAction,
-                        [iouAction.reportActionID]: iouAction,
-                    }),
-                )
-                .then(() => Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${existingTransaction.transactionID}`, existingTransaction))
-                .then(() => {
-                    IOU.requestMoney(chatReport, amount, CONST.CURRENCY.USD, '', '', RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment);
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    // No new reports should be created
-                                    expect(_.size(allReports)).toBe(3);
-                                    expect(_.find(allReports, (report) => report.reportID === chatReportID)).toBeTruthy();
-                                    expect(_.find(allReports, (report) => report.reportID === iouReportID)).toBeTruthy();
-
-                                    chatReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.CHAT);
-                                    iouReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-
-                                    // The total on the iou report should be updated
-                                    expect(iouReport.total).toBe(11000);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (reportActionsForIOUReport) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    expect(_.size(reportActionsForIOUReport)).toBe(3);
-                                    newIOUAction = _.find(
-                                        reportActionsForIOUReport,
-                                        (reportAction) => reportAction.reportActionID !== createdAction.reportActionID && reportAction.reportActionID !== iouAction.reportActionID,
-                                    );
-
-                                    // The IOUReportID should be correct
-                                    expect(iouAction.originalMessage.IOUReportID).toBe(iouReportID);
-
-                                    // The comment should be included in the IOU action
-                                    expect(newIOUAction.originalMessage.comment).toBe(comment);
-
-                                    // The amount in the IOU action should be correct
-                                    expect(newIOUAction.originalMessage.amount).toBe(amount);
-
-                                    // The type of the IOU action should be correct
-                                    expect(newIOUAction.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
-
-                                    // The IOU action should be pending
-                                    expect(newIOUAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                waitForCollectionCallback: true,
-                                callback: (allTransactions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    // There should be two transactions
-                                    expect(_.size(allTransactions)).toBe(2);
-
-                                    newTransaction = _.find(allTransactions, (transaction) => transaction.transactionID !== existingTransaction.transactionID);
-
-                                    expect(newTransaction.reportID).toBe(iouReportID);
-                                    expect(newTransaction.amount).toBe(amount);
-                                    expect(newTransaction.comment.comment).toBe(comment);
-                                    expect(newTransaction.merchant).toBe(CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT);
-                                    expect(newTransaction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-
-                                    // The transactionID on the iou action should match the one from the transactions collection
-                                    expect(newIOUAction.originalMessage.IOUTransactionID).toBe(newTransaction.transactionID);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(fetch.resume)
-                .then(waitForNetworkPromises)
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (reportActionsForIOUReport) => {
-                                    Onyx.disconnect(connectionID);
-                                    expect(_.size(reportActionsForIOUReport)).toBe(3);
-                                    _.each(reportActionsForIOUReport, (reportAction) => expect(reportAction.pendingAction).toBeFalsy());
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                waitForCollectionCallback: true,
-                                callback: (allTransactions) => {
-                                    Onyx.disconnect(connectionID);
-                                    _.each(allTransactions, (transaction) => expect(transaction.pendingAction).toBeFalsy());
-                                    resolve();
-                                },
-                            });
-                        }),
-                );
-        });
-
-        it('correctly implements RedBrickRoad error handling', () => {
-            const amount = 10000;
-            const comment = 'Giv money plz';
-            let chatReportID;
-            let iouReportID;
-            let createdAction;
-            let iouAction;
-            let transactionID;
-            let transactionThreadReport;
-            let transactionThreadAction;
-            fetch.pause();
-            IOU.requestMoney({}, amount, CONST.CURRENCY.USD, '', '', RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment);
-            return (
-                waitForBatchedUpdates()
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                const connectionID = Onyx.connect({
-                                    key: ONYXKEYS.COLLECTION.REPORT,
-                                    waitForCollectionCallback: true,
-                                    callback: (allReports) => {
-                                        Onyx.disconnect(connectionID);
-
-                                        // A chat report, transaction thread and an iou report should be created
-                                        const chatReports = _.filter(allReports, (report) => report.type === CONST.REPORT.TYPE.CHAT);
-                                        const iouReports = _.filter(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-                                        expect(_.size(chatReports)).toBe(2);
-                                        expect(_.size(iouReports)).toBe(1);
-                                        const chatReport = chatReports[0];
-                                        chatReportID = chatReport.reportID;
-                                        transactionThreadReport = chatReports[1];
-
-                                        const iouReport = iouReports[0];
-                                        iouReportID = iouReport.reportID;
-
-                                        expect(iouReport.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
-
-                                        // They should be linked together
-                                        expect(chatReport.participantAccountIDs).toEqual([CARLOS_ACCOUNT_ID]);
-                                        expect(chatReport.iouReportID).toBe(iouReport.reportID);
-
-                                        resolve();
-                                    },
-                                });
-                            }),
-                    )
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                const connectionID = Onyx.connect({
-                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
-                                    waitForCollectionCallback: true,
-                                    callback: (reportActionsForIOUReport) => {
-                                        Onyx.disconnect(connectionID);
-
-                                        // The chat report should have a CREATED action and IOU action
-                                        expect(_.size(reportActionsForIOUReport)).toBe(2);
-                                        const createdActions = _.filter(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED);
-                                        const iouActions = _.filter(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                                        expect(_.size(createdActions)).toBe(1);
-                                        expect(_.size(iouActions)).toBe(1);
-                                        createdAction = createdActions[0];
-                                        iouAction = iouActions[0];
-
-                                        // The CREATED action should not be created after the IOU action
-                                        expect(Date.parse(createdAction.created)).toBeLessThan(Date.parse(iouAction.created));
-
-                                        // The IOUReportID should be correct
-                                        expect(iouAction.originalMessage.IOUReportID).toBe(iouReportID);
-
-                                        // The comment should be included in the IOU action
-                                        expect(iouAction.originalMessage.comment).toBe(comment);
-
-                                        // The amount in the IOU action should be correct
-                                        expect(iouAction.originalMessage.amount).toBe(amount);
-
-                                        // The type should be correct
-                                        expect(iouAction.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
-
-                                        // Both actions should be pending
-                                        expect(createdAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                        expect(iouAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-
-                                        resolve();
-                                    },
-                                });
-                            }),
-                    )
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                const connectionID = Onyx.connect({
-                                    key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                    waitForCollectionCallback: true,
-                                    callback: (allTransactions) => {
-                                        Onyx.disconnect(connectionID);
-
-                                        // There should be one transaction
-                                        expect(_.size(allTransactions)).toBe(1);
-                                        const transaction = _.find(allTransactions, (t) => !_.isEmpty(t));
-                                        transactionID = transaction.transactionID;
-
-                                        expect(transaction.reportID).toBe(iouReportID);
-                                        expect(transaction.amount).toBe(amount);
-                                        expect(transaction.comment.comment).toBe(comment);
-                                        expect(transaction.merchant).toBe(CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT);
-                                        expect(transaction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-
-                                        // The transactionID on the iou action should match the one from the transactions collection
-                                        expect(iouAction.originalMessage.IOUTransactionID).toBe(transactionID);
-
-                                        resolve();
-                                    },
-                                });
-                            }),
-                    )
-                    .then(() => {
-                        fetch.fail();
-                        return fetch.resume();
-                    })
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                const connectionID = Onyx.connect({
-                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
-                                    waitForCollectionCallback: true,
-                                    callback: (reportActionsForIOUReport) => {
-                                        Onyx.disconnect(connectionID);
-                                        expect(_.size(reportActionsForIOUReport)).toBe(2);
-                                        iouAction = _.find(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                                        expect(iouAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                        resolve();
-                                    },
-                                });
-                            }),
-                    )
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                const connectionID = Onyx.connect({
-                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}`,
-                                    waitForCollectionCallback: true,
-                                    callback: (reportActionsForTransactionThread) => {
-                                        Onyx.disconnect(connectionID);
-                                        expect(_.size(reportActionsForTransactionThread)).toBe(3);
-                                        transactionThreadAction = _.find(
-                                            reportActionsForTransactionThread[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`],
-                                            (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED,
-                                        );
-                                        expect(transactionThreadAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                        resolve();
-                                    },
-                                });
-                            }),
-                    )
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                const connectionID = Onyx.connect({
-                                    key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
-                                    waitForCollectionCallback: true,
-                                    callback: (transaction) => {
-                                        Onyx.disconnect(connectionID);
-                                        expect(transaction.pendingAction).toBeFalsy();
-                                        expect(transaction.errors).toBeTruthy();
-                                        expect(_.values(transaction.errors)[0]).toEqual(expect.arrayContaining(['iou.error.genericCreateFailureMessage', {isTranslated: false}]));
-                                        resolve();
-                                    },
-                                });
-                            }),
-                    )
-
-                    // If the user clears the errors on the IOU action
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                ReportActions.clearReportActionErrors(iouReportID, iouAction);
-                                ReportActions.clearReportActionErrors(transactionThreadReport.reportID, transactionThreadAction);
-                                resolve();
-                            }),
-                    )
-
-                    // Then the reportAction should be removed from Onyx
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                const connectionID = Onyx.connect({
-                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`,
-                                    waitForCollectionCallback: true,
-                                    callback: (reportActionsForReport) => {
-                                        Onyx.disconnect(connectionID);
-                                        iouAction = _.find(reportActionsForReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                                        expect(iouAction).toBeFalsy();
-                                        resolve();
-                                    },
-                                });
-                            }),
-                    )
-
-                    // Along with the associated transaction
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                const connectionID = Onyx.connect({
-                                    key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
-                                    waitForCollectionCallback: true,
-                                    callback: (transaction) => {
-                                        Onyx.disconnect(connectionID);
-                                        expect(transaction).toBeFalsy();
-                                        resolve();
-                                    },
-                                });
-                            }),
-                    )
-
-                    // If a user clears the errors on the CREATED action (which, technically are just errors on the report)
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                Report.deleteReport(chatReportID);
-                                Report.deleteReport(transactionThreadReport.reportID);
-                                resolve();
-                            }),
-                    )
-
-                    // Then the report should be deleted
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                const connectionID = Onyx.connect({
-                                    key: ONYXKEYS.COLLECTION.REPORT,
-                                    waitForCollectionCallback: true,
-                                    callback: (allReports) => {
-                                        Onyx.disconnect(connectionID);
-                                        _.each(allReports, (report) => expect(report).toBeFalsy());
-                                        resolve();
-                                    },
-                                });
-                            }),
-                    )
-
-                    // All reportActions should also be deleted
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                const connectionID = Onyx.connect({
-                                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
-                                    waitForCollectionCallback: true,
-                                    callback: (allReportActions) => {
-                                        Onyx.disconnect(connectionID);
-                                        _.each(allReportActions, (reportAction) => expect(reportAction).toBeFalsy());
-                                        resolve();
-                                    },
-                                });
-                            }),
-                    )
-
-                    // All transactions should also be deleted
-                    .then(
-                        () =>
-                            new Promise((resolve) => {
-                                const connectionID = Onyx.connect({
-                                    key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                    waitForCollectionCallback: true,
-                                    callback: (allTransactions) => {
-                                        Onyx.disconnect(connectionID);
-                                        _.each(allTransactions, (transaction) => expect(transaction).toBeFalsy());
-                                        resolve();
-                                    },
-                                });
-                            }),
-                    )
-
-                    // Cleanup
-                    .then(fetch.succeed)
-            );
-        });
-    });
-
-    describe('split bill', () => {
-        it('creates and updates new chats and IOUs as needed', () => {
-            jest.setTimeout(10 * 1000);
-            /*
-             * Given that:
-             *   - Rory and Carlos have chatted before
-             *   - Rory and Jules have chatted before and have an active IOU report
-             *   - Rory and Vit have never chatted together before
-             *   - There is no existing group chat with the four of them
-             */
-            const amount = 400;
-            const comment = 'Yes, I am splitting a bill for $4 USD';
-            const merchant = 'Yema Kitchen';
-            let carlosChatReport = {
-                reportID: NumberUtils.rand64(),
-                type: CONST.REPORT.TYPE.CHAT,
-                participantAccountIDs: [CARLOS_ACCOUNT_ID],
-            };
-            const carlosCreatedAction = {
-                reportActionID: NumberUtils.rand64(),
-                actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
-                created: DateUtils.getDBTime(),
-            };
-            const julesIOUReportID = NumberUtils.rand64();
-            let julesChatReport = {
-                reportID: NumberUtils.rand64(),
-                type: CONST.REPORT.TYPE.CHAT,
-                iouReportID: julesIOUReportID,
-                participantAccountIDs: [JULES_ACCOUNT_ID],
-            };
-            const julesChatCreatedAction = {
-                reportActionID: NumberUtils.rand64(),
-                actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
-                created: DateUtils.getDBTime(),
-            };
-            const julesCreatedAction = {
-                reportActionID: NumberUtils.rand64(),
-                actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
-                created: DateUtils.getDBTime(),
-            };
-            jest.advanceTimersByTime(200);
-            const julesExistingTransaction = {
-                transactionID: NumberUtils.rand64(),
-                amount: 1000,
-                comment: 'This is an existing transaction',
-                created: DateUtils.getDBTime(),
-            };
-            let julesIOUReport = {
-                reportID: julesIOUReportID,
-                chatReportID: julesChatReport.reportID,
-                type: CONST.REPORT.TYPE.IOU,
-                ownerAccountID: RORY_ACCOUNT_ID,
-                managerID: JULES_ACCOUNT_ID,
-                currency: CONST.CURRENCY.USD,
-                total: julesExistingTransaction.amount,
-            };
-            const julesExistingIOUAction = {
-                reportActionID: NumberUtils.rand64(),
-                actionName: CONST.REPORT.ACTIONS.TYPE.IOU,
-                actorAccountID: RORY_ACCOUNT_ID,
-                created: DateUtils.getDBTime(),
-                originalMessage: {
-                    IOUReportID: julesIOUReportID,
-                    IOUTransactionID: julesExistingTransaction.transactionID,
-                    amount: julesExistingTransaction.amount,
-                    currency: CONST.CURRENCY.USD,
-                    type: CONST.IOU.REPORT_ACTION_TYPE.CREATE,
-                    participantAccountIDs: [RORY_ACCOUNT_ID, JULES_ACCOUNT_ID],
-                },
-            };
-
-            let carlosIOUReport;
-            let carlosIOUAction;
-            let carlosIOUCreatedAction;
-            let carlosTransaction;
-
-            let julesIOUAction;
-            let julesIOUCreatedAction;
-            let julesTransaction;
-
-            let vitChatReport;
-            let vitIOUReport;
-            let vitCreatedAction;
-            let vitIOUAction;
-            let vitTransaction;
-
-            let groupChat;
-            let groupCreatedAction;
-            let groupIOUAction;
-            let groupTransaction;
-
-            return Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, {
-                [`${ONYXKEYS.COLLECTION.REPORT}${carlosChatReport.reportID}`]: carlosChatReport,
-                [`${ONYXKEYS.COLLECTION.REPORT}${julesChatReport.reportID}`]: julesChatReport,
-                [`${ONYXKEYS.COLLECTION.REPORT}${julesIOUReport.reportID}`]: julesIOUReport,
-            })
-                .then(() =>
-                    Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT_ACTIONS, {
-                        [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${carlosChatReport.reportID}`]: {
-                            [carlosCreatedAction.reportActionID]: carlosCreatedAction,
-                        },
-                        [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${julesChatReport.reportID}`]: {
-                            [julesChatCreatedAction.reportActionID]: julesChatCreatedAction,
-                        },
-                        [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${julesIOUReport.reportID}`]: {
-                            [julesCreatedAction.reportActionID]: julesCreatedAction,
-                            [julesExistingIOUAction.reportActionID]: julesExistingIOUAction,
-                        },
-                    }),
-                )
-                .then(() => Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${julesExistingTransaction.transactionID}`, julesExistingTransaction))
-                .then(() => {
-                    // When we split a bill offline
-                    fetch.pause();
-                    IOU.splitBill(
-                        // TODO: Migrate after the backend accepts accountIDs
-                        _.map(
-                            [
-                                [CARLOS_EMAIL, CARLOS_ACCOUNT_ID],
-                                [JULES_EMAIL, JULES_ACCOUNT_ID],
-                                [VIT_EMAIL, VIT_ACCOUNT_ID],
-                            ],
-                            ([email, accountID]) => ({login: email, accountID}),
-                        ),
-                        RORY_EMAIL,
-                        RORY_ACCOUNT_ID,
-                        amount,
-                        comment,
-                        CONST.CURRENCY.USD,
-                        merchant,
-                    );
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    // There should now be 10 reports
-                                    expect(_.size(allReports)).toBe(10);
-
-                                    // 1. The chat report with Rory + Carlos
-                                    carlosChatReport = _.find(allReports, (report) => report.reportID === carlosChatReport.reportID);
-                                    expect(_.isEmpty(carlosChatReport)).toBe(false);
-                                    expect(carlosChatReport.pendingFields).toBeFalsy();
-
-                                    // 2. The IOU report with Rory + Carlos (new)
-                                    carlosIOUReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU && report.managerID === CARLOS_ACCOUNT_ID);
-                                    expect(_.isEmpty(carlosIOUReport)).toBe(false);
-                                    expect(carlosIOUReport.total).toBe(amount / 4);
-
-                                    // 3. The chat report with Rory + Jules
-                                    julesChatReport = _.find(allReports, (report) => report.reportID === julesChatReport.reportID);
-                                    expect(_.isEmpty(julesChatReport)).toBe(false);
-                                    expect(julesChatReport.pendingFields).toBeFalsy();
-
-                                    // 4. The IOU report with Rory + Jules
-                                    julesIOUReport = _.find(allReports, (report) => report.reportID === julesIOUReport.reportID);
-                                    expect(_.isEmpty(julesIOUReport)).toBe(false);
-                                    expect(julesChatReport.pendingFields).toBeFalsy();
-                                    expect(julesIOUReport.total).toBe(julesExistingTransaction.amount + amount / 4);
-
-                                    // 5. The chat report with Rory + Vit (new)
-                                    vitChatReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.CHAT && _.isEqual(report.participantAccountIDs, [VIT_ACCOUNT_ID]));
-                                    expect(_.isEmpty(vitChatReport)).toBe(false);
-                                    expect(vitChatReport.pendingFields).toStrictEqual({createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD});
-
-                                    // 6. The IOU report with Rory + Vit (new)
-                                    vitIOUReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU && report.managerID === VIT_ACCOUNT_ID);
-                                    expect(_.isEmpty(vitIOUReport)).toBe(false);
-                                    expect(vitIOUReport.total).toBe(amount / 4);
-
-                                    // 7. The group chat with everyone
-                                    groupChat = _.find(
-                                        allReports,
-                                        (report) => report.type === CONST.REPORT.TYPE.CHAT && _.isEqual(report.participantAccountIDs, [CARLOS_ACCOUNT_ID, JULES_ACCOUNT_ID, VIT_ACCOUNT_ID]),
-                                    );
-                                    expect(_.isEmpty(groupChat)).toBe(false);
-                                    expect(groupChat.pendingFields).toStrictEqual({createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD});
-
-                                    // The 1:1 chat reports and the IOU reports should be linked together
-                                    expect(carlosChatReport.iouReportID).toBe(carlosIOUReport.reportID);
-                                    expect(carlosIOUReport.chatReportID).toBe(carlosChatReport.reportID);
-                                    expect(carlosIOUReport.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
-
-                                    expect(julesChatReport.iouReportID).toBe(julesIOUReport.reportID);
-                                    expect(julesIOUReport.chatReportID).toBe(julesChatReport.reportID);
-
-                                    expect(vitChatReport.iouReportID).toBe(vitIOUReport.reportID);
-                                    expect(vitIOUReport.chatReportID).toBe(vitChatReport.reportID);
-                                    expect(carlosIOUReport.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
-                                waitForCollectionCallback: true,
-                                callback: (allReportActions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    // There should be reportActions on all 7 chat reports + 3 IOU reports in each 1:1 chat
-                                    expect(_.size(allReportActions)).toBe(10);
-
-                                    const carlosReportActions = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${carlosChatReport.iouReportID}`];
-                                    const julesReportActions = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${julesChatReport.iouReportID}`];
-                                    const vitReportActions = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${vitChatReport.iouReportID}`];
-                                    const groupReportActions = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChat.reportID}`];
-
-                                    // Carlos DM should have two reportActions – the existing CREATED action and a pending IOU action
-                                    expect(_.size(carlosReportActions)).toBe(2);
-                                    carlosIOUCreatedAction = _.find(carlosReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED);
-                                    carlosIOUAction = _.find(carlosReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                                    expect(carlosIOUAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                    expect(carlosIOUAction.originalMessage.IOUReportID).toBe(carlosIOUReport.reportID);
-                                    expect(carlosIOUAction.originalMessage.amount).toBe(amount / 4);
-                                    expect(carlosIOUAction.originalMessage.comment).toBe(comment);
-                                    expect(carlosIOUAction.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
-                                    expect(Date.parse(carlosIOUCreatedAction.created)).toBeLessThan(Date.parse(carlosIOUAction.created));
-
-                                    // Jules DM should have three reportActions, the existing CREATED action, the existing IOU action, and a new pending IOU action
-                                    expect(_.size(julesReportActions)).toBe(3);
-                                    expect(julesReportActions[julesCreatedAction.reportActionID]).toStrictEqual(julesCreatedAction);
-                                    julesIOUCreatedAction = _.find(julesReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED);
-                                    julesIOUAction = _.find(
-                                        julesReportActions,
-                                        (reportAction) =>
-                                            reportAction.reportActionID !== julesCreatedAction.reportActionID && reportAction.reportActionID !== julesExistingIOUAction.reportActionID,
-                                    );
-                                    expect(julesIOUAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                    expect(julesIOUAction.originalMessage.IOUReportID).toBe(julesIOUReport.reportID);
-                                    expect(julesIOUAction.originalMessage.amount).toBe(amount / 4);
-                                    expect(julesIOUAction.originalMessage.comment).toBe(comment);
-                                    expect(julesIOUAction.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
-                                    expect(Date.parse(julesIOUCreatedAction.created)).toBeLessThan(Date.parse(julesIOUAction.created));
-
-                                    // Vit DM should have two reportActions – a pending CREATED action and a pending IOU action
-                                    expect(_.size(vitReportActions)).toBe(2);
-                                    vitCreatedAction = _.find(vitReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED);
-                                    vitIOUAction = _.find(vitReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                                    expect(vitCreatedAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                    expect(vitIOUAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                    expect(vitIOUAction.originalMessage.IOUReportID).toBe(vitIOUReport.reportID);
-                                    expect(vitIOUAction.originalMessage.amount).toBe(amount / 4);
-                                    expect(vitIOUAction.originalMessage.comment).toBe(comment);
-                                    expect(vitIOUAction.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
-                                    expect(Date.parse(vitCreatedAction.created)).toBeLessThan(Date.parse(vitIOUAction.created));
-
-                                    // Group chat should have two reportActions – a pending CREATED action and a pending IOU action w/ type SPLIT
-                                    expect(_.size(groupReportActions)).toBe(2);
-                                    groupCreatedAction = _.find(groupReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED);
-                                    groupIOUAction = _.find(groupReportActions, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                                    expect(groupCreatedAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                    expect(groupIOUAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                    expect(groupIOUAction.originalMessage).not.toHaveProperty('IOUReportID');
-                                    expect(groupIOUAction.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.SPLIT);
-                                    expect(Date.parse(groupCreatedAction.created)).toBeLessThanOrEqual(Date.parse(groupIOUAction.created));
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                waitForCollectionCallback: true,
-                                callback: (allTransactions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    /* There should be 5 transactions
-                                     *   – one existing one with Jules
-                                     *   - one for each of the three IOU reports
-                                     *   - one on the group chat w/ deleted report
-                                     */
-                                    expect(_.size(allTransactions)).toBe(5);
-                                    expect(allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${julesExistingTransaction.transactionID}`]).toBeTruthy();
-
-                                    carlosTransaction = _.find(allTransactions, (transaction) => transaction.transactionID === carlosIOUAction.originalMessage.IOUTransactionID);
-                                    julesTransaction = _.find(allTransactions, (transaction) => transaction.transactionID === julesIOUAction.originalMessage.IOUTransactionID);
-                                    vitTransaction = _.find(allTransactions, (transaction) => transaction.transactionID === vitIOUAction.originalMessage.IOUTransactionID);
-                                    groupTransaction = _.find(allTransactions, (transaction) => transaction.reportID === CONST.REPORT.SPLIT_REPORTID);
-
-                                    expect(carlosTransaction.reportID).toBe(carlosIOUReport.reportID);
-                                    expect(julesTransaction.reportID).toBe(julesIOUReport.reportID);
-                                    expect(vitTransaction.reportID).toBe(vitIOUReport.reportID);
-                                    expect(groupTransaction).toBeTruthy();
-
-                                    expect(carlosTransaction.amount).toBe(amount / 4);
-                                    expect(julesTransaction.amount).toBe(amount / 4);
-                                    expect(vitTransaction.amount).toBe(amount / 4);
-                                    expect(groupTransaction.amount).toBe(amount);
-
-                                    expect(carlosTransaction.comment.comment).toBe(comment);
-                                    expect(julesTransaction.comment.comment).toBe(comment);
-                                    expect(vitTransaction.comment.comment).toBe(comment);
-                                    expect(groupTransaction.comment.comment).toBe(comment);
-
-                                    expect(carlosTransaction.merchant).toBe(merchant);
-                                    expect(julesTransaction.merchant).toBe(merchant);
-                                    expect(vitTransaction.merchant).toBe(merchant);
-                                    expect(groupTransaction.merchant).toBe(merchant);
-
-                                    expect(carlosTransaction.comment.source).toBe(CONST.IOU.TYPE.SPLIT);
-                                    expect(julesTransaction.comment.source).toBe(CONST.IOU.TYPE.SPLIT);
-                                    expect(vitTransaction.comment.source).toBe(CONST.IOU.TYPE.SPLIT);
-
-                                    expect(carlosTransaction.comment.originalTransactionID).toBe(groupTransaction.transactionID);
-                                    expect(julesTransaction.comment.originalTransactionID).toBe(groupTransaction.transactionID);
-                                    expect(vitTransaction.comment.originalTransactionID).toBe(groupTransaction.transactionID);
-
-                                    expect(carlosTransaction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                    expect(julesTransaction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                    expect(vitTransaction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                    expect(groupTransaction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.PERSONAL_DETAILS_LIST,
-                                waitForCollectionCallback: true,
-                                callback: (allPersonalDetails) => {
-                                    Onyx.disconnect(connectionID);
-                                    expect(allPersonalDetails).toMatchObject({
-                                        [VIT_ACCOUNT_ID]: {
-                                            accountID: VIT_ACCOUNT_ID,
-                                            displayName: VIT_EMAIL,
-                                            login: VIT_EMAIL,
-                                        },
-                                    });
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(fetch.resume)
-                .then(waitForNetworkPromises)
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    _.each(allReports, (report) => {
-                                        if (!report.pendingFields) {
-                                            return;
-                                        }
-                                        _.each(report.pendingFields, (pendingField) => expect(pendingField).toBeFalsy());
-                                    });
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
-                                waitForCollectionCallback: true,
-                                callback: (allReportActions) => {
-                                    Onyx.disconnect(connectionID);
-                                    _.each(allReportActions, (reportAction) => expect(reportAction.pendingAction).toBeFalsy());
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                waitForCollectionCallback: true,
-                                callback: (allTransactions) => {
-                                    Onyx.disconnect(connectionID);
-                                    _.each(allTransactions, (transaction) => expect(transaction.pendingAction).toBeFalsy());
-                                    resolve();
-                                },
-                            });
-                        }),
-                );
-        });
-    });
-
-    describe('payMoneyRequestElsewhere', () => {
-        it('clears outstanding IOUReport', () => {
-            const amount = 10000;
-            const comment = 'Giv money plz';
-            let chatReport;
-            let iouReport;
-            let createIOUAction;
-            let payIOUAction;
-            let transaction;
-            IOU.requestMoney({}, amount, CONST.CURRENCY.USD, '', '', RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment);
-            return waitForBatchedUpdates()
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    expect(_.size(allReports)).toBe(3);
-
-                                    const chatReports = _.filter(allReports, (report) => report.type === CONST.REPORT.TYPE.CHAT);
-                                    chatReport = chatReports[0];
-                                    expect(chatReport).toBeTruthy();
-                                    expect(chatReport).toHaveProperty('reportID');
-                                    expect(chatReport).toHaveProperty('iouReportID');
-
-                                    iouReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-                                    expect(iouReport).toBeTruthy();
-                                    expect(iouReport).toHaveProperty('reportID');
-                                    expect(iouReport).toHaveProperty('chatReportID');
-
-                                    expect(chatReport.iouReportID).toBe(iouReport.reportID);
-                                    expect(iouReport.chatReportID).toBe(chatReport.reportID);
-
-                                    expect(chatReport.pendingFields).toBeFalsy();
-                                    expect(iouReport.pendingFields).toBeFalsy();
-
-                                    // expect(iouReport.status).toBe(CONST.REPORT.STATUS_NUM.SUBMITTED);
-                                    // expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.APPROVED);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
-                                waitForCollectionCallback: true,
-                                callback: (allReportActions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    const reportActionsForIOUReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.iouReportID}`];
-
-                                    createIOUAction = _.find(reportActionsForIOUReport, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                                    expect(createIOUAction).toBeTruthy();
-                                    expect(createIOUAction.originalMessage.IOUReportID).toBe(iouReport.reportID);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                waitForCollectionCallback: true,
-                                callback: (allTransactions) => {
-                                    Onyx.disconnect(connectionID);
-                                    expect(_.size(allTransactions)).toBe(1);
-                                    transaction = _.find(allTransactions, (t) => t);
-                                    expect(transaction).toBeTruthy();
-                                    expect(transaction.amount).toBe(amount);
-                                    expect(transaction.reportID).toBe(iouReport.reportID);
-                                    expect(createIOUAction.originalMessage.IOUTransactionID).toBe(transaction.transactionID);
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    fetch.pause();
-                    IOU.payMoneyRequest(CONST.IOU.PAYMENT_TYPE.ELSEWHERE, chatReport, iouReport);
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    expect(_.size(allReports)).toBe(3);
-
-                                    chatReport = _.find(allReports, (r) => r.type === CONST.REPORT.TYPE.CHAT);
-                                    iouReport = _.find(allReports, (r) => r.type === CONST.REPORT.TYPE.IOU);
-
-                                    expect(chatReport.iouReportID).toBeFalsy();
-
-                                    // expect(iouReport.status).toBe(CONST.REPORT.STATUS_NUM.REIMBURSED);
-                                    // expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.APPROVED);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
-                                waitForCollectionCallback: true,
-                                callback: (allReportActions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    const reportActionsForIOUReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`];
-                                    expect(_.size(reportActionsForIOUReport)).toBe(3);
-
-                                    payIOUAction = _.find(
-                                        reportActionsForIOUReport,
-                                        (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && ra.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.PAY,
-                                    );
-                                    expect(payIOUAction).toBeTruthy();
-                                    expect(payIOUAction.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(fetch.resume)
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    expect(_.size(allReports)).toBe(3);
-
-                                    chatReport = _.find(allReports, (r) => r.type === CONST.REPORT.TYPE.CHAT);
-                                    iouReport = _.find(allReports, (r) => r.type === CONST.REPORT.TYPE.IOU);
-
-                                    expect(chatReport.iouReportID).toBeFalsy();
-
-                                    // expect(iouReport.status).toBe(CONST.REPORT.STATUS_NUM.REIMBURSED);
-                                    // expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.APPROVED);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
-                                waitForCollectionCallback: true,
-                                callback: (allReportActions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    const reportActionsForIOUReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`];
-                                    expect(_.size(reportActionsForIOUReport)).toBe(3);
-
-                                    payIOUAction = _.find(
-                                        reportActionsForIOUReport,
-                                        (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && ra.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.PAY,
-                                    );
-                                    expect(payIOUAction).toBeTruthy();
-                                    expect(payIOUAction.pendingAction).toBeFalsy();
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                );
-        });
-    });
-
-    describe('edit money request', () => {
-        const amount = 10000;
-        const comment = '💸💸💸💸';
-        const merchant = 'NASDAQ';
-
-        afterEach(() => {
-            fetch.resume();
-        });
-
-        it('updates the IOU request and IOU report when offline', () => {
-            let thread = {};
-            let iouReport = {};
-            let iouAction = {};
-            let transaction = {};
-
-            fetch.pause();
-            IOU.requestMoney({}, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment);
-            return waitForBatchedUpdates()
-                .then(() => {
-                    Onyx.set(ONYXKEYS.SESSION, {email: RORY_EMAIL, accountID: RORY_ACCOUNT_ID});
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    iouReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (reportActionsForIOUReport) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    [iouAction] = _.filter(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                waitForCollectionCallback: true,
-                                callback: (allTransactions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    transaction = _.find(allTransactions, (t) => !_.isEmpty(t));
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    thread = ReportUtils.buildTransactionThread(iouAction, iouReport);
-                    Onyx.set(`report_${thread.reportID}`, thread);
-                    return waitForBatchedUpdates();
-                })
-                .then(() => {
-                    IOU.editMoneyRequest(transaction, thread.reportID, {amount: 20000, comment: 'Double the amount!'});
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                waitForCollectionCallback: true,
-                                callback: (allTransactions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    const updatedTransaction = _.find(allTransactions, (t) => !_.isEmpty(t));
-                                    expect(updatedTransaction.modifiedAmount).toBe(20000);
-                                    expect(updatedTransaction.comment).toMatchObject({comment: 'Double the amount!'});
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (allActions) => {
-                                    Onyx.disconnect(connectionID);
-                                    const updatedAction = _.find(allActions, (reportAction) => !_.isEmpty(reportAction));
-                                    expect(updatedAction.actionName).toEqual('MODIFIEDEXPENSE');
-                                    expect(updatedAction.originalMessage).toEqual(
-                                        expect.objectContaining({amount: 20000, newComment: 'Double the amount!', oldAmount: amount, oldComment: comment}),
-                                    );
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    const updatedIOUReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-                                    const updatedChatReport = _.find(allReports, (report) => report.reportID === iouReport.chatReportID);
-                                    expect(updatedIOUReport).toEqual(
-                                        expect.objectContaining({
-                                            total: 20000,
-                                            cachedTotal: '$200.00',
-                                            lastMessageHtml: 'requested $200.00',
-                                            lastMessageText: 'requested $200.00',
-                                        }),
-                                    );
-                                    expect(updatedChatReport).toEqual(
-                                        expect.objectContaining({
-                                            lastMessageHtml: `${CARLOS_EMAIL} owes $200.00`,
-                                            lastMessageText: `${CARLOS_EMAIL} owes $200.00`,
-                                        }),
-                                    );
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    fetch.resume();
-                });
-        });
-
-        it('resets the IOU request and IOU report when api returns an error', () => {
-            let thread = {};
-            let iouReport = {};
-            let iouAction = {};
-            let transaction = {};
-
-            IOU.requestMoney({}, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment);
-            return waitForBatchedUpdates()
-                .then(() => {
-                    Onyx.set(ONYXKEYS.SESSION, {email: RORY_EMAIL, accountID: RORY_ACCOUNT_ID});
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    [iouReport] = _.filter(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (reportActionsForIOUReport) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    [iouAction] = _.filter(reportActionsForIOUReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                waitForCollectionCallback: true,
-                                callback: (allTransactions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    transaction = _.find(allTransactions, (t) => !_.isEmpty(t));
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    thread = ReportUtils.buildTransactionThread(iouAction, iouReport);
-                    Onyx.set(`report_${thread.reportID}`, thread);
-                    return waitForBatchedUpdates();
-                })
-                .then(() => {
-                    fetch.fail();
-                    IOU.editMoneyRequest(transaction, thread.reportID, {amount: 20000, comment: 'Double the amount!'});
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.TRANSACTION,
-                                waitForCollectionCallback: true,
-                                callback: (allTransactions) => {
-                                    Onyx.disconnect(connectionID);
-
-                                    const updatedTransaction = _.find(allTransactions, (t) => !_.isEmpty(t));
-                                    expect(updatedTransaction.modifiedAmount).toBe(undefined);
-                                    expect(updatedTransaction.amount).toBe(10000);
-                                    expect(updatedTransaction.comment).toMatchObject({comment});
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (allActions) => {
-                                    Onyx.disconnect(connectionID);
-                                    const updatedAction = _.find(allActions, (reportAction) => !_.isEmpty(reportAction));
-                                    expect(updatedAction.actionName).toEqual('MODIFIEDEXPENSE');
-                                    expect(_.values(updatedAction.errors)).toEqual(expect.arrayContaining([['iou.error.genericEditFailureMessage', {isTranslated: false}]]));
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    const updatedIOUReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-                                    const updatedChatReport = _.find(allReports, (report) => report.reportID === iouReport.chatReportID);
-                                    expect(updatedIOUReport).toEqual(
-                                        expect.objectContaining({
-                                            total: 10000,
-                                            cachedTotal: '$100.00',
-                                            lastMessageHtml: `requested $${amount / 100}.00 for ${comment}`,
-                                            lastMessageText: `requested $${amount / 100}.00 for ${comment}`,
-                                        }),
-                                    );
-                                    expect(updatedChatReport).toEqual(
-                                        expect.objectContaining({
-                                            lastMessageHtml: '',
-                                        }),
-                                    );
-                                    resolve();
-                                },
-                            });
-                        }),
-                );
-        });
-    });
-
-    describe('pay expense report via ACH', () => {
-        const amount = 10000;
-        const comment = '💸💸💸💸';
-        const merchant = 'NASDAQ';
-
-        afterEach(() => {
-            fetch.resume();
-        });
-
-        it('updates the expense request and expense report when paid while offline', () => {
-            let expenseReport = {};
-            let chatReport = {};
-
-            fetch.pause();
-            Onyx.set(ONYXKEYS.SESSION, {email: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID});
-            return waitForBatchedUpdates()
-                .then(() => {
-                    PolicyActions.createWorkspace(CARLOS_EMAIL, true, "Carlos's Workspace");
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    chatReport = _.find(allReports, (report) => report.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    IOU.requestMoney(chatReport, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment);
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    expenseReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    IOU.payMoneyRequest(CONST.IOU.PAYMENT_TYPE.VBBA, chatReport, expenseReport);
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (allActions) => {
-                                    Onyx.disconnect(connectionID);
-                                    expect(_.values(allActions)).toEqual(
-                                        expect.arrayContaining([
-                                            expect.objectContaining({
-                                                message: expect.arrayContaining([
-                                                    expect.objectContaining({
-                                                        html: `paid $${amount / 100}.00 with Expensify`,
-                                                        text: `paid $${amount / 100}.00 with Expensify`,
-                                                    }),
-                                                ]),
-                                                originalMessage: expect.objectContaining({
-                                                    amount,
-                                                    paymentType: CONST.IOU.PAYMENT_TYPE.VBBA,
-                                                    type: 'pay',
-                                                }),
-                                            }),
-                                        ]),
-                                    );
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    const updatedIOUReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-                                    const updatedChatReport = _.find(allReports, (report) => report.reportID === expenseReport.chatReportID);
-                                    expect(updatedIOUReport).toEqual(
-                                        expect.objectContaining({
-                                            lastMessageHtml: `paid $${amount / 100}.00 with Expensify`,
-                                            lastMessageText: `paid $${amount / 100}.00 with Expensify`,
-                                            statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED,
-                                            stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
-                                        }),
-                                    );
-                                    expect(updatedChatReport).toEqual(
-                                        expect.objectContaining({
-                                            lastMessageHtml: `paid $${amount / 100}.00 with Expensify`,
-                                            lastMessageText: `paid $${amount / 100}.00 with Expensify`,
-                                        }),
-                                    );
-                                    resolve();
-                                },
-                            });
-                        }),
-                );
-        });
-
-        it('shows an error when paying results in an error', () => {
-            let expenseReport = {};
-            let chatReport = {};
-
-            Onyx.set(ONYXKEYS.SESSION, {email: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID});
-            return waitForBatchedUpdates()
-                .then(() => {
-                    PolicyActions.createWorkspace(CARLOS_EMAIL, true, "Carlos's Workspace");
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    chatReport = _.find(allReports, (report) => report.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    IOU.requestMoney(chatReport, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment);
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    expenseReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    fetch.fail();
-                    IOU.payMoneyRequest('ACH', chatReport, expenseReport);
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`,
-                                waitForCollectionCallback: true,
-                                callback: (allActions) => {
-                                    Onyx.disconnect(connectionID);
-                                    const erroredAction = _.find(_.values(allActions), (action) => !_.isEmpty(action.errors));
-                                    expect(_.values(erroredAction.errors)).toEqual(expect.arrayContaining([['iou.error.other', {isTranslated: false}]]));
-                                    resolve();
-                                },
-                            });
-                        }),
-                );
-        });
-    });
-
-    describe('deleteMoneyRequest', () => {
-        const amount = 10000;
-        const comment = 'Send me money please';
-        let chatReport;
-        let iouReport;
-        let createIOUAction;
-        let transaction;
-        let thread;
-        const TEST_USER_ACCOUNT_ID = 1;
-        const TEST_USER_LOGIN = 'test@test.com';
-        let IOU_REPORT_ID;
-        let reportActionID;
-        const REPORT_ACTION = {
-            actionName: CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT,
-            actorAccountID: TEST_USER_ACCOUNT_ID,
-            automatic: false,
-            avatar: 'https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/avatar_3.png',
-            message: [{type: 'COMMENT', html: 'Testing a comment', text: 'Testing a comment', translationKey: ''}],
-            person: [{type: 'TEXT', style: 'strong', text: 'Test User'}],
-            shouldShow: true,
-        };
-
-        let reportActions;
-
-        beforeEach(async () => {
-            // Given mocks are cleared and helpers are set up
-            jest.clearAllMocks();
-            PusherHelper.setup();
-
-            // Given a test user is signed in with Onyx setup and some initial data
-            await TestHelper.signInWithTestUser(TEST_USER_ACCOUNT_ID, TEST_USER_LOGIN);
-            User.subscribeToUserEvents();
-            await waitForBatchedUpdates();
-            await TestHelper.setPersonalDetails(TEST_USER_LOGIN, TEST_USER_ACCOUNT_ID);
-
-            // When an IOU request for money is made
-            IOU.requestMoney({}, amount, CONST.CURRENCY.USD, '', '', TEST_USER_LOGIN, TEST_USER_ACCOUNT_ID, {login: RORY_EMAIL, accountID: RORY_ACCOUNT_ID}, comment);
-            await waitForBatchedUpdates();
-
-            // When fetching all reports from Onyx
-            const allReports = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: ONYXKEYS.COLLECTION.REPORT,
-                    waitForCollectionCallback: true,
-                    callback: (reports) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(reports);
-                    },
-                });
-            });
-
-            // Then we should have exactly 3 reports
-            expect(_.size(allReports)).toBe(3);
-
-            // Then one of them should be a chat report with relevant properties
-            chatReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.CHAT);
-            expect(chatReport).toBeTruthy();
-            expect(chatReport).toHaveProperty('reportID');
-            expect(chatReport).toHaveProperty('iouReportID');
-
-            // Then one of them should be an IOU report with relevant properties
-            iouReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.IOU);
-            expect(iouReport).toBeTruthy();
-            expect(iouReport).toHaveProperty('reportID');
-            expect(iouReport).toHaveProperty('chatReportID');
-
-            // Then their IDs should reference each other
-            expect(chatReport.iouReportID).toBe(iouReport.reportID);
-            expect(iouReport.chatReportID).toBe(chatReport.reportID);
-
-            // Storing IOU Report ID for further reference
-            IOU_REPORT_ID = chatReport.iouReportID;
-
-            await waitForBatchedUpdates();
-
-            // When fetching all report actions from Onyx
-            const allReportActions = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
-                    waitForCollectionCallback: true,
-                    callback: (actions) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(actions);
-                    },
-                });
-            });
-
-            // Then we should find an IOU action with specific properties
-            const reportActionsForIOUReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.iouReportID}`];
-            createIOUAction = _.find(reportActionsForIOUReport, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-            expect(createIOUAction).toBeTruthy();
-            expect(createIOUAction.originalMessage.IOUReportID).toBe(iouReport.reportID);
-
-            // When fetching all transactions from Onyx
-            const allTransactions = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: ONYXKEYS.COLLECTION.TRANSACTION,
-                    waitForCollectionCallback: true,
-                    callback: (transactions) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(transactions);
-                    },
-                });
-            });
-
-            // Then we should find a specific transaction with relevant properties
-            transaction = _.find(allTransactions, (t) => t);
-            expect(transaction).toBeTruthy();
-            expect(transaction.amount).toBe(amount);
-            expect(transaction.reportID).toBe(iouReport.reportID);
-            expect(createIOUAction.originalMessage.IOUTransactionID).toBe(transaction.transactionID);
-        });
-
-        afterEach(PusherHelper.teardown);
-
-        it('delete a money request (IOU Action and transaction) successfully', async () => {
-            // Given the fetch operations are paused and a money request is initiated
-            fetch.pause();
-
-            // When the money request is deleted
-            IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, true);
-            await waitForBatchedUpdates();
-
-            // Then we check if the IOU report action is removed from the report actions collection
-            let reportActionsForReport = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (actionsForReport) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(actionsForReport);
-                    },
-                });
-            });
-
-            createIOUAction = _.find(reportActionsForReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-            // Then the IOU Action should be truthy for offline support.
-            expect(createIOUAction).toBeTruthy();
-
-            // Then we check if the transaction is removed from the transactions collection
-            const t = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`,
-                    waitForCollectionCallback: true,
-                    callback: (transactionResult) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(transactionResult);
-                    },
-                });
-            });
-
-            expect(t).toBeFalsy();
-
-            // Given fetch operations are resumed
-            fetch.resume();
-            await waitForBatchedUpdates();
-
-            // Then we recheck the IOU report action from the report actions collection
-            reportActionsForReport = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (actionsForReport) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(actionsForReport);
-                    },
-                });
-            });
-
-            createIOUAction = _.find(reportActionsForReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-            expect(createIOUAction).toBeFalsy();
-
-            // Then we recheck the transaction from the transactions collection
-            const tr = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`,
-                    waitForCollectionCallback: true,
-                    callback: (transactionResult) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(transactionResult);
-                    },
-                });
-            });
-
-            expect(tr).toBeFalsy();
-        });
-
-        it('delete the IOU report when there are no visible comments left in the IOU report', async () => {
-            // Given an IOU report and a paused fetch state
-            fetch.pause();
-
-            // When the IOU money request is deleted
-            IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, true);
-            await waitForBatchedUpdates();
-
-            let report = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (res) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(res);
-                    },
-                });
-            });
-
-            // Then the report should be truthy for offline support
-            expect(report).toBeTruthy();
-
-            // Given the resumed fetch state
-            fetch.resume();
-            await waitForBatchedUpdates();
-
-            report = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (res) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(res);
-                    },
-                });
-            });
-
-            // Then the report should be falsy so that there is no trace of the money request.
-            expect(report).toBeFalsy();
-        });
-
-        it('does not delete the IOU report when there are visible comments left in the IOU report', async () => {
-            // Given the initial setup is completed
-            await waitForBatchedUpdates();
-
-            Onyx.connect({
-                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${IOU_REPORT_ID}`,
-                callback: (val) => (reportActions = val),
-            });
-            await waitForBatchedUpdates();
-
-            jest.advanceTimersByTime(10);
-
-            // When a comment is added to the IOU report
-            Report.addComment(IOU_REPORT_ID, 'Testing a comment');
-            await waitForBatchedUpdates();
-
-            // Then verify that the comment is correctly added
-            const resultAction = _.find(reportActions, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
-            reportActionID = resultAction.reportActionID;
-
-            expect(resultAction.message).toEqual(REPORT_ACTION.message);
-            expect(resultAction.person).toEqual(REPORT_ACTION.person);
-            expect(resultAction.pendingAction).toBeUndefined();
-
-            await waitForBatchedUpdates();
-
-            // Verify there are three actions (created + iou + addcomment) and our optimistic comment has been removed
-            expect(_.size(reportActions)).toBe(3);
-
-            // Then check the loading state of our action
-            const resultActionAfterUpdate = reportActions[reportActionID];
-            expect(resultActionAfterUpdate.pendingAction).toBeUndefined();
-
-            // When we attempt to delete a money request from the IOU report
-            fetch.pause();
-            IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, false);
-            await waitForBatchedUpdates();
-
-            // Then expect that the IOU report still exists
-            let allReports = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: ONYXKEYS.COLLECTION.REPORT,
-                    waitForCollectionCallback: true,
-                    callback: (reports) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(reports);
-                    },
-                });
-            });
-
-            await waitForBatchedUpdates();
-
-            iouReport = _.find(allReports, (report) => ReportUtils.isIOUReport(report));
-            expect(iouReport).toBeTruthy();
-            expect(iouReport).toHaveProperty('reportID');
-            expect(iouReport).toHaveProperty('chatReportID');
-
-            // Given the resumed fetch state
-            fetch.resume();
-
-            allReports = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: ONYXKEYS.COLLECTION.REPORT,
-                    waitForCollectionCallback: true,
-                    callback: (reports) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(reports);
-                    },
-                });
-            });
-            // Then expect that the IOU report still exists
-            iouReport = _.find(allReports, (report) => ReportUtils.isIOUReport(report));
-            expect(iouReport).toBeTruthy();
-            expect(iouReport).toHaveProperty('reportID');
-            expect(iouReport).toHaveProperty('chatReportID');
-        });
-
-        it('delete the transaction thread if there are no visible comments in the thread', async () => {
-            // Given all promises are resolved
-            await waitForBatchedUpdates();
-            jest.advanceTimersByTime(10);
-
-            // Given a transaction thread
-            thread = ReportUtils.buildTransactionThread(createIOUAction, {reportID: IOU_REPORT_ID});
-
-            expect(thread.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
-
-            Onyx.connect({
-                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
-                callback: (val) => (reportActions = val),
-            });
-
-            await waitForBatchedUpdates();
-
-            jest.advanceTimersByTime(10);
-
-            // Given User logins from the participant accounts
-            const userLogins = PersonalDetailsUtils.getLoginsByAccountIDs(thread.participantAccountIDs);
-
-            // When Opening a thread report with the given details
-            Report.openReport(thread.reportID, userLogins, thread, createIOUAction.reportActionID);
-            await waitForBatchedUpdates();
-
-            // Then The iou action has the transaction report id as a child report ID
-            const allReportActions = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
-                    waitForCollectionCallback: true,
-                    callback: (actions) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(actions);
-                    },
-                });
-            });
-            const reportActionsForIOUReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.iouReportID}`];
-            createIOUAction = _.find(reportActionsForIOUReport, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-            expect(createIOUAction.childReportID).toBe(thread.reportID);
-
-            await waitForBatchedUpdates();
-
-            // Given Fetch is paused and timers have advanced
-            fetch.pause();
-            jest.advanceTimersByTime(10);
-
-            // When Deleting a money request
-            IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, false);
-            await waitForBatchedUpdates();
-
-            // Then The report for the given thread ID does not exist
-            let report = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (reportData) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(reportData);
-                    },
-                });
-            });
-
-            expect(report).toBeFalsy();
-            fetch.resume();
-
-            // Then After resuming fetch, the report for the given thread ID still does not exist
-            report = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (reportData) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(reportData);
-                    },
-                });
-            });
-
-            expect(report).toBeFalsy();
-        });
-
-        it('delete the transaction thread if there are only changelogs (i.e. MODIFIEDEXPENSE actions) in the thread', async () => {
-            // Given all promises are resolved
-            await waitForBatchedUpdates();
-            jest.advanceTimersByTime(10);
-
-            // Given a transaction thread
-            thread = ReportUtils.buildTransactionThread(createIOUAction, {reportID: IOU_REPORT_ID});
-
-            Onyx.connect({
-                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
-                callback: (val) => (reportActions = val),
-            });
-
-            await waitForBatchedUpdates();
-
-            jest.advanceTimersByTime(10);
-
-            // Given User logins from the participant accounts
-            const userLogins = PersonalDetailsUtils.getLoginsByAccountIDs(thread.participantAccountIDs);
-
-            // When Opening a thread report with the given details
-            Report.openReport(thread.reportID, userLogins, thread, createIOUAction.reportActionID);
-            await waitForBatchedUpdates();
-
-            // Then The iou action has the transaction report id as a child report ID
-            const allReportActions = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
-                    waitForCollectionCallback: true,
-                    callback: (actions) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(actions);
-                    },
-                });
-            });
-            const reportActionsForIOUReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.iouReportID}`];
-            createIOUAction = _.find(reportActionsForIOUReport, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-            expect(createIOUAction.childReportID).toBe(thread.reportID);
-
-            await waitForBatchedUpdates();
-
-            jest.advanceTimersByTime(10);
-            IOU.editMoneyRequest(transaction, thread.reportID, {amount: 20000, comment: 'Double the amount!'});
-            await waitForBatchedUpdates();
-
-            // Verify there are two actions (created + changelog)
-            expect(_.size(reportActions)).toBe(2);
-
-            // Fetch the updated IOU Action from Onyx
-            await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (reportActionsForReport) => {
-                        Onyx.disconnect(connectionID);
-                        createIOUAction = _.find(reportActionsForReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                        resolve();
-                    },
-                });
-            });
-
-            // When Deleting a money request
-            IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, false);
-            await waitForBatchedUpdates();
-
-            // Then, the report for the given thread ID does not exist
-            const report = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (reportData) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(reportData);
-                    },
-                });
-            });
-
-            expect(report).toBeFalsy();
-        });
-
-        it('does not delete the transaction thread if there are visible comments in the thread', async () => {
-            // Given initial environment is set up
-            await waitForBatchedUpdates();
-
-            // Given a transaction thread
-            thread = ReportUtils.buildTransactionThread(createIOUAction, {reportID: IOU_REPORT_ID});
-
-            expect(thread.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
-
-            const userLogins = PersonalDetailsUtils.getLoginsByAccountIDs(thread.participantAccountIDs);
-            jest.advanceTimersByTime(10);
-            Report.openReport(thread.reportID, userLogins, thread, createIOUAction.reportActionID);
-            await waitForBatchedUpdates();
-
-            Onyx.connect({
-                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
-                callback: (val) => (reportActions = val),
-            });
-            await waitForBatchedUpdates();
-
-            await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (report) => {
-                        Onyx.disconnect(connectionID);
-                        expect(report).toBeTruthy();
-                        resolve();
-                    },
-                });
-            });
-
-            jest.advanceTimersByTime(10);
-
-            // When a comment is added
-            Report.addComment(thread.reportID, 'Testing a comment');
-            await waitForBatchedUpdates();
-
-            // Then comment details should match the expected report action
-            const resultAction = _.find(reportActions, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
-            reportActionID = resultAction.reportActionID;
-            expect(resultAction.message).toEqual(REPORT_ACTION.message);
-            expect(resultAction.person).toEqual(REPORT_ACTION.person);
-
-            await waitForBatchedUpdates();
-
-            // Then the report should have 2 actions
-            expect(_.size(reportActions)).toBe(2);
-            const resultActionAfter = reportActions[reportActionID];
-            expect(resultActionAfter.pendingAction).toBeUndefined();
-
-            fetch.pause();
-            // When deleting money request
-            IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, false);
-            await waitForBatchedUpdates();
-
-            // Then the transaction thread report should still exist
-            await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (report) => {
-                        Onyx.disconnect(connectionID);
-                        expect(report).toBeTruthy();
-                        resolve();
-                    },
-                });
-            });
-
-            // When fetch resumes
-            // Then the transaction thread report should still exist
-            fetch.resume();
-            await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (report) => {
-                        Onyx.disconnect(connectionID);
-                        expect(report).toBeTruthy();
-                        resolve();
-                    },
-                });
-            });
-        });
-
-        it('update the moneyRequestPreview to show [Deleted request] when appropriate', async () => {
-            await waitForBatchedUpdates();
-
-            // Given a thread report
-
-            jest.advanceTimersByTime(10);
-            thread = ReportUtils.buildTransactionThread(createIOUAction, {reportID: IOU_REPORT_ID});
-
-            expect(thread.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
-
-            Onyx.connect({
-                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
-                callback: (val) => (reportActions = val),
-            });
-            await waitForBatchedUpdates();
-
-            jest.advanceTimersByTime(10);
-            const userLogins = PersonalDetailsUtils.getLoginsByAccountIDs(thread.participantAccountIDs);
-            Report.openReport(thread.reportID, userLogins, thread, createIOUAction.reportActionID);
-
-            await waitForBatchedUpdates();
-
-            const allReportActions = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
-                    waitForCollectionCallback: true,
-                    callback: (actions) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(actions);
-                    },
-                });
-            });
-
-            const reportActionsForIOUReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.iouReportID}`];
-            createIOUAction = _.find(reportActionsForIOUReport, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-            expect(createIOUAction.childReportID).toBe(thread.reportID);
-
-            await waitForBatchedUpdates();
-
-            // Given an added comment to the thread report
-
-            jest.advanceTimersByTime(10);
-
-            Report.addComment(thread.reportID, 'Testing a comment');
-            await waitForBatchedUpdates();
-
-            // Fetch the updated IOU Action from Onyx due to addition of comment to transaction thread.
-            // This needs to be fetched as `deleteMoneyRequest` depends on `childVisibleActionCount` in `createIOUAction`.
-            await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (reportActionsForReport) => {
-                        Onyx.disconnect(connectionID);
-                        createIOUAction = _.find(reportActionsForReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                        resolve();
-                    },
-                });
-            });
-
-            let resultAction = _.find(reportActions, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
-            reportActionID = resultAction.reportActionID;
-
-            expect(resultAction.message).toEqual(REPORT_ACTION.message);
-            expect(resultAction.person).toEqual(REPORT_ACTION.person);
-            expect(resultAction.pendingAction).toBeUndefined();
-
-            await waitForBatchedUpdates();
-
-            // Verify there are three actions (created + addcomment) and our optimistic comment has been removed
-            expect(_.size(reportActions)).toBe(2);
-
-            let resultActionAfterUpdate = reportActions[reportActionID];
-
-            // Verify that our action is no longer in the loading state
-            expect(resultActionAfterUpdate.pendingAction).toBeUndefined();
-
-            await waitForBatchedUpdates();
-
-            // Given an added comment to the IOU report
-
-            Onyx.connect({
-                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${IOU_REPORT_ID}`,
-                callback: (val) => (reportActions = val),
-            });
-            await waitForBatchedUpdates();
-
-            jest.advanceTimersByTime(10);
-
-            Report.addComment(IOU_REPORT_ID, 'Testing a comment');
-            await waitForBatchedUpdates();
-
-            resultAction = _.find(reportActions, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
-            reportActionID = resultAction.reportActionID;
-
-            expect(resultAction.message).toEqual(REPORT_ACTION.message);
-            expect(resultAction.person).toEqual(REPORT_ACTION.person);
-            expect(resultAction.pendingAction).toBeUndefined();
-
-            await waitForBatchedUpdates();
-
-            // Verify there are three actions (created + iou + addcomment) and our optimistic comment has been removed
-            expect(_.size(reportActions)).toBe(3);
-
-            resultActionAfterUpdate = reportActions[reportActionID];
-
-            // Verify that our action is no longer in the loading state
-            expect(resultActionAfterUpdate.pendingAction).toBeUndefined();
-
-            fetch.pause();
-            // When we delete the money request
-            IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, false);
-            await waitForBatchedUpdates();
-
-            // Then we expect the moneyRequestPreview to show [Deleted request]
-
-            await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (reportActionsForReport) => {
-                        Onyx.disconnect(connectionID);
-                        createIOUAction = _.find(reportActionsForReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                        expect(createIOUAction.message[0].isDeletedParentAction).toBeTruthy();
-                        resolve();
-                    },
-                });
-            });
-
-            // When we resume fetch
-
-            fetch.resume();
-
-            // Then we expect the moneyRequestPreview to show [Deleted request]
-
-            await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
-                    waitForCollectionCallback: true,
-                    callback: (reportActionsForReport) => {
-                        Onyx.disconnect(connectionID);
-                        createIOUAction = _.find(reportActionsForReport, (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-                        expect(createIOUAction.message[0].isDeletedParentAction).toBeTruthy();
-                        resolve();
-                    },
-                });
-            });
-        });
-
-        it('update IOU report and reportPreview with new totals and messages if the IOU report is not deleted', async () => {
-            await waitForBatchedUpdates();
-            Onyx.connect({
-                key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`,
-                callback: (val) => (iouReport = val),
-            });
-            await waitForBatchedUpdates();
-
-            // Given a second money request in addition to the first one
-
-            jest.advanceTimersByTime(10);
-            const amount2 = 20000;
-            const comment2 = 'Send me money please 2';
-            IOU.requestMoney(chatReport, amount2, CONST.CURRENCY.USD, '', '', TEST_USER_LOGIN, TEST_USER_ACCOUNT_ID, {login: RORY_EMAIL, accountID: RORY_ACCOUNT_ID}, comment2);
-
-            await waitForBatchedUpdates();
-
-            // Then we expect the IOU report and reportPreview to update with new totals
-
-            expect(iouReport).toBeTruthy();
-            expect(iouReport).toHaveProperty('reportID');
-            expect(iouReport).toHaveProperty('chatReportID');
-            expect(iouReport.total).toBe(30000);
-
-            const ioupreview = ReportActionsUtils.getReportPreviewAction(chatReport.reportID, iouReport.reportID);
-            expect(ioupreview).toBeTruthy();
-            expect(ioupreview.message[0].text).toBe('rory@expensifail.com owes $300.00');
-
-            // When we delete the first money request
-            fetch.pause();
-            jest.advanceTimersByTime(10);
-            IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, false);
-            await waitForBatchedUpdates();
-
-            // Then we expect the IOU report and reportPreview to update with new totals
-
-            expect(iouReport).toBeTruthy();
-            expect(iouReport).toHaveProperty('reportID');
-            expect(iouReport).toHaveProperty('chatReportID');
-            expect(iouReport.total).toBe(20000);
-
-            // When we resume fetch
-            fetch.resume();
-
-            // Then we expect the IOU report and reportPreview to update with new totals
-            expect(iouReport).toBeTruthy();
-            expect(iouReport).toHaveProperty('reportID');
-            expect(iouReport).toHaveProperty('chatReportID');
-            expect(iouReport.total).toBe(20000);
-        });
-
-        it('navigate the user correctly to the iou Report when appropriate', async () => {
-            await waitForBatchedUpdates();
-
-            Onyx.connect({
-                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${IOU_REPORT_ID}`,
-                callback: (val) => (reportActions = val),
-            });
-            await waitForBatchedUpdates();
-
-            // Given an added comment to the iou report
-
-            jest.advanceTimersByTime(10);
-
-            Report.addComment(IOU_REPORT_ID, 'Testing a comment');
-            await waitForBatchedUpdates();
-
-            const resultAction = _.find(reportActions, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
-            reportActionID = resultAction.reportActionID;
-
-            expect(resultAction.message).toEqual(REPORT_ACTION.message);
-            expect(resultAction.person).toEqual(REPORT_ACTION.person);
-
-            await waitForBatchedUpdates();
-
-            // Verify there are three actions (created + iou + addcomment) and our optimistic comment has been removed
-            expect(_.size(reportActions)).toBe(3);
-
-            await waitForBatchedUpdates();
-
-            // Given a thread report
-
-            jest.advanceTimersByTime(10);
-            thread = ReportUtils.buildTransactionThread(createIOUAction, {reportID: IOU_REPORT_ID});
-
-            expect(thread.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
-
-            Onyx.connect({
-                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
-                callback: (val) => (reportActions = val),
-            });
-            await waitForBatchedUpdates();
-
-            jest.advanceTimersByTime(10);
-            const userLogins = PersonalDetailsUtils.getLoginsByAccountIDs(thread.participantAccountIDs);
-            Report.openReport(thread.reportID, userLogins, thread, createIOUAction.reportActionID);
-            await waitForBatchedUpdates();
-
-            const allReportActions = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
-                    waitForCollectionCallback: true,
-                    callback: (actions) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(actions);
-                    },
-                });
-            });
-
-            const reportActionsForIOUReport = allReportActions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.iouReportID}`];
-            createIOUAction = _.find(reportActionsForIOUReport, (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
-            expect(createIOUAction.childReportID).toBe(thread.reportID);
-
-            await waitForBatchedUpdates();
-
-            // When we delete the money request in SingleTransactionView and we should not delete the IOU report
-
-            fetch.pause();
-
-            IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, true);
-            await waitForBatchedUpdates();
-
-            let allReports = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: ONYXKEYS.COLLECTION.REPORT,
-                    waitForCollectionCallback: true,
-                    callback: (reports) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(reports);
-                    },
-                });
-            });
-
-            await waitForBatchedUpdates();
-
-            iouReport = _.find(allReports, (report) => ReportUtils.isIOUReport(report));
-            expect(iouReport).toBeTruthy();
-            expect(iouReport).toHaveProperty('reportID');
-            expect(iouReport).toHaveProperty('chatReportID');
-
-            fetch.resume();
-
-            allReports = await new Promise((resolve) => {
-                const connectionID = Onyx.connect({
-                    key: ONYXKEYS.COLLECTION.REPORT,
-                    waitForCollectionCallback: true,
-                    callback: (reports) => {
-                        Onyx.disconnect(connectionID);
-                        resolve(reports);
-                    },
-                });
-            });
-
-            iouReport = _.find(allReports, (report) => ReportUtils.isIOUReport(report));
-            expect(iouReport).toBeTruthy();
-            expect(iouReport).toHaveProperty('reportID');
-            expect(iouReport).toHaveProperty('chatReportID');
-
-            // Then we expect to navigate to the iou report
-
-            expect(Navigation.goBack).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(IOU_REPORT_ID));
-        });
-
-        it('navigate the user correctly to the chat Report when appropriate', () => {
-            // When we delete the money request and we should delete the IOU report
-            IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, false);
-            // Then we expect to navigate to the chat report
-            expect(Navigation.goBack).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(chatReport.reportID));
-        });
-    });
-
-    describe('submitReport', () => {
-        it('correctly submits a report', () => {
-            const amount = 10000;
-            const comment = '💸💸💸💸';
-            const merchant = 'NASDAQ';
-            let expenseReport = {};
-            let chatReport = {};
-            return waitForBatchedUpdates()
-                .then(() => {
-                    PolicyActions.createWorkspace(CARLOS_EMAIL, true, "Carlos's Workspace");
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    chatReport = _.find(allReports, (report) => report.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    IOU.requestMoney(
-                        chatReport,
-                        amount,
-                        CONST.CURRENCY.USD,
-                        '',
-                        merchant,
-                        RORY_EMAIL,
-                        RORY_ACCOUNT_ID,
-                        {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID, isPolicyExpenseChat: true, reportID: chatReport.reportID},
-                        comment,
-                    );
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    expenseReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.EXPENSE);
-                                    Onyx.merge(`report_${expenseReport.reportID}`, {
-                                        statusNum: 0,
-                                        stateNum: 0,
-                                    });
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    expenseReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.EXPENSE);
-
-                                    // Verify report is a draft
-                                    expect(expenseReport.stateNum).toBe(0);
-                                    expect(expenseReport.statusNum).toBe(0);
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    IOU.submitReport(expenseReport);
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    expenseReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.EXPENSE);
-
-                                    // Report was submitted correctly
-                                    expect(expenseReport.stateNum).toBe(1);
-                                    expect(expenseReport.statusNum).toBe(1);
-                                    resolve();
-                                },
-                            });
-                        }),
-                );
-        });
-        it('correctly implements error handling', () => {
-            const amount = 10000;
-            const comment = '💸💸💸💸';
-            const merchant = 'NASDAQ';
-            let expenseReport = {};
-            let chatReport = {};
-            return waitForBatchedUpdates()
-                .then(() => {
-                    PolicyActions.createWorkspace(CARLOS_EMAIL, true, "Carlos's Workspace");
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    chatReport = _.find(allReports, (report) => report.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT);
-
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    IOU.requestMoney(
-                        chatReport,
-                        amount,
-                        CONST.CURRENCY.USD,
-                        '',
-                        merchant,
-                        RORY_EMAIL,
-                        RORY_ACCOUNT_ID,
-                        {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID, isPolicyExpenseChat: true, reportID: chatReport.reportID},
-                        comment,
-                    );
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    expenseReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.EXPENSE);
-                                    Onyx.merge(`report_${expenseReport.reportID}`, {
-                                        statusNum: 0,
-                                        stateNum: 0,
-                                    });
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    expenseReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.EXPENSE);
-
-                                    // Verify report is a draft
-                                    expect(expenseReport.stateNum).toBe(0);
-                                    expect(expenseReport.statusNum).toBe(0);
-                                    resolve();
-                                },
-                            });
-                        }),
-                )
-                .then(() => {
-                    fetch.fail();
-                    IOU.submitReport(expenseReport);
-                    return waitForBatchedUpdates();
-                })
-                .then(
-                    () =>
-                        new Promise((resolve) => {
-                            const connectionID = Onyx.connect({
-                                key: ONYXKEYS.COLLECTION.REPORT,
-                                waitForCollectionCallback: true,
-                                callback: (allReports) => {
-                                    Onyx.disconnect(connectionID);
-                                    expenseReport = _.find(allReports, (report) => report.type === CONST.REPORT.TYPE.EXPENSE);
-
-                                    // Report was submitted with some fail
-                                    expect(expenseReport.stateNum).toBe(0);
-                                    expect(expenseReport.statusNum).toBe(0);
-                                    resolve();
-                                },
-                            });
-                        }),
-                );
-        });
-    });
-});
diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts
new file mode 100644
index 000000000000..47d7a616299b
--- /dev/null
+++ b/tests/actions/IOUTest.ts
@@ -0,0 +1,3196 @@
+import isEqual from 'lodash/isEqual';
+import Onyx from 'react-native-onyx';
+import type { OnyxCollection, OnyxEntry } from 'react-native-onyx';
+import type { OptimisticChatReport } from '@libs/ReportUtils';
+import type * as OnyxTypes from '@src/types/onyx';
+import type { IOUMessage } from '@src/types/onyx/OriginalMessage';
+import { toCollectionDataSet } from '@src/types/utils/CollectionDataSet';
+import { isEmptyObject } from '@src/types/utils/EmptyObject';
+import CONST from '../../src/CONST';
+import * as IOU from '../../src/libs/actions/IOU';
+import OnyxUpdateManager from '../../src/libs/actions/OnyxUpdateManager';
+import * as PolicyActions from '../../src/libs/actions/Policy';
+import * as Report from '../../src/libs/actions/Report';
+import * as ReportActions from '../../src/libs/actions/ReportActions';
+import * as User from '../../src/libs/actions/User';
+import DateUtils from '../../src/libs/DateUtils';
+import Navigation from '../../src/libs/Navigation/Navigation';
+import * as NumberUtils from '../../src/libs/NumberUtils';
+import * as PersonalDetailsUtils from '../../src/libs/PersonalDetailsUtils';
+import * as ReportActionsUtils from '../../src/libs/ReportActionsUtils';
+import * as ReportUtils from '../../src/libs/ReportUtils';
+import ONYXKEYS from '../../src/ONYXKEYS';
+import ROUTES from '../../src/ROUTES';
+import PusherHelper from '../utils/PusherHelper';
+import * as TestHelper from '../utils/TestHelper';
+import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
+import waitForNetworkPromises from '../utils/waitForNetworkPromises';
+
+
+jest.mock('../../src/libs/Navigation/Navigation', () => ({
+    navigate: jest.fn(),
+    dismissModal: jest.fn(),
+    dismissModalWithReport: jest.fn(),
+    goBack: jest.fn(),
+}));
+
+const CARLOS_EMAIL = 'cmartins@expensifail.com';
+const CARLOS_ACCOUNT_ID = 1;
+const JULES_EMAIL = 'jules@expensifail.com';
+const JULES_ACCOUNT_ID = 2;
+const RORY_EMAIL = 'rory@expensifail.com';
+const RORY_ACCOUNT_ID = 3;
+const VIT_EMAIL = 'vit@expensifail.com';
+const VIT_ACCOUNT_ID = 4;
+
+OnyxUpdateManager();
+describe('actions/IOU', () => {
+    beforeAll(() => {
+        Onyx.init({
+            keys: ONYXKEYS,
+        });
+    });
+
+    beforeEach(() => {
+        // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+        global.fetch = TestHelper.getGlobalFetchMock();
+        return Onyx.clear().then(waitForBatchedUpdates);
+    });
+
+    describe('requestMoney', () => {
+        it('creates new chat if needed', () => {
+            const amount = 10000;
+            const comment = 'Giv money plz';
+            const merchant = 'KFC';
+            let iouReportID: string | undefined;
+            let createdAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let iouAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let transactionID: string | undefined;
+            let transactionThread: OnyxEntry<OnyxTypes.Report>;
+            let transactionThreadCreatedAction;
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+            IOU.requestMoney({reportID: ''}, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment, {});
+            return (
+                waitForBatchedUpdates()
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReports) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // A chat report, a transaction thread, and an iou report should be created
+                                        const chatReports = Object.values(allReports ?? {}).filter((report) => report?.type === CONST.REPORT.TYPE.CHAT);
+                                        const iouReports = Object.values(allReports ?? {}).filter((report) => report?.type === CONST.REPORT.TYPE.IOU);
+                                        expect(Object.keys(chatReports).length).toBe(2);
+                                        expect(Object.keys(iouReports).length).toBe(1);
+                                        const chatReport = chatReports[0];
+                                        const transactionThreadReport = chatReports[1];
+                                        const iouReport = iouReports[0];
+                                        iouReportID = iouReport?.reportID;
+                                        transactionThread = transactionThreadReport;
+
+                                        expect(iouReport?.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
+
+                                        // They should be linked together
+                                        expect(chatReport?.participantAccountIDs).toEqual([CARLOS_ACCOUNT_ID]);
+                                        expect(chatReport?.iouReportID).toBe(iouReport?.reportID);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
+                                    waitForCollectionCallback: false,
+                                    callback: (reportActionsForIOUReport) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // The IOU report should have a CREATED action and IOU action
+                                        expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(2);
+                                        const createdActions = Object.values(reportActionsForIOUReport ?? {}).filter(
+                                            (reportAction) => (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.CREATED,
+                                        );
+                                        const iouActions = Object.values(reportActionsForIOUReport ?? {}).filter(
+                                            (reportAction) => (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.IOU,
+                                        );
+                                        expect(Object.values(createdActions).length).toBe(1);
+                                        expect(Object.values(iouActions).length).toBe(1);
+                                        createdAction = createdActions?.[0] ?? null;
+                                        iouAction = iouActions?.[0] ?? null;
+
+                                        // The CREATED action should not be created after the IOU action
+                                        expect(Date.parse(createdAction?.created ?? '')).toBeLessThan(Date.parse(iouAction?.created ?? ''));
+
+                                        // The IOUReportID should be correct
+                                        expect((iouAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReportID);
+
+                                        // The comment should be included in the IOU action
+                                        expect((iouAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
+
+                                        // The amount in the IOU action should be correct
+                                        expect((iouAction?.originalMessage as IOUMessage).amount).toBe(amount);
+
+                                        // The IOU type should be correct
+                                        expect((iouAction?.originalMessage as IOUMessage).type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+
+                                        // Both actions should be pending
+                                        expect(createdAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        expect(iouAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThread?.reportID}`,
+                                    waitForCollectionCallback: true,
+                                    callback: (reportActionsForTransactionThread) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // The transaction thread should have a CREATED action
+                                        expect(Object.values(reportActionsForTransactionThread ?? {}).length).toBe(1);
+                                        const createdActions = Object.values(reportActionsForTransactionThread ?? {}).filter(
+                                            (reportAction) => (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.CREATED,
+                                        );
+                                        expect(Object.values(createdActions).length).toBe(1);
+                                        transactionThreadCreatedAction = createdActions[0];
+
+                                        expect(transactionThreadCreatedAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                    waitForCollectionCallback: true,
+                                    callback: (allTransactions) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // There should be one transaction
+                                        expect(Object.values(allTransactions ?? {}).length).toBe(1);
+                                        const transaction = Object.values(allTransactions ?? []).find((t) => !isEmptyObject(t));
+                                        transactionID = transaction?.transactionID;
+
+                                        // The transaction should be attached to the IOU report
+                                        expect(transaction?.reportID).toBe(iouReportID);
+
+                                        // Its amount should match the amount of the request
+                                        expect(transaction?.amount).toBe(amount);
+
+                                        // The comment should be correct
+                                        expect(transaction?.comment.comment).toBe(comment);
+
+                                        // It should be pending
+                                        expect(transaction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+
+                                        // The transactionID on the iou action should match the one from the transactions collection
+                                        expect((iouAction?.originalMessage as IOUMessage)?.IOUTransactionID).toBe(transactionID);
+
+                                        expect(transaction?.merchant).toBe(merchant);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                    .then(fetch.resume)
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
+                                    waitForCollectionCallback: true,
+                                    callback: (reportActionsForIOUReport) => {
+                                        Onyx.disconnect(connectionID);
+                                        expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(2);
+                                        Object.values(reportActionsForIOUReport ?? {}).forEach((reportAction) => expect(reportAction?.pendingAction).toBeFalsy());
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
+                                    waitForCollectionCallback: true,
+                                    callback: (transaction) => {
+                                        Onyx.disconnect(connectionID);
+                                        expect(transaction?.pendingAction).toBeFalsy();
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+            );
+        });
+
+        it('updates existing chat report if there is one', () => {
+            const amount = 10000;
+            const comment = 'Giv money plz';
+            let chatReport: OnyxTypes.Report = {
+                reportID: '1234',
+                type: CONST.REPORT.TYPE.CHAT,
+                participantAccountIDs: [CARLOS_ACCOUNT_ID],
+            };
+            const createdAction = {
+                reportActionID: NumberUtils.rand64(),
+                actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
+                created: DateUtils.getDBTime(),
+            };
+            let iouReportID: string | undefined;
+            let iouAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let iouCreatedAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let transactionID: string | undefined;
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+            return (
+                Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${chatReport.reportID}`, chatReport)
+                    .then(() =>
+                        Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`, {
+                            [createdAction.reportActionID]: createdAction,
+                        }),
+                    )
+                    .then(() => {
+                        IOU.requestMoney(chatReport, amount, CONST.CURRENCY.USD, '', '', RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment, {});
+                        return waitForBatchedUpdates();
+                    })
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReports) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // The same chat report should be reused, a transaction thread and an IOU report should be created
+                                        expect(Object.values(allReports ?? {}).length).toBe(3);
+                                        expect(Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.CHAT)?.reportID).toBe(chatReport.reportID);
+                                        chatReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.CHAT) ?? chatReport;
+                                        const iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU);
+                                        iouReportID = iouReport?.reportID;
+
+                                        expect(iouReport?.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
+
+                                        // They should be linked together
+                                        expect(chatReport.iouReportID).toBe(iouReportID);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
+                                    waitForCollectionCallback: false,
+                                    callback: (allIOUReportActions) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        iouCreatedAction =
+                                            Object.values(allIOUReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null;
+                                        iouAction = Object.values(allIOUReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+
+                                        // The CREATED action should not be created after the IOU action
+                                        expect(Date.parse(iouCreatedAction?.created ?? '')).toBeLessThan(Date.parse(iouAction?.created ?? ''));
+
+                                        // The IOUReportID should be correct
+                                        expect((iouAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReportID);
+
+                                        // The comment should be included in the IOU action
+                                        expect((iouAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
+
+                                        // The amount in the IOU action should be correct
+                                        expect((iouAction?.originalMessage as IOUMessage)?.amount).toBe(amount);
+
+                                        // The IOU action type should be correct
+                                        expect((iouAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+
+                                        // The IOU action should be pending
+                                        expect(iouAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                    waitForCollectionCallback: true,
+                                    callback: (allTransactions) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // There should be one transaction
+                                        expect(Object.values(allTransactions ?? {}).length).toBe(1);
+                                        const transaction = Object.values(allTransactions ?? {}).find((t) => !isEmptyObject(t));
+                                        transactionID = transaction?.transactionID;
+
+                                        // The transaction should be attached to the IOU report
+                                        expect(transaction?.reportID).toBe(iouReportID);
+
+                                        // Its amount should match the amount of the request
+                                        expect(transaction?.amount).toBe(amount);
+
+                                        // The comment should be correct
+                                        expect(transaction?.comment.comment).toBe(comment);
+
+                                        expect(transaction?.merchant).toBe(CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT);
+
+                                        // It should be pending
+                                        expect(transaction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+
+                                        // The transactionID on the iou action should match the one from the transactions collection
+                                        expect((iouAction?.originalMessage as IOUMessage)?.IOUTransactionID).toBe(transactionID);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                    .then(fetch.resume)
+                    .then(waitForBatchedUpdates)
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
+                                    waitForCollectionCallback: false,
+                                    callback: (reportActionsForIOUReport) => {
+                                        Onyx.disconnect(connectionID);
+                                        expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(2);
+                                        Object.values(reportActionsForIOUReport ?? {}).forEach((reportAction) => expect(reportAction?.pendingAction).toBeFalsy());
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
+                                    waitForCollectionCallback: true,
+                                    callback: (transaction) => {
+                                        Onyx.disconnect(connectionID);
+                                        expect(transaction?.pendingAction).toBeFalsy();
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+            );
+        });
+
+        it('updates existing IOU report if there is one', () => {
+            const amount = 10000;
+            const comment = 'Giv money plz';
+            const chatReportID = '1234';
+            const iouReportID = '5678';
+            let chatReport: OnyxEntry<OnyxTypes.Report> = {
+                reportID: chatReportID,
+                type: CONST.REPORT.TYPE.CHAT,
+                iouReportID,
+                participantAccountIDs: [CARLOS_ACCOUNT_ID],
+            };
+            const createdAction = {
+                reportActionID: NumberUtils.rand64(),
+                actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
+                created: DateUtils.getDBTime(),
+            };
+            const existingTransaction: OnyxTypes.Transaction = {
+                transactionID: NumberUtils.rand64(),
+                amount: 1000,
+                comment: {
+                    comment: 'Existing transaction',
+                },
+                created: DateUtils.getDBTime(),
+                currency: CONST.CURRENCY.USD,
+                merchant: '',
+                reportID: '',
+            };
+            let iouReport: OnyxEntry<OnyxTypes.Report> = {
+                reportID: iouReportID,
+                chatReportID,
+                type: CONST.REPORT.TYPE.IOU,
+                ownerAccountID: RORY_ACCOUNT_ID,
+                managerID: CARLOS_ACCOUNT_ID,
+                currency: CONST.CURRENCY.USD,
+                total: existingTransaction.amount,
+            };
+            const iouAction = {
+                reportActionID: NumberUtils.rand64(),
+                actionName: CONST.REPORT.ACTIONS.TYPE.IOU,
+                actorAccountID: RORY_ACCOUNT_ID,
+                created: DateUtils.getDBTime(),
+                originalMessage: {
+                    IOUReportID: iouReportID,
+                    IOUTransactionID: existingTransaction.transactionID,
+                    amount: existingTransaction.amount,
+                    currency: CONST.CURRENCY.USD,
+                    type: CONST.IOU.REPORT_ACTION_TYPE.CREATE,
+                    participantAccountIDs: [RORY_ACCOUNT_ID, CARLOS_ACCOUNT_ID],
+                },
+            };
+            let newIOUAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let newTransaction;
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+            return (
+                Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`, chatReport)
+                    .then(() => Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, iouReport))
+                    .then(() =>
+                        Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, {
+                            [createdAction.reportActionID]: createdAction,
+                            [iouAction.reportActionID]: iouAction,
+                        }),
+                    )
+                    .then(() => Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${existingTransaction.transactionID}`, existingTransaction))
+                    .then(() => {
+                        if (chatReport) {
+                            IOU.requestMoney(chatReport, amount, CONST.CURRENCY.USD, '', '', RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment, {});
+                        }
+                        return waitForBatchedUpdates();
+                    })
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReports) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // No new reports should be created
+                                        expect(Object.values(allReports ?? {}).length).toBe(3);
+                                        expect(Object.values(allReports ?? {}).find((report) => report?.reportID === chatReportID)).toBeTruthy();
+                                        expect(Object.values(allReports ?? {}).find((report) => report?.reportID === iouReportID)).toBeTruthy();
+
+                                        chatReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.CHAT) ?? null;
+                                        iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null;
+
+                                        // The total on the iou report should be updated
+                                        expect(iouReport?.total).toBe(11000);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
+                                    waitForCollectionCallback: false,
+                                    callback: (reportActionsForIOUReport) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(3);
+                                        newIOUAction =
+                                            Object.values(reportActionsForIOUReport ?? {}).find(
+                                                (reportAction) => reportAction?.reportActionID !== createdAction.reportActionID && reportAction?.reportActionID !== iouAction?.reportActionID,
+                                            ) ?? null;
+
+                                        // The IOUReportID should be correct
+                                        expect((iouAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReportID);
+
+                                        // The comment should be included in the IOU action
+                                        expect((newIOUAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
+
+                                        // The amount in the IOU action should be correct
+                                        expect((newIOUAction?.originalMessage as IOUMessage)?.amount).toBe(amount);
+
+                                        // The type of the IOU action should be correct
+                                        expect((newIOUAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+
+                                        // The IOU action should be pending
+                                        expect(newIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                    waitForCollectionCallback: true,
+                                    callback: (allTransactions) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // There should be two transactions
+                                        expect(Object.values(allTransactions ?? {}).length).toBe(2);
+
+                                        newTransaction = Object.values(allTransactions ?? {}).find((transaction) => transaction?.transactionID !== existingTransaction.transactionID);
+
+                                        expect(newTransaction?.reportID).toBe(iouReportID);
+                                        expect(newTransaction?.amount).toBe(amount);
+                                        expect(newTransaction?.comment.comment).toBe(comment);
+                                        expect(newTransaction?.merchant).toBe(CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT);
+                                        expect(newTransaction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+
+                                        // The transactionID on the iou action should match the one from the transactions collection
+                                        expect((newIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID).toBe(newTransaction?.transactionID);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                    .then(fetch.resume)
+                    .then(waitForNetworkPromises)
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
+                                    waitForCollectionCallback: true,
+                                    callback: (reportActionsForIOUReport) => {
+                                        Onyx.disconnect(connectionID);
+                                        expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(3);
+                                        Object.values(reportActionsForIOUReport ?? {}).forEach((reportAction) => expect(reportAction?.pendingAction).toBeFalsy());
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                    waitForCollectionCallback: true,
+                                    callback: (allTransactions) => {
+                                        Onyx.disconnect(connectionID);
+                                        Object.values(allTransactions ?? {}).forEach((transaction) => expect(transaction?.pendingAction).toBeFalsy());
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+            );
+        });
+
+        it('correctly implements RedBrickRoad error handling', () => {
+            const amount = 10000;
+            const comment = 'Giv money plz';
+            let chatReportID: string | undefined;
+            let iouReportID: string | undefined;
+            let createdAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let iouAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let transactionID: string;
+            let transactionThreadReport: OnyxEntry<OnyxTypes.Report>;
+            let transactionThreadAction: OnyxEntry<OnyxTypes.ReportAction>;
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+            IOU.requestMoney({reportID: ''}, amount, CONST.CURRENCY.USD, '', '', RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment, {});
+            return (
+                waitForBatchedUpdates()
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReports) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // A chat report, transaction thread and an iou report should be created
+                                        const chatReports = Object.values(allReports ?? {}).filter((report) => report?.type === CONST.REPORT.TYPE.CHAT);
+                                        const iouReports = Object.values(allReports ?? {}).filter((report) => report?.type === CONST.REPORT.TYPE.IOU);
+                                        expect(Object.values(chatReports).length).toBe(2);
+                                        expect(Object.values(iouReports).length).toBe(1);
+                                        const chatReport = chatReports[0];
+                                        chatReportID = chatReport?.reportID;
+                                        transactionThreadReport = chatReports[1];
+
+                                        const iouReport = iouReports[0];
+                                        iouReportID = iouReport?.reportID;
+
+                                        expect(iouReport?.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
+
+                                        // They should be linked together
+                                        expect(chatReport?.participantAccountIDs).toEqual([CARLOS_ACCOUNT_ID]);
+                                        expect(chatReport?.iouReportID).toBe(iouReport?.reportID);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
+                                    waitForCollectionCallback: false,
+                                    callback: (reportActionsForIOUReport) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // The chat report should have a CREATED action and IOU action
+                                        expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(2);
+                                        const createdActions =
+                                            Object.values(reportActionsForIOUReport ?? {}).filter(
+                                                (reportAction) => (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.CREATED,
+                                            ) ?? null;
+                                        const iouActions =
+                                            Object.values(reportActionsForIOUReport ?? {}).filter(
+                                                (reportAction) => (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.IOU,
+                                            ) ?? null;
+                                        expect(Object.values(createdActions).length).toBe(1);
+                                        expect(Object.values(iouActions).length).toBe(1);
+                                        createdAction = createdActions[0];
+                                        iouAction = iouActions[0];
+
+                                        // The CREATED action should not be created after the IOU action
+                                        expect(Date.parse(createdAction?.created ?? '')).toBeLessThan(Date.parse(iouAction?.created ?? {}));
+
+                                        // The IOUReportID should be correct
+                                        expect((iouAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReportID);
+
+                                        // The comment should be included in the IOU action
+                                        expect((iouAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
+
+                                        // The amount in the IOU action should be correct
+                                        expect((iouAction?.originalMessage as IOUMessage)?.amount).toBe(amount);
+
+                                        // The type should be correct
+                                        expect((iouAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+
+                                        // Both actions should be pending
+                                        expect(createdAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        expect(iouAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                    waitForCollectionCallback: true,
+                                    callback: (allTransactions) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // There should be one transaction
+                                        expect(Object.values(allTransactions ?? {}).length).toBe(1);
+                                        const transaction = Object.values(allTransactions ?? {}).find((t) => !isEmptyObject(t));
+                                        transactionID = transaction?.transactionID ?? '';
+
+                                        expect(transaction?.reportID).toBe(iouReportID);
+                                        expect(transaction?.amount).toBe(amount);
+                                        expect(transaction?.comment.comment).toBe(comment);
+                                        expect(transaction?.merchant).toBe(CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT);
+                                        expect(transaction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+
+                                        // The transactionID on the iou action should match the one from the transactions collection
+                                        expect((iouAction?.originalMessage as IOUMessage)?.IOUTransactionID).toBe(transactionID);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(() => {
+                        // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                        fetch.fail();
+                        // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                        fetch.resume();
+                    })
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
+                                    waitForCollectionCallback: false,
+                                    callback: (reportActionsForIOUReport) => {
+                                        Onyx.disconnect(connectionID);
+                                        expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(2);
+                                        iouAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                                        expect(iouAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}`,
+                                    waitForCollectionCallback: true,
+                                    callback: (reportActionsForTransactionThread) => {
+                                        Onyx.disconnect(connectionID);
+                                        expect(Object.values(reportActionsForTransactionThread ?? {}).length).toBe(3);
+                                        transactionThreadAction =
+                                            Object.values(reportActionsForTransactionThread?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport?.reportID}`] ?? {}).find(
+                                                (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED,
+                                            ) ?? null;
+                                        expect(transactionThreadAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
+                                    waitForCollectionCallback: false,
+                                    callback: (transaction) => {
+                                        Onyx.disconnect(connectionID);
+                                        expect(transaction?.pendingAction).toBeFalsy();
+                                        expect(transaction?.errors).toBeTruthy();
+                                        expect(Object.values(transaction?.errors ?? {})[0]).toEqual(expect.arrayContaining(['iou.error.genericCreateFailureMessage', {isTranslated: false}]));
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+
+                    // If the user clears the errors on the IOU action
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                ReportActions.clearReportActionErrors(iouReportID ?? '', iouAction);
+                                ReportActions.clearReportActionErrors(transactionThreadReport?.reportID ?? '', transactionThreadAction);
+                                resolve();
+                            }),
+                    )
+
+                    // Then the reportAction should be removed from Onyx
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`,
+                                    waitForCollectionCallback: false,
+                                    callback: (reportActionsForReport) => {
+                                        Onyx.disconnect(connectionID);
+                                        iouAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                                        expect(iouAction).toBeFalsy();
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+
+                    // Along with the associated transaction
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
+                                    waitForCollectionCallback: true,
+                                    callback: (transaction) => {
+                                        Onyx.disconnect(connectionID);
+                                        expect(transaction).toBeFalsy();
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+
+                    // If a user clears the errors on the CREATED action (which, technically are just errors on the report)
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                Report.deleteReport(chatReportID ?? '');
+                                Report.deleteReport(transactionThreadReport?.reportID ?? '');
+                                resolve();
+                            }),
+                    )
+
+                    // Then the report should be deleted
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReports) => {
+                                        Onyx.disconnect(connectionID);
+                                        Object.values(allReports ?? {}).forEach((report) => expect(report).toBeFalsy());
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+
+                    // All reportActions should also be deleted
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
+                                    waitForCollectionCallback: false,
+                                    callback: (allReportActions) => {
+                                        Onyx.disconnect(connectionID);
+                                        Object.values(allReportActions ?? {}).forEach((reportAction) => expect(reportAction).toBeFalsy());
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+
+                    // All transactions should also be deleted
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                    waitForCollectionCallback: true,
+                                    callback: (allTransactions) => {
+                                        Onyx.disconnect(connectionID);
+                                        Object.values(allTransactions ?? {}).forEach((transaction) => expect(transaction).toBeFalsy());
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+
+                    // Cleanup
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                    .then(fetch.succeed)
+            );
+        });
+    });
+
+    describe('split bill', () => {
+        it('creates and updates new chats and IOUs as needed', () => {
+            jest.setTimeout(10 * 1000);
+            /*
+             * Given that:
+             *   - Rory and Carlos have chatted before
+             *   - Rory and Jules have chatted before and have an active IOU report
+             *   - Rory and Vit have never chatted together before
+             *   - There is no existing group chat with the four of them
+             */
+            const amount = 400;
+            const comment = 'Yes, I am splitting a bill for $4 USD';
+            const merchant = 'Yema Kitchen';
+            let carlosChatReport: OnyxEntry<OnyxTypes.Report> = {
+                reportID: NumberUtils.rand64(),
+                type: CONST.REPORT.TYPE.CHAT,
+                participantAccountIDs: [CARLOS_ACCOUNT_ID],
+            };
+            const carlosCreatedAction: OnyxEntry<OnyxTypes.ReportAction> = {
+                reportActionID: NumberUtils.rand64(),
+                actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
+                created: DateUtils.getDBTime(),
+                reportID: carlosChatReport.reportID,
+            };
+            const julesIOUReportID = NumberUtils.rand64();
+            let julesChatReport: OnyxEntry<OnyxTypes.Report> = {
+                reportID: NumberUtils.rand64(),
+                type: CONST.REPORT.TYPE.CHAT,
+                iouReportID: julesIOUReportID,
+                participantAccountIDs: [JULES_ACCOUNT_ID],
+            };
+            const julesChatCreatedAction: OnyxEntry<OnyxTypes.ReportAction> = {
+                reportActionID: NumberUtils.rand64(),
+                actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
+                created: DateUtils.getDBTime(),
+                reportID: julesChatReport.reportID,
+            };
+            const julesCreatedAction: OnyxEntry<OnyxTypes.ReportAction> = {
+                reportActionID: NumberUtils.rand64(),
+                actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
+                created: DateUtils.getDBTime(),
+                reportID: julesIOUReportID,
+            };
+            jest.advanceTimersByTime(200);
+            const julesExistingTransaction: OnyxEntry<OnyxTypes.Transaction> = {
+                transactionID: NumberUtils.rand64(),
+                amount: 1000,
+                // @ts-expect-error Test data
+                comment: 'This is an existing transaction',
+                created: DateUtils.getDBTime(),
+            };
+            let julesIOUReport: OnyxEntry<OnyxTypes.Report> = {
+                reportID: julesIOUReportID,
+                chatReportID: julesChatReport.reportID,
+                type: CONST.REPORT.TYPE.IOU,
+                ownerAccountID: RORY_ACCOUNT_ID,
+                managerID: JULES_ACCOUNT_ID,
+                currency: CONST.CURRENCY.USD,
+                total: julesExistingTransaction?.amount,
+            };
+            const julesExistingIOUAction: OnyxEntry<OnyxTypes.ReportAction> = {
+                reportActionID: NumberUtils.rand64(),
+                actionName: CONST.REPORT.ACTIONS.TYPE.IOU,
+                actorAccountID: RORY_ACCOUNT_ID,
+                created: DateUtils.getDBTime(),
+                originalMessage: {
+                    IOUReportID: julesIOUReportID,
+                    IOUTransactionID: julesExistingTransaction?.transactionID,
+                    amount: julesExistingTransaction?.amount ?? 0,
+                    currency: CONST.CURRENCY.USD,
+                    type: CONST.IOU.REPORT_ACTION_TYPE.CREATE,
+                    participantAccountIDs: [RORY_ACCOUNT_ID, JULES_ACCOUNT_ID],
+                },
+                reportID: julesIOUReportID,
+            };
+
+            let carlosIOUReport: OnyxEntry<OnyxTypes.Report>;
+            let carlosIOUAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let carlosIOUCreatedAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let carlosTransaction: OnyxEntry<OnyxTypes.Transaction>;
+
+            let julesIOUAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let julesIOUCreatedAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let julesTransaction: OnyxEntry<OnyxTypes.Transaction>;
+
+            let vitChatReport: OnyxEntry<OnyxTypes.Report>;
+            let vitIOUReport: OnyxEntry<OnyxTypes.Report>;
+            let vitCreatedAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let vitIOUAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let vitTransaction: OnyxEntry<OnyxTypes.Transaction>;
+
+            let groupChat: OnyxEntry<OnyxTypes.Report>;
+            let groupCreatedAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let groupIOUAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let groupTransaction: OnyxEntry<OnyxTypes.Transaction>;
+
+            const reportCollectionDataSet = toCollectionDataSet(ONYXKEYS.COLLECTION.REPORT, [carlosChatReport, julesChatReport, julesIOUReport], (item) => item.reportID);
+
+            const carlosActionsCollectionDataSet = toCollectionDataSet(
+                `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}`,
+                [
+                    {
+                        [carlosCreatedAction.reportActionID]: carlosCreatedAction,
+                    },
+                ],
+                (item) => item[carlosCreatedAction.reportActionID].reportID ?? '',
+            );
+
+            const julesActionsCollectionDataSet = toCollectionDataSet(
+                `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}`,
+            [{
+                    [julesCreatedAction.reportActionID]: julesCreatedAction,
+                    [julesExistingIOUAction.reportActionID]: julesExistingIOUAction,
+                }],
+                (item) => item[julesCreatedAction.reportActionID].reportID ?? '',
+            );
+
+            const julesCreatedActionsCollectionDataSet = toCollectionDataSet(
+                `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}`,
+                [
+                    {
+                        [julesChatCreatedAction.reportActionID]: julesChatCreatedAction,
+                    },
+                ],
+                (item) => item[julesCreatedAction.reportActionID].reportID ?? '',
+            );
+
+            return (
+                Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT, {
+                    ...reportCollectionDataSet,
+                })
+                    .then(() =>
+                        Onyx.mergeCollection(ONYXKEYS.COLLECTION.REPORT_ACTIONS, {
+                            ...carlosActionsCollectionDataSet,
+                            ...julesCreatedActionsCollectionDataSet,
+                            ...julesActionsCollectionDataSet,
+                        }),
+                    )
+                    .then(() => Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${julesExistingTransaction?.transactionID}`, julesExistingTransaction))
+                    .then(() => {
+                        // When we split a bill offline
+                        // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                        fetch.pause();
+                        IOU.splitBill(
+                            // TODO: Migrate after the backend accepts accountIDs
+                            [
+                                [CARLOS_EMAIL, String(CARLOS_ACCOUNT_ID)],
+                                [JULES_EMAIL, String(JULES_ACCOUNT_ID)],
+                                [VIT_EMAIL, String(VIT_ACCOUNT_ID)],
+                            ].map(([email, accountID]) => ({login: email, accountID: Number(accountID)})),
+                            RORY_EMAIL,
+                            RORY_ACCOUNT_ID,
+                            amount,
+                            comment,
+                            CONST.CURRENCY.USD,
+                            merchant,
+                            '',
+                            '',
+                            '',
+                        );
+                        return waitForBatchedUpdates();
+                    })
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReports) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // There should now be 10 reports
+                                        expect(Object.values(allReports ?? {}).length).toBe(10);
+
+                                        // 1. The chat report with Rory + Carlos
+                                        carlosChatReport = Object.values(allReports ?? {}).find((report) => report?.reportID === carlosChatReport?.reportID) ?? null;
+                                        expect(isEmptyObject(carlosChatReport)).toBe(false);
+                                        expect(carlosChatReport?.pendingFields).toBeFalsy();
+
+                                        // 2. The IOU report with Rory + Carlos (new)
+                                        carlosIOUReport =
+                                            Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU && report.managerID === CARLOS_ACCOUNT_ID) ?? null;
+                                        expect(isEmptyObject(carlosIOUReport)).toBe(false);
+                                        expect(carlosIOUReport?.total).toBe(amount / 4);
+
+                                        // 3. The chat report with Rory + Jules
+                                        julesChatReport = Object.values(allReports ?? {}).find((report) => report?.reportID === julesChatReport?.reportID) ?? null;
+                                        expect(isEmptyObject(julesChatReport)).toBe(false);
+                                        expect(julesChatReport?.pendingFields).toBeFalsy();
+
+                                        // 4. The IOU report with Rory + Jules
+                                        julesIOUReport = Object.values(allReports ?? {}).find((report) => report?.reportID === julesIOUReport?.reportID) ?? null;
+                                        expect(isEmptyObject(julesIOUReport)).toBe(false);
+                                        expect(julesChatReport?.pendingFields).toBeFalsy();
+                                        expect(julesIOUReport?.total).toBe((julesExistingTransaction?.amount ?? 0) + amount / 4);
+
+                                        // 5. The chat report with Rory + Vit (new)
+                                        vitChatReport =
+                                            Object.values(allReports ?? {}).find(
+                                                (report) => report?.type === CONST.REPORT.TYPE.CHAT && isEqual(report.participantAccountIDs, [VIT_ACCOUNT_ID]),
+                                            ) ?? null;
+                                        expect(isEmptyObject(vitChatReport)).toBe(false);
+                                        expect(vitChatReport?.pendingFields).toStrictEqual({createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD});
+
+                                        // 6. The IOU report with Rory + Vit (new)
+                                        vitIOUReport =
+                                            Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU && report.managerID === VIT_ACCOUNT_ID) ?? null;
+                                        expect(isEmptyObject(vitIOUReport)).toBe(false);
+                                        expect(vitIOUReport?.total).toBe(amount / 4);
+
+                                        // 7. The group chat with everyone
+                                        groupChat =
+                                            Object.values(allReports ?? {}).find(
+                                                (report) =>
+                                                    report?.type === CONST.REPORT.TYPE.CHAT && isEqual(report.participantAccountIDs, [CARLOS_ACCOUNT_ID, JULES_ACCOUNT_ID, VIT_ACCOUNT_ID]),
+                                            ) ?? null;
+                                        expect(isEmptyObject(groupChat)).toBe(false);
+                                        expect(groupChat?.pendingFields).toStrictEqual({createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD});
+
+                                        // The 1:1 chat reports and the IOU reports should be linked together
+                                        expect(carlosChatReport?.iouReportID).toBe(carlosIOUReport?.reportID);
+                                        expect(carlosIOUReport?.chatReportID).toBe(carlosChatReport?.reportID);
+                                        expect(carlosIOUReport?.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
+
+                                        expect(julesChatReport?.iouReportID).toBe(julesIOUReport?.reportID);
+                                        expect(julesIOUReport?.chatReportID).toBe(julesChatReport?.reportID);
+
+                                        expect(vitChatReport?.iouReportID).toBe(vitIOUReport?.reportID);
+                                        expect(vitIOUReport?.chatReportID).toBe(vitChatReport?.reportID);
+                                        expect(carlosIOUReport?.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReportActions) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        // There should be reportActions on all 7 chat reports + 3 IOU reports in each 1:1 chat
+                                        expect(Object.values(allReportActions ?? {}).length).toBe(10);
+
+                                        const carlosReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${carlosChatReport?.iouReportID}`];
+                                        const julesReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${julesChatReport?.iouReportID}`];
+                                        const vitReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${vitChatReport?.iouReportID}`];
+                                        const groupReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${groupChat?.reportID}`];
+
+                                        // Carlos DM should have two reportActions – the existing CREATED action and a pending IOU action
+                                        expect(Object.values(carlosReportActions ?? {}).length).toBe(2);
+                                        carlosIOUCreatedAction =
+                                            Object.values(carlosReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null;
+                                        carlosIOUAction = Object.values(carlosReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                                        expect(carlosIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        expect((carlosIOUAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(carlosIOUReport?.reportID);
+                                        expect((carlosIOUAction?.originalMessage as IOUMessage)?.amount).toBe(amount / 4);
+                                        expect((carlosIOUAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
+                                        expect((carlosIOUAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+                                        expect(Date.parse(carlosIOUCreatedAction?.created ?? '')).toBeLessThan(Date.parse(carlosIOUAction?.created ?? ''));
+
+                                        // Jules DM should have three reportActions, the existing CREATED action, the existing IOU action, and a new pending IOU action
+                                        expect(Object.values(julesReportActions ?? {}).length).toBe(3);
+                                        expect(julesReportActions?.[julesCreatedAction.reportActionID]).toStrictEqual(julesCreatedAction);
+                                        julesIOUCreatedAction =
+                                            Object.values(julesReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null;
+                                        julesIOUAction =
+                                            Object.values(julesReportActions ?? {}).find(
+                                                (reportAction) =>
+                                                    reportAction.reportActionID !== julesCreatedAction.reportActionID &&
+                                                    reportAction.reportActionID !== julesExistingIOUAction.reportActionID,
+                                            ) ?? null;
+                                        expect(julesIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        expect((julesIOUAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(julesIOUReport?.reportID);
+                                        expect((julesIOUAction?.originalMessage as IOUMessage)?.amount).toBe(amount / 4);
+                                        expect((julesIOUAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
+                                        expect((julesIOUAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+                                        expect(Date.parse(julesIOUCreatedAction?.created ?? '')).toBeLessThan(Date.parse(julesIOUAction?.created ?? ''));
+
+                                        // Vit DM should have two reportActions – a pending CREATED action and a pending IOU action
+                                        expect(Object.values(vitReportActions ?? {}).length).toBe(2);
+                                        vitCreatedAction =
+                                            Object.values(vitReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null;
+                                        vitIOUAction = Object.values(vitReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                                        expect(vitCreatedAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        expect(vitIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        expect((vitIOUAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(vitIOUReport?.reportID);
+                                        expect((vitIOUAction?.originalMessage as IOUMessage)?.amount).toBe(amount / 4);
+                                        expect((vitIOUAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
+                                        expect((vitIOUAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+                                        expect(Date.parse(vitCreatedAction?.created ?? '')).toBeLessThan(Date.parse(vitIOUAction?.created ?? ''));
+
+                                        // Group chat should have two reportActions – a pending CREATED action and a pending IOU action w/ type SPLIT
+                                        expect(Object.values(groupReportActions ?? {}).length).toBe(2);
+                                        groupCreatedAction =
+                                            Object.values(groupReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null;
+                                        groupIOUAction = Object.values(groupReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                                        expect(groupCreatedAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        expect(groupIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        expect(groupIOUAction?.originalMessage).not.toHaveProperty('IOUReportID');
+                                        expect((groupIOUAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.SPLIT);
+                                        expect(Date.parse(groupCreatedAction?.created ?? '')).toBeLessThanOrEqual(Date.parse(groupIOUAction?.created ?? ''));
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                    waitForCollectionCallback: true,
+                                    callback: (allTransactions) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        /* There should be 5 transactions
+                                         *   – one existing one with Jules
+                                         *   - one for each of the three IOU reports
+                                         *   - one on the group chat w/ deleted report
+                                         */
+                                        expect(Object.values(allTransactions ?? {}).length).toBe(5);
+                                        expect(allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${julesExistingTransaction?.transactionID}`]).toBeTruthy();
+
+                                        carlosTransaction =
+                                            Object.values(allTransactions ?? {}).find(
+                                                (transaction) => transaction?.transactionID === (carlosIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID,
+                                            ) ?? null;
+                                        julesTransaction =
+                                            Object.values(allTransactions ?? {}).find(
+                                                (transaction) => transaction?.transactionID === (julesIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID,
+                                            ) ?? null;
+                                        vitTransaction =
+                                            Object.values(allTransactions ?? {}).find(
+                                                (transaction) => transaction?.transactionID === (vitIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID,
+                                            ) ?? null;
+                                        groupTransaction = Object.values(allTransactions ?? {}).find((transaction) => transaction?.reportID === CONST.REPORT.SPLIT_REPORTID) ?? null;
+
+                                        expect(carlosTransaction?.reportID).toBe(carlosIOUReport?.reportID);
+                                        expect(julesTransaction?.reportID).toBe(julesIOUReport?.reportID);
+                                        expect(vitTransaction?.reportID).toBe(vitIOUReport?.reportID);
+                                        expect(groupTransaction).toBeTruthy();
+
+                                        expect(carlosTransaction?.amount).toBe(amount / 4);
+                                        expect(julesTransaction?.amount).toBe(amount / 4);
+                                        expect(vitTransaction?.amount).toBe(amount / 4);
+                                        expect(groupTransaction?.amount).toBe(amount);
+
+                                        expect(carlosTransaction?.comment.comment).toBe(comment);
+                                        expect(julesTransaction?.comment.comment).toBe(comment);
+                                        expect(vitTransaction?.comment.comment).toBe(comment);
+                                        expect(groupTransaction?.comment.comment).toBe(comment);
+
+                                        expect(carlosTransaction?.merchant).toBe(merchant);
+                                        expect(julesTransaction?.merchant).toBe(merchant);
+                                        expect(vitTransaction?.merchant).toBe(merchant);
+                                        expect(groupTransaction?.merchant).toBe(merchant);
+
+                                        expect(carlosTransaction?.comment.source).toBe(CONST.IOU.TYPE.SPLIT);
+                                        expect(julesTransaction?.comment.source).toBe(CONST.IOU.TYPE.SPLIT);
+                                        expect(vitTransaction?.comment.source).toBe(CONST.IOU.TYPE.SPLIT);
+
+                                        expect(carlosTransaction?.comment.originalTransactionID).toBe(groupTransaction?.transactionID);
+                                        expect(julesTransaction?.comment.originalTransactionID).toBe(groupTransaction?.transactionID);
+                                        expect(vitTransaction?.comment.originalTransactionID).toBe(groupTransaction?.transactionID);
+
+                                        expect(carlosTransaction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        expect(julesTransaction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        expect(vitTransaction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+                                        expect(groupTransaction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.PERSONAL_DETAILS_LIST,
+                                    waitForCollectionCallback: false,
+                                    callback: (allPersonalDetails) => {
+                                        Onyx.disconnect(connectionID);
+                                        expect(allPersonalDetails).toMatchObject({
+                                            [VIT_ACCOUNT_ID]: {
+                                                accountID: VIT_ACCOUNT_ID,
+                                                displayName: VIT_EMAIL,
+                                                login: VIT_EMAIL,
+                                            },
+                                        });
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                    .then(fetch.resume)
+                    .then(waitForNetworkPromises)
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReports) => {
+                                        Onyx.disconnect(connectionID);
+                                        Object.values(allReports ?? {}).forEach((report) => {
+                                            if (!report?.pendingFields) {
+                                                return;
+                                            }
+                                            Object.values(report?.pendingFields).forEach((pendingField) => expect(pendingField).toBeFalsy());
+                                        });
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReportActions) => {
+                                        Onyx.disconnect(connectionID);
+                                        Object.values(allReportActions ?? {}).forEach((reportAction) => expect(reportAction?.pendingAction).toBeFalsy());
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                    waitForCollectionCallback: true,
+                                    callback: (allTransactions) => {
+                                        Onyx.disconnect(connectionID);
+                                        Object.values(allTransactions ?? {}).forEach((transaction) => expect(transaction?.pendingAction).toBeFalsy());
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+            );
+        });
+    });
+
+    describe('payMoneyRequestElsewhere', () => {
+        it('clears outstanding IOUReport', () => {
+            const amount = 10000;
+            const comment = 'Giv money plz';
+            let chatReport: OnyxEntry<OnyxTypes.Report>;
+            let iouReport: OnyxEntry<OnyxTypes.Report>;
+            let createIOUAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let payIOUAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let transaction: OnyxEntry<OnyxTypes.Transaction>;
+            IOU.requestMoney({reportID: ''}, amount, CONST.CURRENCY.USD, '', '', RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment, {});
+            return (
+                waitForBatchedUpdates()
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReports) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        expect(Object.values(allReports ?? {}).length).toBe(3);
+
+                                        const chatReports = Object.values(allReports ?? {}).filter((report) => report?.type === CONST.REPORT.TYPE.CHAT);
+                                        chatReport = chatReports[0];
+                                        expect(chatReport).toBeTruthy();
+                                        expect(chatReport).toHaveProperty('reportID');
+                                        expect(chatReport).toHaveProperty('iouReportID');
+
+                                        iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null;
+                                        expect(iouReport).toBeTruthy();
+                                        expect(iouReport).toHaveProperty('reportID');
+                                        expect(iouReport).toHaveProperty('chatReportID');
+
+                                        expect(chatReport?.iouReportID).toBe(iouReport?.reportID);
+                                        expect(iouReport?.chatReportID).toBe(chatReport?.reportID);
+
+                                        expect(chatReport?.pendingFields).toBeFalsy();
+                                        expect(iouReport?.pendingFields).toBeFalsy();
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReportActions) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
+
+                                        createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                                        expect(createIOUAction).toBeTruthy();
+                                        expect((createIOUAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReport?.reportID);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                    waitForCollectionCallback: true,
+                                    callback: (allTransactions) => {
+                                        Onyx.disconnect(connectionID);
+                                        expect(Object.values(allTransactions ?? {}).length).toBe(1);
+                                        transaction = Object.values(allTransactions ?? {}).find((t) => t) ?? null;
+                                        expect(transaction).toBeTruthy();
+                                        expect(transaction?.amount).toBe(amount);
+                                        expect(transaction?.reportID).toBe(iouReport?.reportID);
+                                        expect((createIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID).toBe(transaction?.transactionID);
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(() => {
+                        // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                        fetch.pause();
+                        if (chatReport && iouReport) {
+                            IOU.payMoneyRequest(CONST.IOU.PAYMENT_TYPE.ELSEWHERE, chatReport, iouReport);
+                        }
+                        return waitForBatchedUpdates();
+                    })
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReports) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        expect(Object.values(allReports ?? {}).length).toBe(3);
+
+                                        chatReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.CHAT) ?? null;
+                                        iouReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.IOU) ?? null;
+
+                                        expect(chatReport?.iouReportID).toBeFalsy();
+
+                                        // expect(iouReport.status).toBe(CONST.REPORT.STATUS_NUM.REIMBURSED);
+                                        // expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.APPROVED);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReportActions) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`];
+                                        expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(3);
+
+                                        payIOUAction =
+                                            Object.values(reportActionsForIOUReport ?? {}).find(
+                                                (ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && ra?.originalMessage?.type === CONST.IOU.REPORT_ACTION_TYPE.PAY,
+                                            ) ?? null;
+                                        expect(payIOUAction).toBeTruthy();
+                                        expect(payIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                    .then(fetch.resume)
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReports) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        expect(Object.values(allReports ?? {}).length).toBe(3);
+
+                                        chatReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.CHAT) ?? null;
+                                        iouReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.IOU) ?? null;
+
+                                        expect(chatReport?.iouReportID).toBeFalsy();
+
+                                        // expect(iouReport.status).toBe(CONST.REPORT.STATUS_NUM.REIMBURSED);
+                                        // expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.APPROVED);
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+                    .then(
+                        () =>
+                            new Promise<void>((resolve) => {
+                                const connectionID = Onyx.connect({
+                                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
+                                    waitForCollectionCallback: true,
+                                    callback: (allReportActions) => {
+                                        Onyx.disconnect(connectionID);
+
+                                        const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`];
+                                        expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(3);
+
+                                        payIOUAction =
+                                            Object.values(reportActionsForIOUReport ?? {}).find(
+                                                (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && ra.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.PAY,
+                                            ) ?? null;
+                                        expect(payIOUAction).toBeTruthy();
+                                        expect(payIOUAction?.pendingAction).toBeFalsy();
+
+                                        resolve();
+                                    },
+                                });
+                            }),
+                    )
+            );
+        });
+    });
+
+    describe('edit money request', () => {
+        const amount = 10000;
+        const comment = '💸💸💸💸';
+        const merchant = 'NASDAQ';
+
+        afterEach(() => {
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.resume();
+        });
+
+        it('updates the IOU request and IOU report when offline', () => {
+            let thread: OptimisticChatReport;
+            let iouReport: OnyxEntry<OnyxTypes.Report> = null;
+            let iouAction: OnyxEntry<OnyxTypes.ReportAction> = null;
+            let transaction: OnyxEntry<OnyxTypes.Transaction> = null;
+
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+            IOU.requestMoney({reportID: ''}, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment, {});
+            return waitForBatchedUpdates()
+                .then(() => {
+                    Onyx.set(ONYXKEYS.SESSION, {email: RORY_EMAIL, accountID: RORY_ACCOUNT_ID});
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null;
+
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`,
+                                waitForCollectionCallback: false,
+                                callback: (reportActionsForIOUReport) => {
+                                    Onyx.disconnect(connectionID);
+
+                                    [iouAction] = Object.values(reportActionsForIOUReport ?? {}).filter((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                waitForCollectionCallback: true,
+                                callback: (allTransactions) => {
+                                    Onyx.disconnect(connectionID);
+
+                                    transaction = Object.values(allTransactions ?? {}).find((t) => !isEmptyObject(t)) ?? null;
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(() => {
+                    thread = ReportUtils.buildTransactionThread(iouAction, iouReport) ?? null;
+                    Onyx.set(`report_${thread?.reportID ?? ''}`, thread);
+                    return waitForBatchedUpdates();
+                })
+                .then(() => {
+                    if (transaction) {
+                        IOU.editMoneyRequest(
+                            transaction,
+                            thread.reportID,
+                            {amount: 20000, comment: 'Double the amount!'},
+                            {
+                                id: '123',
+                                role: 'user',
+                                type: 'free',
+                                name: '',
+                                owner: '',
+                                outputCurrency: '',
+                                isPolicyExpenseChatEnabled: false,
+                            },
+                            {},
+                            {},
+                        );
+                    }
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                waitForCollectionCallback: true,
+                                callback: (allTransactions) => {
+                                    Onyx.disconnect(connectionID);
+
+                                    const updatedTransaction = Object.values(allTransactions ?? {}).find((t) => !isEmptyObject(t));
+                                    expect(updatedTransaction?.modifiedAmount).toBe(20000);
+                                    expect(updatedTransaction?.comment).toMatchObject({comment: 'Double the amount!'});
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
+                                waitForCollectionCallback: true,
+                                callback: (allActions) => {
+                                    Onyx.disconnect(connectionID);
+                                    const updatedAction = Object.values(allActions ?? {}).find((reportAction) => !isEmptyObject(reportAction));
+                                    expect(updatedAction?.actionName).toEqual('MODIFIEDEXPENSE');
+                                    expect(updatedAction?.originalMessage).toEqual(
+                                        expect.objectContaining({amount: 20000, newComment: 'Double the amount!', oldAmount: amount, oldComment: comment}),
+                                    );
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    const updatedIOUReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU);
+                                    const updatedChatReport = Object.values(allReports ?? {}).find((report) => report?.reportID === iouReport?.chatReportID);
+                                    expect(updatedIOUReport).toEqual(
+                                        expect.objectContaining({
+                                            total: 20000,
+                                            cachedTotal: '$200.00',
+                                            lastMessageHtml: 'requested $200.00',
+                                            lastMessageText: 'requested $200.00',
+                                        }),
+                                    );
+                                    expect(updatedChatReport).toEqual(
+                                        expect.objectContaining({
+                                            lastMessageHtml: `${CARLOS_EMAIL} owes $200.00`,
+                                            lastMessageText: `${CARLOS_EMAIL} owes $200.00`,
+                                        }),
+                                    );
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(() => {
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                    fetch.resume();
+                });
+        });
+
+        it('resets the IOU request and IOU report when api returns an error', () => {
+            let thread: OptimisticChatReport;
+            let iouReport: OnyxEntry<OnyxTypes.Report>;
+            let iouAction: OnyxEntry<OnyxTypes.ReportAction>;
+            let transaction: OnyxEntry<OnyxTypes.Transaction>;
+
+            IOU.requestMoney({reportID: ''}, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment, {});
+            return waitForBatchedUpdates()
+                .then(() => {
+                    Onyx.set(ONYXKEYS.SESSION, {email: RORY_EMAIL, accountID: RORY_ACCOUNT_ID});
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    [iouReport] = Object.values(allReports ?? {}).filter((report) => report?.type === CONST.REPORT.TYPE.IOU);
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`,
+                                waitForCollectionCallback: false,
+                                callback: (reportActionsForIOUReport) => {
+                                    Onyx.disconnect(connectionID);
+
+                                    [iouAction] = Object.values(reportActionsForIOUReport ?? {}).filter((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                waitForCollectionCallback: true,
+                                callback: (allTransactions) => {
+                                    Onyx.disconnect(connectionID);
+
+                                    transaction = Object.values(allTransactions ?? {}).find((t) => !isEmptyObject(t)) ?? null;
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(() => {
+                    thread = ReportUtils.buildTransactionThread(iouAction, iouReport);
+                    Onyx.set(`report_${thread.reportID}`, thread);
+                    return waitForBatchedUpdates();
+                })
+                .then(() => {
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                    fetch.fail();
+
+                    if (transaction) {
+                        IOU.editMoneyRequest(
+                            transaction,
+                            thread.reportID,
+                            {amount: 20000, comment: 'Double the amount!'},
+                            {
+                                id: '123',
+                                role: 'user',
+                                type: 'free',
+                                name: '',
+                                owner: '',
+                                outputCurrency: '',
+                                isPolicyExpenseChatEnabled: false,
+                            },
+                            {},
+                            {},
+                        );
+                    }
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.TRANSACTION,
+                                waitForCollectionCallback: true,
+                                callback: (allTransactions) => {
+                                    Onyx.disconnect(connectionID);
+
+                                    const updatedTransaction = Object.values(allTransactions ?? {}).find((t) => !isEmptyObject(t));
+                                    expect(updatedTransaction?.modifiedAmount).toBe(undefined);
+                                    expect(updatedTransaction?.amount).toBe(10000);
+                                    expect(updatedTransaction?.comment).toMatchObject({comment});
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
+                                waitForCollectionCallback: true,
+                                callback: (allActions) => {
+                                    Onyx.disconnect(connectionID);
+                                    const updatedAction = Object.values(allActions ?? {}).find((reportAction) => !isEmptyObject(reportAction));
+                                    expect(updatedAction?.actionName).toEqual('MODIFIEDEXPENSE');
+                                    expect(Object.values(updatedAction?.errors ?? {})).toEqual(expect.arrayContaining([['iou.error.genericEditFailureMessage', {isTranslated: false}]]));
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    const updatedIOUReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU);
+                                    const updatedChatReport = Object.values(allReports ?? {}).find((report) => report?.reportID === iouReport?.chatReportID);
+                                    expect(updatedIOUReport).toEqual(
+                                        expect.objectContaining({
+                                            total: 10000,
+                                            cachedTotal: '$100.00',
+                                            lastMessageHtml: `requested $${amount / 100}.00 for ${comment}`,
+                                            lastMessageText: `requested $${amount / 100}.00 for ${comment}`,
+                                        }),
+                                    );
+                                    expect(updatedChatReport).toEqual(
+                                        expect.objectContaining({
+                                            lastMessageHtml: '',
+                                        }),
+                                    );
+                                    resolve();
+                                },
+                            });
+                        }),
+                );
+        });
+    });
+
+    describe('pay expense report via ACH', () => {
+        const amount = 10000;
+        const comment = '💸💸💸💸';
+        const merchant = 'NASDAQ';
+
+        afterEach(() => {
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.resume();
+        });
+
+        it('updates the expense request and expense report when paid while offline', () => {
+            let expenseReport: OnyxEntry<OnyxTypes.Report>;
+            let chatReport: OnyxEntry<OnyxTypes.Report>;
+
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+            Onyx.set(ONYXKEYS.SESSION, {email: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID});
+            return waitForBatchedUpdates()
+                .then(() => {
+                    PolicyActions.createWorkspace(CARLOS_EMAIL, true, "Carlos's Workspace");
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT) ?? null;
+
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(() => {
+                    if (chatReport) {
+                        IOU.requestMoney(chatReport, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment, {});
+                    }
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null;
+
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(() => {
+                    if (chatReport && expenseReport) {
+                        IOU.payMoneyRequest(CONST.IOU.PAYMENT_TYPE.VBBA, chatReport, expenseReport);
+                    }
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport?.reportID}`,
+                                waitForCollectionCallback: true,
+                                callback: (allActions) => {
+                                    Onyx.disconnect(connectionID);
+                                    expect(Object.values(allActions ?? {})).toEqual(
+                                        expect.arrayContaining([
+                                            expect.objectContaining({
+                                                message: expect.arrayContaining([
+                                                    expect.objectContaining({
+                                                        html: `paid $${amount / 100}.00 with Expensify`,
+                                                        text: `paid $${amount / 100}.00 with Expensify`,
+                                                    }),
+                                                ]),
+                                                originalMessage: expect.objectContaining({
+                                                    amount,
+                                                    paymentType: CONST.IOU.PAYMENT_TYPE.VBBA,
+                                                    type: 'pay',
+                                                }),
+                                            }),
+                                        ]),
+                                    );
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    const updatedIOUReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU);
+                                    const updatedChatReport = Object.values(allReports ?? {}).find((report) => report?.reportID === expenseReport?.chatReportID);
+                                    expect(updatedIOUReport).toEqual(
+                                        expect.objectContaining({
+                                            lastMessageHtml: `paid $${amount / 100}.00 with Expensify`,
+                                            lastMessageText: `paid $${amount / 100}.00 with Expensify`,
+                                            statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED,
+                                            stateNum: CONST.REPORT.STATE_NUM.SUBMITTED,
+                                        }),
+                                    );
+                                    expect(updatedChatReport).toEqual(
+                                        expect.objectContaining({
+                                            lastMessageHtml: `paid $${amount / 100}.00 with Expensify`,
+                                            lastMessageText: `paid $${amount / 100}.00 with Expensify`,
+                                        }),
+                                    );
+                                    resolve();
+                                },
+                            });
+                        }),
+                );
+        });
+
+        it('shows an error when paying results in an error', () => {
+            let expenseReport: OnyxEntry<OnyxTypes.Report>;
+            let chatReport: OnyxEntry<OnyxTypes.Report>;
+
+            Onyx.set(ONYXKEYS.SESSION, {email: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID});
+            return waitForBatchedUpdates()
+                .then(() => {
+                    PolicyActions.createWorkspace(CARLOS_EMAIL, true, "Carlos's Workspace");
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT) ?? null;
+
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(() => {
+                    if (chatReport) {
+                        IOU.requestMoney(chatReport, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment, {});
+                    }
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null;
+
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(() => {
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                    fetch.fail();
+                    if (chatReport && expenseReport) {
+                        IOU.payMoneyRequest('ACH', chatReport, expenseReport);
+                    }
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport?.reportID}`,
+                                waitForCollectionCallback: true,
+                                callback: (allActions) => {
+                                    Onyx.disconnect(connectionID);
+                                    const erroredAction = Object.values(allActions ?? {}).find((action) => !isEmptyObject(action?.errors));
+                                    expect(Object.values(erroredAction?.errors ?? {})).toEqual(expect.arrayContaining([['iou.error.other', {isTranslated: false}]]));
+                                    resolve();
+                                },
+                            });
+                        }),
+                );
+        });
+    });
+
+    describe('deleteMoneyRequest', () => {
+        const amount = 10000;
+        const comment = 'Send me money please';
+        let chatReport: OnyxEntry<OnyxTypes.Report>;
+        let iouReport: OnyxEntry<OnyxTypes.Report>;
+        let createIOUAction: OnyxEntry<OnyxTypes.ReportAction>;
+        let transaction: OnyxEntry<OnyxTypes.Transaction>;
+        let thread: OptimisticChatReport;
+        const TEST_USER_ACCOUNT_ID = 1;
+        const TEST_USER_LOGIN = 'test@test.com';
+        let IOU_REPORT_ID: string;
+        let reportActionID;
+        const REPORT_ACTION: OnyxEntry<OnyxTypes.ReportAction> = {
+            actionName: CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT,
+            actorAccountID: TEST_USER_ACCOUNT_ID,
+            automatic: false,
+            avatar: 'https://d2k5nsl2zxldvw.cloudfront.net/images/avatars/avatar_3.png',
+            message: [{type: 'COMMENT', html: 'Testing a comment', text: 'Testing a comment', translationKey: ''}],
+            person: [{type: 'TEXT', style: 'strong', text: 'Test User'}],
+            shouldShow: true,
+            created: DateUtils.getDBTime(),
+            reportActionID: '1',
+            originalMessage: {
+                html: '',
+                whisperedTo: [],
+            },
+        };
+
+        let reportActions: OnyxCollection<OnyxTypes.ReportAction>;
+
+        beforeEach(async () => {
+            // Given mocks are cleared and helpers are set up
+            jest.clearAllMocks();
+            PusherHelper.setup();
+
+            // Given a test user is signed in with Onyx setup and some initial data
+            await TestHelper.signInWithTestUser(TEST_USER_ACCOUNT_ID, TEST_USER_LOGIN);
+            User.subscribeToUserEvents();
+            await waitForBatchedUpdates();
+            await TestHelper.setPersonalDetails(TEST_USER_LOGIN, TEST_USER_ACCOUNT_ID);
+
+            // When an IOU request for money is made
+            IOU.requestMoney({reportID: ''}, amount, CONST.CURRENCY.USD, '', '', TEST_USER_LOGIN, TEST_USER_ACCOUNT_ID, {login: RORY_EMAIL, accountID: RORY_ACCOUNT_ID}, comment, {});
+            await waitForBatchedUpdates();
+
+            // When fetching all reports from Onyx
+            const allReports = await new Promise<OnyxCollection<OnyxTypes.Report>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: ONYXKEYS.COLLECTION.REPORT,
+                    waitForCollectionCallback: true,
+                    callback: (reports) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(reports);
+                    },
+                });
+            });
+
+            // Then we should have exactly 3 reports
+            expect(Object.values(allReports ?? {}).length).toBe(3);
+
+            // Then one of them should be a chat report with relevant properties
+            chatReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.CHAT) ?? null;
+            expect(chatReport).toBeTruthy();
+            expect(chatReport).toHaveProperty('reportID');
+            expect(chatReport).toHaveProperty('iouReportID');
+
+            // Then one of them should be an IOU report with relevant properties
+            iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null;
+            expect(iouReport).toBeTruthy();
+            expect(iouReport).toHaveProperty('reportID');
+            expect(iouReport).toHaveProperty('chatReportID');
+
+            // Then their IDs should reference each other
+            expect(chatReport?.iouReportID).toBe(iouReport?.reportID);
+            expect(iouReport?.chatReportID).toBe(chatReport?.reportID);
+
+            // Storing IOU Report ID for further reference
+            IOU_REPORT_ID = chatReport?.iouReportID ?? '';
+
+            await waitForBatchedUpdates();
+
+            // When fetching all report actions from Onyx
+            const allReportActions = await new Promise<OnyxCollection<OnyxTypes.ReportActions>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
+                    waitForCollectionCallback: true,
+                    callback: (actions) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(actions);
+                    },
+                });
+            });
+
+            // Then we should find an IOU action with specific properties
+            const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
+            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            expect(createIOUAction).toBeTruthy();
+            expect((createIOUAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReport?.reportID);
+
+            // When fetching all transactions from Onyx
+            const allTransactions = await new Promise<OnyxCollection<OnyxTypes.Transaction>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: ONYXKEYS.COLLECTION.TRANSACTION,
+                    waitForCollectionCallback: true,
+                    callback: (transactions) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(transactions);
+                    },
+                });
+            });
+
+            // Then we should find a specific transaction with relevant properties
+            transaction = Object.values(allTransactions ?? {}).find((t) => t) ?? null;
+            expect(transaction).toBeTruthy();
+            expect(transaction?.amount).toBe(amount);
+            expect(transaction?.reportID).toBe(iouReport?.reportID);
+            expect((createIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID).toBe(transaction?.transactionID);
+        });
+
+        afterEach(PusherHelper.teardown);
+
+        it('delete a money request (IOU Action and transaction) successfully', async () => {
+            // Given the fetch operations are paused and a money request is initiated
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+
+            if (transaction && createIOUAction) {
+                // When the money request is deleted
+                IOU.deleteMoneyRequest(transaction?.transactionID, createIOUAction, true);
+            }
+            await waitForBatchedUpdates();
+
+            // Then we check if the IOU report action is removed from the report actions collection
+            let reportActionsForReport = await new Promise<OnyxCollection<OnyxTypes.ReportAction>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`,
+                    waitForCollectionCallback: false,
+                    callback: (actionsForReport) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(actionsForReport);
+                    },
+                });
+            });
+
+            createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            // Then the IOU Action should be truthy for offline support.
+            expect(createIOUAction).toBeTruthy();
+
+            // Then we check if the transaction is removed from the transactions collection
+            const t = await new Promise<OnyxCollection<OnyxTypes.Transaction>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction?.transactionID}`,
+                    waitForCollectionCallback: true,
+                    callback: (transactionResult) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(transactionResult);
+                    },
+                });
+            });
+
+            expect(t).toBeFalsy();
+
+            // Given fetch operations are resumed
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.resume();
+            await waitForBatchedUpdates();
+
+            // Then we recheck the IOU report action from the report actions collection
+            reportActionsForReport = await new Promise<OnyxCollection<OnyxTypes.ReportAction>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`,
+                    waitForCollectionCallback: false,
+                    callback: (actionsForReport) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(actionsForReport);
+                    },
+                });
+            });
+
+            createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            expect(createIOUAction).toBeFalsy();
+
+            // Then we recheck the transaction from the transactions collection
+            const tr = await new Promise<OnyxCollection<OnyxTypes.Transaction>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction?.transactionID}`,
+                    waitForCollectionCallback: true,
+                    callback: (transactionResult) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(transactionResult);
+                    },
+                });
+            });
+
+            expect(tr).toBeFalsy();
+        });
+
+        it('delete the IOU report when there are no visible comments left in the IOU report', async () => {
+            // Given an IOU report and a paused fetch state
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+
+            if (transaction && createIOUAction) {
+                // When the IOU money request is deleted
+                IOU.deleteMoneyRequest(transaction?.transactionID, createIOUAction, true);
+            }
+            await waitForBatchedUpdates();
+
+            let report = await new Promise<OnyxEntry<OnyxTypes.Report>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID}`,
+                    waitForCollectionCallback: false,
+                    callback: (res) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(res);
+                    },
+                });
+            });
+
+            // Then the report should be truthy for offline support
+            expect(report).toBeTruthy();
+
+            // Given the resumed fetch state
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.resume();
+            await waitForBatchedUpdates();
+
+            report = await new Promise<OnyxEntry<OnyxTypes.Report>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID}`,
+                    waitForCollectionCallback: false,
+                    callback: (res) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(res);
+                    },
+                });
+            });
+
+            // Then the report should be falsy so that there is no trace of the money request.
+            expect(report).toBeFalsy();
+        });
+
+        it('does not delete the IOU report when there are visible comments left in the IOU report', async () => {
+            // Given the initial setup is completed
+            await waitForBatchedUpdates();
+
+            Onyx.connect({
+                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${IOU_REPORT_ID}`,
+                callback: (val) => (reportActions = val),
+            });
+            await waitForBatchedUpdates();
+
+            jest.advanceTimersByTime(10);
+
+            // When a comment is added to the IOU report
+            Report.addComment(IOU_REPORT_ID, 'Testing a comment');
+            await waitForBatchedUpdates();
+
+            // Then verify that the comment is correctly added
+            const resultAction = Object.values(reportActions ?? {}).find((ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
+            reportActionID = resultAction?.reportActionID ?? '';
+
+            expect(resultAction?.message).toEqual(REPORT_ACTION.message);
+            expect(resultAction?.person).toEqual(REPORT_ACTION.person);
+            expect(resultAction?.pendingAction).toBeUndefined();
+
+            await waitForBatchedUpdates();
+
+            // Verify there are three actions (created + iou + addcomment) and our optimistic comment has been removed
+            expect(Object.values(reportActions ?? {}).length).toBe(3);
+
+            // Then check the loading state of our action
+            const resultActionAfterUpdate = reportActions?.[reportActionID];
+            expect(resultActionAfterUpdate?.pendingAction).toBeUndefined();
+
+            // When we attempt to delete a money request from the IOU report
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+            if (transaction && createIOUAction) {
+                IOU.deleteMoneyRequest(transaction?.transactionID, createIOUAction, false);
+            }
+            await waitForBatchedUpdates();
+
+            // Then expect that the IOU report still exists
+            let allReports = await new Promise<OnyxCollection<OnyxTypes.Report>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: ONYXKEYS.COLLECTION.REPORT,
+                    waitForCollectionCallback: true,
+                    callback: (reports) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(reports);
+                    },
+                });
+            });
+
+            await waitForBatchedUpdates();
+
+            iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)) ?? null;
+            expect(iouReport).toBeTruthy();
+            expect(iouReport).toHaveProperty('reportID');
+            expect(iouReport).toHaveProperty('chatReportID');
+
+            // Given the resumed fetch state
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.resume();
+
+            allReports = await new Promise<OnyxCollection<OnyxTypes.Report>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: ONYXKEYS.COLLECTION.REPORT,
+                    waitForCollectionCallback: true,
+                    callback: (reports) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(reports);
+                    },
+                });
+            });
+            // Then expect that the IOU report still exists
+            iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)) ?? null;
+            expect(iouReport).toBeTruthy();
+            expect(iouReport).toHaveProperty('reportID');
+            expect(iouReport).toHaveProperty('chatReportID');
+        });
+
+        it('delete the transaction thread if there are no visible comments in the thread', async () => {
+            // Given all promises are resolved
+            await waitForBatchedUpdates();
+            jest.advanceTimersByTime(10);
+
+            // Given a transaction thread
+            thread = ReportUtils.buildTransactionThread(createIOUAction, iouReport);
+
+            expect(thread.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
+
+            Onyx.connect({
+                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
+                callback: (val) => (reportActions = val),
+            });
+
+            await waitForBatchedUpdates();
+
+            jest.advanceTimersByTime(10);
+
+            // Given User logins from the participant accounts
+            const userLogins = PersonalDetailsUtils.getLoginsByAccountIDs(thread?.participantAccountIDs ?? []);
+
+            // When Opening a thread report with the given details
+            Report.openReport(thread.reportID, userLogins, thread, createIOUAction?.reportActionID);
+            await waitForBatchedUpdates();
+
+            // Then The iou action has the transaction report id as a child report ID
+            const allReportActions = await new Promise<OnyxCollection<OnyxTypes.ReportActions>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
+                    waitForCollectionCallback: true,
+                    callback: (actions) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(actions);
+                    },
+                });
+            });
+            const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
+            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            expect(createIOUAction?.childReportID).toBe(thread.reportID);
+
+            await waitForBatchedUpdates();
+
+            // Given Fetch is paused and timers have advanced
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+            jest.advanceTimersByTime(10);
+
+            if (transaction && createIOUAction) {
+                // When Deleting a money request
+                IOU.deleteMoneyRequest(transaction?.transactionID, createIOUAction, false);
+            }
+            await waitForBatchedUpdates();
+
+            // Then The report for the given thread ID does not exist
+            let report = await new Promise<OnyxEntry<OnyxTypes.Report>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
+                    waitForCollectionCallback: false,
+                    callback: (reportData) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(reportData);
+                    },
+                });
+            });
+
+            expect(report).toBeFalsy();
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.resume();
+
+            // Then After resuming fetch, the report for the given thread ID still does not exist
+            report = await new Promise<OnyxEntry<OnyxTypes.Report>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
+                    waitForCollectionCallback: false,
+                    callback: (reportData) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(reportData);
+                    },
+                });
+            });
+
+            expect(report).toBeFalsy();
+        });
+
+        it('delete the transaction thread if there are only changelogs (i.e. MODIFIEDEXPENSE actions) in the thread', async () => {
+            // Given all promises are resolved
+            await waitForBatchedUpdates();
+            jest.advanceTimersByTime(10);
+
+            // Given a transaction thread
+            thread = ReportUtils.buildTransactionThread(createIOUAction, iouReport);
+
+            Onyx.connect({
+                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
+                callback: (val) => (reportActions = val),
+            });
+
+            await waitForBatchedUpdates();
+
+            jest.advanceTimersByTime(10);
+
+            // Given User logins from the participant accounts
+            const userLogins = PersonalDetailsUtils.getLoginsByAccountIDs(thread?.participantAccountIDs ?? []);
+
+            // When Opening a thread report with the given details
+            Report.openReport(thread.reportID, userLogins, thread, createIOUAction?.reportActionID);
+            await waitForBatchedUpdates();
+
+            // Then The iou action has the transaction report id as a child report ID
+            const allReportActions = await new Promise<OnyxCollection<OnyxTypes.ReportActions>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
+                    waitForCollectionCallback: true,
+                    callback: (actions) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(actions);
+                    },
+                });
+            });
+            const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
+            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            expect(createIOUAction?.childReportID).toBe(thread.reportID);
+
+            await waitForBatchedUpdates();
+
+            jest.advanceTimersByTime(10);
+            if (transaction && createIOUAction) {
+                IOU.editMoneyRequest(
+                    transaction,
+                    thread.reportID,
+                    {amount: 20000, comment: 'Double the amount!'},
+                    {
+                        id: '123',
+                        role: 'user',
+                        type: 'free',
+                        name: '',
+                        owner: '',
+                        outputCurrency: '',
+                        isPolicyExpenseChatEnabled: false,
+                    },
+                    {},
+                    {},
+                );
+            }
+            await waitForBatchedUpdates();
+
+            // Verify there are two actions (created + changelog)
+            expect(Object.values(reportActions ?? {}).length).toBe(2);
+
+            // Fetch the updated IOU Action from Onyx
+            await new Promise<void>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`,
+                    waitForCollectionCallback: false,
+                    callback: (reportActionsForReport) => {
+                        Onyx.disconnect(connectionID);
+                        createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                        resolve();
+                    },
+                });
+            });
+
+            if (transaction && createIOUAction) {
+                // When Deleting a money request
+                IOU.deleteMoneyRequest(transaction?.transactionID, createIOUAction, false);
+            }
+            await waitForBatchedUpdates();
+
+            // Then, the report for the given thread ID does not exist
+            const report = await new Promise<OnyxEntry<OnyxTypes.Report>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
+                    waitForCollectionCallback: false,
+                    callback: (reportData) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(reportData);
+                    },
+                });
+            });
+
+            expect(report).toBeFalsy();
+        });
+
+        it('does not delete the transaction thread if there are visible comments in the thread', async () => {
+            // Given initial environment is set up
+            await waitForBatchedUpdates();
+
+            // Given a transaction thread
+            thread = ReportUtils.buildTransactionThread(createIOUAction, iouReport);
+
+            expect(thread.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
+
+            const userLogins = PersonalDetailsUtils.getLoginsByAccountIDs(thread?.participantAccountIDs ?? []);
+            jest.advanceTimersByTime(10);
+            Report.openReport(thread.reportID, userLogins, thread, createIOUAction?.reportActionID);
+            await waitForBatchedUpdates();
+
+            Onyx.connect({
+                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
+                callback: (val) => (reportActions = val),
+            });
+            await waitForBatchedUpdates();
+
+            await new Promise<void>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
+                    waitForCollectionCallback: true,
+                    callback: (report) => {
+                        Onyx.disconnect(connectionID);
+                        expect(report).toBeTruthy();
+                        resolve();
+                    },
+                });
+            });
+
+            jest.advanceTimersByTime(10);
+
+            // When a comment is added
+            Report.addComment(thread.reportID, 'Testing a comment');
+            await waitForBatchedUpdates();
+
+            // Then comment details should match the expected report action
+            const resultAction = Object.values(reportActions ?? {}).find((ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
+            reportActionID = resultAction?.reportActionID ?? '';
+            expect(resultAction?.message).toEqual(REPORT_ACTION.message);
+            expect(resultAction?.person).toEqual(REPORT_ACTION.person);
+
+            await waitForBatchedUpdates();
+
+            // Then the report should have 2 actions
+            expect(Object.values(reportActions ?? {}).length).toBe(2);
+            const resultActionAfter = reportActions?.[reportActionID];
+            expect(resultActionAfter?.pendingAction).toBeUndefined();
+
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+
+            if (transaction && createIOUAction) {
+                // When deleting money request
+                IOU.deleteMoneyRequest(transaction?.transactionID, createIOUAction, false);
+            }
+            await waitForBatchedUpdates();
+
+            // Then the transaction thread report should still exist
+            await new Promise<void>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
+                    waitForCollectionCallback: true,
+                    callback: (report) => {
+                        Onyx.disconnect(connectionID);
+                        expect(report).toBeTruthy();
+                        resolve();
+                    },
+                });
+            });
+
+            // When fetch resumes
+            // Then the transaction thread report should still exist
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.resume();
+            await new Promise<void>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
+                    waitForCollectionCallback: true,
+                    callback: (report) => {
+                        Onyx.disconnect(connectionID);
+                        expect(report).toBeTruthy();
+                        resolve();
+                    },
+                });
+            });
+        });
+
+        it('update the moneyRequestPreview to show [Deleted request] when appropriate', async () => {
+            await waitForBatchedUpdates();
+
+            // Given a thread report
+
+            jest.advanceTimersByTime(10);
+            thread = ReportUtils.buildTransactionThread(createIOUAction, iouReport);
+
+            expect(thread.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
+
+            Onyx.connect({
+                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
+                callback: (val) => (reportActions = val),
+            });
+            await waitForBatchedUpdates();
+
+            jest.advanceTimersByTime(10);
+            const userLogins = PersonalDetailsUtils.getLoginsByAccountIDs(thread?.participantAccountIDs ?? []);
+            Report.openReport(thread.reportID, userLogins, thread, createIOUAction?.reportActionID);
+
+            await waitForBatchedUpdates();
+
+            const allReportActions = await new Promise<OnyxCollection<OnyxTypes.ReportActions>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
+                    waitForCollectionCallback: true,
+                    callback: (actions) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(actions);
+                    },
+                });
+            });
+
+            const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
+            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            expect(createIOUAction?.childReportID).toBe(thread.reportID);
+
+            await waitForBatchedUpdates();
+
+            // Given an added comment to the thread report
+
+            jest.advanceTimersByTime(10);
+
+            Report.addComment(thread.reportID, 'Testing a comment');
+            await waitForBatchedUpdates();
+
+            // Fetch the updated IOU Action from Onyx due to addition of comment to transaction thread.
+            // This needs to be fetched as `deleteMoneyRequest` depends on `childVisibleActionCount` in `createIOUAction`.
+            await new Promise<void>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`,
+                    waitForCollectionCallback: false,
+                    callback: (reportActionsForReport) => {
+                        Onyx.disconnect(connectionID);
+                        createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                        resolve();
+                    },
+                });
+            });
+
+            let resultAction = Object.values(reportActions ?? {}).find((ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
+            reportActionID = resultAction?.reportActionID ?? '';
+
+            expect(resultAction?.message).toEqual(REPORT_ACTION.message);
+            expect(resultAction?.person).toEqual(REPORT_ACTION.person);
+            expect(resultAction?.pendingAction).toBeUndefined();
+
+            await waitForBatchedUpdates();
+
+            // Verify there are three actions (created + addcomment) and our optimistic comment has been removed
+            expect(Object.values(reportActions ?? {}).length).toBe(2);
+
+            let resultActionAfterUpdate = reportActions?.[reportActionID];
+
+            // Verify that our action is no longer in the loading state
+            expect(resultActionAfterUpdate?.pendingAction).toBeUndefined();
+
+            await waitForBatchedUpdates();
+
+            // Given an added comment to the IOU report
+
+            Onyx.connect({
+                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${IOU_REPORT_ID}`,
+                callback: (val) => (reportActions = val),
+            });
+            await waitForBatchedUpdates();
+
+            jest.advanceTimersByTime(10);
+
+            Report.addComment(IOU_REPORT_ID, 'Testing a comment');
+            await waitForBatchedUpdates();
+
+            resultAction = Object.values(reportActions ?? {}).find((ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
+            reportActionID = resultAction?.reportActionID ?? '';
+
+            expect(resultAction?.message).toEqual(REPORT_ACTION.message);
+            expect(resultAction?.person).toEqual(REPORT_ACTION.person);
+            expect(resultAction?.pendingAction).toBeUndefined();
+
+            await waitForBatchedUpdates();
+
+            // Verify there are three actions (created + iou + addcomment) and our optimistic comment has been removed
+            expect(Object.values(reportActions ?? {}).length).toBe(3);
+
+            resultActionAfterUpdate = reportActions?.[reportActionID];
+
+            // Verify that our action is no longer in the loading state
+            expect(resultActionAfterUpdate?.pendingAction).toBeUndefined();
+
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+            if (transaction && createIOUAction) {
+                // When we delete the money request
+                IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, false);
+            }
+            await waitForBatchedUpdates();
+
+            // Then we expect the moneyRequestPreview to show [Deleted request]
+
+            await new Promise<void>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`,
+                    waitForCollectionCallback: false,
+                    callback: (reportActionsForReport) => {
+                        Onyx.disconnect(connectionID);
+                        createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                        expect(createIOUAction?.message?.[0].isDeletedParentAction).toBeTruthy();
+                        resolve();
+                    },
+                });
+            });
+
+            // When we resume fetch
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.resume();
+
+            // Then we expect the moneyRequestPreview to show [Deleted request]
+
+            await new Promise<void>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`,
+                    waitForCollectionCallback: false,
+                    callback: (reportActionsForReport) => {
+                        Onyx.disconnect(connectionID);
+                        createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                        expect(createIOUAction?.message?.[0].isDeletedParentAction).toBeTruthy();
+                        resolve();
+                    },
+                });
+            });
+        });
+
+        it('update IOU report and reportPreview with new totals and messages if the IOU report is not deleted', async () => {
+            await waitForBatchedUpdates();
+            Onyx.connect({
+                key: `${ONYXKEYS.COLLECTION.REPORT}${iouReport?.reportID}`,
+                callback: (val) => (iouReport = val),
+            });
+            await waitForBatchedUpdates();
+
+            // Given a second money request in addition to the first one
+
+            jest.advanceTimersByTime(10);
+            const amount2 = 20000;
+            const comment2 = 'Send me money please 2';
+            if (chatReport) {
+                IOU.requestMoney(chatReport, amount2, CONST.CURRENCY.USD, '', '', TEST_USER_LOGIN, TEST_USER_ACCOUNT_ID, {login: RORY_EMAIL, accountID: RORY_ACCOUNT_ID}, comment2, {});
+            }
+
+            await waitForBatchedUpdates();
+
+            // Then we expect the IOU report and reportPreview to update with new totals
+
+            expect(iouReport).toBeTruthy();
+            expect(iouReport).toHaveProperty('reportID');
+            expect(iouReport).toHaveProperty('chatReportID');
+            expect(iouReport?.total).toBe(30000);
+
+            const ioupreview = ReportActionsUtils.getReportPreviewAction(chatReport?.reportID ?? '', iouReport?.reportID ?? '');
+            expect(ioupreview).toBeTruthy();
+            expect(ioupreview?.message?.[0].text).toBe('rory@expensifail.com owes $300.00');
+
+            // When we delete the first money request
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+            jest.advanceTimersByTime(10);
+            if (transaction && createIOUAction) {
+                IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, false);
+            }
+            await waitForBatchedUpdates();
+
+            // Then we expect the IOU report and reportPreview to update with new totals
+
+            expect(iouReport).toBeTruthy();
+            expect(iouReport).toHaveProperty('reportID');
+            expect(iouReport).toHaveProperty('chatReportID');
+            expect(iouReport?.total).toBe(20000);
+
+            // When we resume
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.resume();
+
+            // Then we expect the IOU report and reportPreview to update with new totals
+            expect(iouReport).toBeTruthy();
+            expect(iouReport).toHaveProperty('reportID');
+            expect(iouReport).toHaveProperty('chatReportID');
+            expect(iouReport?.total).toBe(20000);
+        });
+
+        it('navigate the user correctly to the iou Report when appropriate', async () => {
+            await waitForBatchedUpdates();
+
+            Onyx.connect({
+                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${IOU_REPORT_ID}`,
+                callback: (val) => (reportActions = val),
+            });
+            await waitForBatchedUpdates();
+
+            // Given an added comment to the iou report
+
+            jest.advanceTimersByTime(10);
+
+            Report.addComment(IOU_REPORT_ID, 'Testing a comment');
+            await waitForBatchedUpdates();
+
+            const resultAction = Object.values(reportActions ?? {}).find((ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
+            reportActionID = resultAction?.reportActionID;
+
+            expect(resultAction?.message).toEqual(REPORT_ACTION.message);
+            expect(resultAction?.person).toEqual(REPORT_ACTION.person);
+
+            await waitForBatchedUpdates();
+
+            // Verify there are three actions (created + iou + addcomment) and our optimistic comment has been removed
+            expect(Object.values(reportActions ?? {}).length).toBe(3);
+
+            await waitForBatchedUpdates();
+
+            // Given a thread report
+
+            jest.advanceTimersByTime(10);
+            thread = ReportUtils.buildTransactionThread(createIOUAction, iouReport);
+
+            expect(thread.notificationPreference).toBe(CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
+
+            Onyx.connect({
+                key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
+                callback: (val) => (reportActions = val),
+            });
+            await waitForBatchedUpdates();
+
+            jest.advanceTimersByTime(10);
+            const userLogins = PersonalDetailsUtils.getLoginsByAccountIDs(thread?.participantAccountIDs ?? []);
+            Report.openReport(thread.reportID, userLogins, thread, createIOUAction?.reportActionID);
+            await waitForBatchedUpdates();
+
+            const allReportActions = await new Promise<OnyxCollection<OnyxTypes.ReportActions>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
+                    waitForCollectionCallback: true,
+                    callback: (actions) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(actions);
+                    },
+                });
+            });
+
+            const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
+            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            expect(createIOUAction?.childReportID).toBe(thread.reportID);
+
+            await waitForBatchedUpdates();
+
+            // When we delete the money request in SingleTransactionView and we should not delete the IOU report
+
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.pause();
+
+            if (transaction && createIOUAction) {
+                IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, true);
+            }
+            await waitForBatchedUpdates();
+
+            let allReports = await new Promise<OnyxCollection<OnyxTypes.Report>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: ONYXKEYS.COLLECTION.REPORT,
+                    waitForCollectionCallback: true,
+                    callback: (reports) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(reports);
+                    },
+                });
+            });
+
+            await waitForBatchedUpdates();
+
+            iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)) ?? null;
+            expect(iouReport).toBeTruthy();
+            expect(iouReport).toHaveProperty('reportID');
+            expect(iouReport).toHaveProperty('chatReportID');
+
+            // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+            fetch.resume();
+
+            allReports = await new Promise<OnyxCollection<OnyxTypes.Report>>((resolve) => {
+                const connectionID = Onyx.connect({
+                    key: ONYXKEYS.COLLECTION.REPORT,
+                    waitForCollectionCallback: true,
+                    callback: (reports) => {
+                        Onyx.disconnect(connectionID);
+                        resolve(reports);
+                    },
+                });
+            });
+
+            iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)) ?? null;
+            expect(iouReport).toBeTruthy();
+            expect(iouReport).toHaveProperty('reportID');
+            expect(iouReport).toHaveProperty('chatReportID');
+
+            // Then we expect to navigate to the iou report
+
+            expect(Navigation.goBack).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(IOU_REPORT_ID));
+        });
+
+        it('navigate the user correctly to the chat Report when appropriate', () => {
+            if (transaction && createIOUAction) {
+                // When we delete the money request and we should delete the IOU report
+                IOU.deleteMoneyRequest(transaction.transactionID, createIOUAction, false);
+            }
+            // Then we expect to navigate to the chat report
+            expect(Navigation.goBack).toHaveBeenCalledWith(ROUTES.REPORT_WITH_ID.getRoute(chatReport?.reportID ?? ''));
+        });
+    });
+
+    describe('submitReport', () => {
+        it('correctly submits a report', () => {
+            const amount = 10000;
+            const comment = '💸💸💸💸';
+            const merchant = 'NASDAQ';
+            let expenseReport: OnyxEntry<OnyxTypes.Report>;
+            let chatReport: OnyxEntry<OnyxTypes.Report>;
+            return waitForBatchedUpdates()
+                .then(() => {
+                    PolicyActions.createWorkspace(CARLOS_EMAIL, true, "Carlos's Workspace");
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT) ?? null;
+
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(() => {
+                    if (chatReport) {
+                        IOU.requestMoney(
+                            chatReport,
+                            amount,
+                            CONST.CURRENCY.USD,
+                            '',
+                            merchant,
+                            RORY_EMAIL,
+                            RORY_ACCOUNT_ID,
+                            {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID, isPolicyExpenseChat: true, reportID: chatReport.reportID},
+                            comment,
+                            {},
+                        );
+                    }
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null;
+                                    Onyx.merge(`report_${expenseReport?.reportID}`, {
+                                        statusNum: 0,
+                                        stateNum: 0,
+                                    });
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null;
+
+                                    // Verify report is a draft
+                                    expect(expenseReport?.stateNum).toBe(0);
+                                    expect(expenseReport?.statusNum).toBe(0);
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(() => {
+                    if (expenseReport) {
+                        IOU.submitReport(expenseReport);
+                    }
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null;
+
+                                    // Report was submitted correctly
+                                    expect(expenseReport?.stateNum).toBe(1);
+                                    expect(expenseReport?.statusNum).toBe(1);
+                                    resolve();
+                                },
+                            });
+                        }),
+                );
+        });
+        it('correctly implements error handling', () => {
+            const amount = 10000;
+            const comment = '💸💸💸💸';
+            const merchant = 'NASDAQ';
+            let expenseReport: OnyxEntry<OnyxTypes.Report>;
+            let chatReport: OnyxEntry<OnyxTypes.Report>;
+            return waitForBatchedUpdates()
+                .then(() => {
+                    PolicyActions.createWorkspace(CARLOS_EMAIL, true, "Carlos's Workspace");
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT) ?? null;
+
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(() => {
+                    if (chatReport) {
+                        IOU.requestMoney(
+                            chatReport,
+                            amount,
+                            CONST.CURRENCY.USD,
+                            '',
+                            merchant,
+                            RORY_EMAIL,
+                            RORY_ACCOUNT_ID,
+                            {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID, isPolicyExpenseChat: true, reportID: chatReport.reportID},
+                            comment,
+                            {},
+                        );
+                    }
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null;
+                                    Onyx.merge(`report_${expenseReport?.reportID}`, {
+                                        statusNum: 0,
+                                        stateNum: 0,
+                                    });
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null;
+
+                                    // Verify report is a draft
+                                    expect(expenseReport?.stateNum).toBe(0);
+                                    expect(expenseReport?.statusNum).toBe(0);
+                                    resolve();
+                                },
+                            });
+                        }),
+                )
+                .then(() => {
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
+                    fetch.fail();
+                    if (expenseReport) {
+                        IOU.submitReport(expenseReport);
+                    }
+                    return waitForBatchedUpdates();
+                })
+                .then(
+                    () =>
+                        new Promise<void>((resolve) => {
+                            const connectionID = Onyx.connect({
+                                key: ONYXKEYS.COLLECTION.REPORT,
+                                waitForCollectionCallback: true,
+                                callback: (allReports) => {
+                                    Onyx.disconnect(connectionID);
+                                    expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null;
+
+                                    // Report was submitted with some fail
+                                    expect(expenseReport?.stateNum).toBe(0);
+                                    expect(expenseReport?.statusNum).toBe(0);
+                                    resolve();
+                                },
+                            });
+                        }),
+                );
+        });
+    });
+});

From b6b356921a1e1f193f1460b985c6b6a00f66b60b Mon Sep 17 00:00:00 2001
From: Yauheni Pasiukevich <pasyukevich@live.com>
Date: Tue, 12 Mar 2024 12:34:12 +0100
Subject: [PATCH 2/5] fix prettier, typo

---
 tests/actions/IOUTest.ts | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts
index 47d7a616299b..9901117e9c53 100644
--- a/tests/actions/IOUTest.ts
+++ b/tests/actions/IOUTest.ts
@@ -1,11 +1,11 @@
 import isEqual from 'lodash/isEqual';
 import Onyx from 'react-native-onyx';
-import type { OnyxCollection, OnyxEntry } from 'react-native-onyx';
-import type { OptimisticChatReport } from '@libs/ReportUtils';
+import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
+import type {OptimisticChatReport} from '@libs/ReportUtils';
 import type * as OnyxTypes from '@src/types/onyx';
-import type { IOUMessage } from '@src/types/onyx/OriginalMessage';
-import { toCollectionDataSet } from '@src/types/utils/CollectionDataSet';
-import { isEmptyObject } from '@src/types/utils/EmptyObject';
+import type {IOUMessage} from '@src/types/onyx/OriginalMessage';
+import {toCollectionDataSet} from '@src/types/utils/CollectionDataSet';
+import {isEmptyObject} from '@src/types/utils/EmptyObject';
 import CONST from '../../src/CONST';
 import * as IOU from '../../src/libs/actions/IOU';
 import OnyxUpdateManager from '../../src/libs/actions/OnyxUpdateManager';
@@ -26,7 +26,6 @@ import * as TestHelper from '../utils/TestHelper';
 import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
 import waitForNetworkPromises from '../utils/waitForNetworkPromises';
 
-
 jest.mock('../../src/libs/Navigation/Navigation', () => ({
     navigate: jest.fn(),
     dismissModal: jest.fn(),
@@ -998,10 +997,12 @@ describe('actions/IOU', () => {
 
             const julesActionsCollectionDataSet = toCollectionDataSet(
                 `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}`,
-            [{
-                    [julesCreatedAction.reportActionID]: julesCreatedAction,
-                    [julesExistingIOUAction.reportActionID]: julesExistingIOUAction,
-                }],
+                [
+                    {
+                        [julesCreatedAction.reportActionID]: julesCreatedAction,
+                        [julesExistingIOUAction.reportActionID]: julesExistingIOUAction,
+                    },
+                ],
                 (item) => item[julesCreatedAction.reportActionID].reportID ?? '',
             );
 
@@ -1012,7 +1013,7 @@ describe('actions/IOU', () => {
                         [julesChatCreatedAction.reportActionID]: julesChatCreatedAction,
                     },
                 ],
-                (item) => item[julesCreatedAction.reportActionID].reportID ?? '',
+                (item) => item[julesChatCreatedAction.reportActionID].reportID ?? '',
             );
 
             return (

From 7f41492a27afbd56c4188c5e581ae21aee813885 Mon Sep 17 00:00:00 2001
From: Yauheni Pasiukevich <pasyukevich@live.com>
Date: Tue, 12 Mar 2024 14:17:00 +0100
Subject: [PATCH 3/5] fix test falling

---
 tests/actions/IOUTest.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts
index 9901117e9c53..6776d970f177 100644
--- a/tests/actions/IOUTest.ts
+++ b/tests/actions/IOUTest.ts
@@ -721,11 +721,11 @@ describe('actions/IOU', () => {
                                 });
                             }),
                     )
-                    .then(() => {
+                    .then((): Promise<unknown> => {
                         // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
                         fetch.fail();
                         // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
-                        fetch.resume();
+                        return fetch.resume() as Promise<unknown>;
                     })
                     .then(
                         () =>

From 49d5c84aeabb7010414215e7d6a6fbaa8bf66e94 Mon Sep 17 00:00:00 2001
From: Yauheni Pasiukevich <pasyukevich@live.com>
Date: Mon, 18 Mar 2024 18:05:22 +0100
Subject: [PATCH 4/5] address comments

---
 tests/actions/IOUTest.ts | 215 ++++++++++++++++++++++-----------------
 1 file changed, 123 insertions(+), 92 deletions(-)

diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts
index 6776d970f177..b869d1a0c66b 100644
--- a/tests/actions/IOUTest.ts
+++ b/tests/actions/IOUTest.ts
@@ -2,31 +2,32 @@ import isEqual from 'lodash/isEqual';
 import Onyx from 'react-native-onyx';
 import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
 import type {OptimisticChatReport} from '@libs/ReportUtils';
+import CONST from '@src/CONST';
+import * as IOU from '@src/libs/actions/IOU';
+import OnyxUpdateManager from '@src/libs/actions/OnyxUpdateManager';
+import * as PolicyActions from '@src/libs/actions/Policy';
+import * as Report from '@src/libs/actions/Report';
+import * as ReportActions from '@src/libs/actions/ReportActions';
+import * as User from '@src/libs/actions/User';
+import DateUtils from '@src/libs/DateUtils';
+import Navigation from '@src/libs/Navigation/Navigation';
+import * as NumberUtils from '@src/libs/NumberUtils';
+import * as PersonalDetailsUtils from '@src/libs/PersonalDetailsUtils';
+import * as ReportActionsUtils from '@src/libs/ReportActionsUtils';
+import * as ReportUtils from '@src/libs/ReportUtils';
+import ONYXKEYS from '@src/ONYXKEYS';
+import ROUTES from '@src/ROUTES';
 import type * as OnyxTypes from '@src/types/onyx';
-import type {IOUMessage} from '@src/types/onyx/OriginalMessage';
+import type {IOUMessage, OriginalMessageIOU} from '@src/types/onyx/OriginalMessage';
+import type {ReportActionBase} from '@src/types/onyx/ReportAction';
 import {toCollectionDataSet} from '@src/types/utils/CollectionDataSet';
 import {isEmptyObject} from '@src/types/utils/EmptyObject';
-import CONST from '../../src/CONST';
-import * as IOU from '../../src/libs/actions/IOU';
-import OnyxUpdateManager from '../../src/libs/actions/OnyxUpdateManager';
-import * as PolicyActions from '../../src/libs/actions/Policy';
-import * as Report from '../../src/libs/actions/Report';
-import * as ReportActions from '../../src/libs/actions/ReportActions';
-import * as User from '../../src/libs/actions/User';
-import DateUtils from '../../src/libs/DateUtils';
-import Navigation from '../../src/libs/Navigation/Navigation';
-import * as NumberUtils from '../../src/libs/NumberUtils';
-import * as PersonalDetailsUtils from '../../src/libs/PersonalDetailsUtils';
-import * as ReportActionsUtils from '../../src/libs/ReportActionsUtils';
-import * as ReportUtils from '../../src/libs/ReportUtils';
-import ONYXKEYS from '../../src/ONYXKEYS';
-import ROUTES from '../../src/ROUTES';
 import PusherHelper from '../utils/PusherHelper';
 import * as TestHelper from '../utils/TestHelper';
 import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
 import waitForNetworkPromises from '../utils/waitForNetworkPromises';
 
-jest.mock('../../src/libs/Navigation/Navigation', () => ({
+jest.mock('@src/libs/Navigation/Navigation', () => ({
     navigate: jest.fn(),
     dismissModal: jest.fn(),
     dismissModalWithReport: jest.fn(),
@@ -66,7 +67,7 @@ describe('actions/IOU', () => {
             let iouAction: OnyxEntry<OnyxTypes.ReportAction>;
             let transactionID: string | undefined;
             let transactionThread: OnyxEntry<OnyxTypes.Report>;
-            let transactionThreadCreatedAction;
+            let transactionThreadCreatedAction: OnyxEntry<OnyxTypes.ReportAction>;
             // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
             fetch.pause();
             IOU.requestMoney({reportID: ''}, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment, {});
@@ -115,10 +116,10 @@ describe('actions/IOU', () => {
                                         // The IOU report should have a CREATED action and IOU action
                                         expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(2);
                                         const createdActions = Object.values(reportActionsForIOUReport ?? {}).filter(
-                                            (reportAction) => (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.CREATED,
+                                            (reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED,
                                         );
                                         const iouActions = Object.values(reportActionsForIOUReport ?? {}).filter(
-                                            (reportAction) => (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.IOU,
+                                            (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU,
                                         );
                                         expect(Object.values(createdActions).length).toBe(1);
                                         expect(Object.values(iouActions).length).toBe(1);
@@ -129,16 +130,16 @@ describe('actions/IOU', () => {
                                         expect(Date.parse(createdAction?.created ?? '')).toBeLessThan(Date.parse(iouAction?.created ?? ''));
 
                                         // The IOUReportID should be correct
-                                        expect((iouAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReportID);
+                                        expect(iouAction.originalMessage.IOUReportID).toBe(iouReportID);
 
                                         // The comment should be included in the IOU action
-                                        expect((iouAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
+                                        expect(iouAction.originalMessage.comment).toBe(comment);
 
                                         // The amount in the IOU action should be correct
-                                        expect((iouAction?.originalMessage as IOUMessage).amount).toBe(amount);
+                                        expect(iouAction.originalMessage.amount).toBe(amount);
 
                                         // The IOU type should be correct
-                                        expect((iouAction?.originalMessage as IOUMessage).type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+                                        expect(iouAction.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
 
                                         // Both actions should be pending
                                         expect(createdAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
@@ -154,7 +155,7 @@ describe('actions/IOU', () => {
                             new Promise<void>((resolve) => {
                                 const connectionID = Onyx.connect({
                                     key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThread?.reportID}`,
-                                    waitForCollectionCallback: true,
+                                    waitForCollectionCallback: false,
                                     callback: (reportActionsForTransactionThread) => {
                                         Onyx.disconnect(connectionID);
 
@@ -215,7 +216,7 @@ describe('actions/IOU', () => {
                             new Promise<void>((resolve) => {
                                 const connectionID = Onyx.connect({
                                     key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
-                                    waitForCollectionCallback: true,
+                                    waitForCollectionCallback: false,
                                     callback: (reportActionsForIOUReport) => {
                                         Onyx.disconnect(connectionID);
                                         expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(2);
@@ -230,7 +231,7 @@ describe('actions/IOU', () => {
                             new Promise<void>((resolve) => {
                                 const connectionID = Onyx.connect({
                                     key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
-                                    waitForCollectionCallback: true,
+                                    waitForCollectionCallback: false,
                                     callback: (transaction) => {
                                         Onyx.disconnect(connectionID);
                                         expect(transaction?.pendingAction).toBeFalsy();
@@ -309,22 +310,25 @@ describe('actions/IOU', () => {
 
                                         iouCreatedAction =
                                             Object.values(allIOUReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null;
-                                        iouAction = Object.values(allIOUReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                                        iouAction =
+                                            Object.values(allIOUReportActions ?? {}).find(
+                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU,
+                                            ) ?? null;
 
                                         // The CREATED action should not be created after the IOU action
                                         expect(Date.parse(iouCreatedAction?.created ?? '')).toBeLessThan(Date.parse(iouAction?.created ?? ''));
 
                                         // The IOUReportID should be correct
-                                        expect((iouAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReportID);
+                                        expect(iouAction?.originalMessage?.IOUReportID).toBe(iouReportID);
 
                                         // The comment should be included in the IOU action
-                                        expect((iouAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
+                                        expect(iouAction?.originalMessage?.comment).toBe(comment);
 
                                         // The amount in the IOU action should be correct
-                                        expect((iouAction?.originalMessage as IOUMessage)?.amount).toBe(amount);
+                                        expect(iouAction?.originalMessage?.amount).toBe(amount);
 
                                         // The IOU action type should be correct
-                                        expect((iouAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+                                        expect(iouAction?.originalMessage?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
 
                                         // The IOU action should be pending
                                         expect(iouAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
@@ -441,7 +445,7 @@ describe('actions/IOU', () => {
                 currency: CONST.CURRENCY.USD,
                 total: existingTransaction.amount,
             };
-            const iouAction = {
+            const iouAction: OnyxEntry<OnyxTypes.ReportAction> = {
                 reportActionID: NumberUtils.rand64(),
                 actionName: CONST.REPORT.ACTIONS.TYPE.IOU,
                 actorAccountID: RORY_ACCOUNT_ID,
@@ -512,20 +516,21 @@ describe('actions/IOU', () => {
                                         expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(3);
                                         newIOUAction =
                                             Object.values(reportActionsForIOUReport ?? {}).find(
-                                                (reportAction) => reportAction?.reportActionID !== createdAction.reportActionID && reportAction?.reportActionID !== iouAction?.reportActionID,
+                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU =>
+                                                    reportAction?.reportActionID !== createdAction.reportActionID && reportAction?.reportActionID !== iouAction?.reportActionID,
                                             ) ?? null;
 
                                         // The IOUReportID should be correct
-                                        expect((iouAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReportID);
+                                        expect(iouAction.originalMessage.IOUReportID).toBe(iouReportID);
 
                                         // The comment should be included in the IOU action
-                                        expect((newIOUAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
+                                        expect(newIOUAction?.originalMessage.comment).toBe(comment);
 
                                         // The amount in the IOU action should be correct
-                                        expect((newIOUAction?.originalMessage as IOUMessage)?.amount).toBe(amount);
+                                        expect(newIOUAction?.originalMessage.amount).toBe(amount);
 
                                         // The type of the IOU action should be correct
-                                        expect((newIOUAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+                                        expect(newIOUAction?.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
 
                                         // The IOU action should be pending
                                         expect(newIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
@@ -571,7 +576,7 @@ describe('actions/IOU', () => {
                             new Promise<void>((resolve) => {
                                 const connectionID = Onyx.connect({
                                     key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`,
-                                    waitForCollectionCallback: true,
+                                    waitForCollectionCallback: false,
                                     callback: (reportActionsForIOUReport) => {
                                         Onyx.disconnect(connectionID);
                                         expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(3);
@@ -662,7 +667,8 @@ describe('actions/IOU', () => {
                                             ) ?? null;
                                         const iouActions =
                                             Object.values(reportActionsForIOUReport ?? {}).filter(
-                                                (reportAction) => (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.IOU,
+                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU =>
+                                                    (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.IOU,
                                             ) ?? null;
                                         expect(Object.values(createdActions).length).toBe(1);
                                         expect(Object.values(iouActions).length).toBe(1);
@@ -673,16 +679,16 @@ describe('actions/IOU', () => {
                                         expect(Date.parse(createdAction?.created ?? '')).toBeLessThan(Date.parse(iouAction?.created ?? {}));
 
                                         // The IOUReportID should be correct
-                                        expect((iouAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReportID);
+                                        expect(iouAction.originalMessage.IOUReportID).toBe(iouReportID);
 
                                         // The comment should be included in the IOU action
-                                        expect((iouAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
+                                        expect(iouAction.originalMessage.comment).toBe(comment);
 
                                         // The amount in the IOU action should be correct
-                                        expect((iouAction?.originalMessage as IOUMessage)?.amount).toBe(amount);
+                                        expect(iouAction.originalMessage.amount).toBe(amount);
 
                                         // The type should be correct
-                                        expect((iouAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+                                        expect(iouAction.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
 
                                         // Both actions should be pending
                                         expect(createdAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
@@ -747,7 +753,7 @@ describe('actions/IOU', () => {
                         () =>
                             new Promise<void>((resolve) => {
                                 const connectionID = Onyx.connect({
-                                    key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}`,
+                                    key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
                                     waitForCollectionCallback: true,
                                     callback: (reportActionsForTransactionThread) => {
                                         Onyx.disconnect(connectionID);
@@ -812,7 +818,7 @@ describe('actions/IOU', () => {
                             new Promise<void>((resolve) => {
                                 const connectionID = Onyx.connect({
                                     key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
-                                    waitForCollectionCallback: true,
+                                    waitForCollectionCallback: false,
                                     callback: (transaction) => {
                                         Onyx.disconnect(connectionID);
                                         expect(transaction).toBeFalsy();
@@ -934,9 +940,13 @@ describe('actions/IOU', () => {
             const julesExistingTransaction: OnyxEntry<OnyxTypes.Transaction> = {
                 transactionID: NumberUtils.rand64(),
                 amount: 1000,
-                // @ts-expect-error Test data
-                comment: 'This is an existing transaction',
+                comment: {
+                    comment: 'This is an existing transaction',
+                },
                 created: DateUtils.getDBTime(),
+                currency: '',
+                merchant: '',
+                reportID: '',
             };
             let julesIOUReport: OnyxEntry<OnyxTypes.Report> = {
                 reportID: julesIOUReportID,
@@ -1145,55 +1155,70 @@ describe('actions/IOU', () => {
                                         // Carlos DM should have two reportActions – the existing CREATED action and a pending IOU action
                                         expect(Object.values(carlosReportActions ?? {}).length).toBe(2);
                                         carlosIOUCreatedAction =
-                                            Object.values(carlosReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null;
-                                        carlosIOUAction = Object.values(carlosReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                                            Object.values(carlosReportActions ?? {}).find(
+                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED,
+                                            ) ?? null;
+                                        carlosIOUAction =
+                                            Object.values(carlosReportActions ?? {}).find(
+                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU,
+                                            ) ?? null;
                                         expect(carlosIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                        expect((carlosIOUAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(carlosIOUReport?.reportID);
-                                        expect((carlosIOUAction?.originalMessage as IOUMessage)?.amount).toBe(amount / 4);
-                                        expect((carlosIOUAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
-                                        expect((carlosIOUAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+                                        expect(carlosIOUAction?.originalMessage.IOUReportID).toBe(carlosIOUReport?.reportID);
+                                        expect(carlosIOUAction?.originalMessage.amount).toBe(amount / 4);
+                                        expect(carlosIOUAction?.originalMessage.comment).toBe(comment);
+                                        expect(carlosIOUAction?.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
                                         expect(Date.parse(carlosIOUCreatedAction?.created ?? '')).toBeLessThan(Date.parse(carlosIOUAction?.created ?? ''));
 
                                         // Jules DM should have three reportActions, the existing CREATED action, the existing IOU action, and a new pending IOU action
                                         expect(Object.values(julesReportActions ?? {}).length).toBe(3);
                                         expect(julesReportActions?.[julesCreatedAction.reportActionID]).toStrictEqual(julesCreatedAction);
                                         julesIOUCreatedAction =
-                                            Object.values(julesReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null;
+                                            Object.values(julesReportActions ?? {}).find(
+                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED,
+                                            ) ?? null;
                                         julesIOUAction =
                                             Object.values(julesReportActions ?? {}).find(
-                                                (reportAction) =>
+                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU =>
                                                     reportAction.reportActionID !== julesCreatedAction.reportActionID &&
                                                     reportAction.reportActionID !== julesExistingIOUAction.reportActionID,
                                             ) ?? null;
                                         expect(julesIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                        expect((julesIOUAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(julesIOUReport?.reportID);
-                                        expect((julesIOUAction?.originalMessage as IOUMessage)?.amount).toBe(amount / 4);
-                                        expect((julesIOUAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
-                                        expect((julesIOUAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+                                        expect(julesIOUAction?.originalMessage.IOUReportID).toBe(julesIOUReport?.reportID);
+                                        expect(julesIOUAction?.originalMessage.amount).toBe(amount / 4);
+                                        expect(julesIOUAction?.originalMessage.comment).toBe(comment);
+                                        expect(julesIOUAction?.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
                                         expect(Date.parse(julesIOUCreatedAction?.created ?? '')).toBeLessThan(Date.parse(julesIOUAction?.created ?? ''));
 
                                         // Vit DM should have two reportActions – a pending CREATED action and a pending IOU action
                                         expect(Object.values(vitReportActions ?? {}).length).toBe(2);
                                         vitCreatedAction =
-                                            Object.values(vitReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null;
-                                        vitIOUAction = Object.values(vitReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                                            Object.values(vitReportActions ?? {}).find(
+                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED,
+                                            ) ?? null;
+                                        vitIOUAction =
+                                            Object.values(vitReportActions ?? {}).find(
+                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU,
+                                            ) ?? null;
                                         expect(vitCreatedAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
                                         expect(vitIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
-                                        expect((vitIOUAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(vitIOUReport?.reportID);
-                                        expect((vitIOUAction?.originalMessage as IOUMessage)?.amount).toBe(amount / 4);
-                                        expect((vitIOUAction?.originalMessage as IOUMessage)?.comment).toBe(comment);
-                                        expect((vitIOUAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
+                                        expect(vitIOUAction?.originalMessage.IOUReportID).toBe(vitIOUReport?.reportID);
+                                        expect(vitIOUAction?.originalMessage.amount).toBe(amount / 4);
+                                        expect(vitIOUAction?.originalMessage.comment).toBe(comment);
+                                        expect(vitIOUAction?.originalMessage.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.CREATE);
                                         expect(Date.parse(vitCreatedAction?.created ?? '')).toBeLessThan(Date.parse(vitIOUAction?.created ?? ''));
 
                                         // Group chat should have two reportActions – a pending CREATED action and a pending IOU action w/ type SPLIT
                                         expect(Object.values(groupReportActions ?? {}).length).toBe(2);
                                         groupCreatedAction =
                                             Object.values(groupReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null;
-                                        groupIOUAction = Object.values(groupReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                                        groupIOUAction =
+                                            Object.values(groupReportActions ?? {}).find(
+                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU,
+                                            ) ?? null;
                                         expect(groupCreatedAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
                                         expect(groupIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
                                         expect(groupIOUAction?.originalMessage).not.toHaveProperty('IOUReportID');
-                                        expect((groupIOUAction?.originalMessage as IOUMessage)?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.SPLIT);
+                                        expect(groupIOUAction?.originalMessage?.type).toBe(CONST.IOU.REPORT_ACTION_TYPE.SPLIT);
                                         expect(Date.parse(groupCreatedAction?.created ?? '')).toBeLessThanOrEqual(Date.parse(groupIOUAction?.created ?? ''));
 
                                         resolve();
@@ -1400,7 +1425,8 @@ describe('actions/IOU', () => {
 
                                         const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
 
-                                        createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+                                        createIOUAction =
+                                            Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
                                         expect(createIOUAction).toBeTruthy();
                                         expect((createIOUAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReport?.reportID);
 
@@ -1474,7 +1500,8 @@ describe('actions/IOU', () => {
 
                                         payIOUAction =
                                             Object.values(reportActionsForIOUReport ?? {}).find(
-                                                (ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && ra?.originalMessage?.type === CONST.IOU.REPORT_ACTION_TYPE.PAY,
+                                                (reportAction) =>
+                                                    reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && reportAction?.originalMessage?.type === CONST.IOU.REPORT_ACTION_TYPE.PAY,
                                             ) ?? null;
                                         expect(payIOUAction).toBeTruthy();
                                         expect(payIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
@@ -1524,7 +1551,8 @@ describe('actions/IOU', () => {
 
                                         payIOUAction =
                                             Object.values(reportActionsForIOUReport ?? {}).find(
-                                                (ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && ra.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.PAY,
+                                                (reportAction) =>
+                                                    reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && reportAction.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.PAY,
                                             ) ?? null;
                                         expect(payIOUAction).toBeTruthy();
                                         expect(payIOUAction?.pendingAction).toBeFalsy();
@@ -1655,7 +1683,7 @@ describe('actions/IOU', () => {
                         new Promise<void>((resolve) => {
                             const connectionID = Onyx.connect({
                                 key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
-                                waitForCollectionCallback: true,
+                                waitForCollectionCallback: false,
                                 callback: (allActions) => {
                                     Onyx.disconnect(connectionID);
                                     const updatedAction = Object.values(allActions ?? {}).find((reportAction) => !isEmptyObject(reportAction));
@@ -1811,7 +1839,7 @@ describe('actions/IOU', () => {
                         new Promise<void>((resolve) => {
                             const connectionID = Onyx.connect({
                                 key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${thread.reportID}`,
-                                waitForCollectionCallback: true,
+                                waitForCollectionCallback: false,
                                 callback: (allActions) => {
                                     Onyx.disconnect(connectionID);
                                     const updatedAction = Object.values(allActions ?? {}).find((reportAction) => !isEmptyObject(reportAction));
@@ -1922,7 +1950,7 @@ describe('actions/IOU', () => {
                         new Promise<void>((resolve) => {
                             const connectionID = Onyx.connect({
                                 key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport?.reportID}`,
-                                waitForCollectionCallback: true,
+                                waitForCollectionCallback: false,
                                 callback: (allActions) => {
                                     Onyx.disconnect(connectionID);
                                     expect(Object.values(allActions ?? {})).toEqual(
@@ -2037,7 +2065,7 @@ describe('actions/IOU', () => {
                         new Promise<void>((resolve) => {
                             const connectionID = Onyx.connect({
                                 key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport?.reportID}`,
-                                waitForCollectionCallback: true,
+                                waitForCollectionCallback: false,
                                 callback: (allActions) => {
                                     Onyx.disconnect(connectionID);
                                     const erroredAction = Object.values(allActions ?? {}).find((action) => !isEmptyObject(action?.errors));
@@ -2145,9 +2173,12 @@ describe('actions/IOU', () => {
 
             // Then we should find an IOU action with specific properties
             const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
-            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            createIOUAction =
+                Object.values(reportActionsForIOUReport ?? {}).find(
+                    (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU,
+                ) ?? null;
             expect(createIOUAction).toBeTruthy();
-            expect((createIOUAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReport?.reportID);
+            expect(createIOUAction?.originalMessage.IOUReportID).toBe(iouReport?.reportID);
 
             // When fetching all transactions from Onyx
             const allTransactions = await new Promise<OnyxCollection<OnyxTypes.Transaction>>((resolve) => {
@@ -2166,7 +2197,7 @@ describe('actions/IOU', () => {
             expect(transaction).toBeTruthy();
             expect(transaction?.amount).toBe(amount);
             expect(transaction?.reportID).toBe(iouReport?.reportID);
-            expect((createIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID).toBe(transaction?.transactionID);
+            expect(createIOUAction?.originalMessage.IOUTransactionID).toBe(transaction?.transactionID);
         });
 
         afterEach(PusherHelper.teardown);
@@ -2199,10 +2230,10 @@ describe('actions/IOU', () => {
             expect(createIOUAction).toBeTruthy();
 
             // Then we check if the transaction is removed from the transactions collection
-            const t = await new Promise<OnyxCollection<OnyxTypes.Transaction>>((resolve) => {
+            const t = await new Promise<OnyxEntry<OnyxTypes.Transaction>>((resolve) => {
                 const connectionID = Onyx.connect({
                     key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction?.transactionID}`,
-                    waitForCollectionCallback: true,
+                    waitForCollectionCallback: false,
                     callback: (transactionResult) => {
                         Onyx.disconnect(connectionID);
                         resolve(transactionResult);
@@ -2233,10 +2264,10 @@ describe('actions/IOU', () => {
             expect(createIOUAction).toBeFalsy();
 
             // Then we recheck the transaction from the transactions collection
-            const tr = await new Promise<OnyxCollection<OnyxTypes.Transaction>>((resolve) => {
+            const tr = await new Promise<OnyxEntry<OnyxTypes.Transaction>>((resolve) => {
                 const connectionID = Onyx.connect({
                     key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction?.transactionID}`,
-                    waitForCollectionCallback: true,
+                    waitForCollectionCallback: false,
                     callback: (transactionResult) => {
                         Onyx.disconnect(connectionID);
                         resolve(transactionResult);
@@ -2309,7 +2340,7 @@ describe('actions/IOU', () => {
             await waitForBatchedUpdates();
 
             // Then verify that the comment is correctly added
-            const resultAction = Object.values(reportActions ?? {}).find((ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
+            const resultAction = Object.values(reportActions ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
             reportActionID = resultAction?.reportActionID ?? '';
 
             expect(resultAction?.message).toEqual(REPORT_ACTION.message);
@@ -2411,7 +2442,7 @@ describe('actions/IOU', () => {
                 });
             });
             const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
-            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
             expect(createIOUAction?.childReportID).toBe(thread.reportID);
 
             await waitForBatchedUpdates();
@@ -2494,7 +2525,7 @@ describe('actions/IOU', () => {
                 });
             });
             const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
-            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
             expect(createIOUAction?.childReportID).toBe(thread.reportID);
 
             await waitForBatchedUpdates();
@@ -2596,7 +2627,7 @@ describe('actions/IOU', () => {
             await waitForBatchedUpdates();
 
             // Then comment details should match the expected report action
-            const resultAction = Object.values(reportActions ?? {}).find((ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
+            const resultAction = Object.values(reportActions ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
             reportActionID = resultAction?.reportActionID ?? '';
             expect(resultAction?.message).toEqual(REPORT_ACTION.message);
             expect(resultAction?.person).toEqual(REPORT_ACTION.person);
@@ -2621,7 +2652,7 @@ describe('actions/IOU', () => {
             await new Promise<void>((resolve) => {
                 const connectionID = Onyx.connect({
                     key: `${ONYXKEYS.COLLECTION.REPORT}${thread.reportID}`,
-                    waitForCollectionCallback: true,
+                    waitForCollectionCallback: false,
                     callback: (report) => {
                         Onyx.disconnect(connectionID);
                         expect(report).toBeTruthy();
@@ -2681,7 +2712,7 @@ describe('actions/IOU', () => {
             });
 
             const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
-            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
             expect(createIOUAction?.childReportID).toBe(thread.reportID);
 
             await waitForBatchedUpdates();
@@ -2707,7 +2738,7 @@ describe('actions/IOU', () => {
                 });
             });
 
-            let resultAction = Object.values(reportActions ?? {}).find((ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
+            let resultAction = Object.values(reportActions ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
             reportActionID = resultAction?.reportActionID ?? '';
 
             expect(resultAction?.message).toEqual(REPORT_ACTION.message);
@@ -2739,7 +2770,7 @@ describe('actions/IOU', () => {
             Report.addComment(IOU_REPORT_ID, 'Testing a comment');
             await waitForBatchedUpdates();
 
-            resultAction = Object.values(reportActions ?? {}).find((ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
+            resultAction = Object.values(reportActions ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
             reportActionID = resultAction?.reportActionID ?? '';
 
             expect(resultAction?.message).toEqual(REPORT_ACTION.message);
@@ -2872,7 +2903,7 @@ describe('actions/IOU', () => {
             Report.addComment(IOU_REPORT_ID, 'Testing a comment');
             await waitForBatchedUpdates();
 
-            const resultAction = Object.values(reportActions ?? {}).find((ra) => ra?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
+            const resultAction = Object.values(reportActions ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT);
             reportActionID = resultAction?.reportActionID;
 
             expect(resultAction?.message).toEqual(REPORT_ACTION.message);
@@ -2915,7 +2946,7 @@ describe('actions/IOU', () => {
             });
 
             const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`];
-            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((ra) => ra.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
+            createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null;
             expect(createIOUAction?.childReportID).toBe(thread.reportID);
 
             await waitForBatchedUpdates();

From f1664696b52db2c94c0b3d76d90eebfa18692cac Mon Sep 17 00:00:00 2001
From: Yauheni Pasiukevich <pasyukevich@live.com>
Date: Wed, 20 Mar 2024 11:37:31 +0100
Subject: [PATCH 5/5] address comments

---
 tests/actions/IOUTest.ts | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts
index b869d1a0c66b..505f881e0b22 100644
--- a/tests/actions/IOUTest.ts
+++ b/tests/actions/IOUTest.ts
@@ -162,7 +162,7 @@ describe('actions/IOU', () => {
                                         // The transaction thread should have a CREATED action
                                         expect(Object.values(reportActionsForTransactionThread ?? {}).length).toBe(1);
                                         const createdActions = Object.values(reportActionsForTransactionThread ?? {}).filter(
-                                            (reportAction) => (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.CREATED,
+                                            (reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED,
                                         );
                                         expect(Object.values(createdActions).length).toBe(1);
                                         transactionThreadCreatedAction = createdActions[0];
@@ -251,7 +251,7 @@ describe('actions/IOU', () => {
                 type: CONST.REPORT.TYPE.CHAT,
                 participantAccountIDs: [CARLOS_ACCOUNT_ID],
             };
-            const createdAction = {
+            const createdAction: OnyxTypes.ReportAction = {
                 reportActionID: NumberUtils.rand64(),
                 actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
                 created: DateUtils.getDBTime(),
@@ -420,7 +420,7 @@ describe('actions/IOU', () => {
                 iouReportID,
                 participantAccountIDs: [CARLOS_ACCOUNT_ID],
             };
-            const createdAction = {
+            const createdAction: OnyxTypes.ReportAction = {
                 reportActionID: NumberUtils.rand64(),
                 actionName: CONST.REPORT.ACTIONS.TYPE.CREATED,
                 created: DateUtils.getDBTime(),
@@ -460,7 +460,7 @@ describe('actions/IOU', () => {
                 },
             };
             let newIOUAction: OnyxEntry<OnyxTypes.ReportAction>;
-            let newTransaction;
+            let newTransaction: OnyxEntry<OnyxTypes.Transaction>;
             // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
             fetch.pause();
             return (
@@ -552,7 +552,7 @@ describe('actions/IOU', () => {
                                         // There should be two transactions
                                         expect(Object.values(allTransactions ?? {}).length).toBe(2);
 
-                                        newTransaction = Object.values(allTransactions ?? {}).find((transaction) => transaction?.transactionID !== existingTransaction.transactionID);
+                                        newTransaction = Object.values(allTransactions ?? {}).find((transaction) => transaction?.transactionID !== existingTransaction.transactionID) ?? null;
 
                                         expect(newTransaction?.reportID).toBe(iouReportID);
                                         expect(newTransaction?.amount).toBe(amount);
@@ -662,13 +662,10 @@ describe('actions/IOU', () => {
                                         // The chat report should have a CREATED action and IOU action
                                         expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(2);
                                         const createdActions =
-                                            Object.values(reportActionsForIOUReport ?? {}).filter(
-                                                (reportAction) => (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.CREATED,
-                                            ) ?? null;
+                                            Object.values(reportActionsForIOUReport ?? {}).filter((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null;
                                         const iouActions =
                                             Object.values(reportActionsForIOUReport ?? {}).filter(
-                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU =>
-                                                    (reportAction?.actionName as unknown as string) === CONST.REPORT.ACTIONS.TYPE.IOU,
+                                                (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU,
                                             ) ?? null;
                                         expect(Object.values(createdActions).length).toBe(1);
                                         expect(Object.values(iouActions).length).toBe(1);
