mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
Merge pull request #36011 from overleaf/jel-domain-capture-sales-email
[web] Weekly domain capture digest email GitOrigin-RevId: 6682d1d7fcbb179615dbc009d2da8266113a3b4b
This commit is contained in:
@@ -172,14 +172,38 @@ async function userIsMemberOfGroupSubscription(user) {
|
||||
/**
|
||||
* @param {any} subscription
|
||||
*/
|
||||
function teamHasReachedMemberLimit(subscription) {
|
||||
const currentTotal =
|
||||
function currentGroupTotal(subscription) {
|
||||
return (
|
||||
(subscription.member_ids || []).length +
|
||||
(subscription.teamInvites || []).length +
|
||||
(subscription.invited_emails || []).length
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} subscription
|
||||
*/
|
||||
function teamHasReachedMemberLimit(subscription) {
|
||||
const currentTotal = currentGroupTotal(subscription)
|
||||
|
||||
return currentTotal >= subscription.membersLimit
|
||||
}
|
||||
/**
|
||||
* Calculate the number of remaining seats for a group subscription.
|
||||
*
|
||||
* @param {any} subscriptionId - The subscription ID
|
||||
* @returns {Promise<number>} - Remaining seats (membersLimit - current members/invites)
|
||||
*/
|
||||
async function remainingSeatsForGroup(subscriptionId) {
|
||||
const subscription =
|
||||
await SubscriptionLocator.promises.getSubscription(subscriptionId)
|
||||
if (!subscription) {
|
||||
logger.warn({ subscriptionId }, 'no subscription found')
|
||||
throw new Error('no subscription found')
|
||||
}
|
||||
const currentTotal = currentGroupTotal(subscription)
|
||||
return subscription.membersLimit - currentTotal
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {any} subscriptionId
|
||||
@@ -241,6 +265,7 @@ const LimitationsManager = {
|
||||
userHasSubscription,
|
||||
userIsMemberOfGroupSubscription,
|
||||
hasGroupMembersLimitReached,
|
||||
remainingSeatsForGroup,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -636,4 +636,83 @@ describe('LimitationsManager', function () {
|
||||
expect(limitReached).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
describe('remainingSeatsForGroup', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.subscriptionId = '12312'
|
||||
ctx.subscription = {
|
||||
membersLimit: 10,
|
||||
member_ids: ['u1', 'u2', 'u3'],
|
||||
teamInvites: [
|
||||
{ email: 'bob@example.com', sentAt: new Date(), token: 'hey' },
|
||||
],
|
||||
invited_emails: ['pending@example.com'],
|
||||
}
|
||||
})
|
||||
|
||||
it('should return the number of remaining seats', async function (ctx) {
|
||||
ctx.SubscriptionLocator.promises.getSubscription.resolves(
|
||||
ctx.subscription
|
||||
)
|
||||
// 10 - (3 members + 1 teamInvite + 1 invited_email) = 5
|
||||
const result =
|
||||
await ctx.LimitationsManager.promises.remainingSeatsForGroup(
|
||||
ctx.subscriptionId
|
||||
)
|
||||
expect(result).to.equal(5)
|
||||
})
|
||||
|
||||
it('should return 0 when the limit is exactly reached', async function (ctx) {
|
||||
ctx.subscription.membersLimit = 5
|
||||
ctx.SubscriptionLocator.promises.getSubscription.resolves(
|
||||
ctx.subscription
|
||||
)
|
||||
// 5 - (3 members + 1 teamInvite + 1 invited_email) = 0
|
||||
const result =
|
||||
await ctx.LimitationsManager.promises.remainingSeatsForGroup(
|
||||
ctx.subscriptionId
|
||||
)
|
||||
expect(result).to.equal(0)
|
||||
})
|
||||
|
||||
it('should return a negative number when the limit has been exceeded', async function (ctx) {
|
||||
ctx.subscription.membersLimit = 4
|
||||
ctx.SubscriptionLocator.promises.getSubscription.resolves(
|
||||
ctx.subscription
|
||||
)
|
||||
// 4 - (3 members + 1 teamInvite + 1 invited_email) = -1
|
||||
const result =
|
||||
await ctx.LimitationsManager.promises.remainingSeatsForGroup(
|
||||
ctx.subscriptionId
|
||||
)
|
||||
expect(result).to.equal(-1)
|
||||
})
|
||||
|
||||
it('should treat missing member_ids, teamInvites, and invited_emails as empty', async function (ctx) {
|
||||
ctx.subscription.member_ids = undefined
|
||||
ctx.subscription.teamInvites = undefined
|
||||
ctx.subscription.invited_emails = undefined
|
||||
ctx.SubscriptionLocator.promises.getSubscription.resolves(
|
||||
ctx.subscription
|
||||
)
|
||||
const result =
|
||||
await ctx.LimitationsManager.promises.remainingSeatsForGroup(
|
||||
ctx.subscriptionId
|
||||
)
|
||||
expect(result).to.equal(10)
|
||||
})
|
||||
|
||||
it('should throw when no subscription is found', async function (ctx) {
|
||||
ctx.SubscriptionLocator.promises.getSubscription.resolves(null)
|
||||
let error
|
||||
try {
|
||||
await ctx.LimitationsManager.promises.remainingSeatsForGroup(
|
||||
ctx.subscriptionId
|
||||
)
|
||||
} catch (e) {
|
||||
error = e
|
||||
}
|
||||
expect(error?.message).to.equal('no subscription found')
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user