Skip to content

Commit c42cb91

Browse files
committed
test forced variation
1 parent f8cd69c commit c42cb91

File tree

2 files changed

+137
-13
lines changed

2 files changed

+137
-13
lines changed

lib/core/decision_service/index.spec.ts

Lines changed: 137 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,52 @@ describe('DecisionService', () => {
208208
expect(logger?.info).toHaveBeenNthCalledWith(2, USER_NOT_IN_EXPERIMENT, 'user3', 'testExperimentWithAudiences');
209209
});
210210

211+
it('should return the forced variation set using setForcedVariation \
212+
in presence of a whitelisted variation', function() {
213+
const user = new OptimizelyUserContext({
214+
optimizely: {} as any,
215+
userId: 'user2'
216+
});
217+
218+
const config = createProjectConfig(cloneDeep(testData));
219+
220+
const experiment = config.experimentIdMap['122227'];
221+
222+
const { decisionService } = getDecisionService();
223+
224+
const forcedVariation = 'controlWithAudience';
225+
226+
decisionService.setForcedVariation(config, experiment.key, user.getUserId(), forcedVariation);
227+
228+
const variation = decisionService.getVariation(config, experiment, user);
229+
expect(variation.result).toBe(forcedVariation);
230+
231+
const whitelistedVariation = experiment.forcedVariations?.[user.getUserId()];
232+
expect(whitelistedVariation).toBeDefined();
233+
expect(whitelistedVariation).not.toEqual(forcedVariation);
234+
});
235+
236+
it('should return the forced variation set using setForcedVariation \
237+
even if user does not satisfy audience condition', function() {
238+
const user = new OptimizelyUserContext({
239+
optimizely: {} as any,
240+
userId: 'user3', // no attributes are set, should not satisfy audience condition 11154
241+
});
242+
243+
const config = createProjectConfig(cloneDeep(testData));
244+
245+
const experiment = config.experimentIdMap['122227'];
246+
247+
const { decisionService } = getDecisionService();
248+
249+
const forcedVariation = 'controlWithAudience';
250+
251+
decisionService.setForcedVariation(config, experiment.key, user.getUserId(), forcedVariation);
252+
253+
const variation = decisionService.getVariation(config, experiment, user);
254+
expect(variation.result).toBe(forcedVariation);
255+
});
256+
211257
it('should return null if the experiment is not running', function() {
212258
const user = new OptimizelyUserContext({
213259
optimizely: {} as any,
@@ -741,7 +787,55 @@ describe('DecisionService', () => {
741787
config, config.experimentKeyMap['exp_2'], user, false, expect.anything());
742788
});
743789

744-
it('should save the variation found for an experiment in the user profile without', () => {
790+
it('should return the variation forced for an experiment in the userContext if available', () => {
791+
const { decisionService } = getDecisionService();
792+
793+
const resolveVariationSpy = vi.spyOn(decisionService as any, 'resolveVariation')
794+
.mockImplementation((
795+
config,
796+
experiment: any,
797+
user,
798+
shouldIgnoreUPS,
799+
userProfileTracker
800+
) => {
801+
if (experiment.key === 'exp_2') {
802+
return {
803+
result: 'variation_2',
804+
reasons: [],
805+
};
806+
}
807+
return {
808+
result: null,
809+
reasons: [],
810+
}
811+
});
812+
813+
const config = createProjectConfig(getDecisionTestDatafile());
814+
815+
const user = new OptimizelyUserContext({
816+
optimizely: {} as any,
817+
userId: 'tester',
818+
attributes: {
819+
age: 40,
820+
},
821+
});
822+
823+
user.setForcedDecision(
824+
{ flagKey: 'flag_1', ruleKey: 'exp_2' },
825+
{ variationKey: 'variation_5' }
826+
);
827+
828+
const feature = config.featureKeyMap['flag_1'];
829+
const variation = decisionService.getVariationForFeature(config, feature, user);
830+
831+
expect(variation.result).toEqual({
832+
experiment: config.experimentKeyMap['exp_2'],
833+
variation: config.variationIdMap['5005'],
834+
decisionSource: DECISION_SOURCES.FEATURE_TEST,
835+
});
836+
});
837+
838+
it('should save the variation found for an experiment in the user profile', () => {
745839
const { decisionService, userProfileService } = getDecisionService({ userProfileService: true });
746840

747841
const resolveVariationSpy = vi.spyOn(decisionService as any, 'resolveVariation')
@@ -866,7 +960,7 @@ describe('DecisionService', () => {
866960
const variation = decisionService.getVariationForFeature(config, feature, user);
867961

868962
expect(variation.result).toEqual({
869-
experiment: config.experimentIdMap['3002'],
963+
experiment: config.experimentKeyMap['delivery_2'],
870964
variation: config.variationIdMap['5005'],
871965
decisionSource: DECISION_SOURCES.ROLLOUT,
872966
});
@@ -940,6 +1034,47 @@ describe('DecisionService', () => {
9401034
});
9411035
});
9421036

1037+
it('should return the forced variation for targeted delivery rule when no variation \
1038+
is found for any experiment and a there is a forced decision \
1039+
for a targeted delivery in the userContext', () => {
1040+
const { decisionService } = getDecisionService();
1041+
1042+
const resolveVariationSpy = vi.spyOn(decisionService as any, 'resolveVariation')
1043+
.mockImplementation((
1044+
config,
1045+
experiment: any,
1046+
user,
1047+
shouldIgnoreUPS,
1048+
userProfileTracker
1049+
) => {
1050+
return {
1051+
result: null,
1052+
reasons: [],
1053+
}
1054+
});
1055+
1056+
const config = createProjectConfig(getDecisionTestDatafile());
1057+
1058+
const user = new OptimizelyUserContext({
1059+
optimizely: {} as any,
1060+
userId: 'tester',
1061+
});
1062+
1063+
user.setForcedDecision(
1064+
{ flagKey: 'flag_1', ruleKey: 'delivery_2' },
1065+
{ variationKey: 'variation_1' }
1066+
);
1067+
1068+
const feature = config.featureKeyMap['flag_1'];
1069+
const variation = decisionService.getVariationForFeature(config, feature, user);
1070+
1071+
expect(variation.result).toEqual({
1072+
experiment: config.experimentKeyMap['delivery_2'],
1073+
variation: config.variationIdMap['5001'],
1074+
decisionSource: DECISION_SOURCES.ROLLOUT,
1075+
});
1076+
});
1077+
9431078
it('should return variation from the everyone else targeting rule if no variation \
9441079
is found for any experiment or targeted delivery', () => {
9451080
const { decisionService } = getDecisionService();
@@ -962,7 +1097,6 @@ describe('DecisionService', () => {
9621097

9631098
mockBucket.mockImplementation((param: BucketerParams) => {
9641099
const ruleKey = param.experimentKey;
965-
console.log('bucket called for ' + ruleKey);
9661100
if (ruleKey === 'default-rollout-key') {
9671101
return {
9681102
result: '5007',

lib/core/decision_service/index.tests.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -658,16 +658,6 @@ describe('lib/core/decision_service', function() {
658658
});
659659
});
660660

661-
// describe('checkIfExperimentIsActive', function() {
662-
// it('should return true if experiment is running', function() {
663-
// assert.isTrue(decisionServiceInstance.checkIfExperimentIsActive(configObj, 'testExperiment'));
664-
// });
665-
666-
// it('should return false when experiment is not running', function() {
667-
// assert.isFalse(decisionServiceInstance.checkIfExperimentIsActive(configObj, 'testExperimentNotRunning'));
668-
// });
669-
// });
670-
671661
describe('checkIfUserIsInAudience', function() {
672662
var __audienceEvaluateSpy;
673663

0 commit comments

Comments
 (0)