public void FlagReturnsFallthroughVariationAndEventIfPrerequisiteIsMetAndThereAreNoRules() { var f0 = new FeatureFlagBuilder("feature0") .On(true) .Prerequisites(new Prerequisite("feature1", 1)) .OffVariation(1) .FallthroughVariation(0) .Variations(new JValue("fall"), new JValue("off"), new JValue("on")) .Version(1) .Build(); var f1 = new FeatureFlagBuilder("feature1") .On(true) .FallthroughVariation(1) // this is what makes the prerequisite pass .Variations(new JValue("nogo"), new JValue("go")) .Version(2) .Build(); featureStore.Upsert(VersionedDataKind.Features, f1); var result = f0.Evaluate(baseUser, featureStore, EventFactory.Default); var expected = new EvaluationDetail <LdValue>(LdValue.Of("fall"), 0, EvaluationReason.FallthroughReason); Assert.Equal(expected, result.Result); Assert.Equal(1, result.PrerequisiteEvents.Count); FeatureRequestEvent e = result.PrerequisiteEvents[0]; Assert.Equal(f1.Key, e.Key); Assert.Equal(LdValue.Of("go"), e.LdValue); Assert.Equal(f1.Version, e.Version); Assert.Equal(f0.Key, e.PrereqOf); }
public void FlagReturnsOffVariationAndEventIfPrerequisiteIsOff() { var f0 = new FeatureFlagBuilder("feature0") .On(true) .Prerequisites(new Prerequisite("feature1", 1)) .OffVariation(1) .FallthroughVariation(0) .Variations(new JValue("fall"), new JValue("off"), new JValue("on")) .Version(1) .Build(); var f1 = new FeatureFlagBuilder("feature1") .On(false) .OffVariation(1) // note that even though it returns the desired variation, it is still off and therefore not a match .Variations(new JValue("nogo"), new JValue("go")) .Version(2) .Build(); featureStore.Upsert(VersionedDataKind.Features, f1); var result = f0.Evaluate(baseUser, featureStore, EventFactory.Default); var expected = new EvaluationDetail <LdValue>(LdValue.Of("off"), 1, EvaluationReason.PrerequisiteFailedReason("feature1")); Assert.Equal(expected, result.Result); Assert.Equal(1, result.PrerequisiteEvents.Count); FeatureRequestEvent e = result.PrerequisiteEvents[0]; Assert.Equal(f1.Key, e.Key); Assert.Equal(LdValue.Of("go"), e.LdValue); Assert.Equal(f1.Version, e.Version); Assert.Equal(f0.Key, e.PrereqOf); }
public void MultipleLevelsOfPrerequisitesProduceMultipleEvents() { var f0 = new FeatureFlagBuilder("feature0") .On(true) .Prerequisites(new List <Prerequisite> { new Prerequisite("feature1", 1) }) .OffVariation(1) .FallthroughVariation(0) .Variations(new List <JToken> { new JValue("fall"), new JValue("off"), new JValue("on") }) .Version(1) .Build(); var f1 = new FeatureFlagBuilder("feature1") .On(true) .Prerequisites(new List <Prerequisite> { new Prerequisite("feature2", 1) }) .FallthroughVariation(1) .Variations(new List <JToken> { new JValue("nogo"), new JValue("go") }) .Version(2) .Build(); var f2 = new FeatureFlagBuilder("feature2") .On(true) .FallthroughVariation(1) .Variations(new List <JToken> { new JValue("nogo"), new JValue("go") }) .Version(3) .Build(); featureStore.Upsert(VersionedDataKind.Features, f1); featureStore.Upsert(VersionedDataKind.Features, f2); var result = f0.Evaluate(baseUser, featureStore, EventFactory.Default); var expected = new EvaluationDetail <JToken>(new JValue("fall"), 0, EvaluationReason.Fallthrough.Instance); Assert.Equal(expected, result.Result); Assert.Equal(2, result.PrerequisiteEvents.Count); FeatureRequestEvent e0 = result.PrerequisiteEvents[0]; Assert.Equal(f2.Key, e0.Key); Assert.Equal(new JValue("go"), e0.Value); Assert.Equal(f2.Version, e0.Version); Assert.Equal(f1.Key, e0.PrereqOf); FeatureRequestEvent e1 = result.PrerequisiteEvents[1]; Assert.Equal(f1.Key, e1.Key); Assert.Equal(new JValue("go"), e1.Value); Assert.Equal(f1.Version, e1.Version); Assert.Equal(f0.Key, e1.PrereqOf); }
public void FlagReturnsNullIfFlagIsOffAndOffVariationIsUnspecified() { var f = new FeatureFlagBuilder("feature") .On(false) .FallthroughVariation(0) .Variations(new JValue("fall"), new JValue("off"), new JValue("on")) .Build(); var result = f.Evaluate(baseUser, featureStore, EventFactory.Default); var expected = new EvaluationDetail <LdValue>(LdValue.Null, null, EvaluationReason.OffReason); Assert.Equal(expected, result.Result); Assert.Equal(0, result.PrerequisiteEvents.Count); }
public void FlagReturnsFallthroughIfFlagIsOnAndThereAreNoRules() { var f = new FeatureFlagBuilder("feature") .On(true) .OffVariation(1) .FallthroughVariation(0) .Variations(new JValue("fall"), new JValue("off"), new JValue("on")) .Build(); var result = f.Evaluate(baseUser, featureStore, EventFactory.Default); var expected = new EvaluationDetail <LdValue>(LdValue.Of("fall"), 0, EvaluationReason.FallthroughReason); Assert.Equal(expected, result.Result); Assert.Equal(0, result.PrerequisiteEvents.Count); }
public void FlagReturnsErrorIfFallthroughHasEmptyRolloutVariationList() { var f = new FeatureFlagBuilder("feature") .On(true) .OffVariation(1) .Fallthrough(new VariationOrRollout(null, new Rollout(new List <WeightedVariation>(), null))) .Variations(new JValue("fall"), new JValue("off"), new JValue("on")) .Build(); var result = f.Evaluate(baseUser, 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 FlagReturnsOffVariationIfFlagIsOff() { var f = new FeatureFlagBuilder("feature") .On(false) .OffVariation(1) .FallthroughVariation(0) .Variations(new List <JToken> { new JValue("fall"), new JValue("off"), new JValue("on") }) .Build(); var result = f.Evaluate(baseUser, featureStore, EventFactory.Default); var expected = new EvaluationDetail <JToken>(new JValue("off"), 1, EvaluationReason.Off.Instance); Assert.Equal(expected, result.Result); Assert.Equal(0, result.PrerequisiteEvents.Count); }
public void FlagReturnsOffVariationIfPrerequisiteIsNotFound() { var f0 = new FeatureFlagBuilder("feature0") .On(true) .Prerequisites(new Prerequisite("feature1", 1)) .OffVariation(1) .FallthroughVariation(0) .Variations(new JValue("fall"), new JValue("off"), new JValue("on")) .Build(); var result = f0.Evaluate(baseUser, featureStore, EventFactory.Default); var expected = new EvaluationDetail <LdValue>(LdValue.Of("off"), 1, EvaluationReason.PrerequisiteFailedReason("feature1")); Assert.Equal(expected, result.Result); Assert.Equal(0, result.PrerequisiteEvents.Count); }
public void FlagReturnsErrorIfFlagIsOffAndOffVariationIsNegative() { var f = new FeatureFlagBuilder("feature") .On(false) .OffVariation(-1) .FallthroughVariation(0) .Variations(new List <JToken> { new JValue("fall"), new JValue("off"), new JValue("on") }) .Build(); var result = f.Evaluate(baseUser, featureStore, EventFactory.Default); var expected = new EvaluationDetail <JToken>(null, null, new EvaluationReason.Error(EvaluationErrorKind.MALFORMED_FLAG)); Assert.Equal(expected, result.Result); Assert.Equal(0, result.PrerequisiteEvents.Count); }
public void FlagMatchesUserFromTargets() { var f = new FeatureFlagBuilder("feature") .On(true) .Targets(new Target(new List <string> { "whoever", "userkey" }, 2)) .FallthroughVariation(0) .OffVariation(1) .Variations(new JValue("fall"), new JValue("off"), new JValue("on")) .Build(); var user = User.WithKey("userkey"); var result = f.Evaluate(user, featureStore, EventFactory.Default); var expected = new EvaluationDetail <LdValue>(LdValue.Of("on"), 2, EvaluationReason.TargetMatchReason); Assert.Equal(expected, result.Result); Assert.Equal(0, result.PrerequisiteEvents.Count); }
public void FlagReturnsOffVariationAndEventIfPrerequisiteIsNotMet() { var f0 = new FeatureFlagBuilder("feature0") .On(true) .Prerequisites(new List <Prerequisite> { new Prerequisite("feature1", 1) }) .OffVariation(1) .FallthroughVariation(0) .Variations(new List <JToken> { new JValue("fall"), new JValue("off"), new JValue("on") }) .Version(1) .Build(); var f1 = new FeatureFlagBuilder("feature1") .On(true) .FallthroughVariation(0) .Variations(new List <JToken> { new JValue("nogo"), new JValue("go") }) .Version(2) .Build(); featureStore.Upsert(VersionedDataKind.Features, f1); var result = f0.Evaluate(baseUser, featureStore, EventFactory.Default); var expected = new EvaluationDetail <JToken>(new JValue("off"), 1, new EvaluationReason.PrerequisiteFailed("feature1")); Assert.Equal(expected, result.Result); Assert.Equal(1, result.PrerequisiteEvents.Count); FeatureRequestEvent e = result.PrerequisiteEvents[0]; Assert.Equal(f1.Key, e.Key); Assert.Equal(new JValue("nogo"), e.Value); Assert.Equal(f1.Version, e.Version); Assert.Equal(f0.Key, e.PrereqOf); }