Beispiel #1
0
        /// <summary>
        /// Buckets visitor and sends impression event to Optimizely.
        /// </summary>
        /// <param name="experimentKey">experimentKey string Key identifying the experiment</param>
        /// <param name="userId">string ID for user</param>
        /// <param name="attributes">associative array of Attributes for the user</param>
        /// <returns>null|Variation Representing variation</returns>
        public Variation Activate(string experimentKey, string userId, UserAttributes userAttributes = null)
        {
            if (!IsValid)
            {
                Logger.Log(LogLevel.ERROR, "Datafile has invalid format. Failing 'activate'.");
                return(null);
            }

            var experiment = Config.GetExperimentFromKey(experimentKey);

            if (experiment.Key == null)
            {
                Logger.Log(LogLevel.INFO, string.Format("Not activating user {0}.", userId));
                return(null);
            }

            var variation = DecisionService.GetVariation(experiment, userId, userAttributes);

            if (variation == null || variation.Key == null)
            {
                Logger.Log(LogLevel.INFO, string.Format("Not activating user {0}.", userId));
                return(null);
            }

            if (userAttributes != null)
            {
                userAttributes = userAttributes.FilterNullValues(Logger);
            }

            SendImpressionEvent(experiment, variation, userId, userAttributes);

            return(variation);
        }
Beispiel #2
0
        public void TestGetVariationEvaluatesUserProfileBeforeAudienceTargeting()
        {
            Experiment experiment = ProjectConfig.Experiments[8];
            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(up => up.Lookup(WhitelistedUserId)).Returns(userProfile.ToMap());

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

            decisionService.GetVariation(experiment, GenericUserId, new UserAttributes());

            LoggerMock.Verify(l => l.Log(LogLevel.INFO, string.Format("User \"{0}\" does not meet conditions to be in experiment \"{1}\".",
                                                                      GenericUserId, experiment.Key)), Times.Once);

            // ensure that a user with a saved user profile, sees the same variation regardless of audience evaluation
            decisionService.GetVariation(experiment, UserProfileId, new UserAttributes());

            BucketerMock.Verify(_ => _.Bucket(It.IsAny <ProjectConfig>(), It.IsAny <Experiment>(), It.IsAny <string>(), It.IsAny <string>()), Times.Never);
        }
Beispiel #3
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);
        }
Beispiel #4
0
        public void TestGetVariationSavesANewUserProfile()
        {
            Experiment experiment = ProjectConfig.Experiments[6];
            Variation  variation  = experiment.Variations[0];
            Decision   decision   = new Decision(variation.Id);

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

            var mockBucketer = new Mock <Bucketer>(LoggerMock.Object);

            mockBucketer.Setup(m => m.Bucket(ProjectConfig, experiment, UserProfileId, UserProfileId)).Returns(variation);

            Dictionary <string, object> userProfile = null;

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

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

            Assert.IsTrue(TestData.CompareObjects(variation, decisionService.GetVariation(experiment, UserProfileId, new UserAttributes())));
            UserProfileServiceMock.Verify(_ => _.Save(It.IsAny <Dictionary <string, object> >()), Times.Once);
        }
Beispiel #5
0
        public void TestGetVariationSavesBucketedVariationIntoUserProfile()
        {
            Experiment experiment = ProjectConfig.Experiments[6];
            Variation  variation  = experiment.Variations[0];

            Decision decision = new Decision(variation.Id);

            UserProfile originalUserProfile = new UserProfile(UserProfileId,
                                                              new Dictionary <string, Decision>());

            UserProfileServiceMock.Setup(ups => ups.Lookup(UserProfileId)).Returns(originalUserProfile.ToMap());

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

            var mockBucketer = new Mock <Bucketer>(LoggerMock.Object);

            mockBucketer.Setup(m => m.Bucket(ProjectConfig, experiment, UserProfileId, UserProfileId)).Returns(variation);

            DecisionService decisionService = new DecisionService(mockBucketer.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("Saved variation \"{0}\" of experiment \"{1}\" for user \"{2}\".", variation.Id,
                                                                      experiment.Id, UserProfileId)), Times.Once);
            UserProfileServiceMock.Verify(_ => _.Save(It.IsAny <Dictionary <string, object> >()), Times.Once);
        }
Beispiel #6
0
        /// <summary>
        /// Buckets visitor and sends impression event to Optimizely.
        /// </summary>
        /// <param name="experimentKey">experimentKey string Key identifying the experiment</param>
        /// <param name="userId">string ID for user</param>
        /// <param name="userAttributes">associative array of Attributes for the user</param>
        /// <returns>null|Variation Representing variation</returns>
        public Variation Activate(string experimentKey, string userId, UserAttributes userAttributes = null)
        {
            if (!IsValid)
            {
                Logger.Log(LogLevel.ERROR, "Datafile has invalid format. Failing 'activate'.");
                return(null);
            }

            var inputValues = new Dictionary <string, string>
            {
                { USER_ID, userId },
                { EXPERIMENT_KEY, experimentKey }
            };

            if (!ValidateStringInputs(inputValues))
            {
                return(null);
            }

            var experiment = Config.GetExperimentFromKey(experimentKey);

            if (experiment.Key == null)
            {
                Logger.Log(LogLevel.INFO, string.Format("Not activating user {0}.", userId));
                return(null);
            }

            var variation = DecisionService.GetVariation(experiment, userId, userAttributes);

            if (variation == null || variation.Key == null)
            {
                Logger.Log(LogLevel.INFO, string.Format("Not activating user {0}.", userId));
                return(null);
            }

            SendImpressionEvent(experiment, variation, userId, userAttributes);

            return(variation);
        }
Beispiel #7
0
        /// <summary>
        /// Get variation where user will be bucketed
        /// </summary>
        /// <param name="experimentKey">experimentKey string Key identifying the experiment</param>
        /// <param name="userId">ID for the user</param>
        /// <param name="userAttributes">Attributes for the users</param>
        /// <returns>null|Variation Representing variation</returns>
        public Variation GetVariation(string experimentKey, string userId, UserAttributes userAttributes = null)
        {
            if (!IsValid)
            {
                Logger.Log(LogLevel.ERROR, "Datafile has invalid format. Failing 'GetVariation'.");
                return(null);
            }

            var inputValues = new Dictionary <string, string>
            {
                { USER_ID, userId },
                { EXPERIMENT_KEY, experimentKey }
            };

            if (!ValidateStringInputs(inputValues))
            {
                return(null);
            }

            Experiment experiment = Config.GetExperimentFromKey(experimentKey);

            if (experiment.Key == null)
            {
                return(null);
            }

            var variation    = DecisionService.GetVariation(experiment, userId, userAttributes);
            var decisionInfo = new Dictionary <string, object>
            {
                { "experimentKey", experimentKey },
                { "variationKey", variation?.Key },
            };

            userAttributes = userAttributes ?? new UserAttributes();
            var decisionNotificationType = Config.IsFeatureExperiment(experiment.Id) ? DecisionNotificationTypes.FEATURE_TEST : DecisionNotificationTypes.AB_TEST;

            NotificationCenter.SendNotifications(NotificationCenter.NotificationType.Decision, decisionNotificationType, userId,
                                                 userAttributes, decisionInfo);
            return(variation);
        }
Beispiel #8
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);
        }