public void TestIsUserInExperimentAudienceNoMatch()
        {
            var userAttributes = new UserAttributes
            {
                { "device_type", "Android" },
                { "location", "San Francisco" }
            };

            Assert.IsFalse(ExperimentUtils.IsUserInExperiment(Config, Config.GetExperimentFromKey("test_experiment"), null, Logger));
        }
        /// <summary>
        /// Create impression event to be sent to the logging endpoint.
        /// </summary>
        /// <param name="config">ProjectConfig Configuration for the project</param>
        /// <param name="experiment">Experiment being activated</param>
        /// <param name="variationId">Variation Id</param>
        /// <param name="userId">User Id</param>
        /// <param name="userAttributes">associative array of attributes for the user</param>
        /// <returns>LogEvent object to be sent to dispatcher</returns>
        public virtual LogEvent CreateImpressionEvent(ProjectConfig config, Experiment experiment, string variationId,
                                                      string userId, UserAttributes userAttributes)
        {
            var commonParams         = GetCommonParams(config, userId, userAttributes ?? new UserAttributes());
            var impressionOnlyParams = GetImpressionParams(experiment, variationId);

            var impressionParams = GetImpressionOrConversionParamsWithCommonParams(commonParams, new object[] { impressionOnlyParams });

            return(new LogEvent(IMPRESSION_ENDPOINT, impressionParams, HTTP_VERB, HTTP_HEADERS));
        }
        public CanonicalEvent(string experimentId, string variationId, string eventName, string visitorId, UserAttributes attributes, EventTags tags)
        {
            ExperimentId = experimentId;
            VariationId  = variationId;
            EventName    = eventName;
            VisitorId    = visitorId;

            Attributes = attributes ?? new UserAttributes();
            Tags       = tags ?? new EventTags();
        }
Exemple #4
0
        public void TestDoesUserMeetAudienceConditionsReturnsTrueIfAllAudiencesInANDConditionPass()
        {
            var experiment     = Config.GetExperimentFromKey("audience_combinations_experiment");
            var userAttributes = new UserAttributes
            {
                { "house", "Gryffindor" },
                { "favorite_ice_cream", "walls" }
            };

            Assert.True(ExperimentUtils.DoesUserMeetAudienceConditions(Config, experiment, userAttributes, "experiment", experiment.Key, Logger).ResultObject);
        }
        public void TestEvaluateConditionsDoNotMatch()
        {
            var userAttributes = new UserAttributes
            {
                { "device_type", "iPhone" },
                { "location", "San Francisco" },
                { "browser", "Firefox" }
            };

            Assert.IsFalse(ConditionEvaluator.Evaluate(Conditions, userAttributes));
        }
Exemple #6
0
        /// <summary>
        /// Returns copy of UserAttributes associated with UserContext.
        /// </summary>
        /// <returns>copy of UserAttributes.</returns>
        public UserAttributes GetAttributes()
        {
            UserAttributes copiedAttributes = null;

            lock (mutex)
            {
                copiedAttributes = new UserAttributes(Attributes);
            }

            return(copiedAttributes);
        }
Exemple #7
0
        public void TestIsUserInExperimentReturnsTrueIfAllAudiencesInANDConditionPass()
        {
            var experiment     = Config.GetExperimentFromKey("audience_combinations_experiment");
            var userAttributes = new UserAttributes
            {
                { "house", "Gryffindor" },
                { "favorite_ice_cream", "walls" }
            };

            Assert.True(ExperimentUtils.IsUserInExperiment(Config, experiment, userAttributes, Logger));
        }
        public void TestDoesUserMeetAudienceConditionsReturnsTrueIfAudienceInNOTConditionDoesNotPass()
        {
            var experiment = Config.GetExperimentFromKey("feat_with_var_test");

            experiment.AudienceIds = new string[] { "3468206645" };
            var userAttributes = new UserAttributes
            {
                { "browser_type", "Safari" }
            };

            Assert.True(ExperimentUtils.DoesUserMeetAudienceConditions(Config, experiment, userAttributes, "experiment", experiment.Key, Logger));
        }
Exemple #9
0
        public void TestIsUserInExperimentReturnsFalseIfAudienceInNOTConditionGetsPassed()
        {
            var experiment = Config.GetExperimentFromKey("feat_with_var_test");

            experiment.AudienceIds = new string[] { "3468206645" };
            var userAttributes = new UserAttributes
            {
                { "browser_type", "Chrome" }
            };

            Assert.False(ExperimentUtils.IsUserInExperiment(Config, experiment, userAttributes, Logger));
        }
        public void OptimizelyUserContextWithAttributes()
        {
            var attributes = new UserAttributes()
            {
                { "house", "GRYFFINDOR" }
            };
            OptimizelyUserContext user = new OptimizelyUserContext(Optimizely, UserID, attributes, ErrorHandlerMock.Object, LoggerMock.Object);

            Assert.AreEqual(user.GetOptimizely(), Optimizely);
            Assert.AreEqual(user.GetUserId(), UserID);
            Assert.AreEqual(user.GetAttributes(), attributes);
        }
Exemple #11
0
        public void TestDoesUserMeetAudienceConditionsReturnsFalseIfAudienceInNOTConditionGetsPassed()
        {
            var experiment = Config.GetExperimentFromKey("feat_with_var_test");

            experiment.AudienceIds = new string[] { "3468206645" };
            var userAttributes = new UserAttributes
            {
                { "browser_type", "Chrome" }
            };

            Assert.False(ExperimentUtils.DoesUserMeetAudienceConditions(Config, experiment, userAttributes, "experiment", experiment.Key, Logger).ResultObject);
        }
Exemple #12
0
        /// <summary>
        /// Sends conversion event to Optimizely.
        /// </summary>
        /// <param name="eventKey">Event key representing the event which needs to be recorded</param>
        /// <param name="userId">ID for user</param>
        /// <param name="userAttributes">Attributes of the user</param>
        /// <param name="eventTags">eventTags array Hash representing metadata associated with the event.</param>
        public void Track(string eventKey, string userId, UserAttributes userAttributes = null, EventTags eventTags = null)
        {
            if (!IsValid)
            {
                Logger.Log(LogLevel.ERROR, "Datafile has invalid format. Failing 'track'.");
                return;
            }

            var inputValues = new Dictionary <string, string>
            {
                { USER_ID, userId },
                { EVENT_KEY, eventKey }
            };

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

            var eevent = Config.GetEvent(eventKey);

            if (eevent.Key == null)
            {
                Logger.Log(LogLevel.INFO, string.Format("Not tracking user {0} for event {1}.", userId, eventKey));
                return;
            }


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

            var conversionEvent = EventBuilder.CreateConversionEvent(Config, eventKey,
                                                                     userId, userAttributes, eventTags);

            Logger.Log(LogLevel.INFO, string.Format("Tracking event {0} for user {1}.", eventKey, userId));
            Logger.Log(LogLevel.DEBUG, string.Format("Dispatching conversion event to URL {0} with params {1}.",
                                                     conversionEvent.Url, conversionEvent.GetParamsAsJson()));

            try
            {
                EventDispatcher.DispatchEvent(conversionEvent);
            }
            catch (Exception exception)
            {
                Logger.Log(LogLevel.ERROR, string.Format("Unable to dispatch conversion event. Error {0}", exception.Message));
            }

            NotificationCenter.SendNotifications(NotificationCenter.NotificationType.Track, eventKey, userId,
                                                 userAttributes, eventTags, conversionEvent);
        }
Exemple #13
0
        /// <summary>
        /// Get Bucketing ID from user attributes.
        /// </summary>
        /// <param name = "userId" >User Identifier</param>
        /// <param name = "filteredAttributes" >The user's attributes.</param>
        /// <returns>User ID if bucketing Id is not provided in user attributes, bucketing Id otherwise.</returns>
        private string GetBucketingId(string userId, UserAttributes filteredAttributes)
        {
            string bucketingId = userId;

            // If the bucketing ID key is defined in attributes, then use that in place of the userID for the murmur hash key
            if (filteredAttributes != null && filteredAttributes.ContainsKey(RESERVED_ATTRIBUTE_KEY_BUCKETING_ID))
            {
                bucketingId = filteredAttributes[RESERVED_ATTRIBUTE_KEY_BUCKETING_ID];
                Logger.Log(LogLevel.DEBUG, string.Format("Setting the bucketing ID to \"{0}\"", bucketingId));
            }

            return(bucketingId);
        }
        public void TestIsUserAttributeValidWithInvalidValues()
        {
            var invalidUserAttributes = new UserAttributes
            {
                { "objects", new object() },
                { "arrays", new string[] { "a", "b", "c" } }
            };

            foreach (var attribute in invalidUserAttributes)
            {
                Assert.False(Validator.IsUserAttributeValid(attribute));
            }
        }
Exemple #15
0
        /// <summary>
        /// Create ImpressionEvent instance from ProjectConfig
        /// </summary>
        /// <param name="projectConfig">The ProjectConfig entity</param>
        /// <param name="activatedExperiment">The Experiment entity</param>
        /// <param name="variationId">The variation Id</param>
        /// <param name="userId">The user Id</param>
        /// <param name="userAttributes">The user's attributes</param>
        /// <returns>ImpressionEvent instance</returns>
        public static ImpressionEvent CreateImpressionEvent(ProjectConfig projectConfig,
                                                            Experiment activatedExperiment,
                                                            string variationId,
                                                            string userId,
                                                            UserAttributes userAttributes,
                                                            string flagKey,
                                                            string ruleType,
                                                            bool enabled = false)
        {
            Variation variation = projectConfig.GetVariationFromId(activatedExperiment?.Key, variationId);

            return(CreateImpressionEvent(projectConfig, activatedExperiment, variation, userId, userAttributes, flagKey, ruleType, enabled));
        }
        public void DispatchEvent(LogEvent actualLogEvent)
        {
            Visitor[] visitors = null;
            if (actualLogEvent.Params.ContainsKey("visitors"))
            {
                JArray jArray = (JArray)actualLogEvent.Params["visitors"];
                visitors = jArray.ToObject <Visitor[]>();
            }

            if (visitors == null)
            {
                return;
            }

            foreach (var visitor in visitors)
            {
                foreach (var snapshot in visitor.Snapshots)
                {
                    var decisions = snapshot.Decisions ?? new Decision[1] {
                        new Decision()
                    };
                    foreach (var decision in decisions)
                    {
                        foreach (var @event in snapshot.Events)
                        {
                            var userAttributes = new UserAttributes();
                            foreach (var attribute in visitor.Attributes.Where(attr => !attr.Key.StartsWith(DatafileProjectConfig.RESERVED_ATTRIBUTE_PREFIX)))
                            {
                                userAttributes.Add(attribute.Key, attribute.Value);
                            }

                            ActualEvents.Add(new CanonicalEvent(decision.ExperimentId, decision.VariationId, @event.Key,
                                                                visitor.VisitorId, userAttributes, @event.EventTags));
                        }
                    }
                }
            }

            try
            {
                CountdownEvent?.Signal();
            }
            catch (ObjectDisposedException)
            {
                Logger.Log(LogLevel.ERROR, "The CountdownEvent instance has already been disposed.");
            }
            catch (InvalidOperationException)
            {
                Logger.Log(LogLevel.ERROR, "The CountdownEvent instance has already been set.");
            }
        }
        public void TestIsUserAttributeValidWithEmptyKeyOrValue()
        {
            var validUserAttributes = new UserAttributes
            {
                { "", "Android" },
                { "integer", 0 },
                { "string", string.Empty }
            };

            foreach (var attribute in validUserAttributes)
            {
                Assert.True(Validator.IsUserAttributeValid(attribute));
            }
        }
Exemple #18
0
        private static async void GetCommand(GetOptions authOptions, TaskCompletionSource <object> taskCompletionSource)
        {
            try
            {
                if (authOptions.User)
                {
                    User user = await KitsuAPI.GetUserByIDAsync(authOptions.Id, kitsuSession);

                    UserAttributes userAttributes = user.Attributes.As <UserAttributes>();

                    Console.WriteLine("-");
                    Console.WriteLine("Name: {0}", userAttributes.Name);
                    Console.WriteLine("ID: {0}", user.Id);
                    Console.WriteLine("--About:");
                    Console.WriteLine(userAttributes.About);
                    Console.WriteLine("--");
                    Console.WriteLine("-");
                }
                else
                {
                    IEntity media = null;

                    if (authOptions.Anime)
                    {
                        media = await KitsuAPI.GetAnimeByIDAsync(authOptions.Id, kitsuSession);
                    }
                    else if (authOptions.Manga)
                    {
                        media = await KitsuAPI.GetMangaByIDAsync(authOptions.Id, kitsuSession);
                    }
                    else if (authOptions.Drama)
                    {
                    }

                    if (media != null)
                    {
                        PrintMedia(media);
                    }
                }

                taskCompletionSource.SetResult(null);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine("Error occurred.");
                Console.Error.WriteLine(ex.ToString());

                taskCompletionSource.SetException(ex);
            }
        }
        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));
        }
Exemple #20
0
        /// <summary>
        /// Determine whether a feature is enabled.
        /// Send an impression event if the user is bucketed into an experiment using the feature.
        /// </summary>
        /// <param name="experimentKey">The experiment key</param>
        /// <param name="userId">The user ID</param>
        /// <param name="userAttributes">The user's attributes.</param>
        /// <returns>True if feature is enabled, false or null otherwise</returns>
        public virtual bool IsFeatureEnabled(string featureKey, string userId, UserAttributes userAttributes = null)
        {
            if (string.IsNullOrEmpty(userId))
            {
                Logger.Log(LogLevel.ERROR, "User ID must not be empty.");
                return(false);
            }

            if (string.IsNullOrEmpty(featureKey))
            {
                Logger.Log(LogLevel.ERROR, "Feature flag key must not be empty.");
                return(false);
            }

            var featureFlag = Config.GetFeatureFlagFromKey(featureKey);

            if (string.IsNullOrEmpty(featureFlag.Key))
            {
                return(false);
            }

            if (!Validator.IsFeatureFlagValid(Config, featureFlag))
            {
                return(false);
            }

            var decision = DecisionService.GetVariationForFeature(featureFlag, userId, userAttributes);

            if (decision != null)
            {
                if (decision.Source == FeatureDecision.DECISION_SOURCE_EXPERIMENT)
                {
                    SendImpressionEvent(decision.Experiment, decision.Variation, userId, userAttributes);
                }
                else
                {
                    Logger.Log(LogLevel.INFO, $@"The user ""{userId}"" is not being experimented on feature ""{featureKey}"".");
                }
                if (decision.Variation.IsFeatureEnabled)
                {
                    Logger.Log(LogLevel.INFO, $@"Feature flag ""{featureKey}"" is enabled for user ""{userId}"".");
                    return(true);
                }
            }


            Logger.Log(LogLevel.INFO, $@"Feature flag ""{featureKey}"" is not enabled for user ""{userId}"".");
            return(false);
        }
        public void TestIsUserAttributeValidWithValidValues()
        {
            var userAttributes = new UserAttributes
            {
                { "device_type", "Android" },
                { "is_firefox", true },
                { "num_users", 15 },
                { "pi_value", 3.14 }
            };

            foreach (var attribute in userAttributes)
            {
                Assert.True(Validator.IsUserAttributeValid(attribute));
            }
        }
Exemple #22
0
        public void TestEvaluateWithDifferentTypedAttributes()
        {
            var userAttributes = new UserAttributes
            {
                { "browser_type", "firefox" },
                { "is_registered_user", false },
                { "distance_gt", 15 },
                { "pi_value", 3.14 },
            };

            Assert.That(ExactStrCondition.Evaluate(null, userAttributes, Logger), Is.True);
            Assert.That(ExactBoolCondition.Evaluate(null, userAttributes, Logger), Is.True);
            Assert.That(GTCondition.Evaluate(null, userAttributes, Logger), Is.True);
            Assert.That(ExactDecimalCondition.Evaluate(null, userAttributes, Logger), Is.True);
        }
        public void TestTrackEventWithAudienceConditions()
        {
            var OptimizelyWithTypedAudiences = new Optimizely(TestData.TypedAudienceDatafile, EventDispatcherMock.Object, LoggerMock.Object, ErrorHandlerMock.Object);
            var userAttributes = new UserAttributes
            {
                { "house", "Gryffindor" },
                { "should_do_it", false }
            };

            var user = OptimizelyWithTypedAudiences.CreateUserContext(UserID, userAttributes);

            // Should be excluded as exact match boolean audience with id '3468206643' does not match so the overall conditions fail.
            user.TrackEvent("user_signed_up");

            EventDispatcherMock.Verify(dispatcher => dispatcher.DispatchEvent(It.IsAny <LogEvent>()), Times.Once);
        }
        public void SetAttributeOverride()
        {
            var attributes = new UserAttributes()
            {
                { "house", "GRYFFINDOR" }
            };
            OptimizelyUserContext user = new OptimizelyUserContext(Optimizely, UserID, attributes, ErrorHandlerMock.Object, LoggerMock.Object);

            user.SetAttribute("k1", "v1");
            user.SetAttribute("house", "v2");

            var newAttributes = user.GetAttributes();

            Assert.AreEqual(newAttributes["k1"], "v1");
            Assert.AreEqual(newAttributes["house"], "v2");
        }
Exemple #25
0
        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);
        }
Exemple #26
0
        /// <summary>
        /// Sends conversion event to Optimizely.
        /// </summary>
        /// <param name="eventKey">Event key representing the event which needs to be recorded</param>
        /// <param name="userId">ID for user</param>
        /// <param name="userAttributes">Attributes of the user</param>
        /// <param name="eventTags">eventTags array Hash representing metadata associated with the event.</param>
        public void Track(string eventKey, string userId, UserAttributes userAttributes = null, EventTags eventTags = null)
        {
            var config = ProjectConfigManager?.GetConfig();

            if (config == null)
            {
                Logger.Log(LogLevel.ERROR, "Datafile has invalid format. Failing 'Track'.");
                return;
            }

            var inputValues = new Dictionary <string, string>
            {
                { USER_ID, userId },
                { EVENT_KEY, eventKey }
            };

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

            var eevent = config.GetEvent(eventKey);

            if (eevent.Key == null)
            {
                Logger.Log(LogLevel.INFO, string.Format("Not tracking user {0} for event {1}.", userId, eventKey));
                return;
            }


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

            var userEvent = UserEventFactory.CreateConversionEvent(config, eventKey, userId, userAttributes, eventTags);

            EventProcessor.Process(userEvent);
            Logger.Log(LogLevel.INFO, string.Format("Tracking event {0} for user {1}.", eventKey, userId));

            if (NotificationCenter.GetNotificationCount(NotificationCenter.NotificationType.Track) > 0)
            {
                var conversionEvent = EventFactory.CreateLogEvent(userEvent, Logger);
                NotificationCenter.SendNotifications(NotificationCenter.NotificationType.Track, eventKey, userId,
                                                     userAttributes, eventTags, conversionEvent);
            }
        }
Exemple #27
0
        public void TestIsUserInExperimentReturnsTrueIfAnyAudienceInORConditionPass()
        {
            var experiment     = Config.GetExperimentFromKey("feat_with_var_test");
            var userAttributes = new UserAttributes
            {
                { "house", "Gryffindor" },
                { "lasers", 50 },
                { "should_do_it", false }
            };

            Assert.True(ExperimentUtils.IsUserInExperiment(Config, experiment, userAttributes, Logger));

            LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, @"Evaluating audiences for experiment ""feat_with_var_test"": [""3468206642"",""3988293898"",""3988293899"",""3468206646"",""3468206647"",""3468206644"",""3468206643""]"), Times.Once);
            LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, @"Starting to evaluate audience ""3468206642"" with conditions: [""and"", [""or"", [""or"", {""name"": ""house"", ""type"": ""custom_attribute"", ""value"": ""Gryffindor""}]]]"), Times.Once);
            LoggerMock.Verify(l => l.Log(LogLevel.INFO, @"Audience ""3468206642"" evaluated to TRUE"), Times.Once);
            LoggerMock.Verify(l => l.Log(LogLevel.INFO, @"Audiences for experiment ""feat_with_var_test"" collectively evaluated to TRUE"), Times.Once);
        }
Exemple #28
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\"."));
        }
Exemple #29
0
        public async Task ClientUpdateUser()
        {
            var user = $"{RandomString(12)}@supabase.io";
            await client.SignUp(user, password);

            var attributes = new UserAttributes
            {
                Data = new Dictionary <string, object>
                {
                    { "hello", "world" }
                }
            };
            await client.Update(attributes);

            Assert.AreEqual(user, client.CurrentUser.Email);
            Assert.IsNotNull(client.CurrentUser.UserMetadata);
        }
Exemple #30
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\"."));
        }