diff --git a/lib/project_config/project_config.spec.ts b/lib/project_config/project_config.spec.ts index a955b725a..bb5370ef4 100644 --- a/lib/project_config/project_config.spec.ts +++ b/lib/project_config/project_config.spec.ts @@ -252,6 +252,34 @@ describe('createProjectConfig - flag variations', () => { }); }); +describe('createProjectConfig - cmab experiments', () => { + it('should populate cmab field correctly', function() { + const datafile = testDatafile.getTestProjectConfig(); + datafile.experiments[0].cmab = { + attributes: ['808797688', '808797689'], + }; + + datafile.experiments[2].cmab = { + attributes: ['808797689'], + }; + + const configObj = projectConfig.createProjectConfig(datafile); + + const experiment0 = configObj.experiments[0]; + expect(experiment0.cmab).toEqual({ + attributeIds: ['808797688', '808797689'], + }); + + const experiment1 = configObj.experiments[1]; + expect(experiment1.cmab).toBeUndefined(); + + const experiment2 = configObj.experiments[2]; + expect(experiment2.cmab).toEqual({ + attributeIds: ['808797689'], + }); + }); +}); + describe('getExperimentId', () => { let testData: Record; let configObj: ProjectConfig; diff --git a/lib/project_config/project_config.ts b/lib/project_config/project_config.ts index a41347916..756c8c058 100644 --- a/lib/project_config/project_config.ts +++ b/lib/project_config/project_config.ts @@ -114,6 +114,7 @@ const RESERVED_ATTRIBUTE_PREFIX = '$opt_'; // eslint-disable-next-line @typescript-eslint/no-explicit-any function createMutationSafeDatafileCopy(datafile: any): ProjectConfig { const datafileCopy = { ...datafile }; + datafileCopy.audiences = (datafile.audiences || []).map((audience: Audience) => { return { ...audience }; }); @@ -155,6 +156,15 @@ export const createProjectConfig = function(datafileObj?: JSON, datafileStr: str projectConfig.__datafileStr = datafileStr === null ? JSON.stringify(datafileObj) : datafileStr; + /** rename cmab.attributes field from the datafile to cmab.attributeIds for each experiment */ + projectConfig.experiments.forEach(experiment => { + if (experiment.cmab) { + const attributes = (experiment.cmab as any).attributes; + delete (experiment.cmab as any).attributes; + experiment.cmab.attributeIds = attributes; + } + }); + /* * Conditions of audiences in projectConfig.typedAudiences are not * expected to be string-encoded as they are here in projectConfig.audiences. diff --git a/lib/project_config/project_config_schema.ts b/lib/project_config/project_config_schema.ts index c33f013ae..f842179dc 100644 --- a/lib/project_config/project_config_schema.ts +++ b/lib/project_config/project_config_schema.ts @@ -202,6 +202,19 @@ var schemaDefinition = { type: 'object', required: true, }, + cmab: { + type: 'object', + required: false, + properties: { + attributes: { + type: 'array', + items: { + type: 'string', + }, + required: true, + } + } + } }, }, required: true, diff --git a/lib/shared_types.ts b/lib/shared_types.ts index 40ad29a1f..870b55ddc 100644 --- a/lib/shared_types.ts +++ b/lib/shared_types.ts @@ -152,6 +152,9 @@ export interface Experiment { trafficAllocation: TrafficAllocation[]; forcedVariations?: { [key: string]: string }; isRollout?: boolean; + cmab?: { + attributeIds: string[]; + }; } export enum VariableType {