private FeatureFlag BuildFlag() { var clause = new ClauseBuilder().Attribute("name").Op("in").Values(new JValue("x")).Negate(true).Build(); var wv = new WeightedVariation(0, 50); var rollout = new Rollout(new List <WeightedVariation> { wv }, "key"); var rule = new RuleBuilder().Id("ruleid").Variation(0).Rollout(rollout).Clauses(clause) .TrackEvents(true).Build(); var target = new Target(new List <string> { "userkey" }, 0); return(new FeatureFlagBuilder("flagkey") .DebugEventsUntilDate(100000) .Deleted(true) .Fallthrough(new VariationOrRollout(0, rollout)) .OffVariation(0) .On(true) .Prerequisites(new Prerequisite("prereq", 1)) .Rules(rule) .Salt("NaCl") .Targets(target) .TrackEvents(true) .TrackEventsFallthrough(true) .Variations(new JValue("value")) .Version(100) .Build()); }
public void EventTrackingAndReasonAreNotForcedIfFlagIsNotSetForMatchingRule() { var clause0 = ClauseBuilder.ShouldNotMatchUser(user); var clause1 = ClauseBuilder.ShouldMatchUser(user); var rule0 = new RuleBuilder().Id("id0").Variation(1).Clauses(clause0).TrackEvents(true).Build(); var rule1 = new RuleBuilder().Id("id1").Variation(1).Clauses(clause1).TrackEvents(false).Build(); var flag = new FeatureFlagBuilder("flag") .On(true) .Rules(rule0, rule1) .OffVariation(0) .Variations(new JValue("off"), new JValue("on")) .Build(); featureStore.Upsert(VersionedDataKind.Features, flag); client.StringVariation("flag", user, "default"); // It matched rule1, which has trackEvents: false, so we don't get the override behavior Assert.Equal(1, eventSink.Events.Count); var e = Assert.IsType <FeatureRequestEvent>(eventSink.Events[0]); Assert.False(e.TrackEvents); Assert.Null(e.Reason); }
public void ClauseWithUnknownOperatorDoesNotMatch() { var clause = new ClauseBuilder().Attribute("name").Op("invalidOp").Values(new JValue("Bob")).Build(); var f = BooleanFlagWithClauses(clause); var user = User.Builder("key").Name("Bob").Build(); Assert.Equal(LdValue.Of(false), f.Evaluate(user, featureStore, EventFactory.Default).Result.Value); }
public void ClauseReturnsFalseForMissingAttribute() { var clause = new ClauseBuilder().Attribute("legs").Op("in").Values(new JValue(4)).Build(); var f = BooleanFlagWithClauses(clause); var user = User.Builder("key").Name("bob").Build(); Assert.Equal(LdValue.Of(false), f.Evaluate(user, featureStore, EventFactory.Default).Result.Value); }
public void ClauseCanMatchCustomAttribute() { var clause = new ClauseBuilder().Attribute("legs").Op("in").Values(new JValue(4)).Build(); var f = BooleanFlagWithClauses(clause); var user = User.Builder("key").Custom("legs", 4).Build(); Assert.Equal(LdValue.Of(true), f.Evaluate(user, featureStore, EventFactory.Default).Result.Value); }
public void ClauseCanBeNegated() { var clause = new ClauseBuilder().Attribute("name").Op("in").Values(new JValue("Bob")) .Negate(true).Build(); var f = BooleanFlagWithClauses(clause); var user = User.Builder("key").Name("Bob").Build(); Assert.Equal(LdValue.Of(false), f.Evaluate(user, featureStore, EventFactory.Default).Result.Value); }
public void MatchingRuleWithZeroRollout() { var clause = new ClauseBuilder().Attribute("email").Op("in").Values(JValue.CreateString("*****@*****.**")).Build(); var rule = new SegmentRule(new List <Clause> { clause }, 0, null); var s = new Segment("test", 1, null, null, null, new List <SegmentRule> { rule }, false); var u = User.Builder("foo").Email("*****@*****.**").Build(); Assert.False(s.MatchesUser(u)); }
public void NonMatchingRuleWithMultipleClauses() { var clause1 = new ClauseBuilder().Attribute("email").Op("in").Values(JValue.CreateString("*****@*****.**")).Build(); var clause2 = new ClauseBuilder().Attribute("name").Op("in").Values(JValue.CreateString("bill")).Build(); var rule = new SegmentRule(new List <Clause> { clause1, clause2 }, null, null); var s = new Segment("test", 1, null, null, null, new List <SegmentRule> { rule }, false); var u = User.Builder("foo").Email("*****@*****.**").Name("bob").Build(); Assert.False(s.MatchesUser(u)); }
public void CanMatchUserBySegment() { var segment = new Segment("segment1", 1, new List <string> { user.Key }, null, "", null, false); featureStore.Upsert(VersionedDataKind.Segments, segment); var clause = new ClauseBuilder().Op("segmentMatch").Values(new JValue("segment1")).Build(); var feature = new FeatureFlagBuilder("feature").BooleanWithClauses(clause).Build(); featureStore.Upsert(VersionedDataKind.Features, feature); Assert.True(client.BoolVariation("feature", user, false)); }
public void RuleWithNoVariationOrRolloutReturnsMalformedFlagError() { var user = User.WithKey("userkey"); var clause = ClauseBuilder.ShouldMatchUser(user); var rule = new RuleBuilder().Id("ruleid").Clauses(clause).Build(); var f = FeatureFlagWithRules(rule); var result = f.Evaluate(user, featureStore, EventFactory.Default); var expected = new EvaluationDetail <LdValue>(LdValue.Null, null, EvaluationReason.ErrorReason(EvaluationErrorKind.MALFORMED_FLAG)); Assert.Equal(expected, result.Result); Assert.Equal(0, result.PrerequisiteEvents.Count); }
public void FlagMatchesUserFromRules() { var user = User.WithKey("userkey"); var clause0 = ClauseBuilder.ShouldNotMatchUser(user); var clause1 = ClauseBuilder.ShouldMatchUser(user); var rule0 = new RuleBuilder().Id("ruleid0").Variation(2).Clauses(clause0).Build(); var rule1 = new RuleBuilder().Id("ruleid1").Variation(2).Clauses(clause1).Build(); var f = FeatureFlagWithRules(rule0, rule1); var result = f.Evaluate(user, featureStore, EventFactory.Default); var expected = new EvaluationDetail <LdValue>(LdValue.Of("on"), 2, EvaluationReason.RuleMatchReason(1, "ruleid1")); Assert.Equal(expected, result.Result); Assert.Equal(0, result.PrerequisiteEvents.Count); }
private Segment BuildSegment() { var clause = new ClauseBuilder().Attribute("name").Op("in").Values(new JValue("x")).Negate(true).Build(); var rule = new SegmentRule(new List <Clause> { clause }, 50, "key"); return(new Segment( "segkey", 100, new List <string> { "includeme" }, new List <string> { "excludeme" }, "NaCl", new List <SegmentRule> { rule }, true )); }
public void EventTrackingAndReasonCanBeForcedForRule() { var clause = ClauseBuilder.ShouldMatchUser(user); var rule = new RuleBuilder().Id("rule-id").Variation(1).Clauses(clause).TrackEvents(true).Build(); var flag = new FeatureFlagBuilder("flag") .On(true) .Rules(rule) .OffVariation(0) .Variations(new JValue("off"), new JValue("on")) .Build(); featureStore.Upsert(VersionedDataKind.Features, flag); client.StringVariation("flag", user, "default"); // Note, we did not call StringVariationDetail and the flag is not tracked, but we should still get // tracking and a reason, because the rule-level trackEvents flag is on for the matched rule. Assert.Equal(1, eventSink.Events.Count); var e = Assert.IsType <FeatureRequestEvent>(eventSink.Events[0]); Assert.True(e.TrackEvents); Assert.Equal(EvaluationReason.RuleMatchReason(0, "rule-id"), e.Reason); }
private FeatureFlag SegmentMatchBooleanFlag(string segmentKey) { var clause = new ClauseBuilder().Op("segmentMatch").Values(new JValue(segmentKey)).Build(); return(BooleanFlagWithClauses(clause)); }