diff --git a/OptimizelySDK.DemoApp/OptimizelySDK.DemoApp.csproj b/OptimizelySDK.DemoApp/OptimizelySDK.DemoApp.csproj
index 7da4aa12..adbf4c47 100644
--- a/OptimizelySDK.DemoApp/OptimizelySDK.DemoApp.csproj
+++ b/OptimizelySDK.DemoApp/OptimizelySDK.DemoApp.csproj
@@ -241,6 +241,12 @@
+
+
+ {4dde7faa-110d-441c-ab3b-3f31b593e8bf}
+ OptimizelySDK
+
+
10.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
diff --git a/OptimizelySDK.Net35/OptimizelySDK.Net35.csproj b/OptimizelySDK.Net35/OptimizelySDK.Net35.csproj
index 9d3d441d..11265206 100644
--- a/OptimizelySDK.Net35/OptimizelySDK.Net35.csproj
+++ b/OptimizelySDK.Net35/OptimizelySDK.Net35.csproj
@@ -233,6 +233,9 @@
Config\DatafileProjectConfig
+
+ Entity\Integration
+
Config\ProjectConfigManager
diff --git a/OptimizelySDK.Net40/OptimizelySDK.Net40.csproj b/OptimizelySDK.Net40/OptimizelySDK.Net40.csproj
index 3dfdfbc9..0c7092ea 100644
--- a/OptimizelySDK.Net40/OptimizelySDK.Net40.csproj
+++ b/OptimizelySDK.Net40/OptimizelySDK.Net40.csproj
@@ -232,6 +232,9 @@
Config\DatafileProjectConfig
+
+ Entity\Integration
+
Config\ProjectConfigManager
diff --git a/OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj b/OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj
index 740e5d4d..94828d2b 100644
--- a/OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj
+++ b/OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj
@@ -76,6 +76,7 @@
+
@@ -159,5 +160,4 @@
-
diff --git a/OptimizelySDK.NetStandard20/OptimizelySDK.NetStandard20.csproj b/OptimizelySDK.NetStandard20/OptimizelySDK.NetStandard20.csproj
index 0202fe84..3b2962e0 100644
--- a/OptimizelySDK.NetStandard20/OptimizelySDK.NetStandard20.csproj
+++ b/OptimizelySDK.NetStandard20/OptimizelySDK.NetStandard20.csproj
@@ -115,6 +115,9 @@
Entity\Group.cs
+
+ Entity\Integration.cs
+
Entity\IdKeyEntity.cs
diff --git a/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs b/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs
index dc5d66b2..9d84e4b4 100644
--- a/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs
+++ b/OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs
@@ -1,11 +1,11 @@
/*
- * Copyright 2019-2020, Optimizely
+ * Copyright 2019-2022, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -19,7 +19,9 @@
using OptimizelySDK.AudienceConditions;
using OptimizelySDK.Entity;
using OptimizelySDK.Logger;
+using OptimizelySDK.Tests.Utils;
using System;
+using System.Collections.Generic;
namespace OptimizelySDK.Tests.AudienceConditionsTests
{
@@ -68,26 +70,26 @@ public void TestEvaluateWithDifferentTypedAttributes()
{"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);
+ Assert.That(ExactStrCondition.Evaluate(null, userAttributes.ToUserContext(), Logger), Is.True);
+ Assert.That(ExactBoolCondition.Evaluate(null, userAttributes.ToUserContext(), Logger), Is.True);
+ Assert.That(GTCondition.Evaluate(null, userAttributes.ToUserContext(), Logger), Is.True);
+ Assert.That(ExactDecimalCondition.Evaluate(null, userAttributes.ToUserContext(), Logger), Is.True);
}
[Test]
public void TestEvaluateWithNoMatchType()
{
- Assert.That(LegacyCondition.Evaluate(null, new UserAttributes { { "device_type", "iPhone" } }, Logger), Is.True);
+ Assert.That(LegacyCondition.Evaluate(null, new UserAttributes { { "device_type", "iPhone" } }.ToUserContext(), Logger), Is.True);
// Assumes exact evaluator if no match type is provided.
- Assert.That(LegacyCondition.Evaluate(null, new UserAttributes { { "device_type", "IPhone" } }, Logger), Is.False);
+ Assert.That(LegacyCondition.Evaluate(null, new UserAttributes { { "device_type", "IPhone" } }.ToUserContext(), Logger), Is.False);
}
[Test]
public void TestEvaluateWithInvalidTypeProperty()
{
BaseCondition condition = new BaseCondition { Name = "input_value", Value = "Android", Match = "exists", Type = "invalid_type" };
- Assert.That(condition.Evaluate(null, new UserAttributes { { "device_type", "iPhone" } }, Logger), Is.Null);
+ Assert.That(condition.Evaluate(null, new UserAttributes { { "device_type", "iPhone" } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, $@"Audience condition ""{condition}"" uses an unknown condition type. You may need to upgrade to a newer release of the Optimizely SDK."), Times.Once);
}
@@ -96,7 +98,7 @@ public void TestEvaluateWithInvalidTypeProperty()
public void TestEvaluateWithMissingTypeProperty()
{
var condition = new BaseCondition { Name = "input_value", Value = "Android", Match = "exists" };
- Assert.That(condition.Evaluate(null, new UserAttributes { { "device_type", "iPhone" } }, Logger), Is.Null);
+ Assert.That(condition.Evaluate(null, new UserAttributes { { "device_type", "iPhone" } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, $@"Audience condition ""{condition}"" uses an unknown condition type. You may need to upgrade to a newer release of the Optimizely SDK."), Times.Once);
}
@@ -105,7 +107,7 @@ public void TestEvaluateWithMissingTypeProperty()
public void TestEvaluateWithInvalidMatchProperty()
{
BaseCondition condition = new BaseCondition { Name = "device_type", Value = "Android", Match = "invalid_match", Type = "custom_attribute" };
- Assert.That(condition.Evaluate(null, new UserAttributes { { "device_type", "Android" } }, Logger), Is.Null);
+ Assert.That(condition.Evaluate(null, new UserAttributes { { "device_type", "Android" } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, $@"Audience condition ""{condition}"" uses an unknown match type. You may need to upgrade to a newer release of the Optimizely SDK."), Times.Once);
}
@@ -113,10 +115,10 @@ public void TestEvaluateWithInvalidMatchProperty()
[Test]
public void TestEvaluateLogsWarningAndReturnNullWhenAttributeIsNotProvidedAndConditionTypeIsNotExists()
{
- Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { }, Logger), Is.Null);
- Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { }, Logger), Is.Null);
- Assert.That(LTCondition.Evaluate(null, new UserAttributes { }, Logger), Is.Null);
- Assert.That(GTCondition.Evaluate(null, new UserAttributes { }, Logger), Is.Null);
+ Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { }.ToUserContext(), Logger), Is.Null);
+ Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { }.ToUserContext(), Logger), Is.Null);
+ Assert.That(LTCondition.Evaluate(null, new UserAttributes { }.ToUserContext(), Logger), Is.Null);
+ Assert.That(GTCondition.Evaluate(null, new UserAttributes { }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, @"Audience condition {""type"":""custom_attribute"",""match"":""exact"",""name"":""is_registered_user"",""value"":false} evaluated to UNKNOWN because no value was passed for user attribute ""is_registered_user""."), Times.Once);
LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, @"Audience condition {""type"":""custom_attribute"",""match"":""substring"",""name"":""location"",""value"":""USA""} evaluated to UNKNOWN because no value was passed for user attribute ""location""."), Times.Once);
@@ -127,10 +129,10 @@ public void TestEvaluateLogsWarningAndReturnNullWhenAttributeIsNotProvidedAndCon
[Test]
public void TestEvaluateLogsAndReturnNullWhenAttributeValueIsNullAndConditionTypeIsNotExists()
{
- Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { { "is_registered_user", null } }, Logger), Is.Null);
- Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", null } }, Logger), Is.Null);
- Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", null } }, Logger), Is.Null);
- Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", null } }, Logger), Is.Null);
+ Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { { "is_registered_user", null } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", null } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", null } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", null } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, @"Audience condition {""type"":""custom_attribute"",""match"":""exact"",""name"":""is_registered_user"",""value"":false} evaluated to UNKNOWN because a null value was passed for user attribute ""is_registered_user""."), Times.Once);
LoggerMock.Verify(l => l.Log(LogLevel.DEBUG, @"Audience condition {""type"":""custom_attribute"",""match"":""substring"",""name"":""location"",""value"":""USA""} evaluated to UNKNOWN because a null value was passed for user attribute ""location""."), Times.Once);
@@ -141,17 +143,17 @@ public void TestEvaluateLogsAndReturnNullWhenAttributeValueIsNullAndConditionTyp
[Test]
public void TestEvaluateReturnsFalseAndDoesNotLogForExistsConditionWhenAttributeIsNotProvided()
{
- Assert.That(ExistsCondition.Evaluate(null, new UserAttributes(), Logger), Is.False);
+ Assert.That(ExistsCondition.Evaluate(null, new UserAttributes().ToUserContext(), Logger), Is.False);
LoggerMock.Verify(l => l.Log(It.IsAny(), It.IsAny()), Times.Never);
}
[Test]
public void TestEvaluateLogsWarningAndReturnNullWhenAttributeTypeIsInvalid()
{
- Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { { "is_registered_user", 5 } }, Logger), Is.Null);
- Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", false } }, Logger), Is.Null);
- Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", "invalid" } }, Logger), Is.Null);
- Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", true } }, Logger), Is.Null);
+ Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { { "is_registered_user", 5 } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", false } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", "invalid" } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", true } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""exact"",""name"":""is_registered_user"",""value"":false} evaluated to UNKNOWN because a value of type ""Int32"" was passed for user attribute ""is_registered_user""."), Times.Once);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""substring"",""name"":""location"",""value"":""USA""} evaluated to UNKNOWN because a value of type ""Boolean"" was passed for user attribute ""location""."), Times.Once);
@@ -163,19 +165,19 @@ public void TestEvaluateLogsWarningAndReturnNullWhenAttributeTypeIsInvalid()
public void TestEvaluateLogsWarningAndReturnNullWhenConditionTypeIsInvalid()
{
var invalidCondition = new BaseCondition { Name = "is_registered_user", Value = new string[] { }, Match = "exact", Type = "custom_attribute" };
- Assert.That(invalidCondition.Evaluate(null, new UserAttributes { { "is_registered_user", true } }, Logger), Is.Null);
+ Assert.That(invalidCondition.Evaluate(null, new UserAttributes { { "is_registered_user", true } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""exact"",""name"":""is_registered_user"",""value"":[]} has an unsupported condition value. You may need to upgrade to a newer release of the Optimizely SDK."), Times.Once);
invalidCondition = new BaseCondition { Name = "location", Value = 25, Match = "substring", Type = "custom_attribute" };
- Assert.That(invalidCondition.Evaluate(null, new UserAttributes { { "location", "USA" } }, Logger), Is.Null);
+ Assert.That(invalidCondition.Evaluate(null, new UserAttributes { { "location", "USA" } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""substring"",""name"":""location"",""value"":25} has an unsupported condition value. You may need to upgrade to a newer release of the Optimizely SDK."), Times.Once);
invalidCondition = new BaseCondition { Name = "distance_lt", Value = "invalid", Match = "lt", Type = "custom_attribute" };
- Assert.That(invalidCondition.Evaluate(null, new UserAttributes { { "distance_lt", 5 } }, Logger), Is.Null);
+ Assert.That(invalidCondition.Evaluate(null, new UserAttributes { { "distance_lt", 5 } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""lt"",""name"":""distance_lt"",""value"":""invalid""} has an unsupported condition value. You may need to upgrade to a newer release of the Optimizely SDK."), Times.Once);
invalidCondition = new BaseCondition { Name = "distance_gt", Value = "invalid", Match = "gt", Type = "custom_attribute" };
- Assert.That(invalidCondition.Evaluate(null, new UserAttributes { { "distance_gt", "invalid" } }, Logger), Is.Null);
+ Assert.That(invalidCondition.Evaluate(null, new UserAttributes { { "distance_gt", "invalid" } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""gt"",""name"":""distance_gt"",""value"":""invalid""} has an unsupported condition value. You may need to upgrade to a newer release of the Optimizely SDK."), Times.Once);
}
@@ -186,19 +188,19 @@ public void TestEvaluateLogsWarningAndReturnNullWhenConditionTypeIsInvalid()
[Test]
public void TestExactMatcherReturnsFalseWhenAttributeValueDoesNotMatch()
{
- Assert.That(ExactStrCondition.Evaluate(null, new UserAttributes { { "browser_type", "chrome" } }, Logger), Is.False);
- Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { { "is_registered_user", true } }, Logger), Is.False);
- Assert.That(ExactDecimalCondition.Evaluate(null, new UserAttributes { { "pi_value", 2.5 } }, Logger), Is.False);
- Assert.That(ExactIntCondition.Evaluate(null, new UserAttributes { { "lasers_count", 55 } }, Logger), Is.False);
+ Assert.That(ExactStrCondition.Evaluate(null, new UserAttributes { { "browser_type", "chrome" } }.ToUserContext(), Logger), Is.False);
+ Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { { "is_registered_user", true } }.ToUserContext(), Logger), Is.False);
+ Assert.That(ExactDecimalCondition.Evaluate(null, new UserAttributes { { "pi_value", 2.5 } }.ToUserContext(), Logger), Is.False);
+ Assert.That(ExactIntCondition.Evaluate(null, new UserAttributes { { "lasers_count", 55 } }.ToUserContext(), Logger), Is.False);
}
[Test]
public void TestExactMatcherReturnsNullWhenTypeMismatch()
{
- Assert.That(ExactStrCondition.Evaluate(null, new UserAttributes { { "browser_type", true } }, Logger), Is.Null);
- Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { { "is_registered_user", "abcd" } }, Logger), Is.Null);
- Assert.That(ExactDecimalCondition.Evaluate(null, new UserAttributes { { "pi_value", false } }, Logger), Is.Null);
- Assert.That(ExactIntCondition.Evaluate(null, new UserAttributes { { "lasers_count", "infinity" } }, Logger), Is.Null);
+ Assert.That(ExactStrCondition.Evaluate(null, new UserAttributes { { "browser_type", true } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { { "is_registered_user", "abcd" } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(ExactDecimalCondition.Evaluate(null, new UserAttributes { { "pi_value", false } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(ExactIntCondition.Evaluate(null, new UserAttributes { { "lasers_count", "infinity" } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""exact"",""name"":""browser_type"",""value"":""firefox""} evaluated to UNKNOWN because a value of type ""Boolean"" was passed for user attribute ""browser_type""."), Times.Once);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""exact"",""name"":""is_registered_user"",""value"":false} evaluated to UNKNOWN because a value of type ""String"" was passed for user attribute ""is_registered_user""."), Times.Once);
@@ -209,9 +211,9 @@ public void TestExactMatcherReturnsNullWhenTypeMismatch()
[Test]
public void TestExactMatcherReturnsNullForOutOfBoundNumericValues()
{
- Assert.That(ExactIntCondition.Evaluate(null, new UserAttributes { { "lasers_count", double.NegativeInfinity } }, Logger), Is.Null);
- Assert.That(ExactDecimalCondition.Evaluate(null, new UserAttributes { { "pi_value", Math.Pow(2, 53) + 2 } }, Logger), Is.Null);
- Assert.That(InfinityIntCondition.Evaluate(null, new UserAttributes { { "max_num_value", 15 } }, Logger), Is.Null);
+ Assert.That(ExactIntCondition.Evaluate(null, new UserAttributes { { "lasers_count", double.NegativeInfinity } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(ExactDecimalCondition.Evaluate(null, new UserAttributes { { "pi_value", Math.Pow(2, 53) + 2 } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(InfinityIntCondition.Evaluate(null, new UserAttributes { { "max_num_value", 15 } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""exact"",""name"":""lasers_count"",""value"":9000} evaluated to UNKNOWN because the number value for user attribute ""lasers_count"" is not in the range [-2^53, +2^53]."), Times.Once);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""exact"",""name"":""pi_value"",""value"":3.14} evaluated to UNKNOWN because the number value for user attribute ""pi_value"" is not in the range [-2^53, +2^53]."), Times.Once);
@@ -221,10 +223,10 @@ public void TestExactMatcherReturnsNullForOutOfBoundNumericValues()
[Test]
public void TestExactMatcherReturnsTrueWhenAttributeValueMatches()
{
- Assert.That(ExactStrCondition.Evaluate(null, new UserAttributes { { "browser_type", "firefox" } }, Logger), Is.True);
- Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { { "is_registered_user", false } }, Logger), Is.True);
- Assert.That(ExactDecimalCondition.Evaluate(null, new UserAttributes { { "pi_value", 3.14 } }, Logger), Is.True);
- Assert.That(ExactIntCondition.Evaluate(null, new UserAttributes { { "lasers_count", 9000 } }, Logger), Is.True);
+ Assert.That(ExactStrCondition.Evaluate(null, new UserAttributes { { "browser_type", "firefox" } }.ToUserContext(), Logger), Is.True);
+ Assert.That(ExactBoolCondition.Evaluate(null, new UserAttributes { { "is_registered_user", false } }.ToUserContext(), Logger), Is.True);
+ Assert.That(ExactDecimalCondition.Evaluate(null, new UserAttributes { { "pi_value", 3.14 } }.ToUserContext(), Logger), Is.True);
+ Assert.That(ExactIntCondition.Evaluate(null, new UserAttributes { { "lasers_count", 9000 } }.ToUserContext(), Logger), Is.True);
}
#endregion // ExactMatcher Tests
@@ -234,22 +236,22 @@ public void TestExactMatcherReturnsTrueWhenAttributeValueMatches()
[Test]
public void TestExistsMatcherReturnsFalseWhenAttributeIsNotProvided()
{
- Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { }, Logger), Is.False);
+ Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { }.ToUserContext(), Logger), Is.False);
}
[Test]
public void TestExistsMatcherReturnsFalseWhenAttributeIsNull()
{
- Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { { "input_value", null } }, Logger), Is.False);
+ Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { { "input_value", null } }.ToUserContext(), Logger), Is.False);
}
[Test]
public void TestExistsMatcherReturnsTrueWhenAttributeValueIsProvided()
{
- Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { { "input_value", "" } }, Logger), Is.True);
- Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { { "input_value", "iPhone" } }, Logger), Is.True);
- Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { { "input_value", 10 } }, Logger), Is.True);
- Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { { "input_value", false } }, Logger), Is.True);
+ Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { { "input_value", "" } }.ToUserContext(), Logger), Is.True);
+ Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { { "input_value", "iPhone" } }.ToUserContext(), Logger), Is.True);
+ Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { { "input_value", 10 } }.ToUserContext(), Logger), Is.True);
+ Assert.That(ExistsCondition.Evaluate(null, new UserAttributes { { "input_value", false } }.ToUserContext(), Logger), Is.True);
}
#endregion // ExistsMatcher Tests
@@ -259,21 +261,21 @@ public void TestExistsMatcherReturnsTrueWhenAttributeValueIsProvided()
[Test]
public void TestSubstringMatcherReturnsFalseWhenAttributeValueIsNotASubstring()
{
- Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", "Los Angeles" } }, Logger), Is.False);
+ Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", "Los Angeles" } }.ToUserContext(), Logger), Is.False);
}
[Test]
public void TestSubstringMatcherReturnsNullWhenAttributeValueIsNotAString()
{
- Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", 10.5 } }, Logger), Is.Null);
+ Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", 10.5 } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""substring"",""name"":""location"",""value"":""USA""} evaluated to UNKNOWN because a value of type ""Double"" was passed for user attribute ""location""."), Times.Once);
}
[Test]
public void TestSubstringMatcherReturnsTrueWhenAttributeValueIsASubstring()
{
- Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", "USA" } }, Logger), Is.True);
- Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", "San Francisco, USA" } }, Logger), Is.True);
+ Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", "USA" } }.ToUserContext(), Logger), Is.True);
+ Assert.That(SubstrCondition.Evaluate(null, new UserAttributes { { "location", "San Francisco, USA" } }.ToUserContext(), Logger), Is.True);
}
#endregion // SubstringMatcher Tests
@@ -283,50 +285,50 @@ public void TestSubstringMatcherReturnsTrueWhenAttributeValueIsASubstring()
[Test]
public void TestGTMatcherReturnsFalseWhenAttributeValueIsLessThanOrEqualToConditionValue()
{
- Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", 5 } }, Logger), Is.False);
- Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", 10 } }, Logger), Is.False);
+ Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", 5 } }.ToUserContext(), Logger), Is.False);
+ Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", 10 } }.ToUserContext(), Logger), Is.False);
}
[Test]
public void TestGTMatcherReturnsNullWhenAttributeValueIsNotANumericValue()
{
- Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", "invalid_type" } }, Logger), Is.Null);
+ Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", "invalid_type" } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""gt"",""name"":""distance_gt"",""value"":10} evaluated to UNKNOWN because a value of type ""String"" was passed for user attribute ""distance_gt""."), Times.Once);
}
[Test]
public void TestGTMatcherReturnsNullWhenAttributeValueIsOutOfBounds()
{
- Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", double.PositiveInfinity } }, Logger), Is.Null);
- Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", Math.Pow(2, 53) + 2 } }, Logger), Is.Null);
+ Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", double.PositiveInfinity } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", Math.Pow(2, 53) + 2 } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""gt"",""name"":""distance_gt"",""value"":10} evaluated to UNKNOWN because the number value for user attribute ""distance_gt"" is not in the range [-2^53, +2^53]."), Times.Exactly(2));
}
[Test]
public void TestGTMatcherReturnsTrueWhenAttributeValueIsGreaterThanConditionValue()
{
- Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", 15 } }, Logger), Is.True);
+ Assert.That(GTCondition.Evaluate(null, new UserAttributes { { "distance_gt", 15 } }.ToUserContext(), Logger), Is.True);
}
[Test]
public void TestSemVerGTTargetBetaComplex()
{
var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "2.1.3-beta+1", Match = "semver_gt", Type = "custom_attribute" };
- Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "2.1.3-beta+1.2.3" } }, Logger) ?? false);
+ Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "2.1.3-beta+1.2.3" } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestSemVerGTCompareAgainstPreReleaseToPreRelease()
{
var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "3.7.1-prerelease+build", Match = "semver_gt", Type = "custom_attribute" };
- Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.1-prerelease+rc" } }, Logger) ?? false);
+ Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.1-prerelease+rc" } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestSemVerGTComparePrereleaseSmallerThanBuild()
{
var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "3.7.1-prerelease", Match = "semver_gt", Type = "custom_attribute" };
- Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.1+build" } }, Logger) ?? false);
+ Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.1+build" } }.ToUserContext(), Logger) ?? false);
}
#endregion // GTMatcher Tests
@@ -335,29 +337,29 @@ public void TestSemVerGTComparePrereleaseSmallerThanBuild()
[Test]
public void TestGEMatcherReturnsFalseWhenAttributeValueIsLessButTrueForEqualToConditionValue()
{
- Assert.IsFalse(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", 5 } }, Logger)?? true);
- Assert.IsTrue(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", 10 } }, Logger)?? false);
+ Assert.IsFalse(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", 5 } }.ToUserContext(), Logger)?? true);
+ Assert.IsTrue(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", 10 } }.ToUserContext(), Logger)?? false);
}
[Test]
public void TestGEMatcherReturnsNullWhenAttributeValueIsNotANumericValue()
{
- Assert.IsNull(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", "invalid_type" } }, Logger));
+ Assert.IsNull(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", "invalid_type" } }.ToUserContext(), Logger));
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""ge"",""name"":""distance_ge"",""value"":10} evaluated to UNKNOWN because a value of type ""String"" was passed for user attribute ""distance_ge""."), Times.Once);
}
[Test]
public void TestGEMatcherReturnsNullWhenAttributeValueIsOutOfBounds()
{
- Assert.IsNull(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", double.PositiveInfinity } }, Logger));
- Assert.IsNull(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", Math.Pow(2, 53) + 2 } }, Logger));
+ Assert.IsNull(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", double.PositiveInfinity } }.ToUserContext(), Logger));
+ Assert.IsNull(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", Math.Pow(2, 53) + 2 } }.ToUserContext(), Logger));
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""ge"",""name"":""distance_ge"",""value"":10} evaluated to UNKNOWN because the number value for user attribute ""distance_ge"" is not in the range [-2^53, +2^53]."), Times.Exactly(2));
}
[Test]
public void TestGEMatcherReturnsTrueWhenAttributeValueIsGreaterThanConditionValue()
{
- Assert.IsTrue(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", 15 } }, Logger)?? false);
+ Assert.IsTrue(GECondition.Evaluate(null, new UserAttributes { { "distance_ge", 15 } }.ToUserContext(), Logger)?? false);
}
#endregion // GEMatcher Tests
@@ -367,43 +369,43 @@ public void TestGEMatcherReturnsTrueWhenAttributeValueIsGreaterThanConditionValu
[Test]
public void TestLTMatcherReturnsFalseWhenAttributeValueIsGreaterThanOrEqualToConditionValue()
{
- Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", 15 } }, Logger), Is.False);
- Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", 10 } }, Logger), Is.False);
+ Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", 15 } }.ToUserContext(), Logger), Is.False);
+ Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", 10 } }.ToUserContext(), Logger), Is.False);
}
[Test]
public void TestLTMatcherReturnsNullWhenAttributeValueIsNotANumericValue()
{
- Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", "invalid_type" } }, Logger), Is.Null);
+ Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", "invalid_type" } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""lt"",""name"":""distance_lt"",""value"":10} evaluated to UNKNOWN because a value of type ""String"" was passed for user attribute ""distance_lt""."), Times.Once);
}
[Test]
public void TestLTMatcherReturnsNullWhenAttributeValueIsOutOfBounds()
{
- Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", double.NegativeInfinity } }, Logger), Is.Null);
- Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", -Math.Pow(2, 53) - 2 } }, Logger), Is.Null);
+ Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", double.NegativeInfinity } }.ToUserContext(), Logger), Is.Null);
+ Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", -Math.Pow(2, 53) - 2 } }.ToUserContext(), Logger), Is.Null);
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""lt"",""name"":""distance_lt"",""value"":10} evaluated to UNKNOWN because the number value for user attribute ""distance_lt"" is not in the range [-2^53, +2^53]."), Times.Exactly(2));
}
[Test]
public void TestLTMatcherReturnsTrueWhenAttributeValueIsLessThanConditionValue()
{
- Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", 5 } }, Logger), Is.True);
+ Assert.That(LTCondition.Evaluate(null, new UserAttributes { { "distance_lt", 5 } }.ToUserContext(), Logger), Is.True);
}
[Test]
public void TestSemVerLTTargetBuildComplex()
{
var semverLTCondition = new BaseCondition { Name = "semversion_lt", Value = "2.1.3-beta+1.2.3", Match = "semver_lt", Type = "custom_attribute" };
- Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "2.1.3-beta+1" } }, Logger) ?? false);
+ Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "2.1.3-beta+1" } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestSemVerLTCompareMultipleDash()
{
var semverLTCondition = new BaseCondition { Name = "semversion_lt", Value = "2.1.3-beta-1.2.3", Match = "semver_lt", Type = "custom_attribute" };
- Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "2.1.3-beta-1" } }, Logger) ?? false);
+ Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "2.1.3-beta-1" } }.ToUserContext(), Logger) ?? false);
}
#endregion // LTMatcher Tests
@@ -412,29 +414,29 @@ public void TestSemVerLTCompareMultipleDash()
[Test]
public void TestLEMatcherReturnsFalseWhenAttributeValueIsGreaterAndTrueIfEqualToConditionValue()
{
- Assert.IsFalse(LECondition.Evaluate(null, new UserAttributes { { "distance_le", 15 } }, Logger) ?? true);
- Assert.IsTrue(LECondition.Evaluate(null, new UserAttributes { { "distance_le", 10 } }, Logger) ?? false);
+ Assert.IsFalse(LECondition.Evaluate(null, new UserAttributes { { "distance_le", 15 } }.ToUserContext(), Logger) ?? true);
+ Assert.IsTrue(LECondition.Evaluate(null, new UserAttributes { { "distance_le", 10 } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestLEMatcherReturnsNullWhenAttributeValueIsNotANumericValue()
{
- Assert.IsNull(LECondition.Evaluate(null, new UserAttributes { { "distance_le", "invalid_type" } }, Logger));
+ Assert.IsNull(LECondition.Evaluate(null, new UserAttributes { { "distance_le", "invalid_type" } }.ToUserContext(), Logger));
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""le"",""name"":""distance_le"",""value"":10} evaluated to UNKNOWN because a value of type ""String"" was passed for user attribute ""distance_le""."), Times.Once);
}
[Test]
public void TestLEMatcherReturnsNullWhenAttributeValueIsOutOfBounds()
{
- Assert.IsNull(LECondition.Evaluate(null, new UserAttributes { { "distance_le", double.NegativeInfinity } }, Logger));
- Assert.IsNull(LECondition.Evaluate(null, new UserAttributes { { "distance_le", -Math.Pow(2, 53) - 2 } }, Logger));
+ Assert.IsNull(LECondition.Evaluate(null, new UserAttributes { { "distance_le", double.NegativeInfinity } }.ToUserContext(), Logger));
+ Assert.IsNull(LECondition.Evaluate(null, new UserAttributes { { "distance_le", -Math.Pow(2, 53) - 2 } }.ToUserContext(), Logger));
LoggerMock.Verify(l => l.Log(LogLevel.WARN, @"Audience condition {""type"":""custom_attribute"",""match"":""le"",""name"":""distance_le"",""value"":10} evaluated to UNKNOWN because the number value for user attribute ""distance_le"" is not in the range [-2^53, +2^53]."), Times.Exactly(2));
}
[Test]
public void TestLEMatcherReturnsTrueWhenAttributeValueIsLessThanConditionValue()
{
- Assert.IsTrue(LECondition.Evaluate(null, new UserAttributes { { "distance_le", 5 } }, Logger) ?? false);
+ Assert.IsTrue(LECondition.Evaluate(null, new UserAttributes { { "distance_le", 5 } }.ToUserContext(), Logger) ?? false);
}
#endregion // LEMatcher Tests
@@ -443,28 +445,28 @@ public void TestLEMatcherReturnsTrueWhenAttributeValueIsLessThanConditionValue()
[Test]
public void TestSemVerLTMatcherReturnsFalseWhenAttributeValueIsGreaterThanOrEqualToConditionValue()
{
- Assert.IsFalse(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.2" } }, Logger) ?? true);
- Assert.IsFalse(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.1" } }, Logger) ?? true);
- Assert.IsFalse(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.8" } }, Logger) ?? true);
- Assert.IsFalse(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "4" } }, Logger) ?? true);
+ Assert.IsFalse(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.2" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.1" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.8" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "4" } }.ToUserContext(), Logger) ?? true);
}
[Test]
public void TestSemVerLTMatcherReturnsTrueWhenAttributeValueIsLessThanConditionValue()
{
- Assert.IsTrue(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.0" } }, Logger) ?? false);
- Assert.IsTrue(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.1-beta" } }, Logger) ?? false);
- Assert.IsTrue(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "2.7.1" } }, Logger) ?? false);
- Assert.IsTrue(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7" } }, Logger) ?? false);
- Assert.IsTrue(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3" } }, Logger) ?? false);
+ Assert.IsTrue(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.0" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.1-beta" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "2.7.1" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(SemVerLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3" } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestSemVerLTMatcherReturnsTrueWhenAttributeValueIsLessThanConditionValueBeta()
{
var semverLTCondition = new BaseCondition { Name = "semversion_lt", Value = "3.7.0-beta.2.3", Match = "semver_lt", Type = "custom_attribute" };
- Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.0-beta.2.1" } }, Logger) ?? false);
- Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.0-beta" } }, Logger) ?? false);
+ Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.0-beta.2.1" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverLTCondition.Evaluate(null, new UserAttributes { { "semversion_lt", "3.7.0-beta" } }.ToUserContext(), Logger) ?? false);
}
#endregion // SemVerLTMatcher Tests
@@ -472,28 +474,28 @@ public void TestSemVerLTMatcherReturnsTrueWhenAttributeValueIsLessThanConditionV
[Test]
public void TestSemVerGTMatcherReturnsFalseWhenAttributeValueIsLessThanOrEqualToConditionValue()
{
- Assert.IsFalse(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.0" } }, Logger)?? true);
- Assert.IsFalse(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.1" } }, Logger)?? true);
- Assert.IsFalse(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.6" } }, Logger)?? true);
- Assert.IsFalse(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "2" } }, Logger)?? true);
+ Assert.IsFalse(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.0" } }.ToUserContext(), Logger)?? true);
+ Assert.IsFalse(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.1" } }.ToUserContext(), Logger)?? true);
+ Assert.IsFalse(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.6" } }.ToUserContext(), Logger)?? true);
+ Assert.IsFalse(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "2" } }.ToUserContext(), Logger)?? true);
}
[Test]
public void TestSemVerGTMatcherReturnsTrueWhenAttributeValueIsGreaterThanConditionValue()
{
- Assert.IsTrue(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.2" } }, Logger)?? false);
- Assert.IsTrue(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.2-beta" } }, Logger)?? false);
- Assert.IsTrue(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "4.7.1" } }, Logger)?? false);
- Assert.IsTrue(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.8" } }, Logger)?? false);
- Assert.IsTrue(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "4" } }, Logger)?? false);
+ Assert.IsTrue(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.2" } }.ToUserContext(), Logger)?? false);
+ Assert.IsTrue(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.2-beta" } }.ToUserContext(), Logger)?? false);
+ Assert.IsTrue(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "4.7.1" } }.ToUserContext(), Logger)?? false);
+ Assert.IsTrue(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.8" } }.ToUserContext(), Logger)?? false);
+ Assert.IsTrue(SemVerGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "4" } }.ToUserContext(), Logger)?? false);
}
[Test]
public void TestSemVerGTMatcherReturnsTrueWhenAttributeValueIsGreaterThanConditionValueBeta()
{
var semverGTCondition = new BaseCondition { Name = "semversion_gt", Value = "3.7.0-beta.2.3", Match = "semver_gt", Type = "custom_attribute" };
- Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.0-beta.2.4" } }, Logger)?? false);
- Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.0" } }, Logger)?? false);
+ Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.0-beta.2.4" } }.ToUserContext(), Logger)?? false);
+ Assert.IsTrue(semverGTCondition.Evaluate(null, new UserAttributes { { "semversion_gt", "3.7.0" } }.ToUserContext(), Logger)?? false);
}
#endregion // SemVerGTMatcher Tests
@@ -501,48 +503,48 @@ public void TestSemVerGTMatcherReturnsTrueWhenAttributeValueIsGreaterThanConditi
[Test]
public void TestSemVerEQMatcherReturnsFalseWhenAttributeValueIsNotEqualToConditionValue()
{
- Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.7.0" } }, Logger) ?? true);
- Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.7.2" } }, Logger) ?? true);
- Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.6" } }, Logger)?? true);
- Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "2" } }, Logger)?? true);
- Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "4" } }, Logger)?? true);
- Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3" } }, Logger)?? true);
+ Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.7.0" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.7.2" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.6" } }.ToUserContext(), Logger)?? true);
+ Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "2" } }.ToUserContext(), Logger)?? true);
+ Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "4" } }.ToUserContext(), Logger)?? true);
+ Assert.IsFalse(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3" } }.ToUserContext(), Logger)?? true);
}
[Test]
public void TestSemVerEQMatcherReturnsTrueWhenAttributeValueIsEqualToConditionValue()
{
- Assert.IsTrue(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.7.1" } }, Logger) ?? false);
+ Assert.IsTrue(SemVerEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.7.1" } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestSemVerEQMatcherReturnsTrueWhenAttributeValueIsEqualToConditionValueMajorOnly()
{
var semverEQCondition = new BaseCondition { Name = "semversion_eq", Value = "3", Match = "semver_eq", Type = "custom_attribute" };
- Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.0.0" } }, Logger) ?? false);
- Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.1" } }, Logger) ?? false);
+ Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.0.0" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.1" } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestSemVerEQMatcherReturnsFalseOrFalseWhenAttributeValueIsNotEqualToConditionValueMajorOnly()
{
var semverEQCondition = new BaseCondition { Name = "semversion_eq", Value = "3", Match = "semver_eq", Type = "custom_attribute" };
- Assert.IsFalse(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "4.0" } }, Logger) ?? true);
- Assert.IsFalse(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "2" } }, Logger) ?? true);
+ Assert.IsFalse(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "4.0" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "2" } }.ToUserContext(), Logger) ?? true);
}
[Test]
public void TestSemVerEQMatcherReturnsTrueWhenAttributeValueIsEqualToConditionValueBeta()
{
var semverEQCondition = new BaseCondition { Name = "semversion_eq", Value = "3.7.0-beta.2.3", Match = "semver_eq", Type = "custom_attribute" };
- Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.7.0-beta.2.3" } }, Logger) ?? false);
+ Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "3.7.0-beta.2.3" } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestSemVerEQTargetBuildIgnores()
{
var semverEQCondition = new BaseCondition { Name = "semversion_eq", Value = "2.1.3", Match = "semver_eq", Type = "custom_attribute" };
- Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "2.1.3+build" } }, Logger) ?? false);
+ Assert.IsTrue(semverEQCondition.Evaluate(null, new UserAttributes { { "semversion_eq", "2.1.3+build" } }.ToUserContext(), Logger) ?? false);
}
#endregion // SemVerEQMatcher Tests
@@ -550,46 +552,46 @@ public void TestSemVerEQTargetBuildIgnores()
[Test]
public void TestSemVerGEMatcherReturnsFalseWhenAttributeValueIsNotGreaterOrEqualToConditionValue()
{
- Assert.IsFalse(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.0" } }, Logger) ?? true);
- Assert.IsFalse(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.1-beta" } }, Logger) ?? true);
- Assert.IsFalse(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.6" } }, Logger) ?? true);
- Assert.IsFalse(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "2" } }, Logger) ?? true);
- Assert.IsFalse(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3" } }, Logger) ?? true);
+ Assert.IsFalse(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.0" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.1-beta" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.6" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "2" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3" } }.ToUserContext(), Logger) ?? true);
}
[Test]
public void TestSemVerGEMatcherReturnsTrueWhenAttributeValueIsGreaterOrEqualToConditionValue()
{
- Assert.IsTrue(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.1" } }, Logger) ?? false);
- Assert.IsTrue(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.2" } }, Logger) ?? false);
- Assert.IsTrue(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.8.1" } }, Logger) ?? false); ;
- Assert.IsTrue(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "4.7.1" } }, Logger) ?? false);
+ Assert.IsTrue(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.1" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.2" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.8.1" } }.ToUserContext(), Logger) ?? false); ;
+ Assert.IsTrue(SemVerGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "4.7.1" } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestSemVerGEMatcherReturnsTrueWhenAttributeValueIsGreaterOrEqualToConditionValueMajorOnly()
{
var semverGECondition = new BaseCondition { Name = "semversion_ge", Value = "3", Match = "semver_ge", Type = "custom_attribute" };
- Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.0" } }, Logger) ?? false);
- Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.0.0" } }, Logger) ?? false);
- Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "4.0" } }, Logger) ?? false);
+ Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.0" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.0.0" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "4.0" } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestSemVerGEMatcherReturnsFalseWhenAttributeValueIsNotGreaterOrEqualToConditionValueMajorOnly()
{
var semverGECondition = new BaseCondition { Name = "semversion_ge", Value = "3", Match = "semver_ge", Type = "custom_attribute" };
- Assert.IsFalse(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "2" } }, Logger) ?? true);
+ Assert.IsFalse(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "2" } }.ToUserContext(), Logger) ?? true);
}
[Test]
public void TestSemVerGEMatcherReturnsTrueWhenAttributeValueIsGreaterOrEqualToConditionValueBeta()
{
var semverGECondition = new BaseCondition { Name = "semversion_ge", Value = "3.7.0-beta.2.3", Match = "semver_ge", Type = "custom_attribute" };
- Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.0-beta.2.3" } }, Logger) ?? false);
- Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.0-beta.2.4" } }, Logger) ?? false);
- Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.0-beta.2.3+1.2.3" } }, Logger) ?? false);
- Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.1-beta.2.3" } }, Logger) ?? false);
+ Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.0-beta.2.3" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.0-beta.2.4" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.0-beta.2.3+1.2.3" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverGECondition.Evaluate(null, new UserAttributes { { "semversion_ge", "3.7.1-beta.2.3" } }.ToUserContext(), Logger) ?? false);
}
#endregion // SemVerGEMatcher Tests
@@ -597,46 +599,46 @@ public void TestSemVerGEMatcherReturnsTrueWhenAttributeValueIsGreaterOrEqualToCo
[Test]
public void TestSemVerLEMatcherReturnsFalseWhenAttributeValueIsNotLessOrEqualToConditionValue()
{
- Assert.IsFalse(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.2" } }, Logger) ?? true);
- Assert.IsFalse(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.8" } }, Logger) ?? true);
- Assert.IsFalse(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "4" } }, Logger) ?? true);
+ Assert.IsFalse(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.2" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.8" } }.ToUserContext(), Logger) ?? true);
+ Assert.IsFalse(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "4" } }.ToUserContext(), Logger) ?? true);
}
[Test]
public void TestSemVerLEMatcherReturnsTrueWhenAttributeValueIsLessOrEqualToConditionValue()
{
- Assert.IsTrue(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.1" } }, Logger) ?? false);
- Assert.IsTrue(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.0" } }, Logger) ?? false);
- Assert.IsTrue(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.6.1" } }, Logger) ?? false);
- Assert.IsTrue(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "2.7.1" } }, Logger) ?? false);
- Assert.IsTrue(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.1-beta" } }, Logger) ?? false);
+ Assert.IsTrue(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.1" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.0" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.6.1" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "2.7.1" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(SemVerLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.1-beta" } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestSemVerLEMatcherReturnsTrueWhenAttributeValueIsLessOrEqualToConditionValueMajorOnly()
{
var semverLECondition = new BaseCondition { Name = "semversion_le", Value = "3", Match = "semver_le", Type = "custom_attribute" };
- Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.0-beta.2.4" } }, Logger) ?? false);
- Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.1-beta" } }, Logger) ?? false);
- Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.0.0" } }, Logger) ?? false);
- Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "2.0" } }, Logger) ?? false);
+ Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.0-beta.2.4" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.1-beta" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.0.0" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "2.0" } }.ToUserContext(), Logger) ?? false);
}
[Test]
public void TestSemVerLEMatcherReturnsFalseWhenAttributeValueIsNotLessOrEqualToConditionValueMajorOnly()
{
var semverLECondition = new BaseCondition { Name = "semversion_le", Value = "3", Match = "semver_le", Type = "custom_attribute" };
- Assert.IsFalse(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "4" } }, Logger) ?? true);
+ Assert.IsFalse(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "4" } }.ToUserContext(), Logger) ?? true);
}
[Test]
public void TestSemVerLEMatcherReturnsTrueWhenAttributeValueIsLessOrEqualToConditionValueBeta()
{
var semverLECondition = new BaseCondition { Name = "semversion_le", Value = "3.7.0-beta.2.3", Match = "semver_le", Type = "custom_attribute" };
- Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.0-beta.2.2" } }, Logger) ?? false);
- Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.0-beta.2.3" } }, Logger) ?? false);
- Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.0-beta.2.2+1.2.3" } }, Logger) ?? false);
- Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.6.1-beta.2.3+1.2" } }, Logger) ?? false);
+ Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.0-beta.2.2" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.0-beta.2.3" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.7.0-beta.2.2+1.2.3" } }.ToUserContext(), Logger) ?? false);
+ Assert.IsTrue(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", "3.6.1-beta.2.3+1.2" } }.ToUserContext(), Logger) ?? false);
}
#endregion // SemVerLEMatcher Tests
@@ -649,10 +651,69 @@ public void TestInvalidSemVersions()
".2.2", "3.7.2.2", "3.x", ",", "+build-prerelese"};
var semverLECondition = new BaseCondition { Name = "semversion_le", Value = "3", Match = "semver_le", Type = "custom_attribute" };
foreach(var invalidValue in invalidValues) {
- Assert.IsNull(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", invalidValue } }, Logger), $"returned for {invalidValue}");
+ Assert.IsNull(semverLECondition.Evaluate(null, new UserAttributes { { "semversion_le", invalidValue } }.ToUserContext(), Logger), $"returned for {invalidValue}");
}
}
#endregion
+
+ #region Qualified Tests
+
+ [Test]
+ public void QualifiedConditionWithNonStringValueShouldFail()
+ {
+ var condition = new BaseCondition()
+ {
+ Type = BaseCondition.THIRD_PARTY_DIMENSION,
+ Match = BaseCondition.QUALIFIED,
+ Value = 100,
+ };
+
+ var result = condition.Evaluate(null, null, Logger);
+
+ Assert.That(result, Is.Null);
+ LoggerMock.Verify(l => l.Log(LogLevel.WARN, $@"Audience condition ""{condition}"" has a qualified match but invalid value."), Times.Once);
+ }
+
+
+ private const string QUALIFIED_VALUE = "part-of-the-rebellion";
+ private readonly List _qualifiedSegments = new List()
+ {
+ QUALIFIED_VALUE,
+ };
+
+ [Test]
+ public void QualifiedConditionWithMatchingValueShouldBeTrue()
+ {
+ var condition = new BaseCondition()
+ {
+ Type = BaseCondition.THIRD_PARTY_DIMENSION,
+ Match = BaseCondition.QUALIFIED,
+ Value = QUALIFIED_VALUE,
+ };
+
+ var result = condition.Evaluate(null, _qualifiedSegments.ToUserContext(), Logger);
+
+ Assert.True(result.HasValue && result.Value);
+ LoggerMock.Verify(l => l.Log(It.IsAny(), It.IsAny()), Times.Never);
+ }
+
+ [Test]
+ public void QualifiedConditionWithNonMatchingValueShouldBeFalse()
+ {
+ var condition = new BaseCondition()
+ {
+ Type = BaseCondition.THIRD_PARTY_DIMENSION,
+ Match = BaseCondition.QUALIFIED,
+ Value = "empire-star-system",
+ };
+
+ var result = condition.Evaluate(null, _qualifiedSegments.ToUserContext(), Logger);
+
+ Assert.True(result.HasValue && result.Value == false);
+ LoggerMock.Verify(l => l.Log( It.IsAny(), It.IsAny()), Times.Never);
+ }
+
+ #endregion
}
}
diff --git a/OptimizelySDK.Tests/AudienceConditionsTests/ConditionsTest.cs b/OptimizelySDK.Tests/AudienceConditionsTests/ConditionsTest.cs
index 00daf52f..af311b8e 100644
--- a/OptimizelySDK.Tests/AudienceConditionsTests/ConditionsTest.cs
+++ b/OptimizelySDK.Tests/AudienceConditionsTests/ConditionsTest.cs
@@ -1,11 +1,11 @@
/*
- * Copyright 2019, Optimizely
+ * Copyright 2019-2022, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -41,11 +41,11 @@ public class ConditionsTest
public void Initialize()
{
TrueConditionMock = new Mock();
- TrueConditionMock.Setup(condition => condition.Evaluate(It.IsAny(), It.IsAny(), It.IsAny())).Returns(true);
+ TrueConditionMock.Setup(condition => condition.Evaluate(It.IsAny(), It.IsAny(), It.IsAny())).Returns(true);
FalseConditionMock = new Mock();
- FalseConditionMock.Setup(condition => condition.Evaluate(It.IsAny(), It.IsAny(), It.IsAny())).Returns(false);
+ FalseConditionMock.Setup(condition => condition.Evaluate(It.IsAny(), It.IsAny(), It.IsAny())).Returns(false);
NullConditionMock = new Mock();
- NullConditionMock.Setup(condition => condition.Evaluate(It.IsAny(), It.IsAny(), It.IsAny())).Returns((bool?)null);
+ NullConditionMock.Setup(condition => condition.Evaluate(It.IsAny(), It.IsAny(), It.IsAny())).Returns((bool?)null);
TrueCondition = TrueConditionMock.Object;
FalseCondition = FalseConditionMock.Object;
@@ -76,7 +76,7 @@ public void TestAndEvaluatorReturnsFalseWhenAnyOperandEvaluatesToFalse()
Assert.That(andCondition.Evaluate(null, null, Logger), Is.False);
// Should not be called due to short circuiting.
- TrueConditionMock.Verify(condition => condition.Evaluate(It.IsAny(), It.IsAny(), Logger), Times.Never);
+ TrueConditionMock.Verify(condition => condition.Evaluate(It.IsAny(), It.IsAny(), Logger), Times.Never);
}
[Test]
diff --git a/OptimizelySDK.Tests/EntityTests/IntegrationTest.cs b/OptimizelySDK.Tests/EntityTests/IntegrationTest.cs
new file mode 100644
index 00000000..6daea7a8
--- /dev/null
+++ b/OptimizelySDK.Tests/EntityTests/IntegrationTest.cs
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2022, Optimizely
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using NUnit.Framework;
+using OptimizelySDK.Entity;
+
+namespace OptimizelySDK.Tests.EntityTests
+{
+ [TestFixture]
+ public class IntegrationTest
+ {
+ private const string KEY = "test-key";
+
+ private const string HOST = "api.example.com";
+ private const string PUBLIC_KEY = "FAk3-pUblic-K3y";
+
+ [Test]
+ public void ToStringWithNoHostShouldSucceed()
+ {
+ var integration = new Integration()
+ {
+ Key = KEY,
+ PublicKey = PUBLIC_KEY,
+ };
+
+ var stringValue = integration.ToString();
+
+ Assert.True(stringValue.Contains($@"key='{KEY}'"));
+ Assert.True(stringValue.Contains($@"publicKey='{PUBLIC_KEY}'"));
+ Assert.False(stringValue.Contains("host"));
+ Assert.False(stringValue.Contains(HOST));
+ }
+
+ [Test]
+ public void ToStringWithNoPublicKeyShouldSucceed()
+ {
+ var integration = new Integration()
+ {
+ Key = KEY,
+ Host = HOST,
+ };
+
+ var stringValue = integration.ToString();
+
+ Assert.True(stringValue.Contains($@"key='{KEY}'"));
+ Assert.True(stringValue.Contains($@"host='{HOST}'"));
+ Assert.False(stringValue.Contains("publicKey"));
+ Assert.False(stringValue.Contains(PUBLIC_KEY));
+ }
+
+ [Test]
+ public void ToStringWithAllPropertiesShouldSucceed()
+ {
+ var integration = new Integration()
+ {
+ Key = KEY,
+ Host = HOST,
+ PublicKey = PUBLIC_KEY,
+ };
+
+ var stringValue = integration.ToString();
+
+ Assert.True(
+ stringValue.Contains($@"key='{KEY}', host='{HOST}', publicKey='{PUBLIC_KEY}'"));
+ }
+
+ [Test]
+ public void ToStringWithOnlyKeyShouldSucceed()
+ {
+ var integration = new Integration()
+ {
+ Key = KEY,
+ };
+
+ var stringValue = integration.ToString();
+
+ Assert.True(stringValue.Contains($@"key='{KEY}'"));
+ Assert.False(stringValue.Contains("host"));
+ Assert.False(stringValue.Contains(HOST));
+ Assert.False(stringValue.Contains("publicKey"));
+ Assert.False(stringValue.Contains(PUBLIC_KEY));
+ }
+ }
+}
diff --git a/OptimizelySDK.Tests/IntegrationEmptyDatafile.json b/OptimizelySDK.Tests/IntegrationEmptyDatafile.json
new file mode 100644
index 00000000..1212bc81
--- /dev/null
+++ b/OptimizelySDK.Tests/IntegrationEmptyDatafile.json
@@ -0,0 +1,18 @@
+{
+ "version": "4",
+ "rollouts": [],
+ "anonymizeIP": true,
+ "projectId": "20441150641",
+ "variables": [],
+ "featureFlags": [],
+ "experiments": [],
+ "audiences": [],
+ "groups": [],
+ "integrations": [],
+ "attributes": [],
+ "accountId": "11467598500",
+ "events": [],
+ "revision": "241",
+ "sdkKey": "EmptyIntegrationDatafile",
+ "environmentKey": "Production"
+}
diff --git a/OptimizelySDK.Tests/IntegrationNonOdpDatafile.json b/OptimizelySDK.Tests/IntegrationNonOdpDatafile.json
new file mode 100644
index 00000000..cfdb0819
--- /dev/null
+++ b/OptimizelySDK.Tests/IntegrationNonOdpDatafile.json
@@ -0,0 +1,65 @@
+{
+ "version": "4",
+ "rollouts": [
+ {
+ "experiments": [
+ ],
+ "id": "18309384009"
+ }
+ ],
+ "typedAudiences": [],
+ "anonymizeIP": true,
+ "projectId": "18326250003",
+ "variables": [],
+ "featureFlags": [
+ {
+ "experimentIds": [],
+ "rolloutId": "18309384009",
+ "variables": [
+ {
+ "defaultValue": "",
+ "type": "string",
+ "id": "18323951833",
+ "key": "var_1"
+ }
+ ],
+ "id": "18244658520",
+ "key": "empty_rollout"
+ },
+ {
+ "experimentIds": [],
+ "rolloutId": "",
+ "variables": [
+ {
+ "defaultValue": "",
+ "type": "string",
+ "id": "2832355113",
+ "key": "var_2"
+ }
+ ],
+ "id": "24246538512",
+ "key": "empty_rollout_id"
+ }
+ ],
+ "experiments": [],
+ "audiences": [
+ {
+ "conditions": "[\"or\", {\"match\": \"exact\", \"name\": \"$opt_dummy_attribute\", \"type\": \"custom_attribute\", \"value\": \"$opt_dummy_value\"}]",
+ "id": "$opt_dummy_audience",
+ "name": "Optimizely-Generated Audience for Backwards Compatibility"
+ }
+ ],
+ "groups": [],
+ "integrations": [
+ {
+ "key": "not-odp",
+ "host": "https://example.com",
+ "publicKey": "CleAr1y-!a-R3a7-pUbl1c-k3y"
+ }
+ ],
+ "attributes": [],
+ "botFiltering": false,
+ "accountId": "8272261422",
+ "events": [],
+ "revision": "2"
+}
diff --git a/OptimizelySDK.Tests/IntegrationOdpDatafile.json b/OptimizelySDK.Tests/IntegrationOdpDatafile.json
new file mode 100644
index 00000000..219718e0
--- /dev/null
+++ b/OptimizelySDK.Tests/IntegrationOdpDatafile.json
@@ -0,0 +1,318 @@
+{
+ "version": "4",
+ "rollouts": [{
+ "experiments": [{
+ "status": "Running",
+ "key": "feat_no_vars_rule",
+ "layerId": "11551226731",
+ "trafficAllocation": [{
+ "entityId": "11557362669",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["3468206642", "3988293898", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"],
+ "variations": [{
+ "variables": [],
+ "id": "11557362669",
+ "key": "11557362669",
+ "featureEnabled": true
+ }],
+ "forcedVariations": {},
+ "id": "11488548027"
+ }],
+ "id": "11551226731"
+ },
+ {
+ "experiments": [{
+ "status": "Paused",
+ "key": "feat_with_var_rule",
+ "layerId": "11638870867",
+ "trafficAllocation": [{
+ "entityId": "11475708558",
+ "endOfRange": 0
+ }],
+ "audienceIds": [],
+ "variations": [{
+ "variables": [],
+ "id": "11475708558",
+ "key": "11475708558",
+ "featureEnabled": false
+ }],
+ "forcedVariations": {},
+ "id": "11630490911"
+ }],
+ "id": "11638870867"
+ },
+ {
+ "experiments": [{
+ "status": "Running",
+ "key": "11488548028",
+ "layerId": "11551226732",
+ "trafficAllocation": [{
+ "entityId": "11557362670",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["0"],
+ "audienceConditions": ["and", ["or", "3468206642", "3988293898"],
+ ["or", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"]
+ ],
+ "variations": [{
+ "variables": [],
+ "id": "11557362670",
+ "key": "11557362670",
+ "featureEnabled": true
+ }],
+ "forcedVariations": {},
+ "id": "11488548028"
+ }],
+ "id": "11551226732"
+ },
+ {
+ "experiments": [{
+ "status": "Paused",
+ "key": "11630490912",
+ "layerId": "11638870868",
+ "trafficAllocation": [{
+ "entityId": "11475708559",
+ "endOfRange": 0
+ }],
+ "audienceIds": [],
+ "variations": [{
+ "variables": [],
+ "id": "11475708559",
+ "key": "11475708559",
+ "featureEnabled": false
+ }],
+ "forcedVariations": {},
+ "id": "11630490912"
+ }],
+ "id": "11638870868"
+ }
+ ],
+ "anonymizeIP": false,
+ "projectId": "11624721371",
+ "variables": [],
+ "featureFlags": [{
+ "experimentIds": [],
+ "rolloutId": "11551226731",
+ "variables": [],
+ "id": "11477755619",
+ "key": "feat_no_vars"
+ },
+ {
+ "experimentIds": [
+ "11564051718"
+ ],
+ "rolloutId": "11638870867",
+ "variables": [{
+ "defaultValue": "x",
+ "type": "string",
+ "id": "11535264366",
+ "key": "x"
+ }],
+ "id": "11567102051",
+ "key": "feat_with_var"
+ },
+ {
+ "experimentIds": [],
+ "rolloutId": "11551226732",
+ "variables": [],
+ "id": "11567102052",
+ "key": "feat2"
+ },
+ {
+ "experimentIds": ["1323241599"],
+ "rolloutId": "11638870868",
+ "variables": [{
+ "defaultValue": "10",
+ "type": "integer",
+ "id": "11535264367",
+ "key": "z"
+ }],
+ "id": "11567102053",
+ "key": "feat2_with_var"
+ }
+ ],
+ "experiments": [{
+ "status": "Running",
+ "key": "feat_with_var_test",
+ "layerId": "11504144555",
+ "trafficAllocation": [{
+ "entityId": "11617170975",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["3468206642", "3988293898", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"],
+ "variations": [{
+ "variables": [{
+ "id": "11535264366",
+ "value": "xyz"
+ }],
+ "id": "11617170975",
+ "key": "variation_2",
+ "featureEnabled": true
+ }],
+ "forcedVariations": {},
+ "id": "11564051718"
+ },
+ {
+ "id": "1323241597",
+ "key": "typed_audience_experiment",
+ "layerId": "1630555627",
+ "status": "Running",
+ "variations": [{
+ "id": "1423767503",
+ "key": "A",
+ "variables": []
+ }],
+ "trafficAllocation": [{
+ "entityId": "1423767503",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["3468206642", "3988293898", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"],
+ "forcedVariations": {}
+ },
+ {
+ "id": "1323241598",
+ "key": "audience_combinations_experiment",
+ "layerId": "1323241598",
+ "status": "Running",
+ "variations": [{
+ "id": "1423767504",
+ "key": "A",
+ "variables": []
+ }],
+ "trafficAllocation": [{
+ "entityId": "1423767504",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["0"],
+ "audienceConditions": ["and", ["or", "3468206642", "3988293898"],
+ ["or", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"]
+ ],
+ "forcedVariations": {}
+ },
+ {
+ "id": "1323241599",
+ "key": "feat2_with_var_test",
+ "layerId": "1323241600",
+ "status": "Running",
+ "variations": [{
+ "variables": [{
+ "id": "11535264367",
+ "value": "150"
+ }],
+ "id": "1423767505",
+ "key": "variation_2",
+ "featureEnabled": true
+ }],
+ "trafficAllocation": [{
+ "entityId": "1423767505",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["0"],
+ "audienceConditions": ["and", ["or", "3468206642", "3988293898"],
+ ["or", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"]
+ ],
+ "forcedVariations": {}
+ }
+ ],
+ "audiences": [
+ {
+ "id": "3468206642",
+ "name": "exactString",
+ "conditions": "[\"and\", [\"or\", [\"or\", {\"name\": \"house\", \"type\": \"custom_attribute\", \"value\": \"Gryffindor\"}]]]"
+ },
+ {
+ "id": "3468206645",
+ "name": "notChrome",
+ "conditions": "[\"and\", [\"or\", [\"not\", [\"or\", {\"name\": \"browser_type\", \"type\": \"custom_attribute\", \"value\":\"Chrome\"}]]]]"
+ },
+ {
+ "id": "3988293898",
+ "name": "$$dummySubstringString",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "3988293899",
+ "name": "$$dummyExists",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "3468206646",
+ "name": "$$dummyExactNumber",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "3468206647",
+ "name": "$$dummyGtNumber",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "3468206644",
+ "name": "$$dummyLtNumber",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "3468206643",
+ "name": "$$dummyExactBoolean",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "0",
+ "name": "$$dummy",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "$opt_dummy_audience",
+ "name": "dummy_audience",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ }
+ ],
+ "typedAudiences": [],
+ "groups": [],
+ "integrations": [
+ {
+ "key": "odp",
+ "host": "https://api.zaius.com",
+ "publicKey": "W4WzcEs-ABgXorzY7h1LCQ"
+ }
+ ],
+ "attributes": [{
+ "key": "house",
+ "id": "594015"
+ },
+ {
+ "key": "lasers",
+ "id": "594016"
+ },
+ {
+ "key": "should_do_it",
+ "id": "594017"
+ },
+ {
+ "key": "favorite_ice_cream",
+ "id": "594018"
+ }
+ ],
+ "botFiltering": false,
+ "accountId": "4879520872",
+ "events": [{
+ "key": "item_bought",
+ "id": "594089",
+ "experimentIds": [
+ "11564051718",
+ "1323241597"
+ ]
+ },
+ {
+ "key": "user_signed_up",
+ "id": "594090",
+ "experimentIds": [
+ "1323241598",
+ "1323241599"
+ ]
+ }
+ ],
+ "revision": "3",
+ "sdkKey": "typedAudienceDatafile",
+ "environmentKey": "Production"
+}
diff --git a/OptimizelySDK.Tests/IntegrationOdpWithOtherFieldsDatafile.json b/OptimizelySDK.Tests/IntegrationOdpWithOtherFieldsDatafile.json
new file mode 100644
index 00000000..4f6dd8ea
--- /dev/null
+++ b/OptimizelySDK.Tests/IntegrationOdpWithOtherFieldsDatafile.json
@@ -0,0 +1,321 @@
+{
+ "version": "4",
+ "rollouts": [{
+ "experiments": [{
+ "status": "Running",
+ "key": "feat_no_vars_rule",
+ "layerId": "11551226731",
+ "trafficAllocation": [{
+ "entityId": "11557362669",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["3468206642", "3988293898", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"],
+ "variations": [{
+ "variables": [],
+ "id": "11557362669",
+ "key": "11557362669",
+ "featureEnabled": true
+ }],
+ "forcedVariations": {},
+ "id": "11488548027"
+ }],
+ "id": "11551226731"
+ },
+ {
+ "experiments": [{
+ "status": "Paused",
+ "key": "feat_with_var_rule",
+ "layerId": "11638870867",
+ "trafficAllocation": [{
+ "entityId": "11475708558",
+ "endOfRange": 0
+ }],
+ "audienceIds": [],
+ "variations": [{
+ "variables": [],
+ "id": "11475708558",
+ "key": "11475708558",
+ "featureEnabled": false
+ }],
+ "forcedVariations": {},
+ "id": "11630490911"
+ }],
+ "id": "11638870867"
+ },
+ {
+ "experiments": [{
+ "status": "Running",
+ "key": "11488548028",
+ "layerId": "11551226732",
+ "trafficAllocation": [{
+ "entityId": "11557362670",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["0"],
+ "audienceConditions": ["and", ["or", "3468206642", "3988293898"],
+ ["or", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"]
+ ],
+ "variations": [{
+ "variables": [],
+ "id": "11557362670",
+ "key": "11557362670",
+ "featureEnabled": true
+ }],
+ "forcedVariations": {},
+ "id": "11488548028"
+ }],
+ "id": "11551226732"
+ },
+ {
+ "experiments": [{
+ "status": "Paused",
+ "key": "11630490912",
+ "layerId": "11638870868",
+ "trafficAllocation": [{
+ "entityId": "11475708559",
+ "endOfRange": 0
+ }],
+ "audienceIds": [],
+ "variations": [{
+ "variables": [],
+ "id": "11475708559",
+ "key": "11475708559",
+ "featureEnabled": false
+ }],
+ "forcedVariations": {},
+ "id": "11630490912"
+ }],
+ "id": "11638870868"
+ }
+ ],
+ "anonymizeIP": false,
+ "projectId": "11624721371",
+ "variables": [],
+ "featureFlags": [{
+ "experimentIds": [],
+ "rolloutId": "11551226731",
+ "variables": [],
+ "id": "11477755619",
+ "key": "feat_no_vars"
+ },
+ {
+ "experimentIds": [
+ "11564051718"
+ ],
+ "rolloutId": "11638870867",
+ "variables": [{
+ "defaultValue": "x",
+ "type": "string",
+ "id": "11535264366",
+ "key": "x"
+ }],
+ "id": "11567102051",
+ "key": "feat_with_var"
+ },
+ {
+ "experimentIds": [],
+ "rolloutId": "11551226732",
+ "variables": [],
+ "id": "11567102052",
+ "key": "feat2"
+ },
+ {
+ "experimentIds": ["1323241599"],
+ "rolloutId": "11638870868",
+ "variables": [{
+ "defaultValue": "10",
+ "type": "integer",
+ "id": "11535264367",
+ "key": "z"
+ }],
+ "id": "11567102053",
+ "key": "feat2_with_var"
+ }
+ ],
+ "experiments": [{
+ "status": "Running",
+ "key": "feat_with_var_test",
+ "layerId": "11504144555",
+ "trafficAllocation": [{
+ "entityId": "11617170975",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["3468206642", "3988293898", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"],
+ "variations": [{
+ "variables": [{
+ "id": "11535264366",
+ "value": "xyz"
+ }],
+ "id": "11617170975",
+ "key": "variation_2",
+ "featureEnabled": true
+ }],
+ "forcedVariations": {},
+ "id": "11564051718"
+ },
+ {
+ "id": "1323241597",
+ "key": "typed_audience_experiment",
+ "layerId": "1630555627",
+ "status": "Running",
+ "variations": [{
+ "id": "1423767503",
+ "key": "A",
+ "variables": []
+ }],
+ "trafficAllocation": [{
+ "entityId": "1423767503",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["3468206642", "3988293898", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"],
+ "forcedVariations": {}
+ },
+ {
+ "id": "1323241598",
+ "key": "audience_combinations_experiment",
+ "layerId": "1323241598",
+ "status": "Running",
+ "variations": [{
+ "id": "1423767504",
+ "key": "A",
+ "variables": []
+ }],
+ "trafficAllocation": [{
+ "entityId": "1423767504",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["0"],
+ "audienceConditions": ["and", ["or", "3468206642", "3988293898"],
+ ["or", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"]
+ ],
+ "forcedVariations": {}
+ },
+ {
+ "id": "1323241599",
+ "key": "feat2_with_var_test",
+ "layerId": "1323241600",
+ "status": "Running",
+ "variations": [{
+ "variables": [{
+ "id": "11535264367",
+ "value": "150"
+ }],
+ "id": "1423767505",
+ "key": "variation_2",
+ "featureEnabled": true
+ }],
+ "trafficAllocation": [{
+ "entityId": "1423767505",
+ "endOfRange": 10000
+ }],
+ "audienceIds": ["0"],
+ "audienceConditions": ["and", ["or", "3468206642", "3988293898"],
+ ["or", "3988293899", "3468206646", "3468206647", "3468206644", "3468206643"]
+ ],
+ "forcedVariations": {}
+ }
+ ],
+ "audiences": [
+ {
+ "id": "3468206642",
+ "name": "exactString",
+ "conditions": "[\"and\", [\"or\", [\"or\", {\"name\": \"house\", \"type\": \"custom_attribute\", \"value\": \"Gryffindor\"}]]]"
+ },
+ {
+ "id": "3468206645",
+ "name": "notChrome",
+ "conditions": "[\"and\", [\"or\", [\"not\", [\"or\", {\"name\": \"browser_type\", \"type\": \"custom_attribute\", \"value\":\"Chrome\"}]]]]"
+ },
+ {
+ "id": "3988293898",
+ "name": "$$dummySubstringString",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "3988293899",
+ "name": "$$dummyExists",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "3468206646",
+ "name": "$$dummyExactNumber",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "3468206647",
+ "name": "$$dummyGtNumber",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "3468206644",
+ "name": "$$dummyLtNumber",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "3468206643",
+ "name": "$$dummyExactBoolean",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "0",
+ "name": "$$dummy",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ },
+ {
+ "id": "$opt_dummy_audience",
+ "name": "dummy_audience",
+ "conditions": "{\"type\": \"custom_attribute\", \"name\": \"$opt_dummy_attribute\", \"value\": \"impossible_value\"}"
+ }
+ ],
+ "typedAudiences": [],
+ "groups": [],
+ "integrations": [
+ {
+ "key": "odp",
+ "host": "https://api.zaius.com",
+ "publicKey": "W4WzcEs-ABgXorzY7h1LCQ",
+ "k1": 10,
+ "k2": true,
+ "k3": "any-value"
+ }
+ ],
+ "attributes": [{
+ "key": "house",
+ "id": "594015"
+ },
+ {
+ "key": "lasers",
+ "id": "594016"
+ },
+ {
+ "key": "should_do_it",
+ "id": "594017"
+ },
+ {
+ "key": "favorite_ice_cream",
+ "id": "594018"
+ }
+ ],
+ "botFiltering": false,
+ "accountId": "4879520872",
+ "events": [{
+ "key": "item_bought",
+ "id": "594089",
+ "experimentIds": [
+ "11564051718",
+ "1323241597"
+ ]
+ },
+ {
+ "key": "user_signed_up",
+ "id": "594090",
+ "experimentIds": [
+ "1323241598",
+ "1323241599"
+ ]
+ }
+ ],
+ "revision": "3",
+ "sdkKey": "typedAudienceDatafile",
+ "environmentKey": "Production"
+}
diff --git a/OptimizelySDK.Tests/OptimizelyConfigTests/OptimizelyConfigTest.cs b/OptimizelySDK.Tests/OptimizelyConfigTests/OptimizelyConfigTest.cs
index 007ee360..0689e6a2 100644
--- a/OptimizelySDK.Tests/OptimizelyConfigTests/OptimizelyConfigTest.cs
+++ b/OptimizelySDK.Tests/OptimizelyConfigTests/OptimizelyConfigTest.cs
@@ -1,11 +1,11 @@
/*
- * Copyright 2020-2021, Optimizely
+ * Copyright 2020-2022, Optimizely
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -18,7 +18,6 @@
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using OptimizelySDK.Config;
-using OptimizelySDK.Entity;
using OptimizelySDK.Logger;
using OptimizelySDK.OptlyConfig;
using OptimizelySDK.Tests.UtilsTests;
diff --git a/OptimizelySDK.Tests/OptimizelySDK.Tests.csproj b/OptimizelySDK.Tests/OptimizelySDK.Tests.csproj
index 2a776bcb..d0a2d2ae 100644
--- a/OptimizelySDK.Tests/OptimizelySDK.Tests.csproj
+++ b/OptimizelySDK.Tests/OptimizelySDK.Tests.csproj
@@ -78,6 +78,7 @@
+
@@ -106,6 +107,7 @@
+
@@ -123,6 +125,10 @@
+
+
+
+
@@ -136,7 +142,6 @@
OptimizelySDK
-
@@ -146,7 +151,6 @@
-