chore(workspaces): add test and make product selection more robust

This commit is contained in:
Alessandro Magionami
2025-03-25 17:40:09 +01:00
parent 55648c3125
commit ddae24eedf
4 changed files with 70 additions and 4 deletions
@@ -67,6 +67,7 @@ import {
} from '@/modules/gatekeeper/repositories/workspaceSeat'
import { assignWorkspaceSeatFactory } from '@/modules/workspaces/services/workspaceSeat'
import { getEventBus } from '@/modules/shared/services/eventBus'
import { getTotalSeatsCountByPlanFactory } from '@/modules/gatekeeper/services/subscriptions'
const { FF_GATEKEEPER_MODULE_ENABLED, FF_BILLING_INTEGRATION_ENABLED } =
getFeatureFlags()
@@ -177,14 +178,16 @@ export = FF_GATEKEEPER_MODULE_ENABLED
}
}
// Only editor seats are considered
const totalSeatsCount = parent.subscriptionData.products[0].quantity
const assignedSeatsCount = await countSeatsByTypeInWorkspaceFactory({ db })({
workspaceId: parent.workspaceId,
type: 'editor'
})
return {
assigned: assignedSeatsCount,
totalCount: totalSeatsCount,
totalCount: getTotalSeatsCountByPlanFactory({ getWorkspacePlanProductId })({
workspacePlan,
subscriptionData: parent.subscriptionData
}),
// These values have no reference in the new plans
guest: 0,
plan: 0
@@ -31,6 +31,7 @@ import { cloneDeep, isEqual, sum } from 'lodash'
import { mutateSubscriptionDataWithNewValidSeatNumbers } from '@/modules/gatekeeper/services/subscriptions/mutateSubscriptionDataWithNewValidSeatNumbers'
import { calculateNewBillingCycleEnd } from '@/modules/gatekeeper/services/subscriptions/calculateNewBillingCycleEnd'
import { CountSeatsByTypeInWorkspace } from '@/modules/gatekeeper/domain/operations'
import { WorkspacePlan } from '@/modules/gatekeeperCore/domain/billing'
export const handleSubscriptionUpdateFactory =
({
@@ -411,3 +412,28 @@ export const manageSubscriptionDownscaleFactory =
log.info({ updatedWorkspaceSubscription }, 'Updated workspace billing cycle end')
}
}
export const getTotalSeatsCountByPlanFactory =
({
getWorkspacePlanProductId
}: {
getWorkspacePlanProductId: GetWorkspacePlanProductId
}) =>
({
workspacePlan,
subscriptionData
}: {
workspacePlan: Pick<WorkspacePlan, 'name'>
subscriptionData: Pick<SubscriptionData, 'products'>
}) => {
if (workspacePlan.name === 'free') {
return 3 // Max editors seats in the free plan
}
const productId = getWorkspacePlanProductId({
workspacePlan: workspacePlan.name as 'pro' | 'team'
})
const product = subscriptionData.products.find(
(product) => product.productId === productId
)
return product?.quantity ?? 0
}
@@ -119,7 +119,7 @@ describe('Workspaces Billing', () => {
'workspace.subscription',
() => {
describe('subscription.seats', () => {
it('should return the number of total seats', async () => {
it('should return the number of total and assigned seats', async () => {
const user = await createTestUser({
name: createRandomString(),
email: createRandomEmail(),
@@ -166,7 +166,7 @@ describe('Workspaces Billing', () => {
expect(res).to.not.haveGraphQLErrors()
const seats = res.data?.workspace.subscription?.seats
expect(seats).to.deep.eq({ guest: 0, plan: 0, assigned: 1, totalCount: 12 })
expect(seats?.assigned).to.eq(1)
})
})
}
@@ -16,6 +16,7 @@ import {
addWorkspaceSubscriptionSeatIfNeededFactoryNew,
addWorkspaceSubscriptionSeatIfNeededFactoryOld,
downscaleWorkspaceSubscriptionFactory,
getTotalSeatsCountByPlanFactory,
handleSubscriptionUpdateFactory,
manageSubscriptionDownscaleFactory
} from '@/modules/gatekeeper/services/subscriptions'
@@ -2178,4 +2179,40 @@ describe('subscriptions @gatekeeper', () => {
expect(newProduct!.priceId).to.equal('newPlanPrice')
})
})
describe('getTotalSeatsCountByPlanFactory returns a function that, ', () => {
it('should return the fixed value for the free plan', () => {
const getWorkspacePlanProductId = () => expect.fail()
expect(
getTotalSeatsCountByPlanFactory({ getWorkspacePlanProductId })({
workspacePlan: { name: 'free' },
subscriptionData: { products: [] }
})
).to.eq(3)
})
it('should return 0 if subscription data has no product', () => {
const getWorkspacePlanProductId = () => 'any'
expect(
getTotalSeatsCountByPlanFactory({ getWorkspacePlanProductId })({
workspacePlan: { name: 'pro' },
subscriptionData: { products: [] }
})
).to.eq(0)
})
it('should return the number of purchased seats in the current billing period for the subscription', () => {
const getWorkspacePlanProductId = () => 'productId'
expect(
getTotalSeatsCountByPlanFactory({ getWorkspacePlanProductId })({
workspacePlan: { name: 'pro' },
subscriptionData: {
products: [
{
productId: 'productId',
quantity: 4
} as SubscriptionData['products'][number]
]
}
})
).to.eq(4)
})
})
})