From 5137d743de17fa630f273f85521cbae9bbc3a3f6 Mon Sep 17 00:00:00 2001
From: Pedro Guerreiro <pedro.a.c.guerreiro@gmail.com>
Date: Wed, 4 Jun 2025 00:42:51 +0100
Subject: [PATCH 1/5] fix(testdrive): duplicate tasks in #admin for test drive
 receivers

---
 src/libs/ReportUtils.ts           | 7 +++++++
 src/libs/actions/Policy/Policy.ts | 8 ++++++++
 2 files changed, 15 insertions(+)

diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index 1db9f07f0cdc..c2b3d9e35aa3 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -9929,6 +9929,13 @@ function prepareOnboardingOnyxData(
             ) {
                 return false;
             }
+
+            // Exclude createWorkspace and viewTour tasks from #admin room, for test drive receivers,
+            // since these users already have them in concierge
+            if (introSelected?.choice === CONST.ONBOARDING_CHOICES.TEST_DRIVE_RECEIVER && ['createWorkspace', 'viewTour'].includes(task.type) && shouldPostTasksInAdminsRoom) {
+                return false;
+            }
+
             return true;
         })
         .map((task, index) => {
diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts
index 4b3577f6fe9a..e6379e3b5949 100644
--- a/src/libs/actions/Policy/Policy.ts
+++ b/src/libs/actions/Policy/Policy.ts
@@ -104,6 +104,7 @@ import type {Attributes, CompanyAddress, CustomUnit, NetSuiteCustomList, NetSuit
 import type {CustomFieldType} from '@src/types/onyx/PolicyEmployee';
 import type {OnyxData} from '@src/types/onyx/Request';
 import {isEmptyObject} from '@src/types/utils/EmptyObject';
+import {completeTask} from '../Task';
 import {buildOptimisticMccGroup, buildOptimisticPolicyCategories} from './Category';
 
 type ReportCreationData = Record<
@@ -2164,6 +2165,13 @@ function createWorkspace(
         shouldAddOnboardingTasks,
         companySize,
     );
+
+    // For test drive receivers, we want to complete the createWorkspace task in conciege, instead of #admin room
+    if (introSelected?.choice === CONST.ONBOARDING_CHOICES.TEST_DRIVE_RECEIVER) {
+        const createWorkspaceTaskReport = introSelected.createWorkspace ? {reportID: introSelected.createWorkspace} : undefined;
+        completeTask(createWorkspaceTaskReport);
+    }
+
     API.write(WRITE_COMMANDS.CREATE_WORKSPACE, params, {optimisticData, successData, failureData});
 
     // Publish a workspace created event if this is their first policy

From 96dfb9f85ca9fbdcad62076cf202829cb5ed9ada Mon Sep 17 00:00:00 2001
From: Pedro Guerreiro <pedro.a.c.guerreiro@gmail.com>
Date: Wed, 4 Jun 2025 00:53:38 +0100
Subject: [PATCH 2/5] chore: resolve CI failures

---
 src/libs/actions/Policy/Policy.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts
index e6379e3b5949..be78c1c48b07 100644
--- a/src/libs/actions/Policy/Policy.ts
+++ b/src/libs/actions/Policy/Policy.ts
@@ -81,6 +81,7 @@ import type {PolicySelector} from '@pages/home/sidebar/FloatingActionButtonAndPo
 import * as PaymentMethods from '@userActions/PaymentMethods';
 import * as PersistedRequests from '@userActions/PersistedRequests';
 import {resolveEnableFeatureConflicts} from '@userActions/RequestConflictUtils';
+import {completeTask} from '@userActions/Task';
 import type {OnboardingCompanySize, OnboardingPurpose} from '@src/CONST';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
@@ -104,7 +105,6 @@ import type {Attributes, CompanyAddress, CustomUnit, NetSuiteCustomList, NetSuit
 import type {CustomFieldType} from '@src/types/onyx/PolicyEmployee';
 import type {OnyxData} from '@src/types/onyx/Request';
 import {isEmptyObject} from '@src/types/utils/EmptyObject';
-import {completeTask} from '../Task';
 import {buildOptimisticMccGroup, buildOptimisticPolicyCategories} from './Category';
 
 type ReportCreationData = Record<
@@ -2166,7 +2166,7 @@ function createWorkspace(
         companySize,
     );
 
-    // For test drive receivers, we want to complete the createWorkspace task in conciege, instead of #admin room
+    // For test drive receivers, we want to complete the createWorkspace task in concierge, instead of #admin room
     if (introSelected?.choice === CONST.ONBOARDING_CHOICES.TEST_DRIVE_RECEIVER) {
         const createWorkspaceTaskReport = introSelected.createWorkspace ? {reportID: introSelected.createWorkspace} : undefined;
         completeTask(createWorkspaceTaskReport);

From d09ee1fc1934569899e856d02beff5a9e96b4807 Mon Sep 17 00:00:00 2001
From: Pedro Guerreiro <pedro.a.c.guerreiro@gmail.com>
Date: Tue, 10 Jun 2025 02:31:44 +0100
Subject: [PATCH 3/5] refactor: extract logic to build task data into a
 separate function

---
 src/libs/actions/Task.ts | 27 +++++++++++++++++----------
 1 file changed, 17 insertions(+), 10 deletions(-)

diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts
index c953698a5cb5..f2809d2997fd 100644
--- a/src/libs/actions/Task.ts
+++ b/src/libs/actions/Task.ts
@@ -388,16 +388,7 @@ function getOutstandingChildTask(taskReport: OnyxEntry<OnyxTypes.Report>) {
     });
 }
 
-/**
- * Complete a task
- */
-function completeTask(taskReport: OnyxEntry<OnyxTypes.Report>, reportIDFromAction?: string): OnyxData {
-    const taskReportID = taskReport?.reportID ?? reportIDFromAction;
-
-    if (!taskReportID) {
-        return {};
-    }
-
+function buildTaskData(taskReport: OnyxEntry<OnyxTypes.Report>, taskReportID: string) {
     const message = `marked as complete`;
     const completedTaskReportAction = ReportUtils.buildOptimisticTaskReportAction(taskReportID, CONST.REPORT.ACTIONS.TYPE.TASK_COMPLETED, message);
     const parentReport = getParentReport(taskReport);
@@ -474,6 +465,21 @@ function completeTask(taskReport: OnyxEntry<OnyxTypes.Report>, reportIDFromActio
         completedTaskReportActionID: completedTaskReportAction.reportActionID,
     };
 
+    return {optimisticData, failureData, successData, parameters};
+}
+
+/**
+ * Complete a task
+ */
+function completeTask(taskReport: OnyxEntry<OnyxTypes.Report>, reportIDFromAction?: string): OnyxData {
+    const taskReportID = taskReport?.reportID ?? reportIDFromAction;
+
+    if (!taskReportID) {
+        return {};
+    }
+
+    const {optimisticData, successData, failureData, parameters} = buildTaskData(taskReport, taskReportID);
+
     playSound(SOUNDS.SUCCESS);
     API.write(WRITE_COMMANDS.COMPLETE_TASK, parameters, {optimisticData, successData, failureData});
     return {optimisticData, successData, failureData};
@@ -1335,6 +1341,7 @@ export {
     setShareDestinationValue,
     clearOutTaskInfo,
     reopenTask,
+    buildTaskData,
     completeTask,
     clearOutTaskInfoAndNavigate,
     startOutCreateTaskQuickAction,

From 693d9e4d5c709c16fc1f72ffd3c78a81e040c317 Mon Sep 17 00:00:00 2001
From: Pedro Guerreiro <pedro.a.c.guerreiro@gmail.com>
Date: Tue, 10 Jun 2025 02:33:07 +0100
Subject: [PATCH 4/5] refactor: use buildTaskData to mark createWorkspace as
 complemente without making a call to API

---
 src/libs/actions/Policy/Policy.ts | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts
index 049ccc3ade3e..846b9c8fb027 100644
--- a/src/libs/actions/Policy/Policy.ts
+++ b/src/libs/actions/Policy/Policy.ts
@@ -82,7 +82,7 @@ import type {PolicySelector} from '@pages/home/sidebar/FloatingActionButtonAndPo
 import * as PaymentMethods from '@userActions/PaymentMethods';
 import * as PersistedRequests from '@userActions/PersistedRequests';
 import {resolveEnableFeatureConflicts} from '@userActions/RequestConflictUtils';
-import {completeTask} from '@userActions/Task';
+import {buildTaskData} from '@userActions/Task';
 import type {OnboardingCompanySize, OnboardingPurpose} from '@src/CONST';
 import CONST from '@src/CONST';
 import ONYXKEYS from '@src/ONYXKEYS';
@@ -2143,6 +2143,20 @@ function buildPolicyData(
         failureData.push(...taskFailureData);
     }
 
+    // For test drive receivers, we want to complete the createWorkspace task in concierge, instead of #admin room
+    if (introSelected?.choice === CONST.ONBOARDING_CHOICES.TEST_DRIVE_RECEIVER && introSelected.createWorkspace) {
+        const createWorkspaceTaskReport = {reportID: introSelected.createWorkspace};
+        const {
+            optimisticData: optimisticCreateWorkspaceTaskData,
+            successData: successCreateWorkspaceTaskData,
+            failureData: failureCreateWorkspaceTaskData,
+        } = buildTaskData(createWorkspaceTaskReport, introSelected.createWorkspace);
+
+        optimisticData.push(...optimisticCreateWorkspaceTaskData);
+        successData.push(...successCreateWorkspaceTaskData);
+        failureData.push(...failureCreateWorkspaceTaskData);
+    }
+
     return {successData, optimisticData, failureData, params};
 }
 
@@ -2170,12 +2184,6 @@ function createWorkspace(
         companySize,
     );
 
-    // For test drive receivers, we want to complete the createWorkspace task in concierge, instead of #admin room
-    if (introSelected?.choice === CONST.ONBOARDING_CHOICES.TEST_DRIVE_RECEIVER) {
-        const createWorkspaceTaskReport = introSelected.createWorkspace ? {reportID: introSelected.createWorkspace} : undefined;
-        completeTask(createWorkspaceTaskReport);
-    }
-
     API.write(WRITE_COMMANDS.CREATE_WORKSPACE, params, {optimisticData, successData, failureData});
 
     // Publish a workspace created event if this is their first policy

From c937930234cbbe7928a4bbc8e24f7c3088adc806 Mon Sep 17 00:00:00 2001
From: Pedro Guerreiro <pedro.a.c.guerreiro@gmail.com>
Date: Wed, 11 Jun 2025 23:52:20 +0100
Subject: [PATCH 5/5] fix(testdrive): 3 months free message disappearing from
 boss chat

---
 src/libs/actions/IOU.ts | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts
index 75b2d76270ee..0e82fcbf0d7a 100644
--- a/src/libs/actions/IOU.ts
+++ b/src/libs/actions/IOU.ts
@@ -1343,14 +1343,6 @@ function buildOnyxDataForTestDriveIOU(testDriveIOUParams: BuildOnyxDataForTestDr
         },
     );
 
-    successData.push({
-        onyxMethod: Onyx.METHOD.MERGE,
-        key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${testDriveIOUParams.chatOptimisticParams.report?.reportID}`,
-        value: {
-            [textComment.reportAction.reportActionID]: null,
-        },
-    });
-
     return {
         optimisticData,
         successData,
