feat(shared): add plan helpers (#4347)

* feat(shared): add plan helpers

* feat(shared): naming is hard

* feat(shared): spelling is hard
This commit is contained in:
Gergő Jedlicska
2025-04-08 19:59:30 +02:00
committed by GitHub
parent 5fc2d5c089
commit a986bee2fb
2 changed files with 141 additions and 24 deletions
@@ -1,28 +1,93 @@
import { describe, expect, it } from 'vitest'
import { isNewWorkspacePlan, WorkspacePlans } from './plans.js'
import {
doesPlanIncludeUnlimitedProjectsAddon,
isNewWorkspacePlan,
isSelfServeAvailablePlan,
WorkspacePlans
} from './plans.js'
describe('isNewWorkspacePlan', () => {
const planCases: {
[P in WorkspacePlans]: boolean
} = <const>{
business: false,
businessInvoiced: false,
plus: false,
plusInvoiced: false,
starter: false,
starterInvoiced: false,
free: true,
academia: true,
unlimited: true,
pro: true,
proUnlimited: true,
proUnlimitedInvoiced: true,
team: true,
teamUnlimited: true,
teamUnlimitedInvoiced: true
}
it.each(Object.entries(planCases))('plan %s is new type -> %s', (plan, isNew) => {
const result = isNewWorkspacePlan(plan as WorkspacePlans)
expect(result).toStrictEqual(isNew)
describe('plan helpers', () => {
describe('isNewWorkspacePlan', () => {
const planCases: {
[P in WorkspacePlans]: boolean
} = <const>{
business: false,
businessInvoiced: false,
plus: false,
plusInvoiced: false,
starter: false,
starterInvoiced: false,
free: true,
academia: true,
unlimited: true,
pro: true,
proUnlimited: true,
proUnlimitedInvoiced: true,
team: true,
teamUnlimited: true,
teamUnlimitedInvoiced: true
}
it.each(Object.entries(planCases))('plan %s is new type -> %s', (plan, isNew) => {
const result = isNewWorkspacePlan(plan as WorkspacePlans)
expect(result).toStrictEqual(isNew)
})
})
describe('doesPlanIncludeUnlimitedProjectsAddon', () => {
const planCases: {
[P in WorkspacePlans]: boolean
} = <const>{
business: false,
businessInvoiced: false,
plus: false,
plusInvoiced: false,
starter: false,
starterInvoiced: false,
free: false,
academia: false,
unlimited: false,
pro: false,
proUnlimited: true,
proUnlimitedInvoiced: false,
team: false,
teamUnlimited: true,
teamUnlimitedInvoiced: false
}
it.each(Object.entries(planCases))(
'plan %s include the paid unlimited projects addon -> %s',
(plan, isNew) => {
const result = doesPlanIncludeUnlimitedProjectsAddon(plan as WorkspacePlans)
expect(result).toStrictEqual(isNew)
}
)
})
describe('isSelfServeAvailablePlan', () => {
const planCases: {
[P in WorkspacePlans]: boolean
} = <const>{
business: false,
businessInvoiced: false,
plus: false,
plusInvoiced: false,
starter: false,
starterInvoiced: false,
free: true,
academia: false,
unlimited: false,
pro: true,
proUnlimited: true,
proUnlimitedInvoiced: false,
team: true,
teamUnlimited: true,
teamUnlimitedInvoiced: false
}
it.each(Object.entries(planCases))(
'is plan %s available self served -> %s',
(plan, isNew) => {
const result = isSelfServeAvailablePlan(plan as WorkspacePlans)
expect(result).toStrictEqual(isNew)
}
)
})
})
@@ -94,6 +94,58 @@ export const isNewWorkspacePlan = (
}
}
export const doesPlanIncludeUnlimitedProjectsAddon = (
plan: WorkspacePlans
): boolean => {
switch (plan) {
case 'teamUnlimited':
case 'proUnlimited':
return true
case 'free':
case 'team':
case 'pro':
case 'starter':
case 'plus':
case 'business':
case 'starterInvoiced':
case 'plusInvoiced':
case 'businessInvoiced':
case 'teamUnlimitedInvoiced':
case 'proUnlimitedInvoiced':
case 'unlimited':
case 'academia':
return false
default:
throwUncoveredError(plan)
}
}
export const isSelfServeAvailablePlan = (plan: WorkspacePlans): boolean => {
switch (plan) {
case 'free':
case 'team':
case 'teamUnlimited':
case 'pro':
case 'proUnlimited':
return true
case 'starter':
case 'plus':
case 'business':
case 'starterInvoiced':
case 'plusInvoiced':
case 'businessInvoiced':
case 'teamUnlimitedInvoiced':
case 'proUnlimitedInvoiced':
case 'unlimited':
case 'academia':
return false
default:
throwUncoveredError(plan)
}
}
/**
* BILLING INTERVALS
*/