Skip to content

Commit 7015231

Browse files
authored
Merge pull request Expensify#85326 from Expensify/marco/610942-expand-pregenerated-response
2 parents 0807a41 + 966203b commit 7015231

3 files changed

Lines changed: 142 additions & 13 deletions

File tree

src/libs/ReportUtils.ts

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11640,15 +11640,34 @@ type PrepareOnboardingOnyxDataParams = {
1164011640
betas?: OnyxEntry<Beta[]>;
1164111641
};
1164211642

11643-
function getBespokeWelcomeMessage(userReportedIntegration?: OnboardingAccounting): string {
11643+
function getBespokeWelcomeMessage(companySize: OnboardingCompanySize | undefined, userReportedIntegration?: OnboardingAccounting): string {
1164411644
// Use markdown (not HTML) because buildOptimisticAddCommentReportAction -> getParsedComment
1164511645
// escapes HTML entities before parsing, so raw HTML tags would render as literal text.
11646-
let message =
11647-
"# Your free trial has started! Let's get you set up.\n" +
11648-
"👋 Hey there! I'm your Expensify setup specialist. " +
11649-
'For a small team like yours, the fastest way to get value is to set up a few expense categories, ' +
11650-
'invite your team members, and have them start snapping receipts right away. ' +
11651-
"I'm here to walk you through each step — just ask!";
11646+
const welcomeHeader = "# Your free trial has started! Let's get you set up.\n👋 Hey there! I'm your Expensify setup specialist. ";
11647+
11648+
let message = welcomeHeader;
11649+
switch (companySize) {
11650+
case CONST.ONBOARDING_COMPANY_SIZE.MEDIUM:
11651+
case CONST.ONBOARDING_COMPANY_SIZE.LARGE:
11652+
message +=
11653+
'For an organization your size, the fastest path to value is setting up approval workflows, ' +
11654+
'connecting your accounting software, and rolling out the Expensify Card to your team. ' +
11655+
"I'm here to walk you through each step — just ask!";
11656+
break;
11657+
case CONST.ONBOARDING_COMPANY_SIZE.SMALL:
11658+
case CONST.ONBOARDING_COMPANY_SIZE.MEDIUM_SMALL:
11659+
message +=
11660+
'For a growing team like yours, the fastest way to get value is to set up expense categories, ' +
11661+
'configure approval workflows, and invite your team members. ' +
11662+
"I'm here to walk you through each step — just ask!";
11663+
break;
11664+
default:
11665+
message +=
11666+
'For a small team like yours, the fastest way to get value is to set up a few expense categories, ' +
11667+
'invite your team members, and have them start snapping receipts right away. ' +
11668+
"I'm here to walk you through each step — just ask!";
11669+
break;
11670+
}
1165211671

1165311672
if (userReportedIntegration && userReportedIntegration !== 'other') {
1165411673
const friendlyName = CONST.ONBOARDING_ACCOUNTING_MAPPING[userReportedIntegration as keyof typeof CONST.ONBOARDING_ACCOUNTING_MAPPING];
@@ -11755,14 +11774,14 @@ function prepareOnboardingOnyxData({
1175511774
reportComment: textComment.commentText,
1175611775
};
1175711776

11758-
// When the user is MICRO and using followups, generate a bespoke welcome message from Concierge.
11777+
// When using followups instead of tasks, generate a bespoke welcome message from Concierge.
1175911778
// The frontend displays it optimistically; the server uses it to generate suggested followups.
1176011779
let bespokeWelcomeMessage: string | undefined;
1176111780
let optimisticConciergeReportActionID: string | undefined;
1176211781
let bespokeAction: OptimisticReportAction | undefined;
1176311782

11764-
if (shouldUseFollowupsInsteadOfTasks && companySize === CONST.ONBOARDING_COMPANY_SIZE.MICRO) {
11765-
bespokeWelcomeMessage = getBespokeWelcomeMessage(userReportedIntegration);
11783+
if (shouldUseFollowupsInsteadOfTasks) {
11784+
bespokeWelcomeMessage = getBespokeWelcomeMessage(companySize, userReportedIntegration);
1176611785
optimisticConciergeReportActionID = rand64();
1176711786
bespokeAction = buildOptimisticAddCommentReportAction({
1176811787
text: bespokeWelcomeMessage,

tests/actions/PolicyTest.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ describe('actions/Policy', () => {
188188

189189
// After filtering, two actions are added to the list =- signoff message (+1) and default create action (+1)
190190
const expectedReportActionsOfTypeCreatedCount = 1;
191-
const expectedSignOffMessagesCount = 0;
191+
const expectedSignOffMessagesCount = 1;
192192
expect(adminReportActions.length).toBe(expectedManageTeamDefaultTasksCount + expectedReportActionsOfTypeCreatedCount + expectedSignOffMessagesCount);
193193

194194
let reportActionsOfTypeCreatedCount = 0;

tests/unit/ReportUtilsTest.ts

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,13 +572,123 @@ describe('ReportUtils', () => {
572572
companySize: CONST.ONBOARDING_COMPANY_SIZE.MICRO,
573573
});
574574
expect(result?.guidedSetupData).toHaveLength(0);
575-
// MICRO company size with suggestedFollowups beta adds a bespoke Concierge welcome action optimistically
575+
// suggestedFollowups beta adds a bespoke Concierge welcome action optimistically for all company sizes
576576
const reportActionsEntries = result?.optimisticData.filter((i) => i.key === `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${adminsChatReportID}`);
577577
expect(reportActionsEntries).toHaveLength(1);
578-
expect(result?.bespokeWelcomeMessage).toBeDefined();
578+
expect(result?.bespokeWelcomeMessage).toContain('For a small team like yours');
579579
expect(result?.optimisticConciergeReportActionID).toBeDefined();
580580
});
581581

582+
it('should generate bespoke welcome message for SMALL company sizes with suggestedFollowups beta', async () => {
583+
const adminsChatReportID = '1';
584+
await Onyx.merge(ONYXKEYS.SESSION, {email: 'test@example.com'});
585+
await Onyx.merge(ONYXKEYS.BETAS, [CONST.BETAS.SUGGESTED_FOLLOWUPS]);
586+
await waitForBatchedUpdates();
587+
588+
const result = prepareOnboardingOnyxData({
589+
introSelected: undefined,
590+
engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM,
591+
onboardingMessage: {
592+
message: 'This is a test',
593+
tasks: [{type: CONST.ONBOARDING_TASK_TYPE.CONNECT_CORPORATE_CARD, title: () => '', description: () => '', autoCompleted: false}],
594+
},
595+
adminsChatReportID,
596+
selectedInterestedFeatures: ['areCompanyCardsEnabled'],
597+
companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL,
598+
});
599+
expect(result?.guidedSetupData).toHaveLength(0);
600+
expect(result?.bespokeWelcomeMessage).toContain('growing team');
601+
expect(result?.optimisticConciergeReportActionID).toBeDefined();
602+
});
603+
604+
it('should generate bespoke welcome message for LARGE company sizes with suggestedFollowups beta', async () => {
605+
const adminsChatReportID = '1';
606+
await Onyx.merge(ONYXKEYS.SESSION, {email: 'test@example.com'});
607+
await Onyx.merge(ONYXKEYS.BETAS, [CONST.BETAS.SUGGESTED_FOLLOWUPS]);
608+
await waitForBatchedUpdates();
609+
610+
const result = prepareOnboardingOnyxData({
611+
introSelected: undefined,
612+
engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM,
613+
onboardingMessage: {
614+
message: 'This is a test',
615+
tasks: [{type: CONST.ONBOARDING_TASK_TYPE.CONNECT_CORPORATE_CARD, title: () => '', description: () => '', autoCompleted: false}],
616+
},
617+
adminsChatReportID,
618+
selectedInterestedFeatures: ['areCompanyCardsEnabled'],
619+
companySize: CONST.ONBOARDING_COMPANY_SIZE.LARGE,
620+
});
621+
expect(result?.guidedSetupData).toHaveLength(0);
622+
expect(result?.bespokeWelcomeMessage).toContain('organization your size');
623+
expect(result?.optimisticConciergeReportActionID).toBeDefined();
624+
});
625+
626+
it('should generate bespoke welcome message for MEDIUM_SMALL company sizes with suggestedFollowups beta', async () => {
627+
const adminsChatReportID = '1';
628+
await Onyx.merge(ONYXKEYS.SESSION, {email: 'test@example.com'});
629+
await Onyx.merge(ONYXKEYS.BETAS, [CONST.BETAS.SUGGESTED_FOLLOWUPS]);
630+
await waitForBatchedUpdates();
631+
632+
const result = prepareOnboardingOnyxData({
633+
introSelected: undefined,
634+
engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM,
635+
onboardingMessage: {
636+
message: 'This is a test',
637+
tasks: [{type: CONST.ONBOARDING_TASK_TYPE.CONNECT_CORPORATE_CARD, title: () => '', description: () => '', autoCompleted: false}],
638+
},
639+
adminsChatReportID,
640+
selectedInterestedFeatures: ['areCompanyCardsEnabled'],
641+
companySize: CONST.ONBOARDING_COMPANY_SIZE.MEDIUM_SMALL,
642+
});
643+
expect(result?.guidedSetupData).toHaveLength(0);
644+
expect(result?.bespokeWelcomeMessage).toContain('growing team');
645+
expect(result?.optimisticConciergeReportActionID).toBeDefined();
646+
});
647+
648+
it('should generate bespoke welcome message for MEDIUM company sizes with suggestedFollowups beta', async () => {
649+
const adminsChatReportID = '1';
650+
await Onyx.merge(ONYXKEYS.SESSION, {email: 'test@example.com'});
651+
await Onyx.merge(ONYXKEYS.BETAS, [CONST.BETAS.SUGGESTED_FOLLOWUPS]);
652+
await waitForBatchedUpdates();
653+
654+
const result = prepareOnboardingOnyxData({
655+
introSelected: undefined,
656+
engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM,
657+
onboardingMessage: {
658+
message: 'This is a test',
659+
tasks: [{type: CONST.ONBOARDING_TASK_TYPE.CONNECT_CORPORATE_CARD, title: () => '', description: () => '', autoCompleted: false}],
660+
},
661+
adminsChatReportID,
662+
selectedInterestedFeatures: ['areCompanyCardsEnabled'],
663+
companySize: CONST.ONBOARDING_COMPANY_SIZE.MEDIUM,
664+
});
665+
expect(result?.guidedSetupData).toHaveLength(0);
666+
expect(result?.bespokeWelcomeMessage).toContain('organization your size');
667+
expect(result?.optimisticConciergeReportActionID).toBeDefined();
668+
});
669+
670+
it('should append accounting integration suffix to bespoke welcome message', async () => {
671+
const adminsChatReportID = '1';
672+
await Onyx.merge(ONYXKEYS.SESSION, {email: 'test@example.com'});
673+
await Onyx.merge(ONYXKEYS.BETAS, [CONST.BETAS.SUGGESTED_FOLLOWUPS]);
674+
await waitForBatchedUpdates();
675+
676+
const result = prepareOnboardingOnyxData({
677+
introSelected: undefined,
678+
engagementChoice: CONST.ONBOARDING_CHOICES.MANAGE_TEAM,
679+
onboardingMessage: {
680+
message: 'This is a test',
681+
tasks: [{type: CONST.ONBOARDING_TASK_TYPE.CONNECT_CORPORATE_CARD, title: () => '', description: () => '', autoCompleted: false}],
682+
},
683+
adminsChatReportID,
684+
selectedInterestedFeatures: ['areCompanyCardsEnabled'],
685+
companySize: CONST.ONBOARDING_COMPANY_SIZE.SMALL,
686+
userReportedIntegration: 'quickbooksOnline',
687+
});
688+
expect(result?.bespokeWelcomeMessage).toContain('QuickBooks Online');
689+
expect(result?.bespokeWelcomeMessage).toContain('expenses sync automatically');
690+
});
691+
582692
it('should add guidedSetupData when posting into admin room WITHOUT suggestedFollowups beta', async () => {
583693
const adminsChatReportID = '1';
584694
// Not having `+` in the email allows for `isPostingTasksInAdminsRoom` flow

0 commit comments

Comments
 (0)