Skip to content

Commit

Permalink
chore: added property to know when instance of ConfigBody is created
Browse files Browse the repository at this point in the history
  • Loading branch information
jsalaber committed Dec 12, 2024
1 parent bdab3fa commit 2a3196a
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 10 deletions.
12 changes: 7 additions & 5 deletions lib/shared/bucketing-test-data/src/data/testData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
UserSubType,
VariableType,
} from '@devcycle/types'
import { plainToInstance } from 'class-transformer'

import moment from 'moment'

Expand Down Expand Up @@ -449,7 +450,7 @@ function configBodyAudiences(audiences: PublicAudience[]): {
return auds
}

export const config: ConfigBody = {
export const config = {
project,
environment,
audiences: configBodyAudiences(reusableAudiences),
Expand Down Expand Up @@ -653,7 +654,7 @@ export const config: ConfigBody = {
clientSDKKey: 'test',
}

export const barrenConfig: ConfigBody = {
export const barrenConfig = {
project,
environment,
audiences: {},
Expand Down Expand Up @@ -730,7 +731,7 @@ export const barrenConfig: ConfigBody = {
variableHashes: {},
}

export const configWithNullCustomData: ConfigBody = {
export const configWithNullCustomData = {
project,
environment,
audiences: configBodyAudiences(reusableAudiences),
Expand Down Expand Up @@ -783,9 +784,10 @@ export const configWithNullCustomData: ConfigBody = {
clientSDKKey: 'test',
}

const instancedConfig = plainToInstance(ConfigBody, config)
export const configWithBucketingKey = (bucketingKey: string): ConfigBody => ({
...config,
features: config.features.map((feature) => ({
...instancedConfig,
features: instancedConfig.features.map((feature) => ({
...feature,
configuration: {
...feature.configuration,
Expand Down
52 changes: 48 additions & 4 deletions lib/shared/bucketing/__tests__/bucketing.test.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
/* eslint-disable max-len */
import { Audience, FeatureType, PublicRollout, Rollout } from '@devcycle/types'
import {
Audience,
FeatureType,
PublicRollout,
Rollout,
ConfigBody,
Test,
} from '@devcycle/types'
import {
generateBoundedHashes,
decideTargetVariation,
generateBucketedConfig,
doesUserPassRollout,
} from '../src/bucketing'
import {
config,
barrenConfig,
configWithNullCustomData,
config as plainConfig,
barrenConfig as plainBarrenConfig,
configWithNullCustomData as plainConfigWithNullCustomData,
configWithBucketingKey,
} from '@devcycle/bucketing-test-data'

import moment from 'moment'
import times from 'lodash/times'
import filter from 'lodash/filter'
import * as uuid from 'uuid'
import { plainToInstance } from 'class-transformer'

const config = plainToInstance(ConfigBody, plainConfig)
const barrenConfig = plainToInstance(ConfigBody, plainBarrenConfig)
const configWithNullCustomData = plainToInstance(
ConfigBody,
plainConfigWithNullCustomData,
)

describe('User Hashing and Bucketing', () => {
it('generates buckets approximately in the same distribution as the variation distributions', () => {
Expand Down Expand Up @@ -1597,6 +1612,35 @@ describe('Rollout Logic', () => {
expect(doesUserPassRollout({ boundedHash: 0.9 })).toBeTruthy()
})

it('should not throw when given a ConfigBody config', () => {
expect(() =>
generateBucketedConfig({
config,
user: {
user_id: 'asuh',
},
}),
).not.toThrow()
})

it('should throw when given a non-ConfigBody config', () => {
const config = {} as ConfigBody

expect(() =>
generateBucketedConfig({
config,
user: {
user_id: 'asuh',
},
}),
).toThrow()
})

it('should have isConfigBody set to true', () => {
const config = plainToInstance(ConfigBody, plainConfig)
expect(config.isConfigBody).toBeTruthy()
})

describe('overrides', () => {
it('correctly overrides a bucketing decision and a feature that doesnt normally pass segmentation', () => {
const user = {
Expand Down
6 changes: 6 additions & 0 deletions lib/shared/bucketing/src/bucketing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ export const generateBucketedConfig = ({
user: DVCBucketingUser
overrides?: Record<string, string>
}): BucketedUserConfig => {
if (!config.isConfigBody) {
console.log('config', config)
throw new Error(
'Config is not a ConfigBody, transform config using plainToInstance',
)
}
const variableMap: BucketedUserConfig['variables'] = {}
const featureKeyMap: BucketedUserConfig['features'] = {}
const featureVariationMap: BucketedUserConfig['featureVariationMap'] = {}
Expand Down
6 changes: 6 additions & 0 deletions lib/shared/types/src/types/config/configBody.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ export {
Environment as PublicEnvironment,
}

export class Test {
defaultProp = true
}

export class ConfigBody<IdType = string> {
isConfigBody = true

/**
* Basic project data used for building bucketing response
*/
Expand Down
7 changes: 6 additions & 1 deletion lib/shared/vercel-edge-config/src/edge-config.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ describe('EdgeConfigSource', () => {
expect(get).toHaveBeenCalledWith('devcycle-config-v2-server-sdk-key')

expect(result).toEqual({
config: { key: 'value', lastModified: 'some date' },
config: {
key: 'value',
lastModified: 'some date',
isConfigBody: true,
},
lastModified: 'some date',
metaData: { resLastModified: 'some date' },
})
Expand Down Expand Up @@ -64,6 +68,7 @@ describe('EdgeConfigSource', () => {

expect(result).toEqual({
config: {
isConfigBody: true,
key: 'value',
lastModified: 'some date',
features: [
Expand Down

0 comments on commit 2a3196a

Please sign in to comment.