1
0
Fork 0
mirror of synced 2024-07-15 11:15:59 +12:00

Added new unit tests for feature flags

This commit is contained in:
Dean 2023-02-02 11:38:10 +00:00
parent 0eed617866
commit 065e74024e
2 changed files with 101 additions and 14 deletions

View file

@ -6,7 +6,7 @@ import * as tenancy from "../tenancy"
* The env var is formatted as:
* tenant1:feature1:feature2,tenant2:feature1
*/
function getFeatureFlags() {
export function buildFeatureFlags() {
if (!env.TENANT_FEATURE_FLAGS) {
return
}
@ -27,8 +27,6 @@ function getFeatureFlags() {
return tenantFeatureFlags
}
const TENANT_FEATURE_FLAGS = getFeatureFlags()
export function isEnabled(featureFlag: string) {
const tenantId = tenancy.getTenantId()
const flags = getTenantFeatureFlags(tenantId)
@ -37,20 +35,23 @@ export function isEnabled(featureFlag: string) {
export function getTenantFeatureFlags(tenantId: string) {
let flags: string[] = []
if (TENANT_FEATURE_FLAGS) {
const globalFlags = TENANT_FEATURE_FLAGS["*"]
const tenantFlags = TENANT_FEATURE_FLAGS[tenantId] || []
const envFlags = buildFeatureFlags()
if (envFlags) {
const globalFlags = envFlags["*"]
const tenantFlags = envFlags[tenantId] || []
// Explicitly exclude tenants from global features if required.
// Prefix the tenant flag with '!'
const tenantOverrides = tenantFlags.reduce((acc: string[], flag) => {
if (flag.startsWith("!")) {
let stripped = flag.substring(1)
acc.push(stripped)
}
return acc
}, [])
const tenantOverrides = tenantFlags.reduce(
(acc: string[], flag: string) => {
if (flag.startsWith("!")) {
let stripped = flag.substring(1)
acc.push(stripped)
}
return acc
},
[]
)
if (globalFlags) {
flags.push(...globalFlags)
@ -72,4 +73,5 @@ export enum TenantFeatureFlag {
LICENSING = "LICENSING",
GOOGLE_SHEETS = "GOOGLE_SHEETS",
USER_GROUPS = "USER_GROUPS",
ONBOARDING_TOUR = "ONBOARDING_TOUR",
}

View file

@ -0,0 +1,85 @@
import {
TenantFeatureFlag,
buildFeatureFlags,
getTenantFeatureFlags,
} from "../"
import env from "../../environment"
const { ONBOARDING_TOUR, LICENSING, USER_GROUPS } = TenantFeatureFlag
describe("featureFlags", () => {
beforeEach(() => {
env._set("TENANT_FEATURE_FLAGS", "")
})
it("Should return no flags when the TENANT_FEATURE_FLAG is empty", async () => {
let features = buildFeatureFlags()
expect(features).toBeUndefined()
})
it("Should generate a map of global and named tenant feature flags from the env value", async () => {
env._set(
"TENANT_FEATURE_FLAGS",
`*:${ONBOARDING_TOUR},tenant1:!${ONBOARDING_TOUR},tenant2:${USER_GROUPS},tenant1:${LICENSING}`
)
const parsedFlags: Record<string, string[]> = {
"*": [ONBOARDING_TOUR],
tenant1: [`!${ONBOARDING_TOUR}`, LICENSING],
tenant2: [USER_GROUPS],
}
let features = buildFeatureFlags()
expect(features).toBeDefined()
expect(features).toEqual(parsedFlags)
})
it("Should add feature flag flag only to explicitly configured tenant", async () => {
env._set(
"TENANT_FEATURE_FLAGS",
`*:${LICENSING},*:${USER_GROUPS},tenant1:${ONBOARDING_TOUR}`
)
let tenant1Flags = getTenantFeatureFlags("tenant1")
let tenant2Flags = getTenantFeatureFlags("tenant2")
expect(tenant1Flags).toBeDefined()
expect(tenant1Flags).toEqual([LICENSING, USER_GROUPS, ONBOARDING_TOUR])
expect(tenant2Flags).toBeDefined()
expect(tenant2Flags).toEqual([LICENSING, USER_GROUPS])
})
})
it("Should exclude tenant1 from global feature flag", async () => {
env._set(
"TENANT_FEATURE_FLAGS",
`*:${LICENSING},*:${ONBOARDING_TOUR},tenant1:!${ONBOARDING_TOUR}`
)
let tenant1Flags = getTenantFeatureFlags("tenant1")
let tenant2Flags = getTenantFeatureFlags("tenant2")
expect(tenant1Flags).toBeDefined()
expect(tenant1Flags).toEqual([LICENSING])
expect(tenant2Flags).toBeDefined()
expect(tenant2Flags).toEqual([LICENSING, ONBOARDING_TOUR])
})
it("Should explicitly add flags to configured tenants only", async () => {
env._set(
"TENANT_FEATURE_FLAGS",
`tenant1:${ONBOARDING_TOUR},tenant1:${LICENSING},tenant2:${LICENSING}`
)
let tenant1Flags = getTenantFeatureFlags("tenant1")
let tenant2Flags = getTenantFeatureFlags("tenant2")
expect(tenant1Flags).toBeDefined()
expect(tenant1Flags).toEqual([ONBOARDING_TOUR, LICENSING])
expect(tenant2Flags).toBeDefined()
expect(tenant2Flags).toEqual([LICENSING])
})