Skip to content

Commit 1a3aab3

Browse files
committed
Added fixed of forced decisions
1 parent 9e427fa commit 1a3aab3

File tree

6 files changed

+133
-81
lines changed

6 files changed

+133
-81
lines changed

OptimizelySDK.Tests/DecisionServiceTest.cs

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -651,17 +651,19 @@ public void TestGetVariationForFeatureRolloutWhenNoRuleInRollouts()
651651
var rollout = projectConfig.GetRolloutFromId(featureFlag.RolloutId);
652652

653653
Assert.AreEqual(rollout.Experiments.Count, 0);
654-
654+
var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);
655+
var optimizelyUserContext = new OptimizelyUserContext(optlyObject, "userId1", null, ErrorHandlerMock.Object, LoggerMock.Object);
655656
var decisionService = new DecisionService(new Bucketer(new NoOpLogger()), new NoOpErrorHandler(), null, new NoOpLogger());
656657

657-
var variation = decisionService.GetVariationForFeatureRollout(featureFlag, "userId1", null, projectConfig);
658+
var variation = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext, projectConfig);
658659

659660
Assert.IsNull(variation.ResultObject);
660661
}
661662

662663
[Test]
663664
public void TestGetVariationForFeatureRolloutWhenRolloutIsNotInDataFile()
664665
{
666+
665667
var featureFlag = ProjectConfig.GetFeatureFlagFromKey("boolean_feature");
666668
var invalidRolloutFeature = new FeatureFlag
667669
{
@@ -673,8 +675,9 @@ public void TestGetVariationForFeatureRolloutWhenRolloutIsNotInDataFile()
673675
};
674676

675677
DecisionServiceMock.Setup(ds => ds.GetVariationForFeatureExperiment(It.IsAny<FeatureFlag>(), It.IsAny<OptimizelyUserContext>(), It.IsAny<UserAttributes>(), ProjectConfig, new OptimizelyDecideOption[] { })).Returns<Variation>(null);
676-
677-
var actualDecision = DecisionServiceMock.Object.GetVariationForFeatureRollout(featureFlag, "user1", new UserAttributes(), ProjectConfig);
678+
var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);
679+
var optimizelyUserContext = new OptimizelyUserContext(optlyObject, "user1", new UserAttributes(), ErrorHandlerMock.Object, LoggerMock.Object);
680+
var actualDecision = DecisionServiceMock.Object.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext, ProjectConfig);
678681
Assert.IsNull(actualDecision.ResultObject);
679682

680683
LoggerMock.Verify(l => l.Log(LogLevel.INFO, "The feature flag \"boolean_feature\" is not used in a rollout."));
@@ -699,7 +702,10 @@ public void TestGetVariationForFeatureRolloutWhenUserIsBucketedInTheTargetingRul
699702
It.IsAny<string>())).Returns(variation);
700703
var decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, null, LoggerMock.Object);
701704

702-
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, "user_1", userAttributes, ProjectConfig);
705+
var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);
706+
var optimizelyUserContext = new OptimizelyUserContext(optlyObject, "user_1", userAttributes, ErrorHandlerMock.Object, LoggerMock.Object);
707+
708+
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext, ProjectConfig);
703709
Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision.ResultObject));
704710
}
705711

@@ -724,7 +730,9 @@ public void TestGetVariationForFeatureRolloutWhenUserIsNotBucketedInTheTargeting
724730
BucketerMock.Setup(bm => bm.Bucket(It.IsAny<ProjectConfig>(), everyoneElseRule, It.IsAny<string>(), It.IsAny<string>())).Returns(variation);
725731
var decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, null, LoggerMock.Object);
726732

727-
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, "user_1", userAttributes, ProjectConfig);
733+
var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);
734+
var optimizelyUserContext = new OptimizelyUserContext(optlyObject, "user_1", userAttributes, ErrorHandlerMock.Object, LoggerMock.Object);
735+
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext, ProjectConfig);
728736
Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision.ResultObject));
729737
}
730738

@@ -743,7 +751,9 @@ public void TestGetVariationForFeatureRolloutWhenUserIsNeitherBucketedInTheTarge
743751
BucketerMock.Setup(bm => bm.Bucket(It.IsAny<ProjectConfig>(), It.IsAny<Experiment>(), It.IsAny<string>(), It.IsAny<string>())).Returns(Result<Variation>.NullResult(null));
744752
var decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, null, LoggerMock.Object);
745753

746-
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, "user_1", userAttributes, ProjectConfig);
754+
var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);
755+
var optimizelyUserContext = new OptimizelyUserContext(optlyObject, "user_1", userAttributes, ErrorHandlerMock.Object, LoggerMock.Object);
756+
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext, ProjectConfig);
747757
Assert.IsNull(actualDecision.ResultObject);
748758
}
749759

@@ -766,7 +776,9 @@ public void TestGetVariationForFeatureRolloutWhenUserDoesNotQualifyForAnyTargeti
766776
var decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, null, LoggerMock.Object);
767777

768778
// Provide null attributes so that user does not qualify for audience.
769-
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, "user_1", null, ProjectConfig);
779+
var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);
780+
var optimizelyUserContext = new OptimizelyUserContext(optlyObject, "user_1", null, ErrorHandlerMock.Object, LoggerMock.Object);
781+
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext, ProjectConfig);
770782

771783
Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision.ResultObject));
772784

@@ -792,40 +804,45 @@ public void TestGetVariationForFeatureRolloutAudienceAndTrafficeAllocationCheck(
792804
var decisionService = new DecisionService(mockBucketer.Object, ErrorHandlerMock.Object, null, LoggerMock.Object);
793805

794806
// Calling with audience iPhone users in San Francisco.
795-
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, new UserAttributes
807+
var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);
808+
var optimizelyUserContext = new OptimizelyUserContext(optlyObject, GenericUserId, new UserAttributes
796809
{
797810
{ "device_type", "iPhone" },
798811
{ "location", "San Francisco" }
799-
}, ProjectConfig);
812+
}, ErrorHandlerMock.Object, LoggerMock.Object);
813+
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext, ProjectConfig);
800814

801815
// Returned variation id should be '177773' because of audience 'iPhone users in San Francisco'.
802816
var expectedDecision = new FeatureDecision(expWithAudienceiPhoneUsers, varWithAudienceiPhoneUsers, FeatureDecision.DECISION_SOURCE_ROLLOUT);
803817
Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision.ResultObject));
804818

805819
// Calling with audience Chrome users.
806-
actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, new UserAttributes
820+
var optimizelyUserContext2 = new OptimizelyUserContext(optlyObject, GenericUserId, new UserAttributes
807821
{
808822
{ "browser_type", "chrome" }
809-
}, ProjectConfig);
823+
}, ErrorHandlerMock.Object, LoggerMock.Object);
824+
actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext2, ProjectConfig);
810825

811826
// Returned variation id should be '177771' because of audience 'Chrome users'.
812827
expectedDecision = new FeatureDecision(expWithAudienceChromeUsers, varWithAudienceChromeUsers, FeatureDecision.DECISION_SOURCE_ROLLOUT);
813828
Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision.ResultObject));
814829

815830
// Calling with no audience.
816831
mockBucketer.Setup(bm => bm.GenerateBucketValue(It.IsAny<string>())).Returns(8000);
817-
actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, new UserAttributes(), ProjectConfig);
832+
var optimizelyUserContext3 = new OptimizelyUserContext(optlyObject, GenericUserId, new UserAttributes(), ErrorHandlerMock.Object, LoggerMock.Object);
833+
actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext3, ProjectConfig);
818834

819835
// Returned variation id should be of everyone else rule because of no audience.
820836
expectedDecision = new FeatureDecision(expWithNoAudience, varWithNoAudience, FeatureDecision.DECISION_SOURCE_ROLLOUT);
821837
Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision.ResultObject));
822838

823839
// Calling with audience 'Chrome users' and traffice allocation '9500'.
824840
mockBucketer.Setup(bm => bm.GenerateBucketValue(It.IsAny<string>())).Returns(9500);
825-
actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, new UserAttributes
841+
var optimizelyUserContext4 = new OptimizelyUserContext(optlyObject, GenericUserId, new UserAttributes
826842
{
827843
{ "browser_type", "chrome" }
828-
}, ProjectConfig);
844+
}, ErrorHandlerMock.Object, LoggerMock.Object);
845+
actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext4, ProjectConfig);
829846

830847
// Returned decision entity should be null because bucket value exceeds traffic allocation of everyone else rule.
831848
Assert.Null(actualDecision.ResultObject);
@@ -845,20 +862,23 @@ public void TestGetVariationForFeatureRolloutCheckAudienceInEveryoneElseRule()
845862
BucketerMock.Setup(bm => bm.Bucket(It.IsAny<ProjectConfig>(), everyoneElseRule, It.IsAny<string>(), GenericUserId)).Returns(Result<Variation>.NullResult(DecisionReasons));
846863

847864
var decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, null, LoggerMock.Object);
865+
var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);
848866

849867
// Returned variation id should be of everyone else rule as it passes audience Id checking.
850-
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, WhitelistedUserId, null, ProjectConfig);
868+
var optimizelyUserContext = new OptimizelyUserContext(optlyObject, WhitelistedUserId, null, ErrorHandlerMock.Object, LoggerMock.Object);
869+
var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext, ProjectConfig);
851870
Assert.True(TestData.CompareObjects(expectedDecision, actualDecision.ResultObject));
852871

853872
// Returned variation id should be null.
854-
actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, null, ProjectConfig);
873+
var optimizelyUserContext2 = new OptimizelyUserContext(optlyObject, GenericUserId, null, ErrorHandlerMock.Object, LoggerMock.Object);
874+
actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext2, ProjectConfig);
855875
Assert.Null(actualDecision.ResultObject);
856876

857877
// Returned variation id should be null as it fails audience Id checking.
858878
everyoneElseRule.AudienceIds = new string[] { ProjectConfig.Audiences[0].Id };
859879

860880
BucketerMock.Setup(bm => bm.Bucket(It.IsAny<ProjectConfig>(), It.IsAny<Experiment>(), It.IsAny<string>(), GenericUserId)).Returns(Result<Variation>.NullResult(DecisionReasons));
861-
actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, null, ProjectConfig) ?? Result<FeatureDecision>.NullResult(DecisionReasons);
881+
actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, optimizelyUserContext2, ProjectConfig) ?? Result<FeatureDecision>.NullResult(DecisionReasons);
862882
Assert.Null(actualDecision.ResultObject);
863883

864884
LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, "User \"testUser1\" does not meet the conditions for targeting rule \"1\"."), Times.Once);
@@ -904,8 +924,8 @@ public void TestGetVariationForFeatureWhenTheUserIsNotBucketedIntoFeatureExperim
904924

905925
DecisionServiceMock.Setup(ds => ds.GetVariationForFeatureExperiment(It.IsAny<FeatureFlag>(), It.IsAny<OptimizelyUserContext>(),
906926
It.IsAny<UserAttributes>(), ProjectConfig, It.IsAny<OptimizelyDecideOption[]>())).Returns(Result<FeatureDecision>.NullResult(null));
907-
DecisionServiceMock.Setup(ds => ds.GetVariationForFeatureRollout(It.IsAny<FeatureFlag>(), It.IsAny<string>(),
908-
It.IsAny<UserAttributes>(), ProjectConfig)).Returns(expectedDecision);
927+
DecisionServiceMock.Setup(ds => ds.GetVariationForFeatureRollout(It.IsAny<FeatureFlag>(), It.IsAny<OptimizelyUserContext>(),
928+
ProjectConfig)).Returns(expectedDecision);
909929

910930
var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);
911931
OptimizelyUserContextMock = new Mock<OptimizelyUserContext>(optlyObject, WhitelistedUserId, new UserAttributes(), ErrorHandlerMock.Object, LoggerMock.Object);
@@ -925,7 +945,7 @@ public void TestGetVariationForFeatureWhenTheUserIsNeitherBucketedIntoFeatureExp
925945
var featureFlag = ProjectConfig.GetFeatureFlagFromKey("string_single_variable_feature");
926946

927947
DecisionServiceMock.Setup(ds => ds.GetVariationForFeatureExperiment(It.IsAny<FeatureFlag>(), It.IsAny<OptimizelyUserContext>(), It.IsAny<UserAttributes>(), ProjectConfig, new OptimizelyDecideOption[] { })).Returns(Result<FeatureDecision>.NullResult(null));
928-
DecisionServiceMock.Setup(ds => ds.GetVariationForFeatureRollout(It.IsAny<FeatureFlag>(), It.IsAny<string>(), It.IsAny<UserAttributes>(), ProjectConfig)).Returns(Result<FeatureDecision>.NullResult(null));
948+
DecisionServiceMock.Setup(ds => ds.GetVariationForFeatureRollout(It.IsAny<FeatureFlag>(), It.IsAny<OptimizelyUserContext>(), ProjectConfig)).Returns(Result<FeatureDecision>.NullResult(null));
929949

930950
var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);
931951
OptimizelyUserContextMock = new Mock<OptimizelyUserContext>(optlyObject, WhitelistedUserId, new UserAttributes(), ErrorHandlerMock.Object, LoggerMock.Object);
@@ -967,7 +987,7 @@ public void TestGetVariationForFeatureWhenTheUserIsBuckedtedInBothExperimentAndR
967987
var expectedRolloutDecision = new FeatureDecision(rolloutExperiment, rolloutVariation.ResultObject, FeatureDecision.DECISION_SOURCE_ROLLOUT);
968988

969989
BucketerMock.Setup(bm => bm.Bucket(ProjectConfig, rolloutExperiment, It.IsAny<string>(), It.IsAny<string>())).Returns(rolloutVariation);
970-
var actualRolloutDecision = DecisionServiceMock.Object.GetVariationForFeatureRollout(featureFlag, "user1", userAttributes, ProjectConfig);
990+
var actualRolloutDecision = DecisionServiceMock.Object.GetVariationForFeatureRollout(featureFlag, OptimizelyUserContextMock.Object, ProjectConfig);
971991

972992
// The user is bucketed into feature rollout's variation.
973993

0 commit comments

Comments
 (0)