Skip to content

Commit 1ac1429

Browse files
rashidspmikeproeng37
authored andcommitted
feat(DecisionListener): Adds experiment decision listener. (#161)
1 parent e164ef3 commit 1ac1429

File tree

2 files changed

+152
-4
lines changed

2 files changed

+152
-4
lines changed

src/Optimizely/Optimizely.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,11 +406,23 @@ public function getVariation($experimentKey, $userId, $attributes = null)
406406
}
407407

408408
$variation = $this->_decisionService->getVariation($experiment, $userId, $attributes);
409-
if (is_null($variation)) {
410-
return null;
411-
}
409+
$variationKey = ($variation === null) ? null : $variation->getKey();
410+
411+
$attributes = $attributes ?: [];
412+
$this->notificationCenter->sendNotifications(
413+
NotificationType::DECISION,
414+
array(
415+
DecisionInfoTypes::EXPERIMENT,
416+
$userId,
417+
$attributes,
418+
(object) array(
419+
'experimentKey'=> $experiment->getKey(),
420+
'variationKey'=> $variationKey
421+
)
422+
)
423+
);
412424

413-
return $variation->getKey();
425+
return $variationKey;
414426
}
415427

416428
/**

tests/OptimizelyTest.php

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,72 @@ public function testActivateExperimentNotRunning()
664664
$this->assertNull($optimizelyMock->activate('paused_experiment', 'test_user', null));
665665
}
666666

667+
public function testActivateCallsDecisionListenerWhenUserInExperiment()
668+
{
669+
$userAttributes = [
670+
'device_type' => 'iPhone',
671+
'company' => 'Optimizely',
672+
'location' => 'San Francisco'
673+
];
674+
675+
$optimizelyMock = $this->getMockBuilder(Optimizely::class)
676+
->setConstructorArgs(array($this->datafile, new ValidEventDispatcher(), $this->loggerMock))
677+
->setMethods(array('sendImpressionEvent'))
678+
->getMock();
679+
680+
$arrayParam = array(
681+
DecisionInfoTypes::EXPERIMENT,
682+
'test_user',
683+
[
684+
'device_type' => 'iPhone',
685+
'company' => 'Optimizely',
686+
'location' => 'San Francisco'
687+
],
688+
(object) array(
689+
'experimentKey'=> 'test_experiment',
690+
'variationKey'=> 'control'
691+
)
692+
);
693+
$this->notificationCenterMock->expects($this->once())
694+
->method('sendNotifications')
695+
->with(
696+
NotificationType::DECISION,
697+
$arrayParam
698+
);
699+
$optimizelyMock->notificationCenter = $this->notificationCenterMock;
700+
701+
// Call activate
702+
$optimizelyMock->activate('test_experiment', 'test_user', $userAttributes);
703+
}
704+
705+
public function testActivateCallsDecisionListenerWhenUserNotInExperiment()
706+
{
707+
$optimizelyMock = $this->getMockBuilder(Optimizely::class)
708+
->setConstructorArgs(array($this->datafile, new ValidEventDispatcher(), $this->loggerMock))
709+
->setMethods(array('sendImpressionEvent'))
710+
->getMock();
711+
712+
$arrayParam = array(
713+
DecisionInfoTypes::EXPERIMENT,
714+
'test_user',
715+
[],
716+
(object) array(
717+
'experimentKey'=> 'test_experiment',
718+
'variationKey'=> null
719+
)
720+
);
721+
$this->notificationCenterMock->expects($this->once())
722+
->method('sendNotifications')
723+
->with(
724+
NotificationType::DECISION,
725+
$arrayParam
726+
);
727+
$optimizelyMock->notificationCenter = $this->notificationCenterMock;
728+
729+
// Call activate
730+
$optimizelyMock->activate('test_experiment', 'test_user');
731+
}
732+
667733
public function testGetVariationInvalidOptimizelyObject()
668734
{
669735
$optlyObject = new Optimizely('Random datafile', null, new DefaultLogger(Logger::INFO, self::OUTPUT_STREAM));
@@ -2097,6 +2163,76 @@ public function testGetVariationBucketingIdAttribute()
20972163
$this->assertNull($variationKey, sprintf('Invalid variation key "%s" for getVariation with bucketing ID "%s".', $variationKey, $this->testBucketingIdControl));
20982164
}
20992165

2166+
public function testGetVariationCallsDecisionListenerWhenUserInExperiment()
2167+
{
2168+
$userAttributes = [
2169+
'device_type' => 'iPhone',
2170+
'company' => 'Optimizely',
2171+
'location' => 'San Francisco'
2172+
];
2173+
2174+
$optimizelyMock = $this->getMockBuilder(Optimizely::class)
2175+
->setConstructorArgs(array($this->datafile, new ValidEventDispatcher(), $this->loggerMock))
2176+
->setMethods(array('sendImpressionEvent'))
2177+
->getMock();
2178+
2179+
$arrayParam = array(
2180+
DecisionInfoTypes::EXPERIMENT,
2181+
'test_user',
2182+
[
2183+
'device_type' => 'iPhone',
2184+
'company' => 'Optimizely',
2185+
'location' => 'San Francisco'
2186+
],
2187+
(object) array(
2188+
'experimentKey'=> 'test_experiment',
2189+
'variationKey'=> 'control'
2190+
)
2191+
);
2192+
$this->notificationCenterMock->expects($this->once())
2193+
->method('sendNotifications')
2194+
->with(
2195+
NotificationType::DECISION,
2196+
$arrayParam
2197+
);
2198+
$optimizelyMock->notificationCenter = $this->notificationCenterMock;
2199+
2200+
// Call getVariation
2201+
$optimizelyMock->getVariation('test_experiment', 'test_user', $userAttributes);
2202+
}
2203+
2204+
public function testGetVariationCallsDecisionListenerWhenUserNotInExperiment()
2205+
{
2206+
$userAttributes = [
2207+
'device_type' => 'android'
2208+
];
2209+
2210+
$optimizelyMock = $this->getMockBuilder(Optimizely::class)
2211+
->setConstructorArgs(array($this->datafile, new ValidEventDispatcher(), $this->loggerMock))
2212+
->setMethods(array('sendImpressionEvent'))
2213+
->getMock();
2214+
2215+
$arrayParam = array(
2216+
DecisionInfoTypes::EXPERIMENT,
2217+
'test_user',
2218+
['device_type' => 'android'],
2219+
(object) array(
2220+
'experimentKey'=> 'test_experiment',
2221+
'variationKey'=> null
2222+
)
2223+
);
2224+
$this->notificationCenterMock->expects($this->once())
2225+
->method('sendNotifications')
2226+
->with(
2227+
NotificationType::DECISION,
2228+
$arrayParam
2229+
);
2230+
$optimizelyMock->notificationCenter = $this->notificationCenterMock;
2231+
2232+
// Call getVariation
2233+
$optimizelyMock->getVariation('test_experiment', 'test_user', $userAttributes);
2234+
}
2235+
21002236
public function testIsFeatureEnabledGivenInvalidDataFile()
21012237
{
21022238
$optlyObject = new Optimizely('Random datafile', null, new DefaultLogger(Logger::INFO, self::OUTPUT_STREAM));

0 commit comments

Comments
 (0)