@@ -2199,7 +2199,6 @@ public function testIsFeatureEnabledGivenGetVariationForFeatureReturnsRolloutDec
21992199 FeatureDecision::DECISION_SOURCE_ROLLOUT
22002200 );
22012201
2202- // mock getVariationForFeature to return null
22032202 $ decisionServiceMock ->expects ($ this ->exactly (1 ))
22042203 ->method ('getVariationForFeature ' )
22052204 ->will ($ this ->returnValue ($ expectedDecision ));
@@ -3741,6 +3740,268 @@ public function testGetFeatureVariableReturnsDefaultValueForComplexAudienceMisma
37413740 $ this ->assertSame (10 , $ this ->optimizelyTypedAudienceObject ->getFeatureVariableInteger ('feat2_with_var ' , 'z ' , 'user1 ' , $ userAttributes ));
37423741 }
37433742
3743+ public function testGetFeatureVariableValueForTypeCallsDecisionListenerGivenUserInExperimentAndFeatureFlagIsEnabled ()
3744+ {
3745+ // should return specific value
3746+ $ decisionServiceMock = $ this ->getMockBuilder (DecisionService::class)
3747+ ->setConstructorArgs (array ($ this ->loggerMock , $ this ->projectConfig ))
3748+ ->setMethods (array ('getVariationForFeature ' ))
3749+ ->getMock ();
3750+ $ decisionService = new \ReflectionProperty (Optimizely::class, '_decisionService ' );
3751+ $ decisionService ->setAccessible (true );
3752+ $ decisionService ->setValue ($ this ->optimizelyObject , $ decisionServiceMock );
3753+ $ experiment = $ this ->projectConfig ->getExperimentFromKey ('test_experiment_double_feature ' );
3754+ $ expectedVariation = $ this ->projectConfig ->getVariationFromKey ('test_experiment_double_feature ' , 'control ' );
3755+ $ expectedDecision = new FeatureDecision (
3756+ $ experiment ,
3757+ $ expectedVariation ,
3758+ FeatureDecision::DECISION_SOURCE_EXPERIMENT
3759+ );
3760+
3761+ $ decisionServiceMock ->expects ($ this ->once ())
3762+ ->method ('getVariationForFeature ' )
3763+ ->will ($ this ->returnValue ($ expectedDecision ));
3764+
3765+ $ this ->assertTrue ($ expectedVariation ->getFeatureEnabled ());
3766+ $ arrayParam = array (
3767+ DecisionInfoTypes::FEATURE_VARIABLE ,
3768+ 'user_id ' ,
3769+ [],
3770+ (object ) array (
3771+ 'featureKey ' =>'double_single_variable_feature ' ,
3772+ 'featureEnabled ' => true ,
3773+ 'variableKey ' => 'double_variable ' ,
3774+ 'variableType ' => 'double ' ,
3775+ 'variableValue ' => '42.42 ' ,
3776+ 'source ' => 'EXPERIMENT ' ,
3777+ 'sourceExperimentKey ' => 'test_experiment_double_feature ' ,
3778+ 'sourceVariationKey ' => 'control '
3779+ )
3780+ );
3781+ $ this ->notificationCenterMock ->expects ($ this ->once ())
3782+ ->method ('sendNotifications ' )
3783+ ->with (
3784+ NotificationType::DECISION ,
3785+ $ arrayParam
3786+ );
3787+
3788+ $ this ->optimizelyObject ->notificationCenter = $ this ->notificationCenterMock ;
3789+
3790+ $ this ->optimizelyObject ->getFeatureVariableValueForType ('double_single_variable_feature ' , 'double_variable ' , 'user_id ' , [], 'double ' );
3791+ }
3792+
3793+ public function testGetFeatureVariableValueForTypeCallsDecisionListenerGivenUserInExperimentAndFeatureFlagIsNotEnabled ()
3794+ {
3795+ $ userAttributes = [
3796+ 'device_type ' => 'iPhone '
3797+ ];
3798+
3799+ // should return specific value
3800+ $ decisionServiceMock = $ this ->getMockBuilder (DecisionService::class)
3801+ ->setConstructorArgs (array ($ this ->loggerMock , $ this ->projectConfig ))
3802+ ->setMethods (array ('getVariationForFeature ' ))
3803+ ->getMock ();
3804+ $ decisionService = new \ReflectionProperty (Optimizely::class, '_decisionService ' );
3805+ $ decisionService ->setAccessible (true );
3806+ $ decisionService ->setValue ($ this ->optimizelyObject , $ decisionServiceMock );
3807+ $ experiment = $ this ->projectConfig ->getExperimentFromKey ('test_experiment_double_feature ' );
3808+ $ expectedVariation = $ this ->projectConfig ->getVariationFromKey ('test_experiment_double_feature ' , 'control ' );
3809+ $ expectedVariation ->setFeatureEnabled (false );
3810+ $ expectedDecision = new FeatureDecision (
3811+ $ experiment ,
3812+ $ expectedVariation ,
3813+ FeatureDecision::DECISION_SOURCE_EXPERIMENT
3814+ );
3815+
3816+ $ decisionServiceMock ->expects ($ this ->once ())
3817+ ->method ('getVariationForFeature ' )
3818+ ->will ($ this ->returnValue ($ expectedDecision ));
3819+
3820+ // assert variation's 'featureEnabled' is set to false
3821+ $ this ->assertFalse ($ expectedVariation ->getFeatureEnabled ());
3822+
3823+ $ arrayParam = array (
3824+ DecisionInfoTypes::FEATURE_VARIABLE ,
3825+ 'user_id ' ,
3826+ $ userAttributes ,
3827+ (object ) array (
3828+ 'featureKey ' =>'double_single_variable_feature ' ,
3829+ 'featureEnabled ' => false ,
3830+ 'variableKey ' => 'double_variable ' ,
3831+ 'variableType ' => 'double ' ,
3832+ 'variableValue ' => '14.99 ' ,
3833+ 'source ' => 'EXPERIMENT ' ,
3834+ 'sourceExperimentKey ' => 'test_experiment_double_feature ' ,
3835+ 'sourceVariationKey ' => 'control '
3836+ )
3837+ );
3838+ $ this ->notificationCenterMock ->expects ($ this ->once ())
3839+ ->method ('sendNotifications ' )
3840+ ->with (
3841+ NotificationType::DECISION ,
3842+ $ arrayParam
3843+ );
3844+
3845+ $ this ->optimizelyObject ->notificationCenter = $ this ->notificationCenterMock ;
3846+
3847+ $ this ->optimizelyObject ->getFeatureVariableValueForType ('double_single_variable_feature ' , 'double_variable ' , 'user_id ' , $ userAttributes , 'double ' );
3848+ }
3849+
3850+ public function testGetFeatureVariableValueCallsDecisionListenerGivenUserInRolloutAndFeatureFlagIsEnabled ()
3851+ {
3852+ // should return specific value
3853+ $ decisionServiceMock = $ this ->getMockBuilder (DecisionService::class)
3854+ ->setConstructorArgs (array ($ this ->loggerMock , $ this ->projectConfig ))
3855+ ->setMethods (array ('getVariationForFeature ' ))
3856+ ->getMock ();
3857+ $ decisionService = new \ReflectionProperty (Optimizely::class, '_decisionService ' );
3858+ $ decisionService ->setAccessible (true );
3859+ $ decisionService ->setValue ($ this ->optimizelyObject , $ decisionServiceMock );
3860+ $ featureFlag = $ this ->projectConfig ->getFeatureFlagFromKey ('boolean_single_variable_feature ' );
3861+ $ rolloutId = $ featureFlag ->getRolloutId ();
3862+ $ rollout = $ this ->projectConfig ->getRolloutFromId ($ rolloutId );
3863+ $ experiment = $ rollout ->getExperiments ()[0 ];
3864+ $ expectedVariation = $ experiment ->getVariations ()[0 ];
3865+ $ expectedDecision = new FeatureDecision (
3866+ $ experiment ,
3867+ $ expectedVariation ,
3868+ FeatureDecision::DECISION_SOURCE_ROLLOUT
3869+ );
3870+ $ decisionServiceMock ->expects ($ this ->once ())
3871+ ->method ('getVariationForFeature ' )
3872+ ->will ($ this ->returnValue ($ expectedDecision ));
3873+
3874+ $ this ->assertTrue ($ expectedVariation ->getFeatureEnabled ());
3875+
3876+ $ arrayParam = array (
3877+ DecisionInfoTypes::FEATURE_VARIABLE ,
3878+ 'user_id ' ,
3879+ [],
3880+ (object ) array (
3881+ 'featureKey ' =>'boolean_single_variable_feature ' ,
3882+ 'featureEnabled ' => true ,
3883+ 'variableKey ' => 'boolean_variable ' ,
3884+ 'variableType ' => 'boolean ' ,
3885+ 'variableValue ' => 'true ' ,
3886+ 'source ' => 'ROLLOUT ' ,
3887+ 'sourceExperimentKey ' => null ,
3888+ 'sourceVariationKey ' => null
3889+ )
3890+ );
3891+ $ this ->notificationCenterMock ->expects ($ this ->once ())
3892+ ->method ('sendNotifications ' )
3893+ ->with (
3894+ NotificationType::DECISION ,
3895+ $ arrayParam
3896+ );
3897+
3898+ $ this ->optimizelyObject ->notificationCenter = $ this ->notificationCenterMock ;
3899+
3900+ $ this ->optimizelyObject ->getFeatureVariableBoolean ('boolean_single_variable_feature ' , 'boolean_variable ' , 'user_id ' , []);
3901+ }
3902+
3903+ public function testGetFeatureVariableValueCallsDecisionListenerGivenUserInRolloutAndFeatureFlagIsNotEnabled ()
3904+ {
3905+ // should return specific value
3906+ $ decisionServiceMock = $ this ->getMockBuilder (DecisionService::class)
3907+ ->setConstructorArgs (array ($ this ->loggerMock , $ this ->projectConfig ))
3908+ ->setMethods (array ('getVariationForFeature ' ))
3909+ ->getMock ();
3910+ $ decisionService = new \ReflectionProperty (Optimizely::class, '_decisionService ' );
3911+ $ decisionService ->setAccessible (true );
3912+ $ decisionService ->setValue ($ this ->optimizelyObject , $ decisionServiceMock );
3913+ $ featureFlag = $ this ->projectConfig ->getFeatureFlagFromKey ('boolean_single_variable_feature ' );
3914+ $ rolloutId = $ featureFlag ->getRolloutId ();
3915+ $ rollout = $ this ->projectConfig ->getRolloutFromId ($ rolloutId );
3916+ $ experiment = $ rollout ->getExperiments ()[0 ];
3917+ $ expectedVariation = $ experiment ->getVariations ()[0 ];
3918+ $ expectedVariation ->setFeatureEnabled (false );
3919+ $ expectedDecision = new FeatureDecision (
3920+ $ experiment ,
3921+ $ expectedVariation ,
3922+ FeatureDecision::DECISION_SOURCE_ROLLOUT
3923+ );
3924+ $ decisionServiceMock ->expects ($ this ->once ())
3925+ ->method ('getVariationForFeature ' )
3926+ ->will ($ this ->returnValue ($ expectedDecision ));
3927+
3928+ $ this ->assertFalse ($ expectedVariation ->getFeatureEnabled ());
3929+
3930+ $ arrayParam = array (
3931+ DecisionInfoTypes::FEATURE_VARIABLE ,
3932+ 'user_id ' ,
3933+ [],
3934+ (object ) array (
3935+ 'featureKey ' =>'boolean_single_variable_feature ' ,
3936+ 'featureEnabled ' => false ,
3937+ 'variableKey ' => 'boolean_variable ' ,
3938+ 'variableType ' => 'boolean ' ,
3939+ 'variableValue ' => 'true ' ,
3940+ 'source ' => 'ROLLOUT ' ,
3941+ 'sourceExperimentKey ' => null ,
3942+ 'sourceVariationKey ' => null
3943+ )
3944+ );
3945+ $ this ->notificationCenterMock ->expects ($ this ->once ())
3946+ ->method ('sendNotifications ' )
3947+ ->with (
3948+ NotificationType::DECISION ,
3949+ $ arrayParam
3950+ );
3951+
3952+ $ this ->optimizelyObject ->notificationCenter = $ this ->notificationCenterMock ;
3953+
3954+ $ this ->optimizelyObject ->getFeatureVariableBoolean ('boolean_single_variable_feature ' , 'boolean_variable ' , 'user_id ' , []);
3955+ }
3956+
3957+ public function testGetFeatureVariableValueForTypeCallsDecisionListenerWhenUserNeitherInExperimentNorInRollout ()
3958+ {
3959+ // should return default value
3960+ $ decisionServiceMock = $ this ->getMockBuilder (DecisionService::class)
3961+ ->setConstructorArgs (array ($ this ->loggerMock , $ this ->projectConfig ))
3962+ ->setMethods (array ('getVariationForFeature ' ))
3963+ ->getMock ();
3964+ $ decisionService = new \ReflectionProperty (Optimizely::class, '_decisionService ' );
3965+ $ decisionService ->setAccessible (true );
3966+ $ decisionService ->setValue ($ this ->optimizelyObject , $ decisionServiceMock );
3967+
3968+ // mock getVariationForFeature to return rolloutDecision
3969+ $ expectedDecision = new FeatureDecision (
3970+ null ,
3971+ null ,
3972+ FeatureDecision::DECISION_SOURCE_ROLLOUT
3973+ );
3974+ $ decisionServiceMock ->expects ($ this ->exactly (1 ))
3975+ ->method ('getVariationForFeature ' )
3976+ ->will ($ this ->returnValue ($ expectedDecision ));
3977+
3978+ $ arrayParam = array (
3979+ DecisionInfoTypes::FEATURE_VARIABLE ,
3980+ 'user_id ' ,
3981+ [],
3982+ (object ) array (
3983+ 'featureKey ' =>'double_single_variable_feature ' ,
3984+ 'featureEnabled ' => false ,
3985+ 'variableKey ' => 'double_variable ' ,
3986+ 'variableType ' => 'double ' ,
3987+ 'variableValue ' => '14.99 ' ,
3988+ 'source ' => 'ROLLOUT ' ,
3989+ 'sourceExperimentKey ' => null ,
3990+ 'sourceVariationKey ' => null
3991+ )
3992+ );
3993+ $ this ->notificationCenterMock ->expects ($ this ->once ())
3994+ ->method ('sendNotifications ' )
3995+ ->with (
3996+ NotificationType::DECISION ,
3997+ $ arrayParam
3998+ );
3999+
4000+ $ this ->optimizelyObject ->notificationCenter = $ this ->notificationCenterMock ;
4001+
4002+ $ this ->optimizelyObject ->getFeatureVariableValueForType ('double_single_variable_feature ' , 'double_variable ' , 'user_id ' , [], 'double ' );
4003+ }
4004+
37444005 public function testSendImpressionEventWithNoAttributes ()
37454006 {
37464007 $ optlyObject = new OptimizelyTester ($ this ->datafile , new ValidEventDispatcher (), $ this ->loggerMock );
0 commit comments