Пример #1
0
        public void TestGetEventValidKey()
        {
            var ev = Config.GetEvent("purchase");

            Assert.AreEqual("purchase", ev.Key);
            Assert.AreEqual("7718020063", ev.Id);

            Assert.IsTrue(TestData.CompareObjects(new object[] { "7716830082", "7723330021", "7718750065", "7716830585" }, ev.ExperimentIds));
        }
Пример #2
0
        public void TestGetValueReturnsEntireDictWhenJsonPathIsEmptyAndTypeIsValid()
        {
            var optimizelyJSONUsingString = new OptimizelyJSON(Payload, ErrorHandlerMock.Object, LoggerMock.Object);
            var actualDict    = optimizelyJSONUsingString.ToDictionary();
            var expectedValue = optimizelyJSONUsingString.GetValue <Dictionary <string, object> >("");

            Assert.NotNull(expectedValue);
            Assert.True(TestData.CompareObjects(expectedValue, actualDict));
        }
Пример #3
0
        public void TestGetAudienceInvalidKey()
        {
            var audience = Config.GetAudience("invalid_id");

            LoggerMock.Verify(l => l.Log(It.IsAny <LogLevel>(), It.IsAny <string>()), Times.Once);
            LoggerMock.Verify(l => l.Log(LogLevel.ERROR, @"Audience ID ""invalid_id"" is not in datafile."));

            ErrorHandlerMock.Verify(e => e.HandleError(It.Is <InvalidAudienceException>(ex => ex.Message == "Provided audience is not in datafile.")));
            Assert.IsTrue(TestData.CompareObjects(new Entity.Audience(), audience));
        }
Пример #4
0
        public void TestGetForcedVariationReturnsForcedVariation()
        {
            DecisionService decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, ProjectConfig, null, LoggerMock.Object);

            Assert.IsTrue(TestData.CompareObjects(WhitelistedVariation, decisionService.GetWhitelistedVariation(WhitelistedExperiment, WhitelistedUserId)));
            LoggerMock.Verify(l => l.Log(LogLevel.INFO, string.Format("User \"{0}\" is forced in variation \"{1}\".",
                                                                      WhitelistedUserId, WhitelistedVariation.Key)), Times.Once);

            BucketerMock.Verify(_ => _.Bucket(It.IsAny <ProjectConfig>(), It.IsAny <Experiment>(), It.IsAny <string>(), It.IsAny <string>()), Times.Never);
        }
Пример #5
0
        public void TestBucketRolloutRule()
        {
            var bucketer          = new Bucketer(LoggerMock.Object);
            var rollout           = Config.GetRolloutFromId("166660");
            var rolloutRule       = rollout.Experiments[1];
            var expectedVariation = Config.GetVariationFromId(rolloutRule.Key, "177773");

            Assert.True(TestData.CompareObjects(expectedVariation,
                                                bucketer.Bucket(Config, rolloutRule, "testBucketingId", TestUserId)));
        }
Пример #6
0
        public void TestFlagVariations()
        {
            var allVariations = Config?.FlagVariationMap;

            var expectedVariationDict = new Dictionary <string, Variation>
            {
                { "group_exp_1_var_1", new Variation
                  {
                      FeatureEnabled = true,
                      Id             = "7722260071",
                      Key            = "group_exp_1_var_1",
                      FeatureVariableUsageInstances = new List <FeatureVariableUsage> {
                          new FeatureVariableUsage {
                              Id = "155563", Value = "groupie_1_v1"
                          }
                      }
                  } },
                { "group_exp_1_var_2", new Variation
                  {
                      FeatureEnabled = true,
                      Id             = "7722360022",
                      Key            = "group_exp_1_var_2",
                      FeatureVariableUsageInstances = new List <FeatureVariableUsage> {
                          new FeatureVariableUsage {
                              Id = "155563", Value = "groupie_1_v2"
                          }
                      }
                  } },
                { "group_exp_2_var_1", new Variation
                  {
                      FeatureEnabled = false,
                      Id             = "7713030086",
                      Key            = "group_exp_2_var_1",
                      FeatureVariableUsageInstances = new List <FeatureVariableUsage> {
                          new FeatureVariableUsage {
                              Id = "155563", Value = "groupie_2_v1"
                          }
                      }
                  } },
                { "group_exp_2_var_2", new Variation
                  {
                      FeatureEnabled = false,
                      Id             = "7725250007",
                      Key            = "group_exp_2_var_2",
                      FeatureVariableUsageInstances = new List <FeatureVariableUsage> {
                          new FeatureVariableUsage {
                              Id = "155563", Value = "groupie_2_v2"
                          }
                      }
                  } }
            };
            var filteredActualFlagVariations = allVariations["boolean_feature"];

            TestData.CompareObjects(expectedVariationDict, filteredActualFlagVariations);
        }
Пример #7
0
        public void TestGetExperimentInvalidId()
        {
            var experiment = Config.GetExperimentFromId("42");

            LoggerMock.Verify(l => l.Log(It.IsAny <LogLevel>(), It.IsAny <string>()), Times.Once);
            LoggerMock.Verify(l => l.Log(LogLevel.ERROR, @"Experiment ID ""42"" is not in datafile."));

            ErrorHandlerMock.Verify(e => e.HandleError(It.Is <InvalidExperimentException>(ex => ex.Message == "Provided experiment is not in datafile.")));

            Assert.IsTrue(TestData.CompareObjects(new Entity.Experiment(), experiment));
        }
Пример #8
0
        public void TestGetEventInvalidKey()
        {
            var ev = Config.GetEvent("invalid_key");

            LoggerMock.Verify(l => l.Log(It.IsAny <LogLevel>(), It.IsAny <string>()), Times.Once);
            LoggerMock.Verify(l => l.Log(LogLevel.ERROR, @"Event key ""invalid_key"" is not in datafile."));

            ErrorHandlerMock.Verify(e => e.HandleError(It.Is <InvalidEventException>(ex => ex.Message == "Provided event is not in datafile.")));

            Assert.IsTrue(TestData.CompareObjects(new Entity.Event(), ev));
        }
Пример #9
0
        public void TestGetGroupInvalidId()
        {
            var group = Config.GetGroup("invalid_id");

            LoggerMock.Verify(l => l.Log(It.IsAny <LogLevel>(), It.IsAny <string>()), Times.Exactly(1));
            LoggerMock.Verify(l => l.Log(LogLevel.ERROR, @"Group ID ""invalid_id"" is not in datafile."));

            ErrorHandlerMock.Verify(e => e.HandleError(
                                        It.Is <InvalidGroupException>(ex => ex.Message == "Provided group is not in datafile.")),
                                    Times.Once, "Failed");

            Assert.IsTrue(TestData.CompareObjects(group, new Entity.Group()));
        }
Пример #10
0
        public void TestOptimizelyJsonGetVariablesWhenSetUsingString()
        {
            var optimizelyJSONUsingString = new OptimizelyJSON(Payload, ErrorHandlerMock.Object, LoggerMock.Object);

            Assert.AreEqual(optimizelyJSONUsingString.GetValue <long>("field1"), 1);
            Assert.AreEqual(optimizelyJSONUsingString.GetValue <double>("field2"), 2.5);
            Assert.AreEqual(optimizelyJSONUsingString.GetValue <string>("field3"), "three");
            Assert.AreEqual(optimizelyJSONUsingString.GetValue <long>("field4.inner_field1"), 3);
            Assert.True(TestData.CompareObjects(optimizelyJSONUsingString.GetValue <List <object> >("field4.inner_field2"), new List <object>()
            {
                "1", "2", 3, 4.23, true
            }));
        }
        public void DecideAllTwoFlag()
        {
            var flagKey1 = "multi_variate_feature";
            var flagKey2 = "string_single_variable_feature";
            var flagKeys = new string[] { flagKey1, flagKey2 };

            var variablesExpected1 = Optimizely.GetAllFeatureVariables(flagKey1, UserID);
            var variablesExpected2 = Optimizely.GetAllFeatureVariables(flagKey2, UserID);

            var user = Optimizely.CreateUserContext(UserID);

            user.SetAttribute("browser_type", "chrome");
            // Mocking objects.
            NotificationCallbackMock.Setup(nc => nc.TestDecisionCallback(It.IsAny <string>(), It.IsAny <string>(),
                                                                         It.IsAny <UserAttributes>(), It.IsAny <Dictionary <string, object> >()));

            Optimizely.NotificationCenter.AddNotification(NotificationCenter.NotificationType.Decision, NotificationCallbackMock.Object.TestDecisionCallback);

            var decisions = user.DecideForKeys(flagKeys);

            var userAttributes = new UserAttributes
            {
                { "browser_type", "chrome" }
            };

            Assert.True(decisions.Count == 2);
            NotificationCallbackMock.Verify(nc => nc.TestDecisionCallback(DecisionNotificationTypes.FLAG, UserID, userAttributes, It.IsAny <Dictionary <string, object> >()),
                                            Times.Exactly(2));
            OptimizelyDecision expDecision1 = new OptimizelyDecision(
                "Gred",
                false,
                variablesExpected1,
                "test_experiment_multivariate",
                flagKey1,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey1], expDecision1));

            OptimizelyDecision expDecision2 = new OptimizelyDecision(
                "control",
                true,
                variablesExpected2,
                "test_experiment_with_feature_rollout",
                flagKey2,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey2], expDecision2));
        }
Пример #12
0
        public void TestGetVariationForFeatureWhenTheUserIsNeitherBucketedIntoFeatureExperimentNorToFeatureRollout()
        {
            var featureFlag      = ProjectConfig.GetFeatureFlagFromKey("string_single_variable_feature");
            var expectedDecision = new FeatureDecision(null, null, FeatureDecision.DECISION_SOURCE_ROLLOUT);

            DecisionServiceMock.Setup(ds => ds.GetVariationForFeatureExperiment(It.IsAny <FeatureFlag>(), It.IsAny <string>(), It.IsAny <UserAttributes>())).Returns <Variation>(null);
            DecisionServiceMock.Setup(ds => ds.GetVariationForFeatureRollout(It.IsAny <FeatureFlag>(), It.IsAny <string>(), It.IsAny <UserAttributes>())).Returns <Variation>(null);

            var actualDecision = DecisionServiceMock.Object.GetVariationForFeature(featureFlag, "user1", new UserAttributes());

            Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision));

            LoggerMock.Verify(l => l.Log(LogLevel.INFO, "The user \"user1\" is not bucketed into a rollout for feature flag \"string_single_variable_feature\"."));
        }
Пример #13
0
        public void TestGetVariationForFeatureWhenTheUserIsBucketedIntoFeatureExperiment()
        {
            var featureFlag          = ProjectConfig.GetFeatureFlagFromKey("string_single_variable_feature");
            var expectedExperimentId = featureFlag.ExperimentIds[0];
            var expectedExperiment   = ProjectConfig.GetExperimentFromId(expectedExperimentId);
            var variation            = expectedExperiment.Variations[0];
            var expectedDecision     = new FeatureDecision(expectedExperiment, variation, FeatureDecision.DECISION_SOURCE_EXPERIMENT);

            DecisionServiceMock.Setup(ds => ds.GetVariationForFeatureExperiment(It.IsAny <FeatureFlag>(), It.IsAny <string>(),
                                                                                It.IsAny <UserAttributes>())).Returns(expectedDecision);

            var actualDecision = DecisionServiceMock.Object.GetVariationForFeature(featureFlag, "user1", new UserAttributes());

            Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision));
        }
Пример #14
0
        public void TestGetVariationForcedVariationPrecedesAudienceEval()
        {
            DecisionService decisionService   = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, ProjectConfig, null, LoggerMock.Object);
            Experiment      experiment        = ProjectConfig.Experiments[8];
            Variation       expectedVariation = experiment.Variations[0];

            // user excluded without audiences and whitelisting
            Assert.IsNull(decisionService.GetVariation(experiment, GenericUserId, new UserAttributes()));

            var actualVariation = decisionService.GetVariation(experiment, WhitelistedUserId, new UserAttributes());

            LoggerMock.Verify(l => l.Log(LogLevel.INFO, string.Format("User \"{0}\" is forced in variation \"vtag5\".", WhitelistedUserId)), Times.Once);
            // no attributes provided for a experiment that has an audience
            Assert.IsTrue(TestData.CompareObjects(actualVariation, expectedVariation));
            BucketerMock.Verify(_ => _.Bucket(It.IsAny <ProjectConfig>(), It.IsAny <Experiment>(), It.IsAny <string>(), It.IsAny <string>()), Times.Never);
        }
        public void DecideWhenConfigIsNull()
        {
            Optimizely optimizely = new Optimizely(TestData.UnsupportedVersionDatafile, EventDispatcherMock.Object, LoggerMock.Object, ErrorHandlerMock.Object);

            var flagKey          = "multi_variate_feature";
            var decisionExpected = OptimizelyDecision.NewErrorDecision(
                flagKey,
                new OptimizelyUserContext(optimizely, UserID, new UserAttributes(), ErrorHandlerMock.Object, LoggerMock.Object),
                DecisionMessage.SDK_NOT_READY,
                ErrorHandlerMock.Object,
                LoggerMock.Object);
            var user     = optimizely.CreateUserContext(UserID);
            var decision = user.Decide(flagKey);

            Assert.IsTrue(TestData.CompareObjects(decision, decisionExpected));
        }
Пример #16
0
        public void TestGetVariationForFeatureExperimentGivenMutexGroupAndUserIsBucketed()
        {
            var mutexExperiment  = ProjectConfig.GetExperimentFromKey("group_experiment_1");
            var variation        = mutexExperiment.Variations[0];
            var userAttributes   = new UserAttributes();
            var expectedDecision = new FeatureDecision(mutexExperiment, variation, FeatureDecision.DECISION_SOURCE_EXPERIMENT);

            DecisionServiceMock.Setup(ds => ds.GetVariation(ProjectConfig.GetExperimentFromKey("group_experiment_1"), "user1",
                                                            userAttributes)).Returns(variation);

            var featureFlag    = ProjectConfig.GetFeatureFlagFromKey("boolean_feature");
            var actualDecision = DecisionServiceMock.Object.GetVariationForFeatureExperiment(featureFlag, "user1", userAttributes);

            Assert.IsTrue(TestData.CompareObjects(expectedDecision, actualDecision));

            LoggerMock.Verify(l => l.Log(LogLevel.INFO, "The user \"user1\" is bucketed into experiment \"group_experiment_1\" of feature \"boolean_feature\"."));
        }
Пример #17
0
        public void TestGetVariationForFeatureExperimentGivenNonMutexGroupAndUserIsBucketed()
        {
            var experiment       = ProjectConfig.GetExperimentFromKey("test_experiment_multivariate");
            var variation        = ProjectConfig.GetVariationFromId("test_experiment_multivariate", "122231");
            var expectedDecision = new FeatureDecision(experiment, variation, FeatureDecision.DECISION_SOURCE_EXPERIMENT);
            var userAttributes   = new UserAttributes();

            DecisionServiceMock.Setup(ds => ds.GetVariation(ProjectConfig.GetExperimentFromKey("test_experiment_multivariate"),
                                                            "user1", userAttributes)).Returns(variation);

            var featureFlag = ProjectConfig.GetFeatureFlagFromKey("multi_variate_feature");
            var decision    = DecisionServiceMock.Object.GetVariationForFeatureExperiment(featureFlag, "user1", userAttributes);

            Assert.IsTrue(TestData.CompareObjects(expectedDecision, decision));

            LoggerMock.Verify(l => l.Log(LogLevel.INFO, "The user \"user1\" is bucketed into experiment \"test_experiment_multivariate\" of feature \"multi_variate_feature\"."));
        }
        public void DecideInvalidFlagKey()
        {
            var flagKey = "invalid_feature";

            var user = Optimizely.CreateUserContext(UserID);

            user.SetAttribute("browser_type", "chrome");

            var decisionExpected = OptimizelyDecision.NewErrorDecision(
                flagKey,
                user,
                DecisionMessage.Reason(DecisionMessage.FLAG_KEY_INVALID, flagKey),
                ErrorHandlerMock.Object,
                LoggerMock.Object);
            var decision = user.Decide(flagKey);

            Assert.IsTrue(TestData.CompareObjects(decision, decisionExpected));
        }
        public void TestDecide()
        {
            var flagKey           = "multi_variate_feature";
            var variablesExpected = Optimizely.GetAllFeatureVariables(flagKey, UserID);

            var user = Optimizely.CreateUserContext(UserID);

            user.SetAttribute("browser_type", "chrome");
            var decision = user.Decide(flagKey);

            Assert.AreEqual(decision.VariationKey, "Gred");
            Assert.False(decision.Enabled);
            Assert.AreEqual(decision.Variables.ToDictionary(), variablesExpected.ToDictionary());
            Assert.AreEqual(decision.RuleKey, "test_experiment_multivariate");
            Assert.AreEqual(decision.FlagKey, flagKey);
            Assert.AreNotEqual(decision.UserContext, user);
            Assert.IsTrue(TestData.CompareObjects(decision.UserContext, user));
            Assert.AreEqual(decision.Reasons.Length, 0);
        }
Пример #20
0
        public void TestBucketRolloutRule()
        {
            var bucketer          = new Bucketer(LoggerMock.Object);
            var rollout           = Config.GetRolloutFromId("166660");
            var rolloutRule       = rollout.Experiments[1];
            var expectedVariation = Config.GetVariationFromId(rolloutRule.Key, "177773");

            var variationResult = bucketer.Bucket(Config, rolloutRule, "testBucketingId", TestUserId);

            Assert.True(TestData.CompareObjects(expectedVariation,
                                                variationResult.ResultObject));
            Assert.AreEqual(variationResult.DecisionReasons.ToReport().Count, 0);
            var variationsResult = bucketer.Bucket(Config, rolloutRule, "testBucketingId", TestUserId);

            Assert.True(TestData.CompareObjects(expectedVariation,
                                                variationsResult.ResultObject));
            Assert.AreEqual(variationsResult.DecisionReasons.ToReport(true).Count, 1);
            Assert.AreEqual(variationsResult.DecisionReasons.ToReport(true)[0], "User [testUserId] is in variation [177773] of experiment [177772].");
        }
        public void DecideExcludeVariablesDecideOptions()
        {
            var flagKey           = "multi_variate_feature";
            var variablesExpected = new Dictionary <string, object>();
            var user = Optimizely.CreateUserContext(UserID);

            user.SetAttribute("browser_type", "chrome");
            var decideOptions = new OptimizelyDecideOption[] { OptimizelyDecideOption.EXCLUDE_VARIABLES };

            var decision = user.Decide(flagKey, decideOptions);

            Assert.AreEqual(decision.VariationKey, "Gred");
            Assert.False(decision.Enabled);
            Assert.AreEqual(decision.Variables.ToDictionary(), variablesExpected);
            Assert.AreEqual(decision.RuleKey, "test_experiment_multivariate");
            Assert.AreEqual(decision.FlagKey, flagKey);
            Assert.AreNotEqual(decision.UserContext, user);
            Assert.IsTrue(TestData.CompareObjects(decision.UserContext, user));
            Assert.True(decision.Reasons.IsNullOrEmpty());
        }
Пример #22
0
        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));
        }
Пример #23
0
        public void TestGetVariationUserWithSetForcedVariation()
        {
            var experimentKey       = "test_experiment";
            var pausedExperimentKey = "paused_experiment";
            var userId = "test_user";
            var expectedForcedVariationKey = "variation";
            var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);

            var userAttributes = new UserAttributes
            {
                { "device_type", "iPhone" },
                { "location", "San Francisco" }
            };

            optlyObject.Activate(experimentKey, userId, userAttributes);

            // confirm normal bucketing occurs before setting the forced variation
            var actualVariation = optlyObject.GetVariation(experimentKey, userId, userAttributes);

            Assert.IsTrue(TestData.CompareObjects(VariationWithKeyControl, actualVariation));

            // test valid experiment
            Assert.IsTrue(optlyObject.SetForcedVariation(experimentKey, userId, expectedForcedVariationKey), string.Format(@"Set variation to ""{0}"" failed.", expectedForcedVariationKey));

            var actualForcedVariation = optlyObject.GetVariation(experimentKey, userId, userAttributes);

            Assert.IsTrue(TestData.CompareObjects(VariationWithKeyVariation, actualForcedVariation));

            // clear forced variation and confirm that normal bucketing occurs
            Assert.IsTrue(optlyObject.SetForcedVariation(experimentKey, userId, null));

            actualVariation = optlyObject.GetVariation(experimentKey, userId, userAttributes);
            Assert.IsTrue(TestData.CompareObjects(VariationWithKeyControl, actualVariation));

            // check that a paused experiment returns null
            Assert.IsTrue(optlyObject.SetForcedVariation(pausedExperimentKey, userId, expectedForcedVariationKey), string.Format(@"Set variation to ""{0}"" failed.", expectedForcedVariationKey));
            actualForcedVariation = optlyObject.GetVariation(pausedExperimentKey, userId, userAttributes);

            Assert.IsNull(actualForcedVariation);
        }
Пример #24
0
        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}\"."));
        }
Пример #25
0
        public void TestBucketReturnsVariationStoredInUserProfile()
        {
            Experiment experiment = ProjectConfig.Experiments[6];
            Variation  variation  = experiment.Variations[0];
            Decision   decision   = new Decision(variation.Id);

            UserProfile userProfile = new UserProfile(UserProfileId, new Dictionary <string, Decision>
            {
                { experiment.Id, decision }
            });

            UserProfileServiceMock.Setup(_ => _.Lookup(UserProfileId)).Returns(userProfile.ToMap());


            DecisionService decisionService = new DecisionService(BucketerMock.Object, ErrorHandlerMock.Object, ProjectConfig, UserProfileServiceMock.Object, LoggerMock.Object);

            Assert.IsTrue(TestData.CompareObjects(variation, decisionService.GetVariation(experiment, UserProfileId, new UserAttributes())));

            LoggerMock.Verify(l => l.Log(LogLevel.INFO, string.Format("Returning previously activated variation \"{0}\" of experiment \"{1}\" for user \"{2}\" from user profile.",
                                                                      variation.Key, experiment.Key, UserProfileId)));

            //BucketerMock.Verify(_ => _.Bucket(It.IsAny<ProjectConfig>(), It.IsAny<Experiment>(), It.IsAny<string>()), Times.Once);
        }
        public void TestDecisionNotification()
        {
            var flagKey      = "string_single_variable_feature";
            var variationKey = "control";
            var enabled      = true;
            var variables    = Optimizely.GetAllFeatureVariables(flagKey, UserID);
            var ruleKey      = "test_experiment_with_feature_rollout";
            var reasons      = new string[] { };
            var user         = Optimizely.CreateUserContext(UserID);

            user.SetAttribute("browser_type", "chrome");

            var decisionInfo = new Dictionary <string, object>
            {
                { "flagKey", flagKey },
                { "enabled", enabled },
                { "variables", variables.ToDictionary() },
                { "variationKey", variationKey },
                { "ruleKey", ruleKey },
                { "reasons", reasons },
                { "decisionEventDispatched", true },
            };

            var userAttributes = new UserAttributes
            {
                { "browser_type", "chrome" }
            };

            // Mocking objects.
            NotificationCallbackMock.Setup(nc => nc.TestDecisionCallback(It.IsAny <string>(), It.IsAny <string>(),
                                                                         It.IsAny <UserAttributes>(), It.IsAny <Dictionary <string, object> >()));

            Optimizely.NotificationCenter.AddNotification(NotificationCenter.NotificationType.Decision, NotificationCallbackMock.Object.TestDecisionCallback);

            user.Decide(flagKey);
            NotificationCallbackMock.Verify(nc => nc.TestDecisionCallback(DecisionNotificationTypes.FLAG, UserID, userAttributes, It.Is <Dictionary <string, object> >(info =>
                                                                                                                                                                       TestData.CompareObjects(info, decisionInfo))),
                                            Times.Once);
        }
Пример #27
0
        public void TestGetVariationWithBucketingId()
        {
            var pausedExperimentKey = "paused_experiment";
            var userId = "test_user";
            var testUserIdWhitelisted    = "user1";
            var experimentKey            = "test_experiment";
            var testBucketingIdControl   = "testBucketingIdControl!"; // generates bucketing number 3741
            var testBucketingIdVariation = "123456789";               // generates bucketing number 4567
            var variationKeyControl      = "control";

            var testUserAttributes = new UserAttributes
            {
                { "device_type", "iPhone" },
                { "company", "Optimizely" },
                { "location", "San Francisco" }
            };

            var userAttributesWithBucketingId = new UserAttributes
            {
                { "device_type", "iPhone" },
                { "company", "Optimizely" },
                { "location", "San Francisco" },
                { ControlAttributes.BUCKETING_ID_ATTRIBUTE, testBucketingIdVariation }
            };

            var userAttributesWithInvalidBucketingId = new UserAttributes
            {
                { "device_type", "iPhone" },
                { "company", "Optimizely" },
                { "location", "San Francisco" },
                { ControlAttributes.BUCKETING_ID_ATTRIBUTE, 1.59 }
            };

            var invalidUserAttributesWithBucketingId = new UserAttributes
            {
                { "company", "Optimizely" },
                { ControlAttributes.BUCKETING_ID_ATTRIBUTE, testBucketingIdControl }
            };

            var optlyObject = new Optimizely(TestData.Datafile, new ValidEventDispatcher(), LoggerMock.Object);

            // confirm normal bucketing occurs before setting the bucketing ID
            var actualVariation = optlyObject.GetVariation(experimentKey, userId, testUserAttributes);

            Assert.IsTrue(TestData.CompareObjects(VariationWithKeyControl, actualVariation));

            // confirm valid bucketing with bucketing ID set in attributes
            actualVariation = optlyObject.GetVariation(experimentKey, userId, userAttributesWithBucketingId);
            Assert.IsTrue(TestData.CompareObjects(VariationWithKeyVariation, actualVariation));
            LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, $"BucketingId is valid: \"{testBucketingIdVariation}\""));

            // check audience with invalid bucketing Id
            actualVariation = optlyObject.GetVariation(experimentKey, userId, userAttributesWithInvalidBucketingId);
            Assert.IsTrue(TestData.CompareObjects(VariationWithKeyControl, actualVariation));
            LoggerMock.Verify(l => l.Log(LogLevel.WARN, "BucketingID attribute is not a string. Defaulted to userId"));

            // check invalid audience with bucketing ID
            actualVariation = optlyObject.GetVariation(experimentKey, userId, invalidUserAttributesWithBucketingId);
            Assert.Null(actualVariation);

            // check null audience with bucketing Id
            actualVariation = optlyObject.GetVariation(experimentKey, userId, null);
            Assert.Null(actualVariation);

            // test that an experiment that's not running returns a null variation
            actualVariation = optlyObject.GetVariation(pausedExperimentKey, userId, userAttributesWithBucketingId);
            Assert.Null(actualVariation);

            // check forced variation
            Assert.IsTrue(optlyObject.SetForcedVariation(experimentKey, userId, variationKeyControl), string.Format("Set variation to \"{0}\" failed.", variationKeyControl));
            actualVariation = optlyObject.GetVariation(experimentKey, userId, userAttributesWithBucketingId);
            Assert.IsTrue(TestData.CompareObjects(VariationWithKeyControl, actualVariation));

            // check whitelisted variation
            actualVariation = optlyObject.GetVariation(experimentKey, testUserIdWhitelisted, userAttributesWithBucketingId);
            Assert.IsTrue(TestData.CompareObjects(VariationWithKeyControl, actualVariation));

            var         bucketerMock      = new Mock <Bucketer>(LoggerMock.Object);
            var         decision          = new Decision("7722370027");
            UserProfile storedUserProfile = new UserProfile(userId, new Dictionary <string, Decision>
            {
                { "7716830082", decision }
            });

            UserProfileServiceMock.Setup(up => up.Lookup(userId)).Returns(storedUserProfile.ToMap());
            DecisionService decisionService = new DecisionService(bucketerMock.Object, ErrorHandlerMock.Object, ProjectConfig, UserProfileServiceMock.Object, LoggerMock.Object);

            actualVariation = optlyObject.GetVariation(experimentKey, userId, userAttributesWithBucketingId);
            Assert.IsTrue(TestData.CompareObjects(VariationWithKeyControl, actualVariation), string.Format("Variation \"{0}\" does not match expected user profile variation \"{1}\".", actualVariation?.Key, variationKeyControl));
        }
        public void DecideAllAllFlags()
        {
            var flagKey1  = "boolean_feature";
            var flagKey2  = "double_single_variable_feature";
            var flagKey3  = "integer_single_variable_feature";
            var flagKey4  = "boolean_single_variable_feature";
            var flagKey5  = "string_single_variable_feature";
            var flagKey6  = "multi_variate_feature";
            var flagKey7  = "mutex_group_feature";
            var flagKey8  = "empty_feature";
            var flagKey9  = "no_rollout_experiment_feature";
            var flagKey10 = "unsupported_variabletype";

            var variablesExpected1  = Optimizely.GetAllFeatureVariables(flagKey1, UserID);
            var variablesExpected2  = Optimizely.GetAllFeatureVariables(flagKey2, UserID);
            var variablesExpected3  = Optimizely.GetAllFeatureVariables(flagKey3, UserID);
            var variablesExpected4  = Optimizely.GetAllFeatureVariables(flagKey4, UserID);
            var variablesExpected5  = Optimizely.GetAllFeatureVariables(flagKey5, UserID);
            var variablesExpected6  = Optimizely.GetAllFeatureVariables(flagKey6, UserID);
            var variablesExpected7  = Optimizely.GetAllFeatureVariables(flagKey7, UserID);
            var variablesExpected8  = Optimizely.GetAllFeatureVariables(flagKey8, UserID);
            var variablesExpected9  = Optimizely.GetAllFeatureVariables(flagKey9, UserID);
            var variablesExpected10 = Optimizely.GetAllFeatureVariables(flagKey10, UserID);

            var user = Optimizely.CreateUserContext(UserID);

            user.SetAttribute("browser_type", "chrome");
            // Mocking objects.
            NotificationCallbackMock.Setup(nc => nc.TestDecisionCallback(It.IsAny <string>(), It.IsAny <string>(),
                                                                         It.IsAny <UserAttributes>(), It.IsAny <Dictionary <string, object> >()));

            Optimizely.NotificationCenter.AddNotification(NotificationCenter.NotificationType.Decision, NotificationCallbackMock.Object.TestDecisionCallback);

            var decisions = user.DecideAll();

            var userAttributes = new UserAttributes
            {
                { "browser_type", "chrome" }
            };

            Assert.True(decisions.Count == 10);
            NotificationCallbackMock.Verify(nc => nc.TestDecisionCallback(DecisionNotificationTypes.FLAG, UserID, userAttributes, It.IsAny <Dictionary <string, object> >()),
                                            Times.Exactly(10));

            OptimizelyDecision expDecision1 = new OptimizelyDecision(
                null,
                false,
                variablesExpected1,
                null,
                flagKey1,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey1], expDecision1));

            OptimizelyDecision expDecision2 = new OptimizelyDecision(
                "variation",
                false,
                variablesExpected2,
                "test_experiment_double_feature",
                flagKey2,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey2], expDecision2));

            OptimizelyDecision expDecision3 = new OptimizelyDecision(
                "control",
                false,
                variablesExpected3,
                "test_experiment_integer_feature",
                flagKey3,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey3], expDecision3));

            OptimizelyDecision expDecision4 = new OptimizelyDecision(
                "188881",
                false,
                variablesExpected4,
                "188880",
                flagKey4,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey4], expDecision4));

            OptimizelyDecision expDecision5 = new OptimizelyDecision(
                "control",
                true,
                variablesExpected5,
                "test_experiment_with_feature_rollout",
                flagKey5,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey5], expDecision5));

            OptimizelyDecision expDecision6 = new OptimizelyDecision(
                "Gred",
                false,
                variablesExpected6,
                "test_experiment_multivariate",
                flagKey6,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey6], expDecision6));

            OptimizelyDecision expDecision7 = new OptimizelyDecision(
                null,
                false,
                variablesExpected7,
                null,
                flagKey7,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey7], expDecision7));

            OptimizelyDecision expDecision8 = new OptimizelyDecision(
                null,
                false,
                variablesExpected8,
                null,
                flagKey8,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey8], expDecision8));

            OptimizelyDecision expDecision9 = new OptimizelyDecision(
                null,
                false,
                variablesExpected9,
                null,
                flagKey9,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey9], expDecision9));

            OptimizelyDecision expDecision10 = new OptimizelyDecision(
                null,
                false,
                variablesExpected10,
                null,
                flagKey10,
                user,
                new string[0]);

            Assert.IsTrue(TestData.CompareObjects(decisions[flagKey10], expDecision10));
        }
Пример #29
0
        public void TestInit()
        {
            // Check Version
            Assert.AreEqual("4", Config.Version);

            // Check Account ID
            Assert.AreEqual("1592310167", Config.AccountId);
            // Check Project ID
            Assert.AreEqual("7720880029", Config.ProjectId);
            // Check Revision
            Assert.AreEqual("15", Config.Revision);

            // Check Group ID Map
            var expectedGroupId = CreateDictionary("7722400015", Config.GetGroup("7722400015"));

            var actual = Config.GroupIdMap;

            Assert.IsTrue(TestData.CompareObjects(expectedGroupId, actual));

            // Check Experiment Key Map
            var experimentKeyMap = new Dictionary <string, object>()
            {
                { "test_experiment", Config.GetExperimentFromKey("test_experiment") },
                { "paused_experiment", Config.GetExperimentFromKey("paused_experiment") },
                { "test_experiment_multivariate", Config.GetExperimentFromKey("test_experiment_multivariate") },
                { "test_experiment_with_feature_rollout", Config.GetExperimentFromKey("test_experiment_with_feature_rollout") },
                { "test_experiment_double_feature", Config.GetExperimentFromKey("test_experiment_double_feature") },
                { "test_experiment_integer_feature", Config.GetExperimentFromKey("test_experiment_integer_feature") },
                { "group_experiment_1", Config.GetExperimentFromKey("group_experiment_1") },
                { "group_experiment_2", Config.GetExperimentFromKey("group_experiment_2") },
                { "etag1", Config.GetExperimentFromKey("etag1") },
                { "etag2", Config.GetExperimentFromKey("etag2") },
                { "etag3", Config.GetExperimentFromKey("etag3") },
                { "etag4", Config.GetExperimentFromKey("etag4") }
            };

            Assert.IsTrue(TestData.CompareObjects(experimentKeyMap, Config.ExperimentKeyMap));

            // Check Experiment ID Map

            var experimentIdMap = new Dictionary <string, object>()
            {
                { "7716830082", Config.GetExperimentFromId("7716830082") },
                { "7716830585", Config.GetExperimentFromId("7716830585") },
                { "122230", Config.GetExperimentFromId("122230") },
                { "122235", Config.GetExperimentFromId("122235") },
                { "122238", Config.GetExperimentFromId("122238") },
                { "122241", Config.GetExperimentFromId("122241") },
                { "7723330021", Config.GetExperimentFromId("7723330021") },
                { "7718750065", Config.GetExperimentFromId("7718750065") },
                { "223", Config.GetExperimentFromId("223") },
                { "118", Config.GetExperimentFromId("118") },
                { "224", Config.GetExperimentFromId("224") },
                { "119", Config.GetExperimentFromId("119") }
            };

            Assert.IsTrue(TestData.CompareObjects(experimentIdMap, Config.ExperimentIdMap));

            // Check Event key Map
            var eventKeyMap = new Dictionary <string, object> {
                { "purchase", Config.GetEvent("purchase") }
            };

            Assert.IsTrue(TestData.CompareObjects(eventKeyMap, Config.EventKeyMap));

            // Check Attribute Key Map
            var attributeKeyMap = new Dictionary <string, object>
            {
                { "device_type", Config.GetAttribute("device_type") },
                { "location", Config.GetAttribute("location") },
                { "browser_type", Config.GetAttribute("browser_type") },
                { "boolean_key", Config.GetAttribute("boolean_key") },
                { "integer_key", Config.GetAttribute("integer_key") },
                { "double_key", Config.GetAttribute("double_key") }
            };

            Assert.IsTrue(TestData.CompareObjects(attributeKeyMap, Config.AttributeKeyMap));

            // Check Audience ID Map
            var audienceIdMap = new Dictionary <string, object>
            {
                { "7718080042", Config.GetAudience("7718080042") },
                { "11154", Config.GetAudience("11154") },
                { "100", Config.GetAudience("100") }
            };

            Assert.IsTrue(TestData.CompareObjects(audienceIdMap, Config.AudienceIdMap));

            // Check Variation Key Map
            var expectedVariationKeyMap = new Dictionary <string, object>
            {
                { "test_experiment", new Dictionary <string, object>
                  {
                      { "control", Config.GetVariationFromKey("test_experiment", "control") },
                      { "variation", Config.GetVariationFromKey("test_experiment", "variation") }
                  } },
                { "paused_experiment", new Dictionary <string, object>
                  {
                      { "control", Config.GetVariationFromKey("paused_experiment", "control") },
                      { "variation", Config.GetVariationFromKey("paused_experiment", "variation") }
                  } },
                { "group_experiment_1", new Dictionary <string, object>
                  {
                      { "group_exp_1_var_1", Config.GetVariationFromKey("group_experiment_1", "group_exp_1_var_1") },
                      { "group_exp_1_var_2", Config.GetVariationFromKey("group_experiment_1", "group_exp_1_var_2") }
                  } },
                { "group_experiment_2", new Dictionary <string, object>
                  {
                      { "group_exp_2_var_1", Config.GetVariationFromKey("group_experiment_2", "group_exp_2_var_1") },
                      { "group_exp_2_var_2", Config.GetVariationFromKey("group_experiment_2", "group_exp_2_var_2") }
                  } },
                { "test_experiment_multivariate", new Dictionary <string, object>
                  {
                      { "Fred", Config.GetVariationFromKey("test_experiment_multivariate", "Fred") },
                      { "Feorge", Config.GetVariationFromKey("test_experiment_multivariate", "Feorge") },
                      { "Gred", Config.GetVariationFromKey("test_experiment_multivariate", "Gred") },
                      { "George", Config.GetVariationFromKey("test_experiment_multivariate", "George") }
                  } },
                { "test_experiment_with_feature_rollout", new Dictionary <string, object>
                  {
                      { "control", Config.GetVariationFromKey("test_experiment_with_feature_rollout", "control") },
                      { "variation", Config.GetVariationFromKey("test_experiment_with_feature_rollout", "variation") }
                  } },
                { "test_experiment_double_feature", new Dictionary <string, object>
                  {
                      { "control", Config.GetVariationFromKey("test_experiment_double_feature", "control") },
                      { "variation", Config.GetVariationFromKey("test_experiment_double_feature", "variation") }
                  } },
                { "test_experiment_integer_feature", new Dictionary <string, object>
                  {
                      { "control", Config.GetVariationFromKey("test_experiment_integer_feature", "control") },
                      { "variation", Config.GetVariationFromKey("test_experiment_integer_feature", "variation") }
                  } },
                { "177770", new Dictionary <string, object>
                  {
                      { "177771", Config.GetVariationFromKey("177770", "177771") }
                  } },
                { "177772", new Dictionary <string, object>
                  {
                      { "177773", Config.GetVariationFromKey("177772", "177773") }
                  } },
                { "177776", new Dictionary <string, object>
                  {
                      { "177778", Config.GetVariationFromKey("177776", "177778") }
                  } },
                { "177774", new Dictionary <string, object>
                  {
                      { "177775", Config.GetVariationFromKey("177774", "177775") }
                  } },
                { "177779", new Dictionary <string, object>
                  {
                      { "177780", Config.GetVariationFromKey("177779", "177780") }
                  } },
                { "177781", new Dictionary <string, object>
                  {
                      { "177782", Config.GetVariationFromKey("177781", "177782") }
                  } },
                { "177783", new Dictionary <string, object>
                  {
                      { "177784", Config.GetVariationFromKey("177783", "177784") }
                  } },
                { "188880", new Dictionary <string, object>
                  {
                      { "188881", Config.GetVariationFromKey("188880", "188881") }
                  } },
                { "etag1", new Dictionary <string, object>
                  {
                      { "vtag1", Config.GetVariationFromKey("etag1", "vtag1") },
                      { "vtag2", Config.GetVariationFromKey("etag1", "vtag2") }
                  } },
                { "etag2", new Dictionary <string, object>
                  {
                      { "vtag3", Config.GetVariationFromKey("etag2", "vtag3") },
                      { "vtag4", Config.GetVariationFromKey("etag2", "vtag4") }
                  } },
                { "etag3", new Dictionary <string, object>
                  {
                      { "vtag5", Config.GetVariationFromKey("etag3", "vtag5") },
                      { "vtag6", Config.GetVariationFromKey("etag3", "vtag6") }
                  } },
                { "etag4", new Dictionary <string, object>
                  {
                      { "vtag7", Config.GetVariationFromKey("etag4", "vtag7") },
                      { "vtag8", Config.GetVariationFromKey("etag4", "vtag8") }
                  } }
            };

            Assert.IsTrue(TestData.CompareObjects(expectedVariationKeyMap, Config.VariationKeyMap));

            // Check Variation ID Map
            var expectedVariationIdMap = new Dictionary <string, object>
            {
                { "test_experiment", new Dictionary <string, object>
                  {
                      { "7722370027", Config.GetVariationFromId("test_experiment", "7722370027") },
                      { "7721010009", Config.GetVariationFromId("test_experiment", "7721010009") }
                  } },
                { "paused_experiment", new Dictionary <string, object>
                  {
                      { "7722370427", Config.GetVariationFromId("paused_experiment", "7722370427") },
                      { "7721010509", Config.GetVariationFromId("paused_experiment", "7721010509") }
                  } },
                { "test_experiment_multivariate", new Dictionary <string, object>
                  {
                      { "122231", Config.GetVariationFromId("test_experiment_multivariate", "122231") },
                      { "122232", Config.GetVariationFromId("test_experiment_multivariate", "122232") },
                      { "122233", Config.GetVariationFromId("test_experiment_multivariate", "122233") },
                      { "122234", Config.GetVariationFromId("test_experiment_multivariate", "122234") }
                  } },
                { "test_experiment_with_feature_rollout", new Dictionary <string, object>
                  {
                      { "122236", Config.GetVariationFromId("test_experiment_with_feature_rollout", "122236") },
                      { "122237", Config.GetVariationFromId("test_experiment_with_feature_rollout", "122237") }
                  } },
                { "test_experiment_double_feature", new Dictionary <string, object>
                  {
                      { "122239", Config.GetVariationFromId("test_experiment_double_feature", "122239") },
                      { "122240", Config.GetVariationFromId("test_experiment_double_feature", "122240") }
                  } },
                { "test_experiment_integer_feature", new Dictionary <string, object>
                  {
                      { "122242", Config.GetVariationFromId("test_experiment_integer_feature", "122242") },
                      { "122243", Config.GetVariationFromId("test_experiment_integer_feature", "122243") }
                  } },
                { "group_experiment_1", new Dictionary <string, object>
                  {
                      { "7722260071", Config.GetVariationFromId("group_experiment_1", "7722260071") },
                      { "7722360022", Config.GetVariationFromId("group_experiment_1", "7722360022") }
                  } },
                { "group_experiment_2", new Dictionary <string, object>
                  {
                      { "7713030086", Config.GetVariationFromId("group_experiment_2", "7713030086") },
                      { "7725250007", Config.GetVariationFromId("group_experiment_2", "7725250007") }
                  } },
                { "177770", new Dictionary <string, object>
                  {
                      { "177771", Config.GetVariationFromId("177770", "177771") }
                  } },
                { "177772", new Dictionary <string, object>
                  {
                      { "177773", Config.GetVariationFromId("177772", "177773") }
                  } },
                { "177776", new Dictionary <string, object>
                  {
                      { "177778", Config.GetVariationFromId("177776", "177778") }
                  } },
                { "177774", new Dictionary <string, object>
                  {
                      { "177775", Config.GetVariationFromId("177774", "177775") }
                  } },
                { "177779", new Dictionary <string, object>
                  {
                      { "177780", Config.GetVariationFromId("177779", "177780") }
                  } },
                { "177781", new Dictionary <string, object>
                  {
                      { "177782", Config.GetVariationFromId("177781", "177782") }
                  } },
                { "177783", new Dictionary <string, object>
                  {
                      { "177784", Config.GetVariationFromId("177783", "177784") }
                  } },
                { "188880", new Dictionary <string, object>
                  {
                      { "188881", Config.GetVariationFromId("188880", "188881") }
                  } },
                { "etag1", new Dictionary <string, object>
                  {
                      { "276", Config.GetVariationFromId("etag1", "276") },
                      { "277", Config.GetVariationFromId("etag1", "277") }
                  } },
                { "etag2", new Dictionary <string, object>
                  {
                      { "278", Config.GetVariationFromId("etag2", "278") },
                      { "279", Config.GetVariationFromId("etag2", "279") }
                  } },
                { "etag3", new Dictionary <string, object>
                  {
                      { "280", Config.GetVariationFromId("etag3", "280") },
                      { "281", Config.GetVariationFromId("etag3", "281") }
                  } },
                { "etag4", new Dictionary <string, object>
                  {
                      { "282", Config.GetVariationFromId("etag4", "282") },
                      { "283", Config.GetVariationFromId("etag4", "283") }
                  } }
            };

            Assert.IsTrue(TestData.CompareObjects(expectedVariationIdMap, Config.VariationIdMap));

            // Check Variation returns correct variable usage
            var featureVariableUsageInstance = new List <FeatureVariableUsage>
            {
                new FeatureVariableUsage {
                    Id = "155560", Value = "F"
                },
                new FeatureVariableUsage {
                    Id = "155561", Value = "red"
                },
            };

            var expectedVariationUsage = new Variation {
                Id = "122231", Key = "Fred", FeatureVariableUsageInstances = featureVariableUsageInstance, FeatureEnabled = true
            };
            var actualVariationUsage = Config.GetVariationFromKey("test_experiment_multivariate", "Fred");

            Assert.IsTrue(TestData.CompareObjects(expectedVariationUsage, actualVariationUsage));

            // Check Feature Key map.
            var expectedFeatureKeyMap = new Dictionary <string, FeatureFlag>
            {
                { "boolean_feature", Config.GetFeatureFlagFromKey("boolean_feature") },
                { "double_single_variable_feature", Config.GetFeatureFlagFromKey("double_single_variable_feature") },
                { "integer_single_variable_feature", Config.GetFeatureFlagFromKey("integer_single_variable_feature") },
                { "boolean_single_variable_feature", Config.GetFeatureFlagFromKey("boolean_single_variable_feature") },
                { "string_single_variable_feature", Config.GetFeatureFlagFromKey("string_single_variable_feature") },
                { "multi_variate_feature", Config.GetFeatureFlagFromKey("multi_variate_feature") },
                { "mutex_group_feature", Config.GetFeatureFlagFromKey("mutex_group_feature") },
                { "empty_feature", Config.GetFeatureFlagFromKey("empty_feature") },
                { "no_rollout_experiment_feature", Config.GetFeatureFlagFromKey("no_rollout_experiment_feature") }
            };

            Assert.IsTrue(TestData.CompareObjects(expectedFeatureKeyMap, Config.FeatureKeyMap));

            // Check Feature Key map.
            var expectedRolloutIdMap = new Dictionary <string, Rollout>
            {
                { "166660", Config.GetRolloutFromId("166660") },
                { "166661", Config.GetRolloutFromId("166661") }
            };

            Assert.IsTrue(TestData.CompareObjects(expectedRolloutIdMap, Config.RolloutIdMap));
        }