Skip to content

Commit d369886

Browse files
feat: Datafile parsing + audience evaluation for ODP integration (#305)
* Updated user context * Added ref to SDK from DemoApp so solution builds. * (Datafile)ProjectConfig & Integration added * Update Condition interface & implementing classes * Add copyright notice * Add AttributeType * Implement changes from DoesUserMeetAudienceConditions * Correct accessibility & missing interface item * Bring AttributeType into BaseCondition * Add missing reference * Fix parsing * Add test for Integration parsing * Move reference to Integration * Correction to NetStandard 2.0 project reference * Add empty Integration test * Test for empty integration and non "odp" integration * Fix missed Copyright update * Fix copyright notice * Add additional line to eof * Refactor `user` to `context` for OptimizelyUserContext param * Refactor: use static array of valid types * Oops use `userContext` instead of `context` * Update OptimizelySDK/AudienceConditions/ICondition.cs Co-authored-by: Jae Kim <[email protected]> * Update OptimizelySDK/AudienceConditions/EmptyCondition.cs Co-authored-by: Jae Kim <[email protected]> * Support Copy() including QualifiedSegments * Move datafile Integration tests * Integration ToString made generic + tests * Minor refactor and doc to userconext * Lock UserContext before determining IsQualifiedFor * Separate integration test datafile content * Add good integration config but also has other key-values * Add copyright and EOL * Correction to Qualified Segments check + Add tests * Update OptimizelySDK/OptimizelyUserContext.cs Co-authored-by: Jae Kim <[email protected]> * Update OptimizelySDK.Tests/ProjectConfigTest.cs Co-authored-by: Jae Kim <[email protected]> * Add thread-safe getter+setter; fix formatting * Use third party dimension in qualified segments test * Fixing Mike's sloppiness * Correct parameter order * Rename tests * Maintain previous constructor signature Co-authored-by: Jae Kim <[email protected]>
1 parent c89aa98 commit d369886

35 files changed

+1443
-343
lines changed

OptimizelySDK.DemoApp/OptimizelySDK.DemoApp.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,12 @@
241241
<ItemGroup>
242242
<Content Include="packages.config" />
243243
</ItemGroup>
244+
<ItemGroup>
245+
<ProjectReference Include="..\OptimizelySDK\OptimizelySDK.csproj">
246+
<Project>{4dde7faa-110d-441c-ab3b-3f31b593e8bf}</Project>
247+
<Name>OptimizelySDK</Name>
248+
</ProjectReference>
249+
</ItemGroup>
244250
<PropertyGroup>
245251
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
246252
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

OptimizelySDK.Net35/OptimizelySDK.Net35.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@
233233
<Compile Include="..\OptimizelySDK\Config\DatafileProjectConfig.cs">
234234
<Link>Config\DatafileProjectConfig</Link>
235235
</Compile>
236+
<Compile Include="..\OptimizelySDK\Entity\Integration.cs">
237+
<Link>Entity\Integration</Link>
238+
</Compile>
236239
<Compile Include="..\OptimizelySDK\Config\ProjectConfigManager.cs">
237240
<Link>Config\ProjectConfigManager</Link>
238241
</Compile>

OptimizelySDK.Net40/OptimizelySDK.Net40.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@
232232
<Compile Include="..\OptimizelySDK\Config\DatafileProjectConfig.cs">
233233
<Link>Config\DatafileProjectConfig</Link>
234234
</Compile>
235+
<Compile Include="..\OptimizelySDK\Entity\Integration.cs">
236+
<Link>Entity\Integration</Link>
237+
</Compile>
235238
<Compile Include="..\OptimizelySDK\Config\ProjectConfigManager.cs">
236239
<Link>Config\ProjectConfigManager</Link>
237240
</Compile>

OptimizelySDK.NetStandard16/OptimizelySDK.NetStandard16.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
<Compile Include="..\OptimizelySDK\Bucketing\UserProfileUtil.cs" />
7777
<Compile Include="..\OptimizelySDK\ProjectConfig.cs" />
7878
<Compile Include="..\OptimizelySDK\Config\DatafileProjectConfig.cs" />
79+
<Compile Include="..\OptimizelySDK\Entity\Integration.cs" />
7980
<Compile Include="..\OptimizelySDK\Config\ProjectConfigManager.cs" />
8081
<Compile Include="..\OptimizelySDK\Config\PollingProjectConfigManager.cs" />
8182
<Compile Include="..\OptimizelySDK\Config\HttpProjectConfigManager.cs" />
@@ -159,5 +160,4 @@
159160
<PackageReference Include="NJsonSchema" Version="8.33.6323.36213" />
160161
<PackageReference Include="murmurhash-signed" Version="1.0.2" />
161162
</ItemGroup>
162-
163163
</Project>

OptimizelySDK.NetStandard20/OptimizelySDK.NetStandard20.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@
115115
<Compile Include="..\OptimizelySDK\Entity\Group.cs">
116116
<Link>Entity\Group.cs</Link>
117117
</Compile>
118+
<Compile Include="..\OptimizelySDK\Entity\Integration.cs">
119+
<Link>Entity\Integration.cs</Link>
120+
</Compile>
118121
<Compile Include="..\OptimizelySDK\Entity\IdKeyEntity.cs">
119122
<Link>Entity\IdKeyEntity.cs</Link>
120123
</Compile>

OptimizelySDK.Tests/AudienceConditionsTests/ConditionEvaluationTest.cs

Lines changed: 213 additions & 152 deletions
Large diffs are not rendered by default.

OptimizelySDK.Tests/AudienceConditionsTests/ConditionsTest.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/*
2-
* Copyright 2019, Optimizely
2+
* Copyright 2019-2022, Optimizely
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* https://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -41,11 +41,11 @@ public class ConditionsTest
4141
public void Initialize()
4242
{
4343
TrueConditionMock = new Mock<ICondition>();
44-
TrueConditionMock.Setup(condition => condition.Evaluate(It.IsAny<ProjectConfig>(), It.IsAny<UserAttributes>(), It.IsAny<ILogger>())).Returns(true);
44+
TrueConditionMock.Setup(condition => condition.Evaluate(It.IsAny<ProjectConfig>(), It.IsAny<OptimizelyUserContext>(), It.IsAny<ILogger>())).Returns(true);
4545
FalseConditionMock = new Mock<ICondition>();
46-
FalseConditionMock.Setup(condition => condition.Evaluate(It.IsAny<ProjectConfig>(), It.IsAny<UserAttributes>(), It.IsAny<ILogger>())).Returns(false);
46+
FalseConditionMock.Setup(condition => condition.Evaluate(It.IsAny<ProjectConfig>(), It.IsAny<OptimizelyUserContext>(), It.IsAny<ILogger>())).Returns(false);
4747
NullConditionMock = new Mock<ICondition>();
48-
NullConditionMock.Setup(condition => condition.Evaluate(It.IsAny<ProjectConfig>(), It.IsAny<UserAttributes>(), It.IsAny<ILogger>())).Returns((bool?)null);
48+
NullConditionMock.Setup(condition => condition.Evaluate(It.IsAny<ProjectConfig>(), It.IsAny<OptimizelyUserContext>(), It.IsAny<ILogger>())).Returns((bool?)null);
4949

5050
TrueCondition = TrueConditionMock.Object;
5151
FalseCondition = FalseConditionMock.Object;
@@ -76,7 +76,7 @@ public void TestAndEvaluatorReturnsFalseWhenAnyOperandEvaluatesToFalse()
7676
Assert.That(andCondition.Evaluate(null, null, Logger), Is.False);
7777

7878
// Should not be called due to short circuiting.
79-
TrueConditionMock.Verify(condition => condition.Evaluate(It.IsAny<ProjectConfig>(), It.IsAny<UserAttributes>(), Logger), Times.Never);
79+
TrueConditionMock.Verify(condition => condition.Evaluate(It.IsAny<ProjectConfig>(), It.IsAny<OptimizelyUserContext>(), Logger), Times.Never);
8080
}
8181

8282
[Test]
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Copyright 2022, Optimizely
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
using NUnit.Framework;
18+
using OptimizelySDK.Entity;
19+
20+
namespace OptimizelySDK.Tests.EntityTests
21+
{
22+
[TestFixture]
23+
public class IntegrationTest
24+
{
25+
private const string KEY = "test-key";
26+
27+
private const string HOST = "api.example.com";
28+
private const string PUBLIC_KEY = "FAk3-pUblic-K3y";
29+
30+
[Test]
31+
public void ToStringWithNoHostShouldSucceed()
32+
{
33+
var integration = new Integration()
34+
{
35+
Key = KEY,
36+
PublicKey = PUBLIC_KEY,
37+
};
38+
39+
var stringValue = integration.ToString();
40+
41+
Assert.True(stringValue.Contains($@"key='{KEY}'"));
42+
Assert.True(stringValue.Contains($@"publicKey='{PUBLIC_KEY}'"));
43+
Assert.False(stringValue.Contains("host"));
44+
Assert.False(stringValue.Contains(HOST));
45+
}
46+
47+
[Test]
48+
public void ToStringWithNoPublicKeyShouldSucceed()
49+
{
50+
var integration = new Integration()
51+
{
52+
Key = KEY,
53+
Host = HOST,
54+
};
55+
56+
var stringValue = integration.ToString();
57+
58+
Assert.True(stringValue.Contains($@"key='{KEY}'"));
59+
Assert.True(stringValue.Contains($@"host='{HOST}'"));
60+
Assert.False(stringValue.Contains("publicKey"));
61+
Assert.False(stringValue.Contains(PUBLIC_KEY));
62+
}
63+
64+
[Test]
65+
public void ToStringWithAllPropertiesShouldSucceed()
66+
{
67+
var integration = new Integration()
68+
{
69+
Key = KEY,
70+
Host = HOST,
71+
PublicKey = PUBLIC_KEY,
72+
};
73+
74+
var stringValue = integration.ToString();
75+
76+
Assert.True(
77+
stringValue.Contains($@"key='{KEY}', host='{HOST}', publicKey='{PUBLIC_KEY}'"));
78+
}
79+
80+
[Test]
81+
public void ToStringWithOnlyKeyShouldSucceed()
82+
{
83+
var integration = new Integration()
84+
{
85+
Key = KEY,
86+
};
87+
88+
var stringValue = integration.ToString();
89+
90+
Assert.True(stringValue.Contains($@"key='{KEY}'"));
91+
Assert.False(stringValue.Contains("host"));
92+
Assert.False(stringValue.Contains(HOST));
93+
Assert.False(stringValue.Contains("publicKey"));
94+
Assert.False(stringValue.Contains(PUBLIC_KEY));
95+
}
96+
}
97+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"version": "4",
3+
"rollouts": [],
4+
"anonymizeIP": true,
5+
"projectId": "20441150641",
6+
"variables": [],
7+
"featureFlags": [],
8+
"experiments": [],
9+
"audiences": [],
10+
"groups": [],
11+
"integrations": [],
12+
"attributes": [],
13+
"accountId": "11467598500",
14+
"events": [],
15+
"revision": "241",
16+
"sdkKey": "EmptyIntegrationDatafile",
17+
"environmentKey": "Production"
18+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"version": "4",
3+
"rollouts": [
4+
{
5+
"experiments": [
6+
],
7+
"id": "18309384009"
8+
}
9+
],
10+
"typedAudiences": [],
11+
"anonymizeIP": true,
12+
"projectId": "18326250003",
13+
"variables": [],
14+
"featureFlags": [
15+
{
16+
"experimentIds": [],
17+
"rolloutId": "18309384009",
18+
"variables": [
19+
{
20+
"defaultValue": "",
21+
"type": "string",
22+
"id": "18323951833",
23+
"key": "var_1"
24+
}
25+
],
26+
"id": "18244658520",
27+
"key": "empty_rollout"
28+
},
29+
{
30+
"experimentIds": [],
31+
"rolloutId": "",
32+
"variables": [
33+
{
34+
"defaultValue": "",
35+
"type": "string",
36+
"id": "2832355113",
37+
"key": "var_2"
38+
}
39+
],
40+
"id": "24246538512",
41+
"key": "empty_rollout_id"
42+
}
43+
],
44+
"experiments": [],
45+
"audiences": [
46+
{
47+
"conditions": "[\"or\", {\"match\": \"exact\", \"name\": \"$opt_dummy_attribute\", \"type\": \"custom_attribute\", \"value\": \"$opt_dummy_value\"}]",
48+
"id": "$opt_dummy_audience",
49+
"name": "Optimizely-Generated Audience for Backwards Compatibility"
50+
}
51+
],
52+
"groups": [],
53+
"integrations": [
54+
{
55+
"key": "not-odp",
56+
"host": "https://example.com",
57+
"publicKey": "CleAr1y-!a-R3a7-pUbl1c-k3y"
58+
}
59+
],
60+
"attributes": [],
61+
"botFiltering": false,
62+
"accountId": "8272261422",
63+
"events": [],
64+
"revision": "2"
65+
}

0 commit comments

Comments
 (0)