Skip to content

Commit 6cd7306

Browse files
committed
Added forcedDecisionStoreTests
1 parent 07664a8 commit 6cd7306

File tree

5 files changed

+167
-23
lines changed

5 files changed

+167
-23
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/**
2+
*
3+
* Copyright 2021, Optimizely and contributors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
using NUnit.Framework;
19+
20+
namespace OptimizelySDK.Tests
21+
{
22+
[TestFixture]
23+
public class ForcedDecisionsStoreTest
24+
{
25+
[Test]
26+
public void ForcedDecisionStoreGetSetForcedDecisionWithBothRuleAndFlagKey()
27+
{
28+
var expectedForcedDecision1 = new OptimizelyForcedDecision("sample_variation_key");
29+
var expectedForcedDecision2 = new OptimizelyForcedDecision("sample_variation_key_2");
30+
var context1 = new OptimizelyDecisionContext("flag_key", "rule_key");
31+
var context2 = new OptimizelyDecisionContext("flag_key", "rule_key1");
32+
var forcedDecisionStore = new ForcedDecisionsStore();
33+
forcedDecisionStore[context1] = expectedForcedDecision1;
34+
forcedDecisionStore[context2] = expectedForcedDecision2;
35+
36+
Assert.AreEqual(forcedDecisionStore.Count, 2);
37+
Assert.AreEqual(forcedDecisionStore[context1].VariationKey, expectedForcedDecision1.VariationKey);
38+
Assert.AreEqual(forcedDecisionStore[context2].VariationKey, expectedForcedDecision2.VariationKey);
39+
}
40+
41+
[Test]
42+
public void ForcedDecisionStoreNullFlagKeyForcedDecisionContext()
43+
{
44+
var expectedForcedDecision = new OptimizelyForcedDecision("sample_variation_key");
45+
var context = new OptimizelyDecisionContext(null, "rule_key");
46+
var forcedDecisionStore = new ForcedDecisionsStore();
47+
forcedDecisionStore[context] = expectedForcedDecision;
48+
49+
Assert.AreEqual(forcedDecisionStore.Count, 0);
50+
}
51+
52+
[Test]
53+
public void ForcedDecisionStoreNullContextForcedDecisionContext()
54+
{
55+
var expectedForcedDecision = new OptimizelyForcedDecision("sample_variation_key");
56+
OptimizelyDecisionContext context = null;
57+
var forcedDecisionStore = new ForcedDecisionsStore();
58+
forcedDecisionStore[context] = expectedForcedDecision;
59+
60+
Assert.AreEqual(forcedDecisionStore.Count, 0);
61+
}
62+
63+
[Test]
64+
public void ForcedDecisionStoreGetForcedDecisionWithBothRuleAndFlagKey()
65+
{
66+
var expectedForcedDecision1 = new OptimizelyForcedDecision("sample_variation_key");
67+
var context1 = new OptimizelyDecisionContext("flag_key", "rule_key");
68+
var NullFlagKeyContext = new OptimizelyDecisionContext(null, "rule_key");
69+
var forcedDecisionStore = new ForcedDecisionsStore();
70+
forcedDecisionStore[context1] = expectedForcedDecision1;
71+
72+
Assert.AreEqual(forcedDecisionStore.Count, 1);
73+
Assert.AreEqual(forcedDecisionStore[context1].VariationKey, expectedForcedDecision1.VariationKey);
74+
Assert.IsNull(forcedDecisionStore[NullFlagKeyContext]);
75+
}
76+
77+
[Test]
78+
public void ForcedDecisionStoreRemoveForcedDecisionTrue()
79+
{
80+
var expectedForcedDecision1 = new OptimizelyForcedDecision("sample_variation_key");
81+
var expectedForcedDecision2 = new OptimizelyForcedDecision("sample_variation_key_2");
82+
var context1 = new OptimizelyDecisionContext("flag_key", "rule_key");
83+
var context2 = new OptimizelyDecisionContext("flag_key", "rule_key1");
84+
var forcedDecisionStore = new ForcedDecisionsStore();
85+
forcedDecisionStore[context1] = expectedForcedDecision1;
86+
forcedDecisionStore[context2] = expectedForcedDecision2;
87+
88+
Assert.AreEqual(forcedDecisionStore.Count, 2);
89+
Assert.IsTrue(forcedDecisionStore.Remove(context2));
90+
Assert.AreEqual(forcedDecisionStore.Count, 1);
91+
Assert.AreEqual(forcedDecisionStore[context1].VariationKey, expectedForcedDecision1.VariationKey);
92+
Assert.IsNull(forcedDecisionStore[context2]);
93+
}
94+
95+
[Test]
96+
public void ForcedDecisionStoreRemoveForcedDecisionContextRuleKeyNotMatched()
97+
{
98+
var expectedForcedDecision = new OptimizelyForcedDecision("sample_variation_key");
99+
var contextNotMatched = new OptimizelyDecisionContext("flag_key", "");
100+
var context = new OptimizelyDecisionContext("flag_key", "rule_key");
101+
var forcedDecisionStore = new ForcedDecisionsStore();
102+
forcedDecisionStore[context] = expectedForcedDecision;
103+
104+
Assert.AreEqual(forcedDecisionStore.Count, 1);
105+
Assert.IsFalse(forcedDecisionStore.Remove(contextNotMatched));
106+
Assert.AreEqual(forcedDecisionStore.Count, 1);
107+
}
108+
109+
[Test]
110+
public void ForcedDecisionStoreRemoveAllForcedDecisionContext()
111+
{
112+
var expectedForcedDecision = new OptimizelyForcedDecision("sample_variation_key");
113+
var context = new OptimizelyDecisionContext("flag_key", "rule_key");
114+
var forcedDecisionStore = new ForcedDecisionsStore();
115+
forcedDecisionStore[context] = expectedForcedDecision;
116+
117+
Assert.AreEqual(forcedDecisionStore.Count, 1);
118+
forcedDecisionStore.RemoveAll();
119+
Assert.AreEqual(forcedDecisionStore.Count, 0);
120+
}
121+
122+
}
123+
}

OptimizelySDK.Tests/OptimizelySDK.Tests.csproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
<Compile Include="NotificationTests\NotificationCenterTests.cs" />
9494
<Compile Include="ClientConfigHandlerTest.cs" />
9595
<Compile Include="OptimizelyTest.cs" />
96+
<Compile Include="ForcedDecisionsStoreTest.cs" />
9697
<Compile Include="OptimizelyUserContextTest.cs" />
9798
<Compile Include="Properties\AssemblyInfo.cs" />
9899
<Compile Include="TestBucketer.cs" />
@@ -135,9 +136,7 @@
135136
<Name>OptimizelySDK</Name>
136137
</ProjectReference>
137138
</ItemGroup>
138-
<ItemGroup>
139-
<Folder Include="Utils\" />
140-
</ItemGroup>
139+
<ItemGroup />
141140
<ItemGroup>
142141
<None Include="packages.config" />
143142
<EmbeddedResource Include="unsupported_version_datafile.json" />

OptimizelySDK/ForcedDecisionsStore.cs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,18 @@ namespace OptimizelySDK
2323
/// </summary>
2424
public class ForcedDecisionsStore
2525
{
26-
public const string OPTI_NULL_RULE_KEY = "$opt-null-rule-key";
27-
public const string OPTI_KEY_DIVIDER = "-$opt$-";
28-
2926
private Dictionary<string, OptimizelyForcedDecision> ForcedDecisionsMap { get; set; }
3027

3128
public ForcedDecisionsStore()
3229
{
3330
ForcedDecisionsMap = new Dictionary<string, OptimizelyForcedDecision>();
3431
}
3532

33+
public ForcedDecisionsStore(ForcedDecisionsStore forcedDecisionsStore)
34+
{
35+
ForcedDecisionsMap = new Dictionary<string, OptimizelyForcedDecision>(forcedDecisionsStore.ForcedDecisionsMap);
36+
}
37+
3638
public int Count
3739
{
3840
get
@@ -42,26 +44,20 @@ public int Count
4244
}
4345
public bool Remove(OptimizelyDecisionContext context)
4446
{
45-
var decisionKey = getKey(context);
46-
return ForcedDecisionsMap.Remove(decisionKey);
47+
return ForcedDecisionsMap.Remove(context.GetKey());
4748
}
4849

4950
public void RemoveAll()
5051
{
5152
ForcedDecisionsMap.Clear();
5253
}
5354

54-
private string getKey(OptimizelyDecisionContext context)
55-
{
56-
return string.Format("{0}{1}{2}", context.FlagKey, OPTI_KEY_DIVIDER, context.RuleKey ?? OPTI_NULL_RULE_KEY);
57-
}
58-
5955
public OptimizelyForcedDecision this[OptimizelyDecisionContext context]
6056
{
6157
get
6258
{
6359
if (context != null && context.FlagKey != null
64-
&& ForcedDecisionsMap.TryGetValue(getKey(context), out OptimizelyForcedDecision flagForcedDecision))
60+
&& ForcedDecisionsMap.TryGetValue(context.GetKey(), out OptimizelyForcedDecision flagForcedDecision))
6561
{
6662
return flagForcedDecision;
6763
}
@@ -71,7 +67,7 @@ public OptimizelyForcedDecision this[OptimizelyDecisionContext context]
7167
{
7268
if (context != null && context.FlagKey != null)
7369
{
74-
ForcedDecisionsMap[getKey(context)] = value;
70+
ForcedDecisionsMap[context.GetKey()] = value;
7571
}
7672
}
7773

OptimizelySDK/OptimizelyDecisionContext.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ namespace OptimizelySDK
2222
/// </summary>
2323
public class OptimizelyDecisionContext
2424
{
25+
public const string OPTI_NULL_RULE_KEY = "$opt-null-rule-key";
26+
public const string OPTI_KEY_DIVIDER = "-$opt$-";
27+
2528
private string flagKey;
2629
private string ruleKey;
30+
private string decisionKey;
2731

2832
public string FlagKey { get { return flagKey; } }
2933
public string RuleKey { get { return ruleKey; } }
@@ -34,5 +38,11 @@ public OptimizelyDecisionContext(string flagKey, string ruleKey= null)
3438
this.ruleKey = ruleKey;
3539
}
3640

41+
public string GetKey()
42+
{
43+
return string.Format("{0}{1}{2}", FlagKey, OPTI_KEY_DIVIDER, RuleKey ?? OPTI_NULL_RULE_KEY);
44+
}
45+
46+
3747
}
3848
}

OptimizelySDK/OptimizelyUserContext.cs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public OptimizelyUserContext(Optimizely optimizely, string userId, UserAttribute
5858
UserId = userId;
5959
}
6060

61-
private OptimizelyUserContext Copy() => new OptimizelyUserContext(Optimizely, UserId, GetAttributes(), ForcedDecisionsStore, ErrorHandler, Logger);
61+
private OptimizelyUserContext Copy() => new OptimizelyUserContext(Optimizely, UserId, GetAttributes(), GetForcedDecisionsStore(), ErrorHandler, Logger);
6262

6363
/// <summary>
6464
/// Returns Optimizely instance associated with the UserContext.
@@ -93,6 +93,21 @@ public UserAttributes GetAttributes()
9393
return copiedAttributes;
9494
}
9595

96+
/// <summary>
97+
/// Returns copy of ForcedDecisionsStore associated with UserContext.
98+
/// </summary>
99+
/// <returns>copy of ForcedDecisionsStore.</returns>
100+
public ForcedDecisionsStore GetForcedDecisionsStore()
101+
{
102+
ForcedDecisionsStore copiedForcedDecisionsStore = null;
103+
lock (mutex)
104+
{
105+
copiedForcedDecisionsStore = new ForcedDecisionsStore(ForcedDecisionsStore);
106+
}
107+
108+
return copiedForcedDecisionsStore;
109+
}
110+
96111
/// <summary>
97112
/// Set an attribute for a given key.
98113
/// </summary>
@@ -206,9 +221,8 @@ public virtual void TrackEvent(string eventName,
206221
/// <summary>
207222
/// Set a forced decision.
208223
/// </summary>
209-
/// <param name="flagKey">The flag key.</param>
210-
/// <param name="ruleKey">The rule key.</param>
211-
/// <param name="variationKey">The variation key.</param>
224+
/// <param name="context">The context object containing flag and rule key.</param>
225+
/// <param name="decision">OptimizelyForcedDecision object containing variation key.</param>
212226
/// <returns></returns>
213227
public bool SetForcedDecision(OptimizelyDecisionContext context, OptimizelyForcedDecision decision)
214228
{
@@ -229,8 +243,7 @@ public bool SetForcedDecision(OptimizelyDecisionContext context, OptimizelyForce
229243
/// <summary>
230244
/// Gets a forced variation
231245
/// </summary>
232-
/// <param name="flagKey">The flag key</param>
233-
/// <param name="ruleKey">The rule key</param>
246+
/// <param name="context">The context object containing flag and rule key.</param>
234247
/// <returns>The variation key for a forced decision</returns>
235248
public OptimizelyForcedDecision GetForcedDecision(OptimizelyDecisionContext context)
236249
{
@@ -278,8 +291,11 @@ public bool RemoveForcedDecision(OptimizelyDecisionContext context)
278291
Logger.Log(LogLevel.ERROR, DecisionMessage.SDK_NOT_READY);
279292
return false;
280293
}
281-
282-
return ForcedDecisionsStore.Remove(context);
294+
295+
lock (mutex)
296+
{
297+
return ForcedDecisionsStore.Remove(context);
298+
}
283299
}
284300

285301
/// <summary>

0 commit comments

Comments
 (0)