diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 0dbd8c0b3d3..d3a63eb8e8f 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -11634,8 +11634,10 @@ type PrepareOnboardingOnyxDataParams = { selectedInterestedFeatures?: string[]; isInvitedAccountant?: boolean; onboardingPurposeSelected?: OnboardingPurpose; - isSelfTourViewed?: boolean; + isSelfTourViewed: boolean | undefined; betas: OnyxEntry; + // TODO: hasCompletedGuidedSetupFlow will be required eventually. Refactor issue: https://github.com/Expensify/App/issues/66424 + hasCompletedGuidedSetupFlow?: boolean; }; function getBespokeWelcomeMessage(companySize: OnboardingCompanySize | undefined, userReportedIntegration?: OnboardingAccounting): string { @@ -11691,6 +11693,7 @@ function prepareOnboardingOnyxData({ onboardingPurposeSelected, isSelfTourViewed, betas, + hasCompletedGuidedSetupFlow, }: PrepareOnboardingOnyxDataParams) { if (engagementChoice === CONST.ONBOARDING_CHOICES.PERSONAL_SPEND) { // eslint-disable-next-line no-param-reassign @@ -11877,7 +11880,7 @@ function prepareOnboardingOnyxData({ let isTaskAutoCompleted: boolean = task.autoCompleted; - const onboardingSelfTourViewed = isSelfTourViewed ?? onboarding?.selfTourViewed; + const onboardingSelfTourViewed = isSelfTourViewed; if (task.type === CONST.ONBOARDING_TASK_TYPE.VIEW_TOUR && onboardingSelfTourViewed) { // If the user has already viewed the self tour, we mark the task as auto completed isTaskAutoCompleted = true; @@ -12249,7 +12252,7 @@ function prepareOnboardingOnyxData({ failureData.push({ onyxMethod: Onyx.METHOD.MERGE, key: ONYXKEYS.NVP_ONBOARDING, - value: {hasCompletedGuidedSetupFlow: onboarding?.hasCompletedGuidedSetupFlow ?? null}, + value: {hasCompletedGuidedSetupFlow: hasCompletedGuidedSetupFlow ?? onboarding?.hasCompletedGuidedSetupFlow ?? null}, }); } diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index a1b044df60b..fd574591a1e 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -592,6 +592,7 @@ describe('ReportUtils', () => { adminsChatReportID: '1', // SMALL keeps this in the tasks path; MICRO routes through Phase 1 followups (no tasks generated). companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL, + isSelfTourViewed: undefined, }); expect(title).toHaveBeenCalledWith( @@ -623,6 +624,7 @@ describe('ReportUtils', () => { adminsChatReportID: '1', // SMALL keeps this in the tasks path; MICRO routes through Phase 1 followups (no tasks generated). companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL, + isSelfTourViewed: undefined, }); expect(description).toHaveBeenCalledWith( @@ -650,6 +652,7 @@ describe('ReportUtils', () => { adminsChatReportID, selectedInterestedFeatures: ['areCompanyCardsEnabled'], companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO, + isSelfTourViewed: undefined, }); expect(result?.guidedSetupData).toHaveLength(0); // suggestedFollowups beta adds a bespoke Concierge welcome action optimistically for all company sizes @@ -678,6 +681,7 @@ describe('ReportUtils', () => { adminsChatReportID, selectedInterestedFeatures: ['areCompanyCardsEnabled'], companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL, + isSelfTourViewed: undefined, }); expect(result?.guidedSetupData).toHaveLength(0); expect(result?.bespokeWelcomeMessage).toContain('growing team'); @@ -700,6 +704,7 @@ describe('ReportUtils', () => { adminsChatReportID, selectedInterestedFeatures: ['areCompanyCardsEnabled'], companySize: CONST.ONBOARDING_COMPANY_SIZE.LARGE, + isSelfTourViewed: undefined, }); expect(result?.guidedSetupData).toHaveLength(0); expect(result?.bespokeWelcomeMessage).toContain('organization your size'); @@ -722,6 +727,7 @@ describe('ReportUtils', () => { adminsChatReportID, selectedInterestedFeatures: ['areCompanyCardsEnabled'], companySize: CONST.ONBOARDING_COMPANY_SIZE.MEDIUM_SMALL, + isSelfTourViewed: undefined, }); expect(result?.guidedSetupData).toHaveLength(0); expect(result?.bespokeWelcomeMessage).toContain('growing team'); @@ -744,6 +750,7 @@ describe('ReportUtils', () => { adminsChatReportID, selectedInterestedFeatures: ['areCompanyCardsEnabled'], companySize: CONST.ONBOARDING_COMPANY_SIZE.MEDIUM, + isSelfTourViewed: undefined, }); expect(result?.guidedSetupData).toHaveLength(0); expect(result?.bespokeWelcomeMessage).toContain('organization your size'); @@ -767,6 +774,7 @@ describe('ReportUtils', () => { selectedInterestedFeatures: ['areCompanyCardsEnabled'], companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL, userReportedIntegration: 'quickbooksOnline', + isSelfTourViewed: undefined, }); expect(result?.bespokeWelcomeMessage).toContain('QuickBooks Online'); expect(result?.bespokeWelcomeMessage).toContain('expenses sync automatically'); @@ -789,6 +797,7 @@ describe('ReportUtils', () => { adminsChatReportID, selectedInterestedFeatures: ['areCompanyCardsEnabled'], companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL, + isSelfTourViewed: undefined, }); // Without the beta, tasks SHOULD be generated (old behavior) — uses SMALL (not MICRO) // because MICRO + MANAGE_TEAM users bypass the beta gate and get followups directly @@ -825,6 +834,7 @@ describe('ReportUtils', () => { adminsChatReportID, selectedInterestedFeatures: ['areCompanyCardsEnabled'], companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO, + isSelfTourViewed: undefined, }); // Followups path active: no tasks generated, bespoke welcome posted optimistically to #admins. expect(result?.guidedSetupData.filter((data) => data.type === 'task')).toHaveLength(0); @@ -846,6 +856,7 @@ describe('ReportUtils', () => { adminsChatReportID: '1', selectedInterestedFeatures: ['categories', 'accounting', 'tags'], companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO, + isSelfTourViewed: undefined, }); expect(result?.guidedSetupData.filter((data) => data.type === 'task')).toHaveLength(0); @@ -869,6 +880,7 @@ describe('ReportUtils', () => { }, adminsChatReportID: '1', companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO, + isSelfTourViewed: undefined, }); const personalDetailsCall = mergeSpy.mock.calls.find((call) => call[0] === ONYXKEYS.PERSONAL_DETAILS_LIST); @@ -906,6 +918,7 @@ describe('ReportUtils', () => { adminsChatReportID: '1', // SMALL keeps the tasks path active; MICRO routes through Phase 1 followups (no tasks generated). companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL, + isSelfTourViewed: undefined, }); expect(title).toHaveBeenCalledWith( @@ -932,6 +945,7 @@ describe('ReportUtils', () => { }, adminsChatReportID: '1', companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO, + isSelfTourViewed: undefined, }); expect(result?.guidedSetupData).toHaveLength(0); @@ -948,6 +962,7 @@ describe('ReportUtils', () => { }, adminsChatReportID: '1', companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO, + isSelfTourViewed: undefined, }); // For LOOKING_AROUND with empty message and no tasks, guidedSetupData should be empty @@ -970,6 +985,7 @@ describe('ReportUtils', () => { }, adminsChatReportID: '1', companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO, + isSelfTourViewed: undefined, }); // Non-LOOKING_AROUND intents with a message should have guidedSetupData entries @@ -1036,38 +1052,6 @@ describe('ReportUtils', () => { expect(viewTourTask).toBeDefined(); expect(viewTourTask?.completedTaskReportActionID).toBeUndefined(); }); - - it('should auto-complete VIEW_TOUR task when isSelfTourViewed is undefined but onboarding.selfTourViewed is true via Onyx', async () => { - await Onyx.merge(ONYXKEYS.NVP_ONBOARDING, {selfTourViewed: true, hasCompletedGuidedSetupFlow: false}); - await waitForBatchedUpdates(); - - const result = prepareOnboardingOnyxData({ - introSelected: undefined, - betas: undefined, - engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM, - onboardingMessage: { - message: 'This is a test', - tasks: [ - { - type: CONST.ONBOARDING_TASK_TYPE.VIEW_TOUR, - title: () => 'View Tour', - description: () => 'Take a tour', - autoCompleted: false, - }, - ], - }, - adminsChatReportID: '1', - // SMALL keeps the tasks path active; MANAGE_TEAM + MICRO routes through Phase 1 followups. - companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL, - isSelfTourViewed: undefined, - }); - - const viewTourTask = result?.guidedSetupData.find( - (item): item is Extract => item.type === 'task' && 'task' in item && item.task === CONST.ONBOARDING_TASK_TYPE.VIEW_TOUR, - ); - expect(viewTourTask).toBeDefined(); - expect(viewTourTask?.completedTaskReportActionID).toBeDefined(); - }); }); describe('getIconsForParticipants', () => {