Skip to content

Commit a45c940

Browse files
authored
Merge pull request #3869 from codecrafters-io/tropicolx/lobbyside-other-emails
Push non-primary emails to Lobbyside (other_emails column)
2 parents a5ab2f5 + 39a0096 commit a45c940

4 files changed

Lines changed: 57 additions & 0 deletions

File tree

app/components/lobbyside-widget/index.hbs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
this.customFields.stages_completed
2626
this.customFields.signed_up_date
2727
this.customFields.subscription_type
28+
this.customFields.other_emails
2829
}}
2930
{{will-destroy this.removeScript}}
3031
></div>

app/components/lobbyside-widget/index.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ declare global {
1515
stages_completed: string;
1616
signed_up_date: string;
1717
subscription_type: string;
18+
other_emails: string;
1819
}): void;
1920
};
2021
}
@@ -30,12 +31,15 @@ interface VisitorSource {
3031
hasActiveSubscription?: boolean;
3132
teamHasActiveSubscription?: boolean;
3233
courseParticipations?: { completedStageSlugs?: string[] }[];
34+
primaryEmailAddress?: string | null;
35+
emailAddresses?: { value?: string | null }[];
3336
}
3437

3538
export interface LobbysideCustomFields {
3639
stages_completed: string;
3740
signed_up_date: string;
3841
subscription_type: string;
42+
other_emails: string;
3943
}
4044

4145
function subscriptionType(user: VisitorSource | null | undefined): string {
@@ -62,6 +66,21 @@ function subscriptionType(user: VisitorSource | null | undefined): string {
6266
return 'free';
6367
}
6468

69+
function otherEmails(user: VisitorSource | null | undefined): string {
70+
const primary = (user?.primaryEmailAddress ?? '').trim();
71+
const seen = new Set<string>();
72+
73+
for (const entry of user?.emailAddresses ?? []) {
74+
const value = (entry?.value ?? '').trim();
75+
76+
if (value && value !== primary) {
77+
seen.add(value);
78+
}
79+
}
80+
81+
return Array.from(seen).join(', ');
82+
}
83+
6584
export function lobbysideCustomFields(user: VisitorSource | null | undefined): LobbysideCustomFields {
6685
const stagesCompleted = (user?.courseParticipations ?? []).reduce(
6786
(sum, participation) => sum + (participation.completedStageSlugs?.length ?? 0),
@@ -72,6 +91,7 @@ export function lobbysideCustomFields(user: VisitorSource | null | undefined): L
7291
stages_completed: String(stagesCompleted),
7392
signed_up_date: user?.createdAt ? user.createdAt.toISOString().slice(0, 10) : '',
7493
subscription_type: subscriptionType(user),
94+
other_emails: otherEmails(user),
7595
};
7696
}
7797

app/services/authenticator.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ export default class AuthenticatorService extends Service {
118118
'affiliate-links.user',
119119
// Powers the `stages_completed` field the Lobbyside widget pushes via setVisitor.
120120
'course-participations',
121+
// Powers the `other_emails` field the Lobbyside widget pushes via setVisitor.
122+
'email-addresses',
121123
'feature-suggestions',
122124
'promotional-discounts',
123125
'promotional-discounts.affiliate-referral',

tests/unit/components/lobbyside-widget-test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module('Unit | Component | lobbyside-widget', function () {
2020
stages_completed: '0',
2121
signed_up_date: '',
2222
subscription_type: '',
23+
other_emails: '',
2324
});
2425
});
2526

@@ -57,4 +58,37 @@ module('Unit | Component | lobbyside-widget', function () {
5758

5859
assert.strictEqual(lobbysideCustomFields(createUser()).subscription_type, 'free');
5960
});
61+
62+
test('other_emails joins every non-primary email, comma-separated', function (assert) {
63+
const user = createUser({
64+
primaryEmailAddress: 'primary@example.com',
65+
emailAddresses: [{ value: 'primary@example.com' }, { value: 'work@example.com' }, { value: 'school@example.com' }],
66+
} as unknown as Partial<UserModel>);
67+
68+
assert.strictEqual(lobbysideCustomFields(user).other_emails, 'work@example.com, school@example.com');
69+
});
70+
71+
test('other_emails excludes the primary email and is empty when it is the only one', function (assert) {
72+
const user = createUser({
73+
primaryEmailAddress: 'primary@example.com',
74+
emailAddresses: [{ value: 'primary@example.com' }],
75+
} as unknown as Partial<UserModel>);
76+
77+
assert.strictEqual(lobbysideCustomFields(user).other_emails, '');
78+
});
79+
80+
test('other_emails dedupes and drops blank values', function (assert) {
81+
const user = createUser({
82+
primaryEmailAddress: 'primary@example.com',
83+
emailAddresses: [{ value: 'work@example.com' }, { value: ' work@example.com ' }, { value: '' }, { value: 'alt@example.com' }],
84+
} as unknown as Partial<UserModel>);
85+
86+
assert.strictEqual(lobbysideCustomFields(user).other_emails, 'work@example.com, alt@example.com');
87+
});
88+
89+
test('other_emails is empty when the user has no email addresses', function (assert) {
90+
const user = createUser({ primaryEmailAddress: 'primary@example.com', emailAddresses: [] } as unknown as Partial<UserModel>);
91+
92+
assert.strictEqual(lobbysideCustomFields(user).other_emails, '');
93+
});
6094
});

0 commit comments

Comments
 (0)