public void TestGetVariationForFeatureRolloutCheckAudienceInEveryoneElseRule() { var featureFlag = ProjectConfig.GetFeatureFlagFromKey("boolean_single_variable_feature"); var rolloutId = featureFlag.RolloutId; var rollout = ProjectConfig.GetRolloutFromId(rolloutId); var everyoneElseRule = rollout.Experiments[2]; var variation = everyoneElseRule.Variations[0]; var expectedDecision = new FeatureDecision(everyoneElseRule, variation, FeatureDecision.DECISION_SOURCE_ROLLOUT); BucketerMock.Setup(bm => bm.Bucket(It.IsAny <ProjectConfig>(), everyoneElseRule, It.IsAny <string>(), WhitelistedUserId)).Returns(variation); BucketerMock.Setup(bm => bm.Bucket(It.IsAny <ProjectConfig>(), everyoneElseRule, It.IsAny <string>(), GenericUserId)).Returns <Variation>(null); var decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, ProjectConfig, null, LoggerMock.Object); // Returned variation id should be of everyone else rule as it passes audience Id checking. var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, WhitelistedUserId, null); Assert.True(TestData.CompareObjects(expectedDecision, actualDecision)); // Returned variation id should be null. actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, null); Assert.Null(actualDecision); // Returned variation id should be null as it fails audience Id checking. everyoneElseRule.AudienceIds = new string[] { ProjectConfig.Audiences[0].Id }; actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, null); Assert.Null(actualDecision); LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, "User \"testUser1\" does not meet the conditions to be in rollout rule for audience \"Chrome users\"."), Times.Once); LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, "User \"testUser1\" does not meet the conditions to be in rollout rule for audience \"iPhone users in San Francisco\"."), Times.Once); LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, "User \"genericUserId\" does not meet the conditions to be in rollout rule for audience \"Chrome users\"."), Times.Exactly(2)); LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, "User \"genericUserId\" does not meet the conditions to be in rollout rule for audience \"iPhone users in San Francisco\"."), Times.Exactly(3)); }
public void TestGetVariationForFeatureRolloutAudienceAndTrafficeAllocationCheck() { var featureFlag = ProjectConfig.GetFeatureFlagFromKey("boolean_single_variable_feature"); var rolloutId = featureFlag.RolloutId; var rollout = ProjectConfig.GetRolloutFromId(rolloutId); var expWithAudienceiPhoneUsers = rollout.Experiments[1]; var expWithAudienceChromeUsers = rollout.Experiments[0]; var expWithNoAudience = rollout.Experiments[2]; var varWithAudienceiPhoneUsers = expWithAudienceiPhoneUsers.Variations[0]; var varWithAudienceChromeUsers = expWithAudienceChromeUsers.Variations[0]; var varWithNoAudience = expWithNoAudience.Variations[0]; var mockBucketer = new Mock <Bucketer>(LoggerMock.Object) { CallBase = true }; mockBucketer.Setup(bm => bm.GenerateBucketValue(It.IsAny <string>())).Returns(980); var decisionService = new DecisionService(mockBucketer.Object, ErrorHandlerMock.Object, ProjectConfig, null, LoggerMock.Object); // Calling with audience iPhone users in San Francisco. var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, new UserAttributes { { "device_type", "iPhone" }, { "location", "San Francisco" } }); // Returned variation id should be '177773' because of audience 'iPhone users in San Francisco'. var expectedDecision = new FeatureDecision(expWithAudienceiPhoneUsers, varWithAudienceiPhoneUsers, FeatureDecision.DECISION_SOURCE_ROLLOUT); Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision)); // Calling with audience Chrome users. actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, new UserAttributes { { "browser_type", "chrome" } }); // Returned variation id should be '177771' because of audience 'Chrome users'. expectedDecision = new FeatureDecision(expWithAudienceChromeUsers, varWithAudienceChromeUsers, FeatureDecision.DECISION_SOURCE_ROLLOUT); Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision)); // Calling with no audience. mockBucketer.Setup(bm => bm.GenerateBucketValue(It.IsAny <string>())).Returns(8000); actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, new UserAttributes()); // Returned variation id should be of everyone else rule because of no audience. expectedDecision = new FeatureDecision(expWithNoAudience, varWithNoAudience, FeatureDecision.DECISION_SOURCE_ROLLOUT); Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision)); // Calling with audience 'Chrome users' and traffice allocation '9500'. mockBucketer.Setup(bm => bm.GenerateBucketValue(It.IsAny <string>())).Returns(9500); actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, GenericUserId, new UserAttributes { { "browser_type", "chrome" } }); // Returned decision entity should be null because bucket value exceeds traffice allocation of everyone else rule. Assert.Null(actualDecision); }
public void TestGetVariationForFeatureRolloutWhenUserIsNotBucketedInTheTargetingRuleButBucketedToEveryoneElseRule() { var featureFlag = ProjectConfig.GetFeatureFlagFromKey("boolean_single_variable_feature"); var rolloutId = featureFlag.RolloutId; var rollout = ProjectConfig.GetRolloutFromId(rolloutId); var experiment = rollout.Experiments[0]; var everyoneElseRule = rollout.Experiments[rollout.Experiments.Count - 1]; var variation = everyoneElseRule.Variations[0]; var expectedDecision = new FeatureDecision(everyoneElseRule, variation, FeatureDecision.DECISION_SOURCE_ROLLOUT); var userAttributes = new UserAttributes { { "browser_type", "chrome" } }; BucketerMock.Setup(bm => bm.Bucket(It.IsAny <ProjectConfig>(), experiment, It.IsAny <string>(), It.IsAny <string>())).Returns <Variation>(null); BucketerMock.Setup(bm => bm.Bucket(It.IsAny <ProjectConfig>(), everyoneElseRule, It.IsAny <string>(), It.IsAny <string>())).Returns(variation); var decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, ProjectConfig, null, LoggerMock.Object); var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, "user_1", userAttributes); Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision)); LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, $"Attempting to bucket user \"user_1\" into rollout rule \"{experiment.Key}\".")); LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, "User \"user_1\" is excluded due to traffic allocation. Checking \"Eveyrone Else\" rule now.")); }
public void TestGetVariationForFeatureRolloutWhenUserIsNeitherBucketedInTheTargetingRuleNorToEveryoneElseRule() { var featureFlag = ProjectConfig.GetFeatureFlagFromKey("boolean_single_variable_feature"); var rolloutId = featureFlag.RolloutId; var rollout = ProjectConfig.GetRolloutFromId(rolloutId); var userAttributes = new UserAttributes { { "browser_type", "chrome" } }; BucketerMock.Setup(bm => bm.Bucket(It.IsAny <ProjectConfig>(), It.IsAny <Experiment>(), It.IsAny <string>(), It.IsAny <string>())).Returns <Variation>(null); var decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, ProjectConfig, null, LoggerMock.Object); var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, "user_1", userAttributes); Assert.IsNull(actualDecision); }
public void TestGetVariationForFeatureRolloutWhenUserIsBucketedInTheTargetingRule() { var featureFlag = ProjectConfig.GetFeatureFlagFromKey("boolean_single_variable_feature"); var rolloutId = featureFlag.RolloutId; var rollout = ProjectConfig.GetRolloutFromId(rolloutId); var experiment = rollout.Experiments[0]; var variation = experiment.Variations[0]; var expectedDecision = new FeatureDecision(experiment, variation, FeatureDecision.DECISION_SOURCE_ROLLOUT); var userAttributes = new UserAttributes { { "browser_type", "chrome" } }; BucketerMock.Setup(bm => bm.Bucket(It.IsAny <ProjectConfig>(), It.IsAny <Experiment>(), It.IsAny <string>(), It.IsAny <string>())).Returns(variation); var decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, ProjectConfig, null, LoggerMock.Object); var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, "user_1", userAttributes); Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision)); }
public void TestGetVariationForFeatureRolloutWhenUserDoesNotQualifyForAnyTargetingRule() { var featureFlag = ProjectConfig.GetFeatureFlagFromKey("boolean_single_variable_feature"); var rolloutId = featureFlag.RolloutId; var rollout = ProjectConfig.GetRolloutFromId(rolloutId); var experiment0 = rollout.Experiments[0]; var experiment1 = rollout.Experiments[1]; var everyoneElseRule = rollout.Experiments[rollout.Experiments.Count - 1]; var variation = everyoneElseRule.Variations[0]; var expectedDecision = new FeatureDecision(everyoneElseRule, variation, FeatureDecision.DECISION_SOURCE_ROLLOUT); BucketerMock.Setup(bm => bm.Bucket(It.IsAny <ProjectConfig>(), everyoneElseRule, It.IsAny <string>(), It.IsAny <string>())).Returns(variation); var decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, ProjectConfig, null, LoggerMock.Object); // Provide null attributes so that user does not qualify for audience. var actualDecision = decisionService.GetVariationForFeatureRollout(featureFlag, "user_1", null); Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision)); LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, $"User \"user_1\" does not meet the conditions to be in rollout rule for audience \"{ProjectConfig.AudienceIdMap[experiment0.AudienceIds[0]].Name}\".")); LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, $"User \"user_1\" does not meet the conditions to be in rollout rule for audience \"{ProjectConfig.AudienceIdMap[experiment1.AudienceIds[0]].Name}\".")); }