-
Notifications
You must be signed in to change notification settings - Fork 336
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: Restrict prompt to join org to a smaller set of orgs (#9265)
Prefer higher tiers and bigger over smaller orgs.
- Loading branch information
1 parent
fb34aa1
commit 8cbc121
Showing
2 changed files
with
278 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,13 +45,15 @@ type TestOrganizationUser = Pick< | |
const addOrg = async ( | ||
activeDomain: string | null, | ||
members: TestOrganizationUser[], | ||
featureFlags?: string[] | ||
rest?: {featureFlags?: string[]; tier?: string} | ||
) => { | ||
const {featureFlags, tier} = rest ?? {} | ||
const orgId = generateUID() | ||
const org = { | ||
id: orgId, | ||
activeDomain, | ||
featureFlags: featureFlags ?? [] | ||
featureFlags: featureFlags ?? [], | ||
tier: tier ?? 'starter' | ||
} | ||
|
||
const orgUsers = members.map((member) => ({ | ||
|
@@ -143,7 +145,7 @@ test('Org with noPromptToJoinOrg feature flag is ignored', async () => { | |
userId: 'user2' | ||
} | ||
], | ||
['noPromptToJoinOrg'] | ||
{featureFlags: ['noPromptToJoinOrg']} | ||
) | ||
|
||
const orgIds = await getEligibleOrgIdsByDomain('parabol.co', 'newUser', dataLoader) | ||
|
@@ -285,7 +287,84 @@ test('Org matching the user are ignored', async () => { | |
expect(userLoader.loadMany).toHaveBeenCalledTimes(0) | ||
}) | ||
|
||
test('All orgs with verified emails qualify', async () => { | ||
test('Only the biggest org with verified emails qualify', async () => { | ||
const org = await addOrg('parabol.co', [ | ||
{ | ||
joinedAt: new Date('2023-09-06'), | ||
userId: 'founder1' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member1' | ||
} | ||
]) | ||
const biggerOrg = await addOrg('parabol.co', [ | ||
{ | ||
joinedAt: new Date('2023-09-06'), | ||
userId: 'founder2' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member2' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member3' | ||
} | ||
]) | ||
await addOrg('parabol.co', [ | ||
{ | ||
joinedAt: new Date('2023-09-06'), | ||
userId: 'founder3' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member3' | ||
} | ||
]) | ||
|
||
userLoader.loadMany.mockImplementation((userIds) => { | ||
const users = { | ||
founder1: { | ||
email: '[email protected]', | ||
identities: [ | ||
{ | ||
isEmailVerified: true | ||
} | ||
] | ||
}, | ||
founder2: { | ||
email: '[email protected]', | ||
identities: [ | ||
{ | ||
isEmailVerified: true | ||
} | ||
] | ||
}, | ||
founder3: { | ||
email: '[email protected]', | ||
identities: [ | ||
{ | ||
isEmailVerified: false | ||
} | ||
] | ||
} | ||
} | ||
return userIds.map((id) => ({ | ||
id, | ||
...users[id] | ||
})) | ||
}) | ||
|
||
const orgIds = await getEligibleOrgIdsByDomain('parabol.co', 'newUser', dataLoader) | ||
expect(userLoader.loadMany).toHaveBeenCalledTimes(3) | ||
expect(userLoader.loadMany).toHaveBeenCalledWith(['founder1']) | ||
expect(userLoader.loadMany).toHaveBeenCalledWith(['founder2']) | ||
expect(userLoader.loadMany).toHaveBeenCalledWith(['founder3']) | ||
expect(orgIds).toIncludeSameMembers([biggerOrg]) | ||
}) | ||
|
||
test('All the biggest orgs with verified emails qualify', async () => { | ||
const org1 = await addOrg('parabol.co', [ | ||
{ | ||
joinedAt: new Date('2023-09-06'), | ||
|
@@ -358,6 +437,172 @@ test('All orgs with verified emails qualify', async () => { | |
expect(orgIds).toIncludeSameMembers([org1, org2]) | ||
}) | ||
|
||
test('Team trumps starter tier with more users org', async () => { | ||
const teamOrg = await addOrg( | ||
'parabol.co', | ||
[ | ||
{ | ||
joinedAt: new Date('2023-09-06'), | ||
userId: 'founder1' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member1' | ||
} | ||
], | ||
{tier: 'team'} | ||
) | ||
const biggerStarterOrg = await addOrg('parabol.co', [ | ||
{ | ||
joinedAt: new Date('2023-09-06'), | ||
userId: 'founder2' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member2' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member3' | ||
} | ||
]) | ||
await addOrg('parabol.co', [ | ||
{ | ||
joinedAt: new Date('2023-09-06'), | ||
userId: 'founder3' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member3' | ||
} | ||
]) | ||
|
||
userLoader.loadMany.mockImplementation((userIds) => { | ||
const users = { | ||
founder1: { | ||
email: '[email protected]', | ||
identities: [ | ||
{ | ||
isEmailVerified: true | ||
} | ||
] | ||
}, | ||
founder2: { | ||
email: '[email protected]', | ||
identities: [ | ||
{ | ||
isEmailVerified: true | ||
} | ||
] | ||
}, | ||
founder3: { | ||
email: '[email protected]', | ||
identities: [ | ||
{ | ||
isEmailVerified: false | ||
} | ||
] | ||
} | ||
} | ||
return userIds.map((id) => ({ | ||
id, | ||
...users[id] | ||
})) | ||
}) | ||
|
||
const orgIds = await getEligibleOrgIdsByDomain('parabol.co', 'newUser', dataLoader) | ||
expect(userLoader.loadMany).toHaveBeenCalledTimes(3) | ||
expect(userLoader.loadMany).toHaveBeenCalledWith(['founder1']) | ||
expect(userLoader.loadMany).toHaveBeenCalledWith(['founder2']) | ||
expect(userLoader.loadMany).toHaveBeenCalledWith(['founder3']) | ||
expect(orgIds).toIncludeSameMembers([teamOrg]) | ||
}) | ||
|
||
test('Enterprise trumps team tier with more users org', async () => { | ||
const enterpriseOrg = await addOrg( | ||
'parabol.co', | ||
[ | ||
{ | ||
joinedAt: new Date('2023-09-06'), | ||
userId: 'founder1' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member1' | ||
} | ||
], | ||
{tier: 'enterprise'} | ||
) | ||
const starterOrg = await addOrg( | ||
'parabol.co', | ||
[ | ||
{ | ||
joinedAt: new Date('2023-09-06'), | ||
userId: 'founder2' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member2' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member3' | ||
} | ||
], | ||
{tier: 'team'} | ||
) | ||
await addOrg('parabol.co', [ | ||
{ | ||
joinedAt: new Date('2023-09-06'), | ||
userId: 'founder3' | ||
}, | ||
{ | ||
joinedAt: new Date('2023-09-07'), | ||
userId: 'member3' | ||
} | ||
]) | ||
|
||
userLoader.loadMany.mockImplementation((userIds) => { | ||
const users = { | ||
founder1: { | ||
email: '[email protected]', | ||
identities: [ | ||
{ | ||
isEmailVerified: true | ||
} | ||
] | ||
}, | ||
founder2: { | ||
email: '[email protected]', | ||
identities: [ | ||
{ | ||
isEmailVerified: true | ||
} | ||
] | ||
}, | ||
founder3: { | ||
email: '[email protected]', | ||
identities: [ | ||
{ | ||
isEmailVerified: false | ||
} | ||
] | ||
} | ||
} | ||
return userIds.map((id) => ({ | ||
id, | ||
...users[id] | ||
})) | ||
}) | ||
|
||
const orgIds = await getEligibleOrgIdsByDomain('parabol.co', 'newUser', dataLoader) | ||
expect(userLoader.loadMany).toHaveBeenCalledTimes(3) | ||
expect(userLoader.loadMany).toHaveBeenCalledWith(['founder1']) | ||
expect(userLoader.loadMany).toHaveBeenCalledWith(['founder2']) | ||
expect(userLoader.loadMany).toHaveBeenCalledWith(['founder3']) | ||
expect(orgIds).toIncludeSameMembers([enterpriseOrg]) | ||
}) | ||
|
||
test('Orgs with verified emails from different domains do not qualify', async () => { | ||
const org1 = await addOrg('parabol.co', [ | ||
{ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters