Skip to content

Commit

Permalink
feat: added "enabled" field to decision metadata structure (#217)
Browse files Browse the repository at this point in the history
  • Loading branch information
zashraf1985 committed Nov 14, 2020
1 parent 04f5300 commit 878fc64
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 27 deletions.
9 changes: 5 additions & 4 deletions src/Optimizely/Event/Builder/EventBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private function getCommonParams($config, $userId, $attributes)
*
* @return array Hash representing parameters particular to impression event.
*/
private function getImpressionParams(Experiment $experiment, $variation, $flagKey, $ruleKey, $ruleType)
private function getImpressionParams(Experiment $experiment, $variation, $flagKey, $ruleKey, $ruleType, $enabled)
{
$variationKey = $variation->getKey() ? $variation->getKey() : '';
$impressionParams = [
Expand All @@ -156,7 +156,8 @@ private function getImpressionParams(Experiment $experiment, $variation, $flagKe
FLAG_KEY => $flagKey,
RULE_KEY => $ruleKey,
RULE_TYPE => $ruleType,
VARIATION_KEY => $variationKey
VARIATION_KEY => $variationKey,
ENABLED => $enabled
],
]
],
Expand Down Expand Up @@ -228,13 +229,13 @@ private function getConversionParams($eventEntity, $eventTags)
*
* @return LogEvent Event object to be sent to dispatcher.
*/
public function createImpressionEvent($config, $experimentKey, $variationKey, $flagKey, $ruleKey, $ruleType, $userId, $attributes)
public function createImpressionEvent($config, $experimentKey, $variationKey, $flagKey, $ruleKey, $ruleType, $enabled, $userId, $attributes)
{
$eventParams = $this->getCommonParams($config, $userId, $attributes);

$experiment = $config->getExperimentFromKey($experimentKey);
$variation = $config->getVariationFromKey($experimentKey, $variationKey);
$impressionParams = $this->getImpressionParams($experiment, $variation, $flagKey, $ruleKey, $ruleType);
$impressionParams = $this->getImpressionParams($experiment, $variation, $flagKey, $ruleKey, $ruleType, $enabled);

$eventParams[VISITORS][0][SNAPSHOTS][] = $impressionParams;

Expand Down
1 change: 1 addition & 0 deletions src/Optimizely/Event/Builder/Params.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,4 @@
define('RULE_KEY', 'rule_key');
define('RULE_TYPE', 'rule_type');
define('VARIATION_KEY', 'variation_key');
define('ENABLED', 'enabled');
13 changes: 8 additions & 5 deletions src/Optimizely/Optimizely.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,10 @@ private function validateUserInputs($attributes, $eventTags = null)
* @param array Associative array of user attributes
* @param DatafileProjectConfig DatafileProjectConfig instance
*/
protected function sendImpressionEvent($config, $experimentKey, $variationKey, $flagKey, $ruleKey, $ruleType, $userId, $attributes)
protected function sendImpressionEvent($config, $experimentKey, $variationKey, $flagKey, $ruleKey, $ruleType, $enabled, $userId, $attributes)
{
$impressionEvent = $this->_eventBuilder
->createImpressionEvent($config, $experimentKey, $variationKey, $flagKey, $ruleKey, $ruleType, $userId, $attributes);
->createImpressionEvent($config, $experimentKey, $variationKey, $flagKey, $ruleKey, $ruleType, $enabled, $userId, $attributes);
$this->_logger->log(Logger::INFO, sprintf('Activating user "%s" in experiment "%s".', $userId, $experimentKey));
$this->_logger->log(
Logger::DEBUG,
Expand Down Expand Up @@ -274,7 +274,7 @@ public function activate($experimentKey, $userId, $attributes = null)
return null;
}

$this->sendImpressionEvent($config, $experimentKey, $variationKey, '', $experimentKey, FeatureDecision::DECITION_SOURCE_EXPERIMENT, $userId, $attributes);
$this->sendImpressionEvent($config, $experimentKey, $variationKey, '', $experimentKey, FeatureDecision::DECITION_SOURCE_EXPERIMENT, true, $userId, $attributes);

return $variationKey;
}
Expand Down Expand Up @@ -556,8 +556,11 @@ public function isFeatureEnabled($featureFlagKey, $userId, $attributes = null)
$variation = $decision->getVariation();

if ($config->getSendFlagDecisions() && ($decision->getSource() == FeatureDecision::DECISION_SOURCE_ROLLOUT || !$variation)) {
if ($variation) {
$featureEnabled = $variation->getFeatureEnabled();
}
$ruleKey = $decision->getExperiment() ? $decision->getExperiment()->getKey() : '';
$this->sendImpressionEvent($config, $ruleKey, $variation ? $variation->getKey() : '', $featureFlagKey, $ruleKey, $decision->getSource(), $userId, $attributes);
$this->sendImpressionEvent($config, $ruleKey, $variation ? $variation->getKey() : '', $featureFlagKey, $ruleKey, $decision->getSource(), $featureEnabled, $userId, $attributes);
}

if ($variation) {
Expand All @@ -569,7 +572,7 @@ public function isFeatureEnabled($featureFlagKey, $userId, $attributes = null)
'variationKey'=> $variation->getKey()
);

$this->sendImpressionEvent($config, $experimentKey, $variation->getKey(), $featureFlagKey, $experimentKey, $decision->getSource(), $userId, $attributes);
$this->sendImpressionEvent($config, $experimentKey, $variation->getKey(), $featureFlagKey, $experimentKey, $decision->getSource(), $featureEnabled, $userId, $attributes);
} else {
$this->_logger->log(Logger::INFO, "The user '{$userId}' is not being experimented on Feature Flag '{$featureFlagKey}'.");
}
Expand Down
13 changes: 12 additions & 1 deletion tests/EventTests/EventBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ public function setUp()
'flag_key' => 'test_experiment',
'rule_key' => 'test_experiment',
'rule_type' => 'experiment',
'variation_key'=> 'variation'
'variation_key'=> 'variation',
'enabled' => true
]
]]
);
Expand Down Expand Up @@ -146,6 +147,7 @@ public function testCreateImpressionEventNoAttributesNoValue()
'test_experiment',
'test_experiment',
'experiment',
true,
$this->testUserId,
null
);
Expand Down Expand Up @@ -205,6 +207,7 @@ public function testCreateImpressionEventWithAttributesNoValue()
'test_experiment',
'test_experiment',
'experiment',
true,
$this->testUserId,
$userAttributes
);
Expand Down Expand Up @@ -245,6 +248,7 @@ public function testCreateImpressionEventWithFalseAttributesNoValue()
'test_experiment',
'test_experiment',
'experiment',
true,
$this->testUserId,
$userAttributes
);
Expand Down Expand Up @@ -286,6 +290,7 @@ public function testCreateImpressionEventWithZeroAttributesNoValue()
'test_experiment',
'test_experiment',
'experiment',
true,
$this->testUserId,
$userAttributes
);
Expand Down Expand Up @@ -317,6 +322,7 @@ public function testCreateImpressionEventWithInvalidAttributesNoValue()
'test_experiment',
'test_experiment',
'experiment',
true,
$this->testUserId,
$userAttributes
);
Expand Down Expand Up @@ -357,6 +363,7 @@ public function testCreateImpressionEventWithUserAgentWhenBotFilteringIsEnabled(
'test_experiment',
'test_experiment',
'experiment',
true,
$this->testUserId,
$userAttributes
);
Expand Down Expand Up @@ -404,6 +411,7 @@ public function testCreateImpressionEventWithInvalidAttributeTypes()
'test_experiment',
'test_experiment',
'experiment',
true,
$this->testUserId,
$userAttributes
);
Expand Down Expand Up @@ -454,6 +462,7 @@ public function testCreateImpressionEventWithUserAgentWhenBotFilteringIsDisabled
'test_experiment',
'test_experiment',
'experiment',
true,
$this->testUserId,
$userAttributes
);
Expand Down Expand Up @@ -500,6 +509,7 @@ public function testCreateImpressionEventWithUserAgentWhenBotFilteringIsNull()
'test_experiment',
'test_experiment',
'experiment',
true,
$this->testUserId,
$userAttributes
);
Expand Down Expand Up @@ -829,6 +839,7 @@ public function testCreateImpressionEventWithBucketingIDAttribute()
'test_experiment',
'test_experiment',
'experiment',
true,
$this->testUserId,
$userAttributes
);
Expand Down
32 changes: 17 additions & 15 deletions tests/OptimizelyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ public function testActivateWithEmptyUserID()
// Verify that sendImpressionEvent is called with expected attributes
$optimizelyMock->expects($this->exactly(1))
->method('sendImpressionEvent')
->with($this->projectConfig, 'test_experiment', 'variation', '', 'test_experiment', 'experiment', '', $userAttributes);
->with($this->projectConfig, 'test_experiment', 'variation', '', 'test_experiment', 'experiment', true, '', $userAttributes);

// Call activate
$this->assertEquals('variation', $optimizelyMock->activate('test_experiment', '', $userAttributes));
Expand Down Expand Up @@ -487,7 +487,7 @@ public function testActivateNoAudienceNoAttributes()
// Verify that sendImpression is called with expected params
$optimizelyMock->expects($this->exactly(1))
->method('sendImpressionEvent')
->with($this->projectConfig, 'group_experiment_1', 'group_exp_1_var_2', '', 'group_experiment_1', 'experiment', 'user_1', null);
->with($this->projectConfig, 'group_experiment_1', 'group_exp_1_var_2', '', 'group_experiment_1', 'experiment', true, 'user_1', null);

// Call activate
$this->assertSame('group_exp_1_var_2', $optimizelyMock->activate('group_experiment_1', 'user_1'));
Expand Down Expand Up @@ -520,7 +520,7 @@ public function testActivateNoAudienceNoAttributesAfterSetForcedVariation()
// Verify that sendImpression is called with expected params
$optimizelyMock->expects($this->exactly(1))
->method('sendImpressionEvent')
->with($this->projectConfig, 'group_experiment_1', 'group_exp_1_var_2', '', 'group_experiment_1', 'experiment', 'user_1', null);
->with($this->projectConfig, 'group_experiment_1', 'group_exp_1_var_2', '', 'group_experiment_1', 'experiment', true, 'user_1', null);

// set forced variation
$this->assertTrue($optimizelyMock->setForcedVariation($experimentKey, $userId, $variationKey), 'Set variation for paused experiment should have failed.');
Expand Down Expand Up @@ -581,7 +581,7 @@ public function testActivateWithAttributes()
// Verify that sendImpressionEvent is called with expected attributes
$optimizelyMock->expects($this->exactly(1))
->method('sendImpressionEvent')
->with($this->projectConfig, 'test_experiment', 'control', '', 'test_experiment', 'experiment', 'test_user', $userAttributes);
->with($this->projectConfig, 'test_experiment', 'control', '', 'test_experiment', 'experiment', true, 'test_user', $userAttributes);

// Call activate
$this->assertEquals('control', $optimizelyMock->activate('test_experiment', 'test_user', $userAttributes));
Expand Down Expand Up @@ -614,7 +614,7 @@ public function testActivateWithAttributesOfDifferentTypes()
// Verify that sendImpressionEvent is called with expected attributes
$optimizelyMock->expects($this->exactly(1))
->method('sendImpressionEvent')
->with($this->projectConfig, 'test_experiment', 'control', '', 'test_experiment', 'experiment', 'test_user', $userAttributes);
->with($this->projectConfig, 'test_experiment', 'control', '', 'test_experiment', 'experiment', true, 'test_user', $userAttributes);

// Call activate
$this->assertEquals('control', $optimizelyMock->activate('test_experiment', 'test_user', $userAttributes));
Expand All @@ -639,7 +639,7 @@ public function testActivateWithAttributesTypedAudienceMatch()
// Verify that sendImpressionEvent is called with expected attributes
$optimizelyMock->expects($this->at(0))
->method('sendImpressionEvent')
->with($this->projectConfigForTypedAudience, 'typed_audience_experiment', 'A', '', 'typed_audience_experiment', 'experiment', 'test_user', $userAttributes);
->with($this->projectConfigForTypedAudience, 'typed_audience_experiment', 'A', '', 'typed_audience_experiment', 'experiment', true, 'test_user', $userAttributes);

// Should be included via exact match string audience with id '3468206642'
$this->assertEquals('A', $optimizelyMock->activate('typed_audience_experiment', 'test_user', $userAttributes));
Expand All @@ -651,7 +651,7 @@ public function testActivateWithAttributesTypedAudienceMatch()
// Verify that sendImpressionEvent is called with expected attributes
$optimizelyMock->expects($this->at(0))
->method('sendImpressionEvent')
->with($this->projectConfigForTypedAudience, 'typed_audience_experiment', 'A', '', 'typed_audience_experiment', 'experiment', 'test_user', $userAttributes);
->with($this->projectConfigForTypedAudience, 'typed_audience_experiment', 'A', '', 'typed_audience_experiment', 'experiment', true, 'test_user', $userAttributes);

//Should be included via exact match number audience with id '3468206646'
$this->assertEquals('A', $optimizelyMock->activate('typed_audience_experiment', 'test_user', $userAttributes));
Expand Down Expand Up @@ -691,7 +691,7 @@ public function testActivateWithAttributesComplexAudienceMatch()
// Verify that sendImpressionEvent is called once with expected attributes
$optimizelyMock->expects($this->exactly(1))
->method('sendImpressionEvent')
->with($this->projectConfigForTypedAudience, 'audience_combinations_experiment', 'A', '', 'audience_combinations_experiment', 'experiment', 'test_user', $userAttributes);
->with($this->projectConfigForTypedAudience, 'audience_combinations_experiment', 'A', '', 'audience_combinations_experiment', 'experiment', true, 'test_user', $userAttributes);

// Should be included via substring match string audience with id '3988293898', and
// exact match number audience with id '3468206646'
Expand Down Expand Up @@ -2554,7 +2554,7 @@ public function testIsFeatureEnabledGivenFeatureExperimentAndFeatureEnabledIsTru
// assert that sendImpressionEvent is called with expected params
$optimizelyMock->expects($this->exactly(1))
->method('sendImpressionEvent')
->with($this->projectConfig, 'test_experiment_double_feature', 'control', 'double_single_variable_feature', 'test_experiment_double_feature', FeatureDecision::DECISION_SOURCE_FEATURE_TEST, 'user_id', []);
->with($this->projectConfig, 'test_experiment_double_feature', 'control', 'double_single_variable_feature', 'test_experiment_double_feature', FeatureDecision::DECISION_SOURCE_FEATURE_TEST, true, 'user_id', []);

$this->loggerMock->expects($this->at(0))
->method('log')
Expand Down Expand Up @@ -2659,7 +2659,7 @@ public function testIsFeatureEnabledGivenFeatureExperimentAndFeatureEnabledIsFal

$optimizelyMock->expects($this->exactly(1))
->method('sendImpressionEvent')
->with($this->projectConfig, 'test_experiment_double_feature', 'variation', 'double_single_variable_feature', 'test_experiment_double_feature', FeatureDecision::DECISION_SOURCE_FEATURE_TEST, 'user_id', []);
->with($this->projectConfig, 'test_experiment_double_feature', 'variation', 'double_single_variable_feature', 'test_experiment_double_feature', FeatureDecision::DECISION_SOURCE_FEATURE_TEST, false, 'user_id', []);

$this->loggerMock->expects($this->at(0))
->method('log')
Expand Down Expand Up @@ -3042,7 +3042,7 @@ public function testIsFeatureEnabledWithEmptyUserID()
// assert that sendImpressionEvent is called with expected params
$optimizelyMock->expects($this->exactly(1))
->method('sendImpressionEvent')
->with($this->projectConfig, 'test_experiment_double_feature', 'control', 'double_single_variable_feature', 'test_experiment_double_feature', FeatureDecision::DECISION_SOURCE_FEATURE_TEST, '', []);
->with($this->projectConfig, 'test_experiment_double_feature', 'control', 'double_single_variable_feature', 'test_experiment_double_feature', FeatureDecision::DECISION_SOURCE_FEATURE_TEST, true, '', []);

$this->loggerMock->expects($this->at(0))
->method('log')
Expand Down Expand Up @@ -4682,6 +4682,7 @@ public function testSendImpressionEventWithNoAttributes()
'group_experiment_1',
'group_experiment_1',
'experiment',
true,
'user_1',
null
)
Expand Down Expand Up @@ -4734,7 +4735,7 @@ public function testSendImpressionEventWithNoAttributes()
'Dispatching impression event to URL logx.optimizely.com/decision with params {"param1":"val1","param2":"val2"}.'
);

$optlyObject->sendImpressionEvent($this->projectConfig, 'group_experiment_1', 'group_exp_1_var_2', 'group_experiment_1', 'group_experiment_1', 'experiment', 'user_1', null);
$optlyObject->sendImpressionEvent($this->projectConfig, 'group_experiment_1', 'group_exp_1_var_2', 'group_experiment_1', 'group_experiment_1', 'experiment', true, 'user_1', null);
}

public function testSendImpressionEventDispatchFailure()
Expand All @@ -4757,7 +4758,7 @@ public function testSendImpressionEventDispatchFailure()
->method('log')
->with(Logger::ERROR, 'Unable to dispatch impression event. Error ');

$optlyObject->sendImpressionEvent($this->projectConfig, 'test_experiment', 'control', 'test_experiment', 'test_experiment', 'experiment', 'test_user', []);
$optlyObject->sendImpressionEvent($this->projectConfig, 'test_experiment', 'control', 'test_experiment', 'test_experiment', 'experiment', true, 'test_user', []);
}

public function testSendImpressionEventWithAttributes()
Expand All @@ -4780,6 +4781,7 @@ public function testSendImpressionEventWithAttributes()
'test_experiment',
'test_experiment',
'experiment',
true,
'test_user',
$userAttributes
)
Expand Down Expand Up @@ -4822,7 +4824,7 @@ public function testSendImpressionEventWithAttributes()

$optlyObject->notificationCenter = $this->notificationCenterMock;

$optlyObject->sendImpressionEvent($this->projectConfig, 'test_experiment', 'control', 'test_experiment', 'test_experiment', 'experiment', 'test_user', $userAttributes);
$optlyObject->sendImpressionEvent($this->projectConfig, 'test_experiment', 'control', 'test_experiment', 'test_experiment', 'experiment', true, 'test_user', $userAttributes);
}

/*
Expand Down Expand Up @@ -4998,7 +5000,7 @@ public function testRolloutSendImpressionWhenSendFlagDecisionFlagInDatafile()
// Verify that sendImpressionEvent is called with expected attributes
$optimizelyMock->expects($this->exactly(1))
->method('sendImpressionEvent')
->with($this->anything(), 'rollout_1_exp_1', '177771', 'boolean_single_variable_feature', 'rollout_1_exp_1', 'rollout', 'user_id', []);
->with($this->anything(), 'rollout_1_exp_1', '177771', 'boolean_single_variable_feature', 'rollout_1_exp_1', 'rollout', true, 'user_id', []);

$this->assertTrue($optimizelyMock->isFeatureEnabled('boolean_single_variable_feature', 'user_id', []));
}
Expand Down
Loading

0 comments on commit 878fc64

Please sign in to comment.