Skip to content

Commit 48a10f8

Browse files
authored
Fix impression sent from feature experiment variation toggled off. (#84)
1 parent 8d7011f commit 48a10f8

File tree

2 files changed

+47
-18
lines changed

2 files changed

+47
-18
lines changed

OptimizelySDK.Tests/OptimizelyTest.cs

+33-4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public class OptimizelyTest
3838
private ProjectConfig Config;
3939
private Mock<EventBuilder> EventBuilderMock;
4040
private Mock<IErrorHandler> ErrorHandlerMock;
41+
private Mock<IEventDispatcher> EventDispatcherMock;
4142
private Optimizely Optimizely;
4243
private IEventDispatcher EventDispatcher;
4344
private const string TestUserId = "testUserId";
@@ -73,19 +74,19 @@ public void Initialize()
7374
logger: LoggerMock.Object,
7475
errorHandler: new NoOpErrorHandler());
7576

76-
EventDispatcher = new ValidEventDispatcher();
77-
Optimizely = new Optimizely(TestData.Datafile, EventDispatcher, LoggerMock.Object, ErrorHandlerMock.Object);
77+
EventDispatcherMock = new Mock<IEventDispatcher>();
78+
Optimizely = new Optimizely(TestData.Datafile, EventDispatcherMock.Object, LoggerMock.Object, ErrorHandlerMock.Object);
7879

7980
Helper = new OptimizelyHelper
8081
{
8182
Datafile = TestData.Datafile,
82-
EventDispatcher = EventDispatcher,
83+
EventDispatcher = EventDispatcherMock.Object,
8384
Logger = LoggerMock.Object,
8485
ErrorHandler = ErrorHandlerMock.Object,
8586
SkipJsonValidation = false,
8687
};
8788

88-
OptimizelyMock = new Mock<Optimizely>(TestData.Datafile, EventDispatcher, LoggerMock.Object, ErrorHandlerMock.Object, null, false)
89+
OptimizelyMock = new Mock<Optimizely>(TestData.Datafile, EventDispatcherMock.Object, LoggerMock.Object, ErrorHandlerMock.Object, null, false)
8990
{
9091
CallBase = true
9192
};
@@ -1539,6 +1540,34 @@ public void TestIsFeatureEnabledGivenFeatureFlagIsEnabledAndUserIsBeingExperimen
15391540
$@"Feature flag ""{featureKey}"" is enabled for user ""{TestUserId}""."));
15401541
}
15411542

1543+
// Should return false and send an impression event when feature is enabled for the user
1544+
// and user is being experimented.
1545+
[Test]
1546+
public void TestIsFeatureEnabledGivenFeatureFlagIsNotEnabledAndUserIsBeingExperimented()
1547+
{
1548+
var featureKey = "double_single_variable_feature";
1549+
var experiment = Config.GetExperimentFromKey("test_experiment_double_feature");
1550+
var variation = Config.GetVariationFromKey("test_experiment_double_feature", "variation");
1551+
var featureFlag = Config.GetFeatureFlagFromKey(featureKey);
1552+
var decision = new FeatureDecision(experiment, variation, FeatureDecision.DECISION_SOURCE_EXPERIMENT);
1553+
1554+
DecisionServiceMock.Setup(ds => ds.GetVariationForFeature(featureFlag, TestUserId, null)).Returns(decision);
1555+
1556+
var optly = Helper.CreatePrivateOptimizely();
1557+
optly.SetFieldOrProperty("DecisionService", DecisionServiceMock.Object);
1558+
1559+
bool result = (bool)optly.Invoke("IsFeatureEnabled", featureKey, TestUserId, null);
1560+
Assert.False(result);
1561+
1562+
// SendImpressionEvent() gets called.
1563+
LoggerMock.Verify(l => l.Log(LogLevel.INFO,
1564+
$@"The user ""{TestUserId}"" is not being experimented on feature ""{featureKey}""."), Times.Never);
1565+
1566+
LoggerMock.Verify(l => l.Log(LogLevel.INFO,
1567+
$@"Feature flag ""{featureKey}"" is not enabled for user ""{TestUserId}""."));
1568+
EventDispatcherMock.Verify(dispatcher => dispatcher.DispatchEvent(It.IsAny<LogEvent>()));
1569+
}
1570+
15421571
// Verify that IsFeatureEnabled returns true if a variation does not get found in the feature
15431572
// flag experiment but found in the rollout rule.
15441573
[Test]

OptimizelySDK/Optimizely.cs

+14-14
Original file line numberDiff line numberDiff line change
@@ -366,14 +366,12 @@ public Variation GetForcedVariation(string experimentKey, string userId)
366366
/// <returns>True if feature is enabled, false or null otherwise</returns>
367367
public virtual bool IsFeatureEnabled(string featureKey, string userId, UserAttributes userAttributes = null)
368368
{
369-
if (string.IsNullOrEmpty(userId))
370-
{
369+
if (string.IsNullOrEmpty(userId)) {
371370
Logger.Log(LogLevel.ERROR, "User ID must not be empty.");
372371
return false;
373372
}
374373

375-
if (string.IsNullOrEmpty(featureKey))
376-
{
374+
if (string.IsNullOrEmpty(featureKey)) {
377375
Logger.Log(LogLevel.ERROR, "Feature flag key must not be empty.");
378376
return false;
379377
}
@@ -386,19 +384,21 @@ public virtual bool IsFeatureEnabled(string featureKey, string userId, UserAttri
386384
return false;
387385

388386
var decision = DecisionService.GetVariationForFeature(featureFlag, userId, userAttributes);
389-
if (decision == null || !decision.Variation.IsFeatureEnabled)
390-
{
391-
Logger.Log(LogLevel.INFO, $@"Feature flag ""{featureKey}"" is not enabled for user ""{userId}"".");
392-
return false;
387+
if (decision != null) {
388+
if (decision.Source == FeatureDecision.DECISION_SOURCE_EXPERIMENT) {
389+
SendImpressionEvent(decision.Experiment, decision.Variation, userId, userAttributes);
390+
} else {
391+
Logger.Log(LogLevel.INFO, $@"The user ""{userId}"" is not being experimented on feature ""{featureKey}"".");
392+
}
393+
if (decision.Variation.IsFeatureEnabled) {
394+
Logger.Log(LogLevel.INFO, $@"Feature flag ""{featureKey}"" is enabled for user ""{userId}"".");
395+
return true;
396+
}
393397
}
394398

395-
if (decision.Source == FeatureDecision.DECISION_SOURCE_EXPERIMENT)
396-
SendImpressionEvent(decision.Experiment, decision.Variation, userId, userAttributes);
397-
else
398-
Logger.Log(LogLevel.INFO, $@"The user ""{userId}"" is not being experimented on feature ""{featureKey}"".");
399399

400-
Logger.Log(LogLevel.INFO, $@"Feature flag ""{featureKey}"" is enabled for user ""{userId}"".");
401-
return true;
400+
Logger.Log(LogLevel.INFO, $@"Feature flag ""{featureKey}"" is not enabled for user ""{userId}"".");
401+
return false;
402402
}
403403

404404
/// <summary>

0 commit comments

Comments
 (0)