diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 560cb89df250..a5194134d0a0 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6844,6 +6844,7 @@ function updateOptimisticParentReportAction( * @param taskAssigneeAccountID - AccountID of the person assigned to the task * @param text - Text of the comment * @param parentReportID - Report ID of the parent report + * @param delegateAccountID - AccountID of the delegate acting on behalf of the current user * @param createdOffset - The offset for task's created time that created via a loop */ function buildOptimisticTaskCommentReportAction( @@ -6852,13 +6853,20 @@ function buildOptimisticTaskCommentReportAction( taskAssigneeAccountID: number, text: string, parentReportID: string | undefined, + delegateAccountID: number | undefined, actorAccountID?: number, createdOffset = 0, currentUserEmail?: string, currentUserAccountID?: number, ): OptimisticReportAction { - // delegateAccountIDParam: will be threaded in PR 14; buildOptimisticAddCommentReportAction falls back to module-level Onyx.connect value (https://github.com/Expensify/App/issues/66425) - const reportAction = buildOptimisticAddCommentReportAction({text, reportID: taskReportID, createdOffset, currentUserEmail, currentUserAccountID, delegateAccountIDParam: undefined}); + const reportAction = buildOptimisticAddCommentReportAction({ + text, + reportID: taskReportID, + createdOffset, + currentUserEmail, + currentUserAccountID, + delegateAccountIDParam: delegateAccountID, + }); if (Array.isArray(reportAction.reportAction.message)) { const message = reportAction.reportAction.message.at(0); if (message) { @@ -10906,6 +10914,7 @@ function getTaskAssigneeChatOnyxData( assigneeChatReport: OnyxEntry, currentUserEmail: string, currentUserAccountID: number, + delegateAccountID: number | undefined, isOptimisticAssigneeChatReport?: boolean, ): OnyxDataTaskAssigneeChat { // Set if we need to add a comment to the assignee chat notifying them that they have been assigned a task @@ -11027,6 +11036,7 @@ function getTaskAssigneeChatOnyxData( assigneeAccountID, `assigned to ${displayname}`, parentReportID, + delegateAccountID, undefined, 0, currentUserEmail, @@ -12320,7 +12330,7 @@ function prepareOnboardingOnyxData({ // Text message const message = typeof onboardingMessage.message === 'function' ? onboardingMessage.message(onboardingTaskParams) : onboardingMessage.message; - // delegateAccountIDParam: will be threaded in PR 14; buildOptimisticAddCommentReportAction falls back to module-level Onyx.connect value (https://github.com/Expensify/App/issues/66425) + // delegateAccountIDParam: will be threaded in PR 15b; buildOptimisticAddCommentReportAction falls back to module-level Onyx.connect value (https://github.com/Expensify/App/issues/66425) const textComment = buildOptimisticAddCommentReportAction({text: message, actorAccountID, createdOffset: 1, delegateAccountIDParam: undefined}); const textCommentAction: OptimisticAddCommentReportAction = textComment.reportAction; const textMessage: AddCommentOrAttachmentParams = { @@ -12373,7 +12383,17 @@ function prepareOnboardingOnyxData({ ); const emailCreatingAction = CONST.EMAIL.CONCIERGE; const taskCreatedAction = buildOptimisticCreatedReportAction({emailCreatingAction}); - const taskReportAction = buildOptimisticTaskCommentReportAction(currentTask.reportID, taskTitle, 0, `task for ${taskTitle}`, targetChatReportID, actorAccountID, index + 3); + // delegateAccountID: will be threaded in PR 15b; buildOptimisticAddCommentReportAction falls back to module-level Onyx.connect value (https://github.com/Expensify/App/issues/66425) + const taskReportAction = buildOptimisticTaskCommentReportAction( + currentTask.reportID, + taskTitle, + 0, + `task for ${taskTitle}`, + targetChatReportID, + undefined, + actorAccountID, + index + 3, + ); currentTask.parentReportActionID = taskReportAction.reportAction.reportActionID; let isTaskAutoCompleted: boolean = task.autoCompleted; @@ -12389,7 +12409,7 @@ function prepareOnboardingOnyxData({ } const completedTaskReportAction = isTaskAutoCompleted - ? // delegateEmailParam: will be threaded in PR 14; buildOptimisticTaskReportAction falls back to module-level Onyx.connect value (https://github.com/Expensify/App/issues/66425) + ? // delegateEmailParam: will be threaded in PR 17; buildOptimisticTaskReportAction falls back to module-level Onyx.connect value (https://github.com/Expensify/App/issues/66425) buildOptimisticTaskReportAction(currentTask.reportID, CONST.REPORT.ACTIONS.TYPE.TASK_COMPLETED, undefined, 'marked as complete', actorAccountID, 2) : null; if (task.type === CONST.ONBOARDING_TASK_TYPE.CREATE_WORKSPACE) { @@ -12418,7 +12438,7 @@ function prepareOnboardingOnyxData({ // Sign-off welcome message const welcomeSignOffText = engagementChoice === CONST.ONBOARDING_CHOICES.MANAGE_TEAM ? translateLocal('onboarding.welcomeSignOffTitleManageTeam') : translateLocal('onboarding.welcomeSignOffTitle'); - // delegateAccountIDParam: will be threaded in PR 14; buildOptimisticAddCommentReportAction falls back to module-level Onyx.connect value (https://github.com/Expensify/App/issues/66425) + // delegateAccountIDParam: will be threaded in PR 15b; buildOptimisticAddCommentReportAction falls back to module-level Onyx.connect value (https://github.com/Expensify/App/issues/66425) const welcomeSignOffComment = buildOptimisticAddCommentReportAction({text: welcomeSignOffText, actorAccountID, createdOffset: tasksData.length + 3, delegateAccountIDParam: undefined}); const welcomeSignOffCommentAction: OptimisticAddCommentReportAction = welcomeSignOffComment.reportAction; const welcomeSignOffMessage = { diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 97674ebf1492..fa3eb1c8d328 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -49,6 +49,7 @@ type EditTaskAssigneeOptions = { currentUserAccountID: number; hasOutstandingChildTask: boolean; delegateEmail: string | undefined; + delegateAccountID: number | undefined; assigneeAccountID?: number | null; assigneeChatReport?: OnyxEntry; isOptimisticReport?: boolean; @@ -76,6 +77,7 @@ type CreateTaskAndNavigateParams = { assigneeEmail: string; currentUserAccountID: number; currentUserEmail: string; + delegateAccountID: number | undefined; assigneeAccountID?: number; assigneeChatReport?: OnyxEntry; policyID?: string; @@ -128,6 +130,7 @@ function createTaskAndNavigate(params: CreateTaskAndNavigateParams) { currentUserEmail, currentUserDisplayName, currentUserAvatar, + delegateAccountID, assigneeAccountID = 0, assigneeChatReport, policyID = CONST.POLICY.OWNER_EMAIL_FAKE, @@ -164,7 +167,7 @@ function createTaskAndNavigate(params: CreateTaskAndNavigateParams) { currentUserEmail, currentUserAvatar, }); - const optimisticAddCommentReport = ReportUtils.buildOptimisticTaskCommentReportAction(taskReportID, title, assigneeAccountID, `task for ${title}`, parentReportID); + const optimisticAddCommentReport = ReportUtils.buildOptimisticTaskCommentReportAction(taskReportID, title, assigneeAccountID, `task for ${title}`, parentReportID, delegateAccountID); optimisticTaskReport.parentReportActionID = optimisticAddCommentReport.reportAction.reportActionID; const currentTime = getDBTimeWithSkew(); @@ -268,6 +271,7 @@ function createTaskAndNavigate(params: CreateTaskAndNavigateParams) { assigneeChatReport, currentUserEmail, currentUserAccountID, + delegateAccountID, ); optimisticData.push(...assigneeChatReportOnyxData.optimisticData); @@ -791,6 +795,7 @@ function editTaskAssignee({ currentUserAccountID, hasOutstandingChildTask, delegateEmail, + delegateAccountID, assigneeAccountID = 0, assigneeChatReport, isOptimisticReport, @@ -917,6 +922,7 @@ function editTaskAssignee({ assigneeChatReport, currentUserEmail, currentUserAccountID, + delegateAccountID, isOptimisticReport, ); diff --git a/src/pages/inbox/report/ReportActionCompose/useComposerSubmit.ts b/src/pages/inbox/report/ReportActionCompose/useComposerSubmit.ts index 07fde54d87ad..9c114a1ca191 100644 --- a/src/pages/inbox/report/ReportActionCompose/useComposerSubmit.ts +++ b/src/pages/inbox/report/ReportActionCompose/useComposerSubmit.ts @@ -146,6 +146,7 @@ function useComposerSubmit(reportID: string) { currentUserEmail, currentUserDisplayName: currentUserPersonalDetails.displayName, currentUserAvatar: currentUserPersonalDetails.avatar, + delegateAccountID, assigneeAccountID: assignee?.accountID, assigneeChatReport, policyID: report?.policyID, diff --git a/src/pages/tasks/DynamicNewTaskDetailsPage.tsx b/src/pages/tasks/DynamicNewTaskDetailsPage.tsx index bd666348d3dc..2fc9ff740d98 100644 --- a/src/pages/tasks/DynamicNewTaskDetailsPage.tsx +++ b/src/pages/tasks/DynamicNewTaskDetailsPage.tsx @@ -8,6 +8,7 @@ import TextInput from '@components/TextInput'; import useAncestors from '@hooks/useAncestors'; import useAutoFocusInput from '@hooks/useAutoFocusInput'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; @@ -38,6 +39,7 @@ function DynamicNewTaskDetailsPage() { const [parentReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${task?.parentReportID}`); const ancestors = useAncestors(parentReport); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const [taskCreatorAndAssigneeDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, { selector: personalDetailsListSelector([currentUserPersonalDetails.accountID, task?.assigneeAccountID]), }); @@ -89,6 +91,7 @@ function DynamicNewTaskDetailsPage() { currentUserEmail: currentUserPersonalDetails.email ?? '', currentUserDisplayName: currentUserPersonalDetails.displayName, currentUserAvatar: currentUserPersonalDetails.avatar, + delegateAccountID, assigneeAccountID: task.assigneeAccountID, assigneeChatReport: task.assigneeChatReport, policyID: CONST.POLICY.OWNER_EMAIL_FAKE, diff --git a/src/pages/tasks/DynamicNewTaskPage.tsx b/src/pages/tasks/DynamicNewTaskPage.tsx index a420f48cf6d6..1e77a2facdc9 100644 --- a/src/pages/tasks/DynamicNewTaskPage.tsx +++ b/src/pages/tasks/DynamicNewTaskPage.tsx @@ -9,6 +9,7 @@ import ScrollView from '@components/ScrollView'; import useAncestors from '@hooks/useAncestors'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useLocalize from '@hooks/useLocalize'; import useOnyx from '@hooks/useOnyx'; @@ -42,6 +43,7 @@ function DynamicNewTaskPage() { const [conciergeReportID] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); const reportAttributes = useReportAttributes(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const [taskCreatorAndAssigneeDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST, { selector: personalDetailsListSelector([currentUserPersonalDetails.accountID, task?.assigneeAccountID]), }); @@ -115,6 +117,7 @@ function DynamicNewTaskPage() { currentUserEmail: currentUserPersonalDetails.email ?? '', currentUserDisplayName: currentUserPersonalDetails.displayName, currentUserAvatar: currentUserPersonalDetails.avatar, + delegateAccountID, assigneeAccountID: task.assigneeAccountID, assigneeChatReport: task.assigneeChatReport, policyID: parentReport?.policyID, diff --git a/src/pages/tasks/DynamicTaskAssigneeSelectorModal.tsx b/src/pages/tasks/DynamicTaskAssigneeSelectorModal.tsx index 6689291f1d62..6344ff7fc961 100644 --- a/src/pages/tasks/DynamicTaskAssigneeSelectorModal.tsx +++ b/src/pages/tasks/DynamicTaskAssigneeSelectorModal.tsx @@ -7,6 +7,7 @@ import SelectionListWithSections from '@components/SelectionList/SelectionListWi import type {ListItem} from '@components/SelectionList/types'; import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails'; +import useDelegateAccountID from '@hooks/useDelegateAccountID'; import useDynamicBackPath from '@hooks/useDynamicBackPath'; import useHasOutstandingChildTask from '@hooks/useHasOutstandingChildTask'; import useLocalize from '@hooks/useLocalize'; @@ -54,6 +55,7 @@ function DynamicTaskAssigneeSelectorModal() { const [isSearchingForReports] = useOnyx(ONYXKEYS.RAM_ONLY_IS_SEARCHING_FOR_REPORTS); const [countryCode = CONST.DEFAULT_COUNTRY_CODE] = useOnyx(ONYXKEYS.COUNTRY_CODE); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); + const delegateAccountID = useDelegateAccountID(); const currentUserEmail = currentUserPersonalDetails.email ?? ''; const [delegateEmail] = useOnyx(ONYXKEYS.ACCOUNT, { selector: delegateEmailSelector, @@ -173,6 +175,7 @@ function DynamicTaskAssigneeSelectorModal() { currentUserAccountID: currentUserPersonalDetails.accountID, hasOutstandingChildTask, delegateEmail, + delegateAccountID, assigneeAccountID: option?.accountID, assigneeChatReport, isOptimisticReport, diff --git a/tests/actions/TaskTest.ts b/tests/actions/TaskTest.ts index 1e78844dbbf9..66e869d08eb5 100644 --- a/tests/actions/TaskTest.ts +++ b/tests/actions/TaskTest.ts @@ -479,6 +479,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, assigneeChatReport: mockAssigneeChatReport, policyID: mockPolicyID, @@ -528,6 +529,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, policyID: mockPolicyID, isCreatedUsingMarkdown: false, @@ -559,6 +561,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, policyID: mockPolicyID, isCreatedUsingMarkdown: false, @@ -594,6 +597,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, assigneeChatReport: undefined, policyID: mockPolicyID, @@ -656,6 +660,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, assigneeChatReport: mockAssigneeChatReport, policyID: mockPolicyID, @@ -697,6 +702,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, assigneeChatReport: mockAssigneeChatReport, policyID: CONST.POLICY.OWNER_EMAIL_FAKE, @@ -745,6 +751,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockCurrentUserAccountID, // assignee is current user assigneeChatReport: mockAssigneeChatReport, policyID: mockPolicyID, @@ -806,6 +813,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, assigneeChatReport: mockAssigneeChatReport, policyID: mockPolicyID, @@ -844,6 +852,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, assigneeChatReport: mockAssigneeChatReport, policyID: mockPolicyID, @@ -886,6 +895,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, policyID: mockPolicyID, isCreatedUsingMarkdown: false, @@ -915,6 +925,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: undefined, currentUserAvatar: undefined, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, policyID: mockPolicyID, isCreatedUsingMarkdown: false, @@ -944,6 +955,7 @@ describe('actions/Task', () => { currentUserEmail: '', currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, policyID: mockPolicyID, isCreatedUsingMarkdown: false, @@ -975,6 +987,7 @@ describe('actions/Task', () => { currentUserEmail: mockCurrentUserEmail, currentUserDisplayName: mockCurrentUserDisplayName, currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, assigneeAccountID: mockAssigneeAccountID, policyID: mockPolicyID, isCreatedUsingMarkdown: false, @@ -996,6 +1009,54 @@ describe('actions/Task', () => { }), ); }); + + it('should set the passed delegateAccountID on the optimistic task comment in the parent report', () => { + const DELEGATE_ACCOUNT_ID = 999; + + createTaskAndNavigate({ + parentReport: {reportID: mockParentReportID}, + title: mockTitle, + description: mockDescription, + assigneeEmail: mockAssigneeEmail, + currentUserAccountID: mockCurrentUserAccountID, + currentUserEmail: mockCurrentUserEmail, + currentUserDisplayName: mockCurrentUserDisplayName, + currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: DELEGATE_ACCOUNT_ID, + assigneeAccountID: mockAssigneeAccountID, + policyID: mockPolicyID, + isCreatedUsingMarkdown: false, + quickAction: {}, + taskCreatorAndAssigneeDetails: undefined, + }); + + const reportActionsUpdate = getRequiredOnyxUpdate(getRequiredWriteOnyxData(), 'optimisticData', `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${mockParentReportID}`); + const reportAction = getRequiredReportAction(reportActionsUpdate, CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT); + expect(reportAction.delegateAccountID).toBe(DELEGATE_ACCOUNT_ID); + }); + + it('should leave delegateAccountID unset on the optimistic task comment when no delegate is passed', () => { + createTaskAndNavigate({ + parentReport: {reportID: mockParentReportID}, + title: mockTitle, + description: mockDescription, + assigneeEmail: mockAssigneeEmail, + currentUserAccountID: mockCurrentUserAccountID, + currentUserEmail: mockCurrentUserEmail, + currentUserDisplayName: mockCurrentUserDisplayName, + currentUserAvatar: mockCurrentUserAvatar, + delegateAccountID: undefined, + assigneeAccountID: mockAssigneeAccountID, + policyID: mockPolicyID, + isCreatedUsingMarkdown: false, + quickAction: {}, + taskCreatorAndAssigneeDetails: undefined, + }); + + const reportActionsUpdate = getRequiredOnyxUpdate(getRequiredWriteOnyxData(), 'optimisticData', `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${mockParentReportID}`); + const reportAction = getRequiredReportAction(reportActionsUpdate, CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT); + expect(reportAction.delegateAccountID).toBeUndefined(); + }); }); describe('completeTask', () => { @@ -1383,6 +1444,7 @@ describe('actions/Task', () => { currentUserAccountID: CURRENT_USER_ACCOUNT_ID, hasOutstandingChildTask: false, delegateEmail: DELEGATE_EMAIL, + delegateAccountID: undefined, assigneeAccountID: ASSIGNEE_ACCOUNT_ID, formatPhoneNumber, }); @@ -1414,6 +1476,7 @@ describe('actions/Task', () => { currentUserAccountID: CURRENT_USER_ACCOUNT_ID, hasOutstandingChildTask: false, delegateEmail: undefined, + delegateAccountID: undefined, assigneeAccountID: ASSIGNEE_ACCOUNT_ID, formatPhoneNumber, }); diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 42393cb095f9..72c218eeea4f 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -667,6 +667,7 @@ describe('ReportUtils', () => { createMock>({}), passedCurrentUserEmail, passedCurrentUserAccountID, + undefined, ); expect(optimisticAssigneeAddComment).toBeDefined(); @@ -691,6 +692,7 @@ describe('ReportUtils', () => { createMock>({}), passedCurrentUserEmail, passedCurrentUserAccountID, + undefined, ); const reportAction = result.optimisticAssigneeAddComment?.reportAction as ReportAction | undefined; @@ -701,10 +703,73 @@ describe('ReportUtils', () => { }); it('does not create optimistic assignee comment when assigneeChatReportID equals parentReportID', () => { - const result = getTaskAssigneeChatOnyxData(1, 2, 'taskReportID', 'sameReportID', 'sameReportID', 'Task title', createMock>({}), 'email@user.com', 50); + const result = getTaskAssigneeChatOnyxData( + 1, + 2, + 'taskReportID', + 'sameReportID', + 'sameReportID', + 'Task title', + createMock>({}), + 'email@user.com', + 50, + undefined, + ); expect(result.optimisticAssigneeAddComment).toBeUndefined(); }); + + describe('delegateAccountID', () => { + const MODULE_DELEGATE_EMAIL = 'module-delegate@vikings.net'; + const MODULE_DELEGATE_ACCOUNT_ID = 900; + const PASSED_DELEGATE_ACCOUNT_ID = 901; + + const buildAssigneeChatOnyxData = (delegateAccountID: number | undefined) => + getTaskAssigneeChatOnyxData( + 1, + 2, + 'taskReportID', + 'assigneeChatReportID', + 'parentReportID', + 'Task title', + createMock>({}), + 'email@user.com', + 50, + delegateAccountID, + ); + + beforeEach(async () => { + // The module-level delegate is what `buildOptimisticAddCommentReportAction` falls back to, so it has to + // differ from the passed value for these tests to prove which one wins. + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, { + [MODULE_DELEGATE_ACCOUNT_ID]: {accountID: MODULE_DELEGATE_ACCOUNT_ID, login: MODULE_DELEGATE_EMAIL, displayName: 'Module Delegate'}, + }); + await Onyx.merge(ONYXKEYS.ACCOUNT, {delegatedAccess: {delegate: MODULE_DELEGATE_EMAIL}}); + await waitForBatchedUpdates(); + }); + + afterEach(async () => { + await Onyx.merge(ONYXKEYS.ACCOUNT, {delegatedAccess: {delegate: null}}); + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, {[MODULE_DELEGATE_ACCOUNT_ID]: null}); + await waitForBatchedUpdates(); + }); + + it('uses the passed delegateAccountID instead of the module-level delegate', () => { + const {optimisticAssigneeAddComment} = buildAssigneeChatOnyxData(PASSED_DELEGATE_ACCOUNT_ID); + + const reportAction = optimisticAssigneeAddComment?.reportAction as ReportAction | undefined; + expect(reportAction?.delegateAccountID).toBe(PASSED_DELEGATE_ACCOUNT_ID); + }); + + // TODO: the fallback assertion below flips to `toBeUndefined()` once the module-level Onyx.connect is + // removed (https://github.com/Expensify/App/issues/66425). + it('falls back to the module-level delegate when no delegateAccountID is passed', () => { + const {optimisticAssigneeAddComment} = buildAssigneeChatOnyxData(undefined); + + const reportAction = optimisticAssigneeAddComment?.reportAction as ReportAction | undefined; + expect(reportAction?.delegateAccountID).toBe(MODULE_DELEGATE_ACCOUNT_ID); + }); + }); }); describe('prepareOnboardingOnyxData', () => {