From 38f9db1e6c3faf940d55e411beba6c499d22f57c Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Tue, 30 May 2023 17:12:37 -0400 Subject: [PATCH 01/42] Add bug bash autoloader --- bug-bash/bug-bash-autoload.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 bug-bash/bug-bash-autoload.php diff --git a/bug-bash/bug-bash-autoload.php b/bug-bash/bug-bash-autoload.php new file mode 100644 index 00000000..2d7d7424 --- /dev/null +++ b/bug-bash/bug-bash-autoload.php @@ -0,0 +1,15 @@ + Date: Tue, 30 May 2023 17:12:48 -0400 Subject: [PATCH 02/42] Initial version of decide tests --- bug-bash/decide.php | 106 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 bug-bash/decide.php diff --git a/bug-bash/decide.php b/bug-bash/decide.php new file mode 100644 index 00000000..bc079ad1 --- /dev/null +++ b/bug-bash/decide.php @@ -0,0 +1,106 @@ +verifyDecisionProperties(); +//$test->testWithVariationsOfDecideOptions(); +//$test->verifyLogsImpressionsEventsDispatched(); +//$test->verifyResultsPageInYourProjectShowsImpressionEvent(); +//$test->verifyDecisionListenerWasCalled(); +//$test->verifyAnInvalidFlagKeyIsHandledCorrectly(); + +// 3. Run the following command to execute uncommented test: +// php ./bug-bash/decide.php + +class DecideTests +{ + private Optimizely $optimizelyClient; + private ?OptimizelyUserContext $userContext; + private array $options; + + public function __construct() + { + $this->optimizelyClient = new Optimizely(datafile:null, sdkKey: SDK_KEY); + + $userId = 'user-' . mt_rand(10, 99); + $attributes = ['age' => 11, 'country' => 'usa']; + $this->userContext = $this->optimizelyClient->createUserContext($userId, $attributes); + } + + // verify decision return properties with default DecideOptions + public function verifyDecisionProperties(): void + { + $decision = $this->userContext->decide('product_sort'); + + print "{${self::LOG_TAG}} [Decide] Check that the following decision properties are expected: + {$decision->getEnabled()}, + {$decision->getFlagKey()}, + {$decision->getRuleKey()}, + {$decision->getUserContext()}, + {$decision->getVariationKey()}, + {$decision->getVariables()}, + {$decision->getReasons()}"; + } + + // test decide w all options: DISABLE_DECISION_EVENT, ENABLED_FLAGS_ONLY, IGNORE_USER_PROFILE_SERVICE, INCLUDE_REASONS, EXCLUDE_VARIABLES (will need to add variables) + public function testWithVariationsOfDecideOptions(): void + { + $options = [ + OptimizelyDecideOption::INCLUDE_REASONS, + // OptimizelyDecideOption::DISABLE_DECISION_EVENT, + // OptimizelyDecideOption::ENABLED_FLAGS_ONLY, + // OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE, + // OptimizelyDecideOption::EXCLUDE_VARIABLES, + ]; + + $decision = $this->userContext->decide('product_sort', $options); + + print "{${self::LOG_TAG}} [Decide] DECISION 1: + {$decision->getEnabled()}, + {$decision->getFlagKey()}, + {$decision->getRuleKey()}, + {$decision->getUserContext()}, + {$decision->getVariationKey()}, + {$decision->getVariables()}, + {$decision->getReasons()}"; + } + + // verify in logs that impression event of this decision was dispatched + public function verifyLogsImpressionsEventsDispatched(): void + { + + } + + // verify on Results page that impression even was created + public function verifyResultsPageInYourProjectShowsImpressionEvent(): void + { + printf('%s Go to your project\'s results page and verify the decision events', self::LOG_TAG); + } + + // verify that decision listener contains correct information + public function verifyDecisionListenerWasCalled(): void + { + + } + + // verify that invalid flag key is handled correctly + public function verifyAnInvalidFlagKeyIsHandledCorrectly(): void + { + + } + + const LOG_TAG = '>>>'; +} From 005157364eff2cc2b831b23881333ffef869af1b Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Tue, 30 May 2023 17:37:28 -0400 Subject: [PATCH 03/42] Fix autoloads; DRY print to console --- bug-bash/decide.php | 46 ++++++++++++++++++++------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/bug-bash/decide.php b/bug-bash/decide.php index bc079ad1..267cabd3 100644 --- a/bug-bash/decide.php +++ b/bug-bash/decide.php @@ -2,9 +2,11 @@ namespace Optimizely\BugBash; -require_once 'bug-bash-autoload.php'; +require_once '..\vendor\autoload.php'; +require_once '..\bug-bash\bug-bash-autoload.php'; use Optimizely\Decide\OptimizelyDecideOption; +use Optimizely\Decide\OptimizelyDecision; use Optimizely\Optimizely; use Optimizely\OptimizelyUserContext; @@ -45,14 +47,7 @@ public function verifyDecisionProperties(): void { $decision = $this->userContext->decide('product_sort'); - print "{${self::LOG_TAG}} [Decide] Check that the following decision properties are expected: - {$decision->getEnabled()}, - {$decision->getFlagKey()}, - {$decision->getRuleKey()}, - {$decision->getUserContext()}, - {$decision->getVariationKey()}, - {$decision->getVariables()}, - {$decision->getReasons()}"; + $this->printDecision($decision, "[Decide] Check that the following decision properties are expected"); } // test decide w all options: DISABLE_DECISION_EVENT, ENABLED_FLAGS_ONLY, IGNORE_USER_PROFILE_SERVICE, INCLUDE_REASONS, EXCLUDE_VARIABLES (will need to add variables) @@ -60,47 +55,46 @@ public function testWithVariationsOfDecideOptions(): void { $options = [ OptimizelyDecideOption::INCLUDE_REASONS, - // OptimizelyDecideOption::DISABLE_DECISION_EVENT, - // OptimizelyDecideOption::ENABLED_FLAGS_ONLY, - // OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE, - // OptimizelyDecideOption::EXCLUDE_VARIABLES, +// OptimizelyDecideOption::DISABLE_DECISION_EVENT, +// OptimizelyDecideOption::ENABLED_FLAGS_ONLY, +// OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE, +// OptimizelyDecideOption::EXCLUDE_VARIABLES, ]; $decision = $this->userContext->decide('product_sort', $options); - print "{${self::LOG_TAG}} [Decide] DECISION 1: - {$decision->getEnabled()}, - {$decision->getFlagKey()}, - {$decision->getRuleKey()}, - {$decision->getUserContext()}, - {$decision->getVariationKey()}, - {$decision->getVariables()}, - {$decision->getReasons()}"; + $this->printDecision($decision, "[Decide] Modify the OptimizelyDecideOptions and check the decision variables expected"); } // verify in logs that impression event of this decision was dispatched public function verifyLogsImpressionsEventsDispatched(): void { - } // verify on Results page that impression even was created public function verifyResultsPageInYourProjectShowsImpressionEvent(): void { - printf('%s Go to your project\'s results page and verify the decision events', self::LOG_TAG); + print 'Go to your project\'s results page and verify the decision events'; } // verify that decision listener contains correct information public function verifyDecisionListenerWasCalled(): void { - } // verify that invalid flag key is handled correctly public function verifyAnInvalidFlagKeyIsHandledCorrectly(): void { - } - const LOG_TAG = '>>>'; + private function printDecision($decision, $message): void + { + print ">>> $message: + enabled: {$decision->getEnabled()}, + flagKey: {$decision->getFlagKey()}, + ruleKey: {$decision->getRuleKey()}, + variationKey: {$decision->getVariationKey()}, + variables: " . var_dump($decision->getVariables()) . ", + reasons: " . var_dump($decision->getReasons()); + } } From c31820ae8695b8f5cc1a0a003920ffd12b64a556 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Tue, 30 May 2023 17:40:40 -0400 Subject: [PATCH 04/42] Refactor and clean using --- bug-bash/decide.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/bug-bash/decide.php b/bug-bash/decide.php index 267cabd3..57e3befb 100644 --- a/bug-bash/decide.php +++ b/bug-bash/decide.php @@ -6,14 +6,15 @@ require_once '..\bug-bash\bug-bash-autoload.php'; use Optimizely\Decide\OptimizelyDecideOption; -use Optimizely\Decide\OptimizelyDecision; use Optimizely\Optimizely; use Optimizely\OptimizelyUserContext; // 1. Change this SDK key to your project's SDK Key const SDK_KEY = "K4UmaV5Pk7cEh2hbcjgwe"; +// 2. Change this to your flag key +const FLAG_KEY = "product_sort"; -// 2. Uncomment each scenario 1 by 1 modifying the contents of the method +// 3. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. $test = new DecideTests(); @@ -24,7 +25,7 @@ //$test->verifyDecisionListenerWasCalled(); //$test->verifyAnInvalidFlagKeyIsHandledCorrectly(); -// 3. Run the following command to execute uncommented test: +// 4. Run the following command to execute uncommented test: // php ./bug-bash/decide.php class DecideTests @@ -45,7 +46,7 @@ public function __construct() // verify decision return properties with default DecideOptions public function verifyDecisionProperties(): void { - $decision = $this->userContext->decide('product_sort'); + $decision = $this->userContext->decide(FLAG_KEY); $this->printDecision($decision, "[Decide] Check that the following decision properties are expected"); } @@ -61,7 +62,7 @@ public function testWithVariationsOfDecideOptions(): void // OptimizelyDecideOption::EXCLUDE_VARIABLES, ]; - $decision = $this->userContext->decide('product_sort', $options); + $decision = $this->userContext->decide(FLAG_KEY, $options); $this->printDecision($decision, "[Decide] Modify the OptimizelyDecideOptions and check the decision variables expected"); } From 833e6bb3bf8156ff13b1904e5c3885146861effa Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Wed, 31 May 2023 09:27:50 -0400 Subject: [PATCH 05/42] Refactor; Fix array outputs --- bug-bash/decide.php | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/bug-bash/decide.php b/bug-bash/decide.php index 57e3befb..65be1228 100644 --- a/bug-bash/decide.php +++ b/bug-bash/decide.php @@ -7,12 +7,13 @@ use Optimizely\Decide\OptimizelyDecideOption; use Optimizely\Optimizely; +use Optimizely\OptimizelyFactory; use Optimizely\OptimizelyUserContext; // 1. Change this SDK key to your project's SDK Key -const SDK_KEY = "K4UmaV5Pk7cEh2hbcjgwe"; +const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; // 2. Change this to your flag key -const FLAG_KEY = "product_sort"; +const FLAG_KEY = 'product_sort'; // 3. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. @@ -30,25 +31,12 @@ class DecideTests { - private Optimizely $optimizelyClient; - private ?OptimizelyUserContext $userContext; - private array $options; - - public function __construct() - { - $this->optimizelyClient = new Optimizely(datafile:null, sdkKey: SDK_KEY); - - $userId = 'user-' . mt_rand(10, 99); - $attributes = ['age' => 11, 'country' => 'usa']; - $this->userContext = $this->optimizelyClient->createUserContext($userId, $attributes); - } - // verify decision return properties with default DecideOptions public function verifyDecisionProperties(): void { $decision = $this->userContext->decide(FLAG_KEY); - $this->printDecision($decision, "[Decide] Check that the following decision properties are expected"); + $this->printDecision($decision, '[Decide] Check that the following decision properties are expected'); } // test decide w all options: DISABLE_DECISION_EVENT, ENABLED_FLAGS_ONLY, IGNORE_USER_PROFILE_SERVICE, INCLUDE_REASONS, EXCLUDE_VARIABLES (will need to add variables) @@ -64,7 +52,7 @@ public function testWithVariationsOfDecideOptions(): void $decision = $this->userContext->decide(FLAG_KEY, $options); - $this->printDecision($decision, "[Decide] Modify the OptimizelyDecideOptions and check the decision variables expected"); + $this->printDecision($decision, '[Decide] Modify the OptimizelyDecideOptions and check the decision variables expected'); } // verify in logs that impression event of this decision was dispatched @@ -95,7 +83,20 @@ private function printDecision($decision, $message): void flagKey: {$decision->getFlagKey()}, ruleKey: {$decision->getRuleKey()}, variationKey: {$decision->getVariationKey()}, - variables: " . var_dump($decision->getVariables()) . ", - reasons: " . var_dump($decision->getReasons()); + variables: " . implode(', ', $decision->getVariables()) . ", + reasons: " . implode(', ', $decision->getReasons()); + } + + private Optimizely $optimizelyClient; + private ?OptimizelyUserContext $userContext; + private array $options; + + public function __construct() + { + $this->optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY); + + $userId = 'user-' . mt_rand(10, 99); + $attributes = ['age' => 11, 'country' => 'usa']; + $this->userContext = $this->optimizelyClient->createUserContext($userId, $attributes); } } From 785389fdedac5d4ad8720191cb44f1d6d79c9d65 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Wed, 31 May 2023 11:56:10 -0400 Subject: [PATCH 06/42] Better output in linux env --- bug-bash/decide.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/bug-bash/decide.php b/bug-bash/decide.php index 65be1228..5de8b3b2 100644 --- a/bug-bash/decide.php +++ b/bug-bash/decide.php @@ -2,8 +2,8 @@ namespace Optimizely\BugBash; -require_once '..\vendor\autoload.php'; -require_once '..\bug-bash\bug-bash-autoload.php'; +require_once '../vendor/autoload.php'; +require_once '../bug-bash/bug-bash-autoload.php'; use Optimizely\Decide\OptimizelyDecideOption; use Optimizely\Optimizely; @@ -12,6 +12,7 @@ // 1. Change this SDK key to your project's SDK Key const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; + // 2. Change this to your flag key const FLAG_KEY = 'product_sort'; @@ -20,11 +21,11 @@ $test = new DecideTests(); $test->verifyDecisionProperties(); -//$test->testWithVariationsOfDecideOptions(); -//$test->verifyLogsImpressionsEventsDispatched(); -//$test->verifyResultsPageInYourProjectShowsImpressionEvent(); -//$test->verifyDecisionListenerWasCalled(); -//$test->verifyAnInvalidFlagKeyIsHandledCorrectly(); +// $test->testWithVariationsOfDecideOptions(); +// $test->verifyLogsImpressionsEventsDispatched(); +// $test->verifyResultsPageInYourProjectShowsImpressionEvent(); +// $test->verifyDecisionListenerWasCalled(); +// $test->verifyAnInvalidFlagKeyIsHandledCorrectly(); // 4. Run the following command to execute uncommented test: // php ./bug-bash/decide.php @@ -84,7 +85,7 @@ private function printDecision($decision, $message): void ruleKey: {$decision->getRuleKey()}, variationKey: {$decision->getVariationKey()}, variables: " . implode(', ', $decision->getVariables()) . ", - reasons: " . implode(', ', $decision->getReasons()); + reasons: " . implode(', ', $decision->getReasons()) . "\r\n"; } private Optimizely $optimizelyClient; From 47fcac7d93add869a0ce56d67776470b727fea80 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Wed, 31 May 2023 12:36:11 -0400 Subject: [PATCH 07/42] Add notification on decide test --- bug-bash/decide.php | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/bug-bash/decide.php b/bug-bash/decide.php index 5de8b3b2..88b248bf 100644 --- a/bug-bash/decide.php +++ b/bug-bash/decide.php @@ -6,6 +6,7 @@ require_once '../bug-bash/bug-bash-autoload.php'; use Optimizely\Decide\OptimizelyDecideOption; +use Optimizely\Notification\NotificationType; use Optimizely\Optimizely; use Optimizely\OptimizelyFactory; use Optimizely\OptimizelyUserContext; @@ -20,15 +21,15 @@ // to test additional scenarios. $test = new DecideTests(); -$test->verifyDecisionProperties(); -// $test->testWithVariationsOfDecideOptions(); -// $test->verifyLogsImpressionsEventsDispatched(); -// $test->verifyResultsPageInYourProjectShowsImpressionEvent(); -// $test->verifyDecisionListenerWasCalled(); -// $test->verifyAnInvalidFlagKeyIsHandledCorrectly(); +//$test->verifyDecisionProperties(); +//$test->testWithVariationsOfDecideOptions(); +$test->verifyLogsImpressionsEventsDispatched(); +//$test->verifyResultsPageInYourProjectShowsImpressionEvent(); +//$test->verifyDecisionListenerWasCalled(); +//$test->verifyAnInvalidFlagKeyIsHandledCorrectly(); -// 4. Run the following command to execute uncommented test: -// php ./bug-bash/decide.php +// 4. From within the /bug-bash/ directory, the following command will run the uncommented test: +// php decide.php class DecideTests { @@ -37,7 +38,7 @@ public function verifyDecisionProperties(): void { $decision = $this->userContext->decide(FLAG_KEY); - $this->printDecision($decision, '[Decide] Check that the following decision properties are expected'); + $this->printDecision($decision, 'Check that the following decision properties are expected'); } // test decide w all options: DISABLE_DECISION_EVENT, ENABLED_FLAGS_ONLY, IGNORE_USER_PROFILE_SERVICE, INCLUDE_REASONS, EXCLUDE_VARIABLES (will need to add variables) @@ -53,12 +54,26 @@ public function testWithVariationsOfDecideOptions(): void $decision = $this->userContext->decide(FLAG_KEY, $options); - $this->printDecision($decision, '[Decide] Modify the OptimizelyDecideOptions and check the decision variables expected'); + $this->printDecision($decision, 'Modify the OptimizelyDecideOptions and check the decision variables expected'); } // verify in logs that impression event of this decision was dispatched public function verifyLogsImpressionsEventsDispatched(): void { + $onDecision = function ($type, $userId, $attributes, $decisionInfo) { + print ">>> [NotificationCenter] OnDecision: + type: $type, + userId: $userId, + attributes: " . print_r($attributes, true) . " + decisionInfo: " . print_r($decisionInfo, true) . "\r\n"; + }; + + $this->optimizelyClient->notificationCenter->addNotificationListener( + NotificationType::DECISION, + $onDecision + ); + + $this->userContext->decide(FLAG_KEY); } // verify on Results page that impression even was created @@ -79,13 +94,13 @@ public function verifyAnInvalidFlagKeyIsHandledCorrectly(): void private function printDecision($decision, $message): void { - print ">>> $message: + print ">>> [Decision] $message: enabled: {$decision->getEnabled()}, flagKey: {$decision->getFlagKey()}, ruleKey: {$decision->getRuleKey()}, variationKey: {$decision->getVariationKey()}, - variables: " . implode(', ', $decision->getVariables()) . ", - reasons: " . implode(', ', $decision->getReasons()) . "\r\n"; + variables: " . print_r($decision->getVariables(), true) . ", + reasons: " . print_r($decision->getReasons(), true) . "\r\n"; } private Optimizely $optimizelyClient; From e7c18c7eaa235f6566dd3c05ac6e6bbef62b5adf Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Wed, 31 May 2023 13:50:10 -0400 Subject: [PATCH 08/42] Output log to ensure logx impression sent --- bug-bash/decide.php | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/bug-bash/decide.php b/bug-bash/decide.php index 88b248bf..8f1f3848 100644 --- a/bug-bash/decide.php +++ b/bug-bash/decide.php @@ -5,7 +5,9 @@ require_once '../vendor/autoload.php'; require_once '../bug-bash/bug-bash-autoload.php'; +use Monolog\Logger; use Optimizely\Decide\OptimizelyDecideOption; +use Optimizely\Logger\DefaultLogger; use Optimizely\Notification\NotificationType; use Optimizely\Optimizely; use Optimizely\OptimizelyFactory; @@ -41,7 +43,7 @@ public function verifyDecisionProperties(): void $this->printDecision($decision, 'Check that the following decision properties are expected'); } - // test decide w all options: DISABLE_DECISION_EVENT, ENABLED_FLAGS_ONLY, IGNORE_USER_PROFILE_SERVICE, INCLUDE_REASONS, EXCLUDE_VARIABLES (will need to add variables) + // test decide w all options: DISABLE_DECISION_EVENT, ENABLED_FLAGS_ONLY, IGNORE_USER_PROFILE_SERVICE, INCLUDE_REASONS, EXCLUDE_VARIABLES (will need to add variables) public function testWithVariationsOfDecideOptions(): void { $options = [ @@ -57,9 +59,31 @@ public function testWithVariationsOfDecideOptions(): void $this->printDecision($decision, 'Modify the OptimizelyDecideOptions and check the decision variables expected'); } - // verify in logs that impression event of this decision was dispatched + // verify in logs that impression event of this decision was dispatched public function verifyLogsImpressionsEventsDispatched(): void { + // Create a new flag with an A/B Test eg "product_version" + $featureFlagKey = 'product_version'; + $logger = new DefaultLogger(Logger::DEBUG); + $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); + $userId = 'user-' . mt_rand(10, 99); + $localUserContext = $localOptimizelyClient->createUserContext($userId); + + // review the DEBUG output, ensuring you see an impression log + // "Dispatching impression event to URL https://logx.optimizely.com/v1/events with params..." + $localUserContext->decide($featureFlagKey); + } + + // verify on Results page that impression even was created + public function verifyResultsPageInYourProjectShowsImpressionEvent(): void + { + print "Go to your project's results page and verify decisions events are showing (might be a delay)"; + } + + // verify that decision listener contains correct information + public function verifyDecisionListenerWasCalled(): void + { + // Check that this was called during the... $onDecision = function ($type, $userId, $attributes, $decisionInfo) { print ">>> [NotificationCenter] OnDecision: type: $type, @@ -67,27 +91,16 @@ public function verifyLogsImpressionsEventsDispatched(): void attributes: " . print_r($attributes, true) . " decisionInfo: " . print_r($decisionInfo, true) . "\r\n"; }; - $this->optimizelyClient->notificationCenter->addNotificationListener( NotificationType::DECISION, $onDecision ); + // ...decide. $this->userContext->decide(FLAG_KEY); } - // verify on Results page that impression even was created - public function verifyResultsPageInYourProjectShowsImpressionEvent(): void - { - print 'Go to your project\'s results page and verify the decision events'; - } - - // verify that decision listener contains correct information - public function verifyDecisionListenerWasCalled(): void - { - } - - // verify that invalid flag key is handled correctly + // verify that invalid flag key is handled correctly public function verifyAnInvalidFlagKeyIsHandledCorrectly(): void { } From 610279a2874a16ad7430963fc7e07d33393d086a Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Wed, 31 May 2023 13:58:55 -0400 Subject: [PATCH 09/42] Verify error is logged for invalid flag --- bug-bash/decide.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/bug-bash/decide.php b/bug-bash/decide.php index 8f1f3848..987163d1 100644 --- a/bug-bash/decide.php +++ b/bug-bash/decide.php @@ -23,9 +23,9 @@ // to test additional scenarios. $test = new DecideTests(); -//$test->verifyDecisionProperties(); +$test->verifyDecisionProperties(); //$test->testWithVariationsOfDecideOptions(); -$test->verifyLogsImpressionsEventsDispatched(); +//$test->verifyLogsImpressionsEventsDispatched(); //$test->verifyResultsPageInYourProjectShowsImpressionEvent(); //$test->verifyDecisionListenerWasCalled(); //$test->verifyAnInvalidFlagKeyIsHandledCorrectly(); @@ -77,7 +77,7 @@ public function verifyLogsImpressionsEventsDispatched(): void // verify on Results page that impression even was created public function verifyResultsPageInYourProjectShowsImpressionEvent(): void { - print "Go to your project's results page and verify decisions events are showing (might be a delay)"; + print "Go to your project's results page and verify decisions events are showing (might be a 5 min delay)"; } // verify that decision listener contains correct information @@ -103,6 +103,13 @@ public function verifyDecisionListenerWasCalled(): void // verify that invalid flag key is handled correctly public function verifyAnInvalidFlagKeyIsHandledCorrectly(): void { + $logger = new DefaultLogger(Logger::ERROR); + $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); + $userId = 'user-' . mt_rand(10, 99); + $localUserContext = $localOptimizelyClient->createUserContext($userId); + + // ensure you see an error -- Optimizely.ERROR: FeatureFlag Key "a_key_not_in_the_project" is not in datafile. + $localUserContext->decide("a_key_not_in_the_project"); } private function printDecision($decision, $message): void From 2d1b5a1022b5520e496cff20b296148846987cf8 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Thu, 1 Jun 2023 08:42:16 -0400 Subject: [PATCH 10/42] Add devcontainer config --- .devcontainer/devcontainer.json | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..6de8a11b --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,33 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/php +{ + "name": "PHP", + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile + "image": "mcr.microsoft.com/devcontainers/php:0-8.2", + + // Features to add to the dev container. More info: https://containers.dev/features. + // "features": {}, + + // Configure tool-specific properties. + // "customizations": {}, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [ + 8080 + ], + "customizations": { + "vscode": { + "extensions": [ + "bmewburn.vscode-intelephense-client", + "xdebug.php-debug", + "DEVSENSE.composer-php-vscode" + ] + } + } + + // Use 'postCreateCommand' to run commands after the container is created. + // "postCreateCommand": "sudo chmod a+x \"$(pwd)\" && sudo rm -rf /var/www/html && sudo ln -s \"$(pwd)\" /var/www/html" + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} From af218441ea5dc3c91b5ade4e4a7f86faee785d94 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Thu, 1 Jun 2023 12:55:19 +0000 Subject: [PATCH 11/42] Install dependencies in devcontainer --- .devcontainer/devcontainer.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 6de8a11b..500986e4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,6 +7,8 @@ // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, + + "postCreateCommand": "composer install", // Configure tool-specific properties. // "customizations": {}, From 1567ac295a2dc2c47218eb9d5420c253ae1d10bd Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Thu, 1 Jun 2023 13:03:17 +0000 Subject: [PATCH 12/42] Update decide instructions --- bug-bash/decide.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/bug-bash/decide.php b/bug-bash/decide.php index 987163d1..5304d63a 100644 --- a/bug-bash/decide.php +++ b/bug-bash/decide.php @@ -24,13 +24,16 @@ $test = new DecideTests(); $test->verifyDecisionProperties(); -//$test->testWithVariationsOfDecideOptions(); -//$test->verifyLogsImpressionsEventsDispatched(); -//$test->verifyResultsPageInYourProjectShowsImpressionEvent(); -//$test->verifyDecisionListenerWasCalled(); -//$test->verifyAnInvalidFlagKeyIsHandledCorrectly(); +// $test->testWithVariationsOfDecideOptions(); +// $test->verifyLogsImpressionsEventsDispatched(); +// $test->verifyResultsPageInYourProjectShowsImpressionEvent(); +// $test->verifyDecisionListenerWasCalled(); +// $test->verifyAnInvalidFlagKeyIsHandledCorrectly(); -// 4. From within the /bug-bash/ directory, the following command will run the uncommented test: +// 4. Change directory into ./bug-bash +// cd ./bug-bash/ + +// 5. Run the following command to execute the uncommented tests above: // php decide.php class DecideTests From 12a9b7070aa699ff8280cc8bd1ed7e52d3d76cd6 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Thu, 1 Jun 2023 13:17:34 +0000 Subject: [PATCH 13/42] Add postCreateCommand shell postCreateCommand --- .devcontainer/devcontainer.json | 5 ++++- .devcontainer/prep-env.sh | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/prep-env.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 500986e4..07de58b6 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,7 +8,10 @@ // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, - "postCreateCommand": "composer install", + "postCreateCommand": "./prep-env.sh", + "mounts": [ + "source=.,target=/workspace,type=bind,consistency=cached" + ], // Configure tool-specific properties. // "customizations": {}, diff --git a/.devcontainer/prep-env.sh b/.devcontainer/prep-env.sh new file mode 100644 index 00000000..1f3d3df2 --- /dev/null +++ b/.devcontainer/prep-env.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# install php dependencies +composer install + +# turn off xdebug messages +echo "xdebug.remote_enable = 0" | sudo tee -a /usr/local/etc/php/conf.d/xdebug.ini > /dev/null From e59ed4bb6e43fa576698ccc63c19e1b5ebe4b60e Mon Sep 17 00:00:00 2001 From: Mike Chu <104384559+mikechu-optimizely@users.noreply.github.com> Date: Thu, 1 Jun 2023 09:24:56 -0400 Subject: [PATCH 14/42] Fix path on postCreateCommand --- .devcontainer/devcontainer.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 07de58b6..48aa69b0 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -8,10 +8,7 @@ // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, - "postCreateCommand": "./prep-env.sh", - "mounts": [ - "source=.,target=/workspace,type=bind,consistency=cached" - ], + "postCreateCommand": "/workspaces/php-sdk/prep-env.sh", // Configure tool-specific properties. // "customizations": {}, From a15ce1989358aa3baed6f656938bc840e0b79408 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Thu, 1 Jun 2023 15:48:31 +0000 Subject: [PATCH 15/42] Finish devcontainer config --- .devcontainer/devcontainer.json | 8 +++++++- .devcontainer/prep-env.sh | 7 ------- 2 files changed, 7 insertions(+), 8 deletions(-) delete mode 100644 .devcontainer/prep-env.sh diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 48aa69b0..7316d069 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -2,13 +2,19 @@ // README at: https://github.com/devcontainers/templates/tree/main/src/php { "name": "PHP", + + "remoteEnv": { + "SDK_ROOT": "/workspaces/php-sdk", + "XDEBUG_CONFIG": "log_level=0", + }, + // Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile "image": "mcr.microsoft.com/devcontainers/php:0-8.2", // Features to add to the dev container. More info: https://containers.dev/features. // "features": {}, - "postCreateCommand": "/workspaces/php-sdk/prep-env.sh", + "postStartCommand": "composer install", // Configure tool-specific properties. // "customizations": {}, diff --git a/.devcontainer/prep-env.sh b/.devcontainer/prep-env.sh deleted file mode 100644 index 1f3d3df2..00000000 --- a/.devcontainer/prep-env.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -# install php dependencies -composer install - -# turn off xdebug messages -echo "xdebug.remote_enable = 0" | sudo tee -a /usr/local/etc/php/conf.d/xdebug.ini > /dev/null From 3a13a5e25b1e1b8c8daa53071a355b53007ceb4a Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Thu, 1 Jun 2023 15:49:25 +0000 Subject: [PATCH 16/42] Refine decide.php --- bug-bash/decide.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/bug-bash/decide.php b/bug-bash/decide.php index 5304d63a..12f588e2 100644 --- a/bug-bash/decide.php +++ b/bug-bash/decide.php @@ -43,7 +43,7 @@ public function verifyDecisionProperties(): void { $decision = $this->userContext->decide(FLAG_KEY); - $this->printDecision($decision, 'Check that the following decision properties are expected'); + $this->printDecision($decision, "Check that the following decision properties are expected for user $this->userId"); } // test decide w all options: DISABLE_DECISION_EVENT, ENABLED_FLAGS_ONLY, IGNORE_USER_PROFILE_SERVICE, INCLUDE_REASONS, EXCLUDE_VARIABLES (will need to add variables) @@ -51,10 +51,10 @@ public function testWithVariationsOfDecideOptions(): void { $options = [ OptimizelyDecideOption::INCLUDE_REASONS, -// OptimizelyDecideOption::DISABLE_DECISION_EVENT, -// OptimizelyDecideOption::ENABLED_FLAGS_ONLY, -// OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE, -// OptimizelyDecideOption::EXCLUDE_VARIABLES, + // OptimizelyDecideOption::DISABLE_DECISION_EVENT, + // OptimizelyDecideOption::ENABLED_FLAGS_ONLY, + // OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE, + // OptimizelyDecideOption::EXCLUDE_VARIABLES, ]; $decision = $this->userContext->decide(FLAG_KEY, $options); @@ -117,8 +117,10 @@ public function verifyAnInvalidFlagKeyIsHandledCorrectly(): void private function printDecision($decision, $message): void { + $enabled = $decision->getEnabled() ? "true" : "false"; + print ">>> [Decision] $message: - enabled: {$decision->getEnabled()}, + enabled: $enabled, flagKey: {$decision->getFlagKey()}, ruleKey: {$decision->getRuleKey()}, variationKey: {$decision->getVariationKey()}, @@ -127,6 +129,7 @@ private function printDecision($decision, $message): void } private Optimizely $optimizelyClient; + private string $userId; private ?OptimizelyUserContext $userContext; private array $options; @@ -134,8 +137,8 @@ public function __construct() { $this->optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY); - $userId = 'user-' . mt_rand(10, 99); + $this->userId = 'user-' . mt_rand(10, 99); $attributes = ['age' => 11, 'country' => 'usa']; - $this->userContext = $this->optimizelyClient->createUserContext($userId, $attributes); + $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); } } From 82faf929e98e8a0c53323217dbe96223aba0ee28 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 2 Jun 2023 08:44:46 -0400 Subject: [PATCH 17/42] Renamed files & their refs --- bug-bash/{decide.php => Decide.php} | 6 +++--- bug-bash/{bug-bash-autoload.php => _bug-bash-autoload.php} | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename bug-bash/{decide.php => Decide.php} (98%) rename bug-bash/{bug-bash-autoload.php => _bug-bash-autoload.php} (100%) diff --git a/bug-bash/decide.php b/bug-bash/Decide.php similarity index 98% rename from bug-bash/decide.php rename to bug-bash/Decide.php index 12f588e2..248c0295 100644 --- a/bug-bash/decide.php +++ b/bug-bash/Decide.php @@ -3,7 +3,7 @@ namespace Optimizely\BugBash; require_once '../vendor/autoload.php'; -require_once '../bug-bash/bug-bash-autoload.php'; +require_once '../bug-bash/_bug-bash-autoload.php'; use Monolog\Logger; use Optimizely\Decide\OptimizelyDecideOption; @@ -30,11 +30,11 @@ // $test->verifyDecisionListenerWasCalled(); // $test->verifyAnInvalidFlagKeyIsHandledCorrectly(); -// 4. Change directory into ./bug-bash +// 4. Change directory into ./bug-bash // cd ./bug-bash/ // 5. Run the following command to execute the uncommented tests above: -// php decide.php +// php Decide.php class DecideTests { diff --git a/bug-bash/bug-bash-autoload.php b/bug-bash/_bug-bash-autoload.php similarity index 100% rename from bug-bash/bug-bash-autoload.php rename to bug-bash/_bug-bash-autoload.php From e05a86f6d1a3af9b4680532f14de5046c5ee08d8 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 2 Jun 2023 09:48:53 -0400 Subject: [PATCH 18/42] Instruction update --- bug-bash/Decide.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bug-bash/Decide.php b/bug-bash/Decide.php index 248c0295..63e0f4b2 100644 --- a/bug-bash/Decide.php +++ b/bug-bash/Decide.php @@ -30,8 +30,8 @@ // $test->verifyDecisionListenerWasCalled(); // $test->verifyAnInvalidFlagKeyIsHandledCorrectly(); -// 4. Change directory into ./bug-bash -// cd ./bug-bash/ +// 4. Change the current folder into the bug-bash directory +// cd bug-bash/ // 5. Run the following command to execute the uncommented tests above: // php Decide.php From 00a2522f2f0e1201a0d94e668fc3a2b22cf00d16 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 2 Jun 2023 09:49:16 -0400 Subject: [PATCH 19/42] Add DecideAll skeleton --- bug-bash/DecideAll.php | 97 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 bug-bash/DecideAll.php diff --git a/bug-bash/DecideAll.php b/bug-bash/DecideAll.php new file mode 100644 index 00000000..89c638b0 --- /dev/null +++ b/bug-bash/DecideAll.php @@ -0,0 +1,97 @@ +verifyDecisionProperties(); +$test->testDefaultDecideAllOptions(); +$test->testWithAllOptions(); +$test->verifyLogImpressionEventDispatched(); +$test->verifyResultsPageShowsImpressionEvents(); +$test->verifyDecisionListenerContainsCorrectInformation(); +$test->verifyInvalidFlagsAreHandled(); + +// 4. Change the current folder into the bug-bash directory if you're not already there: +// cd bug-bash/ + +// 5. Run the following command to execute the uncommented tests above: +// php DecideAll.php + +class DecideAllTests +{ + // verify decision properties + public function verifyDecisionProperties(): void + { + + } + + // test with default options + public function testDefaultDecideAllOptions(): void + { + + } + + // test with all options + public function testWithAllOptions(): void + { + + } + + // verify in logs that impression event of this decision was dispatched + public function verifyLogImpressionEventDispatched(): void + { + + } + + // verify on Results page that impression events was created + public function verifyResultsPageShowsImpressionEvents(): void + { + + } + + // verify that decision listener contains correct information + public function verifyDecisionListenerContainsCorrectInformation(): void + { + + } + + // verify that invalid flag key is handled + public function verifyInvalidFlagsAreHandled(): void + { + + } + + private Optimizely $optimizelyClient; + private string $userId; + private ?OptimizelyUserContext $userContext; + private array $options; + + public function __construct() + { + $this->optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY); + + $this->userId = 'user-' . mt_rand(10, 99); + $attributes = ['age' => 11, 'country' => 'usa']; + $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); + } +} From cc1648676c0a8bbafbeeb7077f34a1b8135798fe Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 2 Jun 2023 09:57:55 -0400 Subject: [PATCH 20/42] Initial DecideAll test --- bug-bash/Decide.php | 26 +++++++++++++------------- bug-bash/DecideAll.php | 42 ++++++++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/bug-bash/Decide.php b/bug-bash/Decide.php index 63e0f4b2..0d93c31b 100644 --- a/bug-bash/Decide.php +++ b/bug-bash/Decide.php @@ -115,19 +115,6 @@ public function verifyAnInvalidFlagKeyIsHandledCorrectly(): void $localUserContext->decide("a_key_not_in_the_project"); } - private function printDecision($decision, $message): void - { - $enabled = $decision->getEnabled() ? "true" : "false"; - - print ">>> [Decision] $message: - enabled: $enabled, - flagKey: {$decision->getFlagKey()}, - ruleKey: {$decision->getRuleKey()}, - variationKey: {$decision->getVariationKey()}, - variables: " . print_r($decision->getVariables(), true) . ", - reasons: " . print_r($decision->getReasons(), true) . "\r\n"; - } - private Optimizely $optimizelyClient; private string $userId; private ?OptimizelyUserContext $userContext; @@ -141,4 +128,17 @@ public function __construct() $attributes = ['age' => 11, 'country' => 'usa']; $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); } + + private function printDecision($decision, $message): void + { + $enabled = $decision->getEnabled() ? "true" : "false"; + + print ">>> [Decision] $message: + enabled: $enabled, + flagKey: {$decision->getFlagKey()}, + ruleKey: {$decision->getRuleKey()}, + variationKey: {$decision->getVariationKey()}, + variables: " . print_r($decision->getVariables(), true) . ", + reasons: " . print_r($decision->getReasons(), true) . "\r\n"; + } } diff --git a/bug-bash/DecideAll.php b/bug-bash/DecideAll.php index 89c638b0..c62a7f0a 100644 --- a/bug-bash/DecideAll.php +++ b/bug-bash/DecideAll.php @@ -16,20 +16,20 @@ // 1. Change this SDK key to your project's SDK Key const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; -// 2. Change this to your flag key -const FLAG_KEY = 'product_sort'; +// 2. Change this array of flag keys (2+) to what you have in your project +const FLAG_KEYS = ['product_sort', 'product_version', 'marketing_banner']; // 3. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. $test = new DecideAllTests(); $test->verifyDecisionProperties(); -$test->testDefaultDecideAllOptions(); -$test->testWithAllOptions(); -$test->verifyLogImpressionEventDispatched(); -$test->verifyResultsPageShowsImpressionEvents(); -$test->verifyDecisionListenerContainsCorrectInformation(); -$test->verifyInvalidFlagsAreHandled(); +// $test->testDefaultDecideAllOptions(); +// $test->testWithAllOptions(); +// $test->verifyLogImpressionEventDispatched(); +// ->verifyResultsPageShowsImpressionEvents(); +// $test->verifyDecisionListenerContainsCorrectInformation(); +// $test->verifyInvalidFlagsAreHandled(); // 4. Change the current folder into the bug-bash directory if you're not already there: // cd bug-bash/ @@ -42,43 +42,39 @@ class DecideAllTests // verify decision properties public function verifyDecisionProperties(): void { + $decision = $this->userContext->decideAll(FLAG_KEYS); + $this->printDecisions($decision, "Check that the following decision properties are expected for user $this->userId"); } // test with default options public function testDefaultDecideAllOptions(): void { - } // test with all options public function testWithAllOptions(): void { - } // verify in logs that impression event of this decision was dispatched public function verifyLogImpressionEventDispatched(): void { - } // verify on Results page that impression events was created public function verifyResultsPageShowsImpressionEvents(): void { - } // verify that decision listener contains correct information public function verifyDecisionListenerContainsCorrectInformation(): void { - } // verify that invalid flag key is handled public function verifyInvalidFlagsAreHandled(): void { - } private Optimizely $optimizelyClient; @@ -94,4 +90,22 @@ public function __construct() $attributes = ['age' => 11, 'country' => 'usa']; $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); } + + private function printDecisions($decisions, $message): void + { + $count = 0; + foreach ($decisions as $decision) { + $enabled = $decision->getEnabled() ? "true" : "false"; + + print ">>> [Decision #$count] $message: + enabled: $enabled, + flagKey: {$decision->getFlagKey()}, + ruleKey: {$decision->getRuleKey()}, + variationKey: {$decision->getVariationKey()}, + variables: " . print_r($decision->getVariables(), true) . ", + reasons: " . print_r($decision->getReasons(), true) . "\r\n"; + + $count++; + } + } } From 8453c4a8aade755a57e414809ca7212a3f636423 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 2 Jun 2023 11:49:26 -0400 Subject: [PATCH 21/42] Finish DecideAll test; Decide fixes --- bug-bash/Decide.php | 6 ++-- bug-bash/DecideAll.php | 63 ++++++++++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/bug-bash/Decide.php b/bug-bash/Decide.php index 0d93c31b..ae8d5926 100644 --- a/bug-bash/Decide.php +++ b/bug-bash/Decide.php @@ -52,7 +52,7 @@ public function testWithVariationsOfDecideOptions(): void $options = [ OptimizelyDecideOption::INCLUDE_REASONS, // OptimizelyDecideOption::DISABLE_DECISION_EVENT, - // OptimizelyDecideOption::ENABLED_FLAGS_ONLY, + // OptimizelyDecideOption::ENABLED_FLAGS_ONLY, // ⬅️ Disable some of your flags // OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE, // OptimizelyDecideOption::EXCLUDE_VARIABLES, ]; @@ -69,8 +69,7 @@ public function verifyLogsImpressionsEventsDispatched(): void $featureFlagKey = 'product_version'; $logger = new DefaultLogger(Logger::DEBUG); $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); - $userId = 'user-' . mt_rand(10, 99); - $localUserContext = $localOptimizelyClient->createUserContext($userId); + $localUserContext = $localOptimizelyClient->createUserContext($this->userId); // review the DEBUG output, ensuring you see an impression log // "Dispatching impression event to URL https://logx.optimizely.com/v1/events with params..." @@ -118,7 +117,6 @@ public function verifyAnInvalidFlagKeyIsHandledCorrectly(): void private Optimizely $optimizelyClient; private string $userId; private ?OptimizelyUserContext $userContext; - private array $options; public function __construct() { diff --git a/bug-bash/DecideAll.php b/bug-bash/DecideAll.php index c62a7f0a..61b43b33 100644 --- a/bug-bash/DecideAll.php +++ b/bug-bash/DecideAll.php @@ -16,20 +16,17 @@ // 1. Change this SDK key to your project's SDK Key const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; -// 2. Change this array of flag keys (2+) to what you have in your project -const FLAG_KEYS = ['product_sort', 'product_version', 'marketing_banner']; +// 2. Create additional flag keys in your project (2+) // 3. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. $test = new DecideAllTests(); $test->verifyDecisionProperties(); -// $test->testDefaultDecideAllOptions(); -// $test->testWithAllOptions(); +// $test->testWithVariousCombinationsOfOptions(); // $test->verifyLogImpressionEventDispatched(); -// ->verifyResultsPageShowsImpressionEvents(); +// $test->verifyResultsPageShowsImpressionEvents(); // $test->verifyDecisionListenerContainsCorrectInformation(); -// $test->verifyInvalidFlagsAreHandled(); // 4. Change the current folder into the bug-bash directory if you're not already there: // cd bug-bash/ @@ -39,48 +36,72 @@ class DecideAllTests { - // verify decision properties + // verify decide all returns properties without specifying default options public function verifyDecisionProperties(): void { - $decision = $this->userContext->decideAll(FLAG_KEYS); + $decision = $this->userContext->decideAll(); - $this->printDecisions($decision, "Check that the following decision properties are expected for user $this->userId"); + $this->printDecisions($decision, "Check that all of the decisions' multiple properties are expected for user `$this->userId`"); } - // test with default options - public function testDefaultDecideAllOptions(): void + // test with all and variations/combinations of options + public function testWithVariousCombinationsOfOptions(): void { - } + $options = [ + OptimizelyDecideOption::INCLUDE_REASONS, + // OptimizelyDecideOption::DISABLE_DECISION_EVENT, + // OptimizelyDecideOption::ENABLED_FLAGS_ONLY, // ⬅️ Disable some of your flags + // OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE, + OptimizelyDecideOption::EXCLUDE_VARIABLES, + ]; - // test with all options - public function testWithAllOptions(): void - { + $decisions = $this->userContext->decideAll($options); + + $this->printDecisions($decisions, "Check that all of your flags' decisions respected the options passed."); } // verify in logs that impression event of this decision was dispatched public function verifyLogImpressionEventDispatched(): void { + // *** Be sure you have >=1 of your project's flags has an EXPERIMENT type + $logger = new DefaultLogger(Logger::DEBUG); + $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); + $localUserContext = $localOptimizelyClient->createUserContext($this->userId); + + // review the DEBUG output, ensuring you see an impression log for each *EXPERIMENT* with a message like + // "Dispatching impression event to URL https://logx.optimizely.com/v1/events with params..." + // Rollout flag types will not dispatch and impression event + $localUserContext->decideAll(); } // verify on Results page that impression events was created public function verifyResultsPageShowsImpressionEvents(): void { + print "After about 5-10 minutes, go to your project's results page and verify decisions events are showing."; } // verify that decision listener contains correct information public function verifyDecisionListenerContainsCorrectInformation(): void { - } - - // verify that invalid flag key is handled - public function verifyInvalidFlagsAreHandled(): void - { + // Check that this was called for each of your project flag keys + $onDecision = function ($type, $userId, $attributes, $decisionInfo) { + print ">>> [NotificationCenter] OnDecision: + type: $type, + userId: $userId, + attributes: " . print_r($attributes, true) . " + decisionInfo: " . print_r($decisionInfo, true) . "\r\n"; + }; + $this->optimizelyClient->notificationCenter->addNotificationListener( + NotificationType::DECISION, + $onDecision + ); + + $this->userContext->decideAll(); } private Optimizely $optimizelyClient; private string $userId; private ?OptimizelyUserContext $userContext; - private array $options; public function __construct() { From 8774b37b1d219245b53b9745a1e3f7f978e2ef16 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Fri, 2 Jun 2023 11:59:07 -0400 Subject: [PATCH 22/42] DecideForKeys skeleton --- bug-bash/DecideForKeys.php | 67 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 bug-bash/DecideForKeys.php diff --git a/bug-bash/DecideForKeys.php b/bug-bash/DecideForKeys.php new file mode 100644 index 00000000..359673a7 --- /dev/null +++ b/bug-bash/DecideForKeys.php @@ -0,0 +1,67 @@ +optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY); + + $this->userId = 'user-' . mt_rand(10, 99); + $attributes = ['age' => 11, 'country' => 'usa']; + $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); + } + + private function printDecisions($decisions, $message): void + { + $count = 0; + foreach ($decisions as $decision) { + $enabled = $decision->getEnabled() ? "true" : "false"; + + print ">>> [Decision #$count] $message: + enabled: $enabled, + flagKey: {$decision->getFlagKey()}, + ruleKey: {$decision->getRuleKey()}, + variationKey: {$decision->getVariationKey()}, + variables: " . print_r($decision->getVariables(), true) . ", + reasons: " . print_r($decision->getReasons(), true) . "\r\n"; + + $count++; + } + } +} From 626c7d4a6f3bad28a45626657810c695e3a37907 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Mon, 5 Jun 2023 08:32:04 -0400 Subject: [PATCH 23/42] Add decide for keys; update other decide classes --- bug-bash/Decide.php | 9 ++-- bug-bash/DecideAll.php | 9 ++-- bug-bash/DecideForKeys.php | 88 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 95 insertions(+), 11 deletions(-) diff --git a/bug-bash/Decide.php b/bug-bash/Decide.php index ae8d5926..41227576 100644 --- a/bug-bash/Decide.php +++ b/bug-bash/Decide.php @@ -65,7 +65,7 @@ public function testWithVariationsOfDecideOptions(): void // verify in logs that impression event of this decision was dispatched public function verifyLogsImpressionsEventsDispatched(): void { - // Create a new flag with an A/B Test eg "product_version" + // 💡️ Create a new flag with an A/B Test eg "product_version" $featureFlagKey = 'product_version'; $logger = new DefaultLogger(Logger::DEBUG); $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); @@ -79,7 +79,7 @@ public function verifyLogsImpressionsEventsDispatched(): void // verify on Results page that impression even was created public function verifyResultsPageInYourProjectShowsImpressionEvent(): void { - print "Go to your project's results page and verify decisions events are showing (might be a 5 min delay)"; + print "Go to your project's results page and verify decisions events are showing (5 min delay)"; } // verify that decision listener contains correct information @@ -87,7 +87,7 @@ public function verifyDecisionListenerWasCalled(): void { // Check that this was called during the... $onDecision = function ($type, $userId, $attributes, $decisionInfo) { - print ">>> [NotificationCenter] OnDecision: + print ">>> [$this->outputTag] OnDecision: type: $type, userId: $userId, attributes: " . print_r($attributes, true) . " @@ -117,6 +117,7 @@ public function verifyAnInvalidFlagKeyIsHandledCorrectly(): void private Optimizely $optimizelyClient; private string $userId; private ?OptimizelyUserContext $userContext; + private string $outputTag = "Decide"; public function __construct() { @@ -131,7 +132,7 @@ private function printDecision($decision, $message): void { $enabled = $decision->getEnabled() ? "true" : "false"; - print ">>> [Decision] $message: + print ">>> [$this->outputTag] $message: enabled: $enabled, flagKey: {$decision->getFlagKey()}, ruleKey: {$decision->getRuleKey()}, diff --git a/bug-bash/DecideAll.php b/bug-bash/DecideAll.php index 61b43b33..bc0edd99 100644 --- a/bug-bash/DecideAll.php +++ b/bug-bash/DecideAll.php @@ -63,14 +63,14 @@ public function testWithVariousCombinationsOfOptions(): void // verify in logs that impression event of this decision was dispatched public function verifyLogImpressionEventDispatched(): void { - // *** Be sure you have >=1 of your project's flags has an EXPERIMENT type + // 💡️ Be sure you have >=1 of your project's flags has an EXPERIMENT type $logger = new DefaultLogger(Logger::DEBUG); $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); $localUserContext = $localOptimizelyClient->createUserContext($this->userId); // review the DEBUG output, ensuring you see an impression log for each *EXPERIMENT* with a message like // "Dispatching impression event to URL https://logx.optimizely.com/v1/events with params..." - // Rollout flag types will not dispatch and impression event + // ⚠️ Rollout flag types should not dispatch and impression event $localUserContext->decideAll(); } @@ -85,7 +85,7 @@ public function verifyDecisionListenerContainsCorrectInformation(): void { // Check that this was called for each of your project flag keys $onDecision = function ($type, $userId, $attributes, $decisionInfo) { - print ">>> [NotificationCenter] OnDecision: + print ">>> [$this->outputTag] OnDecision: type: $type, userId: $userId, attributes: " . print_r($attributes, true) . " @@ -102,6 +102,7 @@ public function verifyDecisionListenerContainsCorrectInformation(): void private Optimizely $optimizelyClient; private string $userId; private ?OptimizelyUserContext $userContext; + private string $outputTag = "Decide All"; public function __construct() { @@ -118,7 +119,7 @@ private function printDecisions($decisions, $message): void foreach ($decisions as $decision) { $enabled = $decision->getEnabled() ? "true" : "false"; - print ">>> [Decision #$count] $message: + print ">>> [$this->outputTag #$count] $message: enabled: $enabled, flagKey: {$decision->getFlagKey()}, ruleKey: {$decision->getRuleKey()}, diff --git a/bug-bash/DecideForKeys.php b/bug-bash/DecideForKeys.php index 359673a7..adac0377 100644 --- a/bug-bash/DecideForKeys.php +++ b/bug-bash/DecideForKeys.php @@ -17,13 +17,18 @@ const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; // 2. Check that you have 3+ flag keys in your project and add them here -const FLAG_KEYS = ['product_sort', 'marketing_banner']; +const FLAG_KEYS = ['product_sort', 'marketing_banner', 'product_version']; // 3. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. $test = new DecideForKeysTests(); - +$test->verifyDecisionProperties(); + $test->testWithVariationsOfDecideOptions(); + $test->verifyLogsImpressionsEventsDispatched(); + $test->verifyResultsPageInYourProjectShowsImpressionEvent(); + $test->verifyDecisionListenerWasCalled(); + $test->verifyAnInvalidFlagKeyIsHandledCorrectly(); // 4. Change the current folder into the bug-bash directory if you've not already // cd bug-bash/ @@ -34,9 +39,86 @@ class DecideForKeysTests { + // verify decision return properties with default DecideOptions + public function verifyDecisionProperties(): void + { + $decision = $this->userContext->decideForKeys(FLAG_KEYS); + + $this->printDecisions($decision, "Check that the following decisions' properties are expected"); + } + + // test decide w all options: DISABLE_DECISION_EVENT, ENABLED_FLAGS_ONLY, IGNORE_USER_PROFILE_SERVICE, INCLUDE_REASONS, EXCLUDE_VARIABLES (will need to add variables) + public function testWithVariationsOfDecideOptions(): void + { + $options = [ + OptimizelyDecideOption::INCLUDE_REASONS, + // OptimizelyDecideOption::DISABLE_DECISION_EVENT, + // OptimizelyDecideOption::ENABLED_FLAGS_ONLY, // ⬅️ Disable some of your flags + // OptimizelyDecideOption::IGNORE_USER_PROFILE_SERVICE, + // OptimizelyDecideOption::EXCLUDE_VARIABLES, + ]; + + $decision = $this->userContext->decideForKeys(FLAG_KEYS, $options); + + $this->printDecisions($decision, "Modify the OptimizelyDecideOptions and check all the decisions' are as expected"); + } + + // verify in logs that impression event of this decision was dispatched + public function verifyLogsImpressionsEventsDispatched(): void + { + // 💡️ Be sure that your FLAG_KEYS array above includes A/B Test eg "product_version" + $logger = new DefaultLogger(Logger::DEBUG); + $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); + $localUserContext = $localOptimizelyClient->createUserContext($this->userId); + + // review the DEBUG output, ensuring you see an impression log for each experiment type in your FLAG_KEYS + // "Dispatching impression event to URL https://logx.optimizely.com/v1/events with params..." + // ⚠️ Your Rollout type flags should not have impression events + $localUserContext->decideForKeys(FLAG_KEYS); + } + + // verify on Results page that impression even was created + public function verifyResultsPageInYourProjectShowsImpressionEvent(): void + { + print "Go to your project's results page and verify decisions events are showing (5 min delay)"; + } + + // verify that decision listener contains correct information + public function verifyDecisionListenerWasCalled(): void + { + // Check that this was called during the... + $onDecision = function ($type, $userId, $attributes, $decisionInfo) { + print ">>> [$this->outputTag] OnDecision: + type: $type, + userId: $userId, + attributes: " . print_r($attributes, true) . " + decisionInfo: " . print_r($decisionInfo, true) . "\r\n"; + }; + $this->optimizelyClient->notificationCenter->addNotificationListener( + NotificationType::DECISION, + $onDecision + ); + + // ...decide. + $this->userContext->decide(FLAG_KEY); + } + + // verify that invalid flag key is handled correctly + public function verifyAnInvalidFlagKeyIsHandledCorrectly(): void + { + $logger = new DefaultLogger(Logger::ERROR); + $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); + $userId = 'user-' . mt_rand(10, 99); + $localUserContext = $localOptimizelyClient->createUserContext($userId); + + // ensure you see an error -- Optimizely.ERROR: FeatureFlag Key "a_key_not_in_the_project" is not in datafile. + $localUserContext->decide("a_key_not_in_the_project"); + } + private Optimizely $optimizelyClient; private string $userId; private ?OptimizelyUserContext $userContext; + private string $outputTag = "Decide For Keys"; public function __construct() { @@ -53,7 +135,7 @@ private function printDecisions($decisions, $message): void foreach ($decisions as $decision) { $enabled = $decision->getEnabled() ? "true" : "false"; - print ">>> [Decision #$count] $message: + print ">>> [$this->outputTag #$count] $message: enabled: $enabled, flagKey: {$decision->getFlagKey()}, ruleKey: {$decision->getRuleKey()}, From 96bb0c0fd3964bc61d1f648cfe1d091602762b63 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Mon, 5 Jun 2023 08:35:12 -0400 Subject: [PATCH 24/42] Comment DecideForKeys test calls --- bug-bash/DecideForKeys.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bug-bash/DecideForKeys.php b/bug-bash/DecideForKeys.php index adac0377..a6ac2105 100644 --- a/bug-bash/DecideForKeys.php +++ b/bug-bash/DecideForKeys.php @@ -24,11 +24,11 @@ $test = new DecideForKeysTests(); $test->verifyDecisionProperties(); - $test->testWithVariationsOfDecideOptions(); - $test->verifyLogsImpressionsEventsDispatched(); - $test->verifyResultsPageInYourProjectShowsImpressionEvent(); - $test->verifyDecisionListenerWasCalled(); - $test->verifyAnInvalidFlagKeyIsHandledCorrectly(); +// $test->testWithVariationsOfDecideOptions(); +// $test->verifyLogsImpressionsEventsDispatched(); +// $test->verifyResultsPageInYourProjectShowsImpressionEvent(); +// $test->verifyDecisionListenerWasCalled(); +// $test->verifyAnInvalidFlagKeyIsHandledCorrectly(); // 4. Change the current folder into the bug-bash directory if you've not already // cd bug-bash/ From fcb1ee45f05de505b18b94cc4c8a3dbc65cb8301 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Mon, 5 Jun 2023 08:36:28 -0400 Subject: [PATCH 25/42] Track event test class skeleton --- bug-bash/TrackEvent.php | 46 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 bug-bash/TrackEvent.php diff --git a/bug-bash/TrackEvent.php b/bug-bash/TrackEvent.php new file mode 100644 index 00000000..8bde0ec7 --- /dev/null +++ b/bug-bash/TrackEvent.php @@ -0,0 +1,46 @@ +optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY); + + $this->userId = 'user-' . mt_rand(10, 99); + $attributes = ['age' => 11, 'country' => 'usa']; + $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); + } +} From aabd4329bd71466af9b69deb2a348c5370151b76 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Mon, 5 Jun 2023 08:54:10 -0400 Subject: [PATCH 26/42] Update attributes in decide tests --- bug-bash/Decide.php | 2 +- bug-bash/DecideAll.php | 2 +- bug-bash/DecideForKeys.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bug-bash/Decide.php b/bug-bash/Decide.php index 41227576..73681887 100644 --- a/bug-bash/Decide.php +++ b/bug-bash/Decide.php @@ -124,7 +124,7 @@ public function __construct() $this->optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY); $this->userId = 'user-' . mt_rand(10, 99); - $attributes = ['age' => 11, 'country' => 'usa']; + $attributes = ['age' => 25, 'country' => 'canada', 'abandoned_cart' => false]; $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); } diff --git a/bug-bash/DecideAll.php b/bug-bash/DecideAll.php index bc0edd99..3d318cfb 100644 --- a/bug-bash/DecideAll.php +++ b/bug-bash/DecideAll.php @@ -109,7 +109,7 @@ public function __construct() $this->optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY); $this->userId = 'user-' . mt_rand(10, 99); - $attributes = ['age' => 11, 'country' => 'usa']; + $attributes = ['country' => 'nederland', 'age' => 43, 'is_return_visitor' => true]; $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); } diff --git a/bug-bash/DecideForKeys.php b/bug-bash/DecideForKeys.php index a6ac2105..838934ba 100644 --- a/bug-bash/DecideForKeys.php +++ b/bug-bash/DecideForKeys.php @@ -125,7 +125,7 @@ public function __construct() $this->optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY); $this->userId = 'user-' . mt_rand(10, 99); - $attributes = ['age' => 11, 'country' => 'usa']; + $attributes = ['likes_yams' => true, 'cart_value' => 34.13, 'country' => 'sweden']; $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); } From 5378d93cde2fac78d0e37528cc77a269be124b9d Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Mon, 5 Jun 2023 09:49:42 -0400 Subject: [PATCH 27/42] Add track event tests --- bug-bash/TrackEvent.php | 70 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/bug-bash/TrackEvent.php b/bug-bash/TrackEvent.php index 8bde0ec7..a4661b77 100644 --- a/bug-bash/TrackEvent.php +++ b/bug-bash/TrackEvent.php @@ -6,7 +6,6 @@ require_once '../bug-bash/_bug-bash-autoload.php'; use Monolog\Logger; -use Optimizely\Decide\OptimizelyDecideOption; use Optimizely\Logger\DefaultLogger; use Optimizely\Notification\NotificationType; use Optimizely\Optimizely; @@ -16,10 +15,17 @@ // 1. Change this SDK key to your project's SDK Key const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; +// 2. Add an event to your project, adding it to your Experiment flag as a metric, then set the name here +const EVENT_NAME = 'version_presented'; + // 2. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. $test = new TrackEventTests(); +$test->checkTrackNotificationListenerProducesEvent(); +// $test->checkConversionEventLogDispatchedOnTrackEvent(); +// $test->checkConversionEventLogIsNOTDispatchedOnTrackEventForInvalidEventName(); +// $test->testEventTagsShowInDispatchedEventAndAppOptimizelyCom(); // 3. Change the current folder into the bug-bash directory if you've not already // cd bug-bash/ @@ -29,6 +35,66 @@ class TrackEventTests { + // check that track notification listener produces event with event key + public function checkTrackNotificationListenerProducesEvent(): void + { + // Check that this was called during the... + $onTrackEvent = function ($type, $userId, $attributes, $decisionInfo) { + print ">>> [$this->outputTag] OnTrackEvent: + type: $type, + userId: $userId, + attributes: " . print_r($attributes, true) . " + decisionInfo: " . print_r($decisionInfo, true) . "\r\n"; + }; + $this->optimizelyClient->notificationCenter->addNotificationListener( + NotificationType::TRACK, + $onTrackEvent + ); + + // ...send track event. + $this->userContext->trackEvent(EVENT_NAME); + } + + // check that conversion event in the dispatch logs contains event key below + public function checkConversionEventLogDispatchedOnTrackEvent(): void + { + $logger = new DefaultLogger(Logger::DEBUG); + $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); + $localUserContext = $localOptimizelyClient->createUserContext($this->userId); + + $localUserContext->trackEvent(EVENT_NAME); + } + + // check that event is NOT dispatched if invalid event key is used + // test changing event key in the UI and in the code + public function checkConversionEventLogIsNOTDispatchedOnTrackEventForInvalidEventName(): void + { + $logger = new DefaultLogger(Logger::DEBUG); + $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); + $localUserContext = $localOptimizelyClient->createUserContext($this->userId); + + // You should not see any "Optimizely.DEBUG: Dispatching conversion event" but instead see + // "Optimizely.INFO: Not tracking user "{user-id}" for event "an_invalid_event_name_not_in_the_project". + $localUserContext->trackEvent("an_invalid_event_name_not_in_the_project"); + } + + // try adding event tags (in the project and in the line below) and see if they show in the event body + public function testEventTagsShowInDispatchedEventAndAppOptimizelyCom(): void + { + $logger = new DefaultLogger(Logger::DEBUG); + $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); + $localUserContext = $localOptimizelyClient->createUserContext($this->userId); + $custom_tags = [ + 'shoe_size_paris_points' => 44, + 'shoe_size_us_size' => 11.5, + 'use_us_size' => false, + 'color' => 'blue' + ]; + + // Dispatched event should have the tags added to the payload `params { ... }` and also + // should show on app.optimizely.com Reports tab after 5-10 minutes + $localUserContext->trackEvent(EVENT_NAME, $custom_tags); + } private Optimizely $optimizelyClient; private string $userId; @@ -40,7 +106,7 @@ public function __construct() $this->optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY); $this->userId = 'user-' . mt_rand(10, 99); - $attributes = ['age' => 11, 'country' => 'usa']; + $attributes = ['age' => 19, 'country' => 'bangledesh', 'has_purchased' => true]; $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); } } From 165c566fe4ed89f6591cf02471d248ce6533cca1 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Mon, 5 Jun 2023 09:56:46 -0400 Subject: [PATCH 28/42] DRY $onTrackEvent and use in negative test --- bug-bash/TrackEvent.php | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/bug-bash/TrackEvent.php b/bug-bash/TrackEvent.php index a4661b77..2f8d5cba 100644 --- a/bug-bash/TrackEvent.php +++ b/bug-bash/TrackEvent.php @@ -38,17 +38,9 @@ class TrackEventTests // check that track notification listener produces event with event key public function checkTrackNotificationListenerProducesEvent(): void { - // Check that this was called during the... - $onTrackEvent = function ($type, $userId, $attributes, $decisionInfo) { - print ">>> [$this->outputTag] OnTrackEvent: - type: $type, - userId: $userId, - attributes: " . print_r($attributes, true) . " - decisionInfo: " . print_r($decisionInfo, true) . "\r\n"; - }; $this->optimizelyClient->notificationCenter->addNotificationListener( NotificationType::TRACK, - $onTrackEvent + $this->onTrackEvent // ⬅️ This should be called with a valid EVENT_NAME ); // ...send track event. @@ -72,6 +64,10 @@ public function checkConversionEventLogIsNOTDispatchedOnTrackEventForInvalidEven $logger = new DefaultLogger(Logger::DEBUG); $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); $localUserContext = $localOptimizelyClient->createUserContext($this->userId); + $this->optimizelyClient->notificationCenter->addNotificationListener( + NotificationType::TRACK, + $this->onTrackEvent // ⬅️ There should not be a Notification Listener OnTrackEvent called on invalid event name + ); // You should not see any "Optimizely.DEBUG: Dispatching conversion event" but instead see // "Optimizely.INFO: Not tracking user "{user-id}" for event "an_invalid_event_name_not_in_the_project". @@ -100,6 +96,7 @@ public function testEventTagsShowInDispatchedEventAndAppOptimizelyCom(): void private string $userId; private ?OptimizelyUserContext $userContext; private string $outputTag = "Track Event"; + private \Closure $onTrackEvent; public function __construct() { @@ -108,5 +105,13 @@ public function __construct() $this->userId = 'user-' . mt_rand(10, 99); $attributes = ['age' => 19, 'country' => 'bangledesh', 'has_purchased' => true]; $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); + + $this->onTrackEvent = function ($type, $userId, $attributes, $decisionInfo) { + print ">>> [$this->outputTag] OnTrackEvent: + type: $type, + userId: $userId, + attributes: " . print_r($attributes, true) . " + decisionInfo: " . print_r($decisionInfo, true) . "\r\n"; + }; } } From bb0eeaf70aa2de06121316cb2a9a6362fab92263 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Mon, 5 Jun 2023 10:01:52 -0400 Subject: [PATCH 29/42] Event Key instead of "name" --- bug-bash/TrackEvent.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bug-bash/TrackEvent.php b/bug-bash/TrackEvent.php index 2f8d5cba..a6c016e9 100644 --- a/bug-bash/TrackEvent.php +++ b/bug-bash/TrackEvent.php @@ -15,8 +15,8 @@ // 1. Change this SDK key to your project's SDK Key const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; -// 2. Add an event to your project, adding it to your Experiment flag as a metric, then set the name here -const EVENT_NAME = 'version_presented'; +// 2. Add an event to your project, adding it to your Experiment flag as a metric, then set the key here +const EVENT_KEY = 'version_presented'; // 2. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. @@ -44,7 +44,7 @@ public function checkTrackNotificationListenerProducesEvent(): void ); // ...send track event. - $this->userContext->trackEvent(EVENT_NAME); + $this->userContext->trackEvent(EVENT_KEY); } // check that conversion event in the dispatch logs contains event key below @@ -54,7 +54,7 @@ public function checkConversionEventLogDispatchedOnTrackEvent(): void $localOptimizelyClient = new Optimizely(datafile: null, logger: $logger, sdkKey: SDK_KEY); $localUserContext = $localOptimizelyClient->createUserContext($this->userId); - $localUserContext->trackEvent(EVENT_NAME); + $localUserContext->trackEvent(EVENT_KEY); } // check that event is NOT dispatched if invalid event key is used @@ -89,7 +89,7 @@ public function testEventTagsShowInDispatchedEventAndAppOptimizelyCom(): void // Dispatched event should have the tags added to the payload `params { ... }` and also // should show on app.optimizely.com Reports tab after 5-10 minutes - $localUserContext->trackEvent(EVENT_NAME, $custom_tags); + $localUserContext->trackEvent(EVENT_KEY, $custom_tags); } private Optimizely $optimizelyClient; From b29dead48677008a50284473a978650e94a51f40 Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Mon, 5 Jun 2023 10:02:19 -0400 Subject: [PATCH 30/42] Forced Decision skeleton --- bug-bash/ForcedDecision.php | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 bug-bash/ForcedDecision.php diff --git a/bug-bash/ForcedDecision.php b/bug-bash/ForcedDecision.php new file mode 100644 index 00000000..20b2f14f --- /dev/null +++ b/bug-bash/ForcedDecision.php @@ -0,0 +1,48 @@ +optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY); + + $this->userId = 'user-' . mt_rand(10, 99); + $attributes = ['eats_vegetables' => true, 'age' => 7, 'favorite_vegetable' => 'turnips']; + $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); + } +} From e7781de06f271901ca68aff712dcf643dcbdd97f Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Mon, 5 Jun 2023 10:03:37 -0400 Subject: [PATCH 31/42] Add PHP documentation links --- bug-bash/Decide.php | 1 + bug-bash/DecideAll.php | 1 + bug-bash/DecideForKeys.php | 1 + bug-bash/ForcedDecision.php | 1 + bug-bash/TrackEvent.php | 1 + 5 files changed, 5 insertions(+) diff --git a/bug-bash/Decide.php b/bug-bash/Decide.php index 73681887..3125118c 100644 --- a/bug-bash/Decide.php +++ b/bug-bash/Decide.php @@ -36,6 +36,7 @@ // 5. Run the following command to execute the uncommented tests above: // php Decide.php +// https://docs.developers.optimizely.com/feature-experimentation/docs/decide-methods-php class DecideTests { // verify decision return properties with default DecideOptions diff --git a/bug-bash/DecideAll.php b/bug-bash/DecideAll.php index 3d318cfb..6488e61d 100644 --- a/bug-bash/DecideAll.php +++ b/bug-bash/DecideAll.php @@ -34,6 +34,7 @@ // 5. Run the following command to execute the uncommented tests above: // php DecideAll.php +// https://docs.developers.optimizely.com/feature-experimentation/docs/decide-methods-php class DecideAllTests { // verify decide all returns properties without specifying default options diff --git a/bug-bash/DecideForKeys.php b/bug-bash/DecideForKeys.php index 838934ba..f1f86378 100644 --- a/bug-bash/DecideForKeys.php +++ b/bug-bash/DecideForKeys.php @@ -36,6 +36,7 @@ // 5. Run the following command to execute the uncommented tests above: // php DecideForKeys.php +// https://docs.developers.optimizely.com/feature-experimentation/docs/decide-methods-php class DecideForKeysTests { diff --git a/bug-bash/ForcedDecision.php b/bug-bash/ForcedDecision.php index 20b2f14f..05079bf7 100644 --- a/bug-bash/ForcedDecision.php +++ b/bug-bash/ForcedDecision.php @@ -29,6 +29,7 @@ // 4. Run the following command to execute the uncommented tests above: // php ForcedDecision.php +// https://docs.developers.optimizely.com/feature-experimentation/docs/forced-decision-methods-php class ForcedDecisionTests { diff --git a/bug-bash/TrackEvent.php b/bug-bash/TrackEvent.php index a6c016e9..dce4d9ce 100644 --- a/bug-bash/TrackEvent.php +++ b/bug-bash/TrackEvent.php @@ -33,6 +33,7 @@ // 4. Run the following command to execute the uncommented tests above: // php TrackEvent.php +// https://docs.developers.optimizely.com/feature-experimentation/docs/track-event-php class TrackEventTests { // check that track notification listener produces event with event key From 035747e9744626f9490aeaaea4b7333ba2484ecf Mon Sep 17 00:00:00 2001 From: Mike Chu Date: Mon, 5 Jun 2023 15:55:39 -0400 Subject: [PATCH 32/42] Initial attempt forced decision tests --- bug-bash/ForcedDecision.php | 138 +++++++++++++++++++++++++++++++++--- bug-bash/TrackEvent.php | 6 +- 2 files changed, 133 insertions(+), 11 deletions(-) diff --git a/bug-bash/ForcedDecision.php b/bug-bash/ForcedDecision.php index 05079bf7..f1a4c4a3 100644 --- a/bug-bash/ForcedDecision.php +++ b/bug-bash/ForcedDecision.php @@ -5,33 +5,142 @@ require_once '../vendor/autoload.php'; require_once '../bug-bash/_bug-bash-autoload.php'; -use Monolog\Logger; -use Optimizely\Logger\DefaultLogger; -use Optimizely\Notification\NotificationType; +use Optimizely\Decide\OptimizelyDecideOption; use Optimizely\Optimizely; +use Optimizely\OptimizelyDecisionContext; use Optimizely\OptimizelyFactory; +use Optimizely\OptimizelyForcedDecision; use Optimizely\OptimizelyUserContext; // 1. Change this SDK key to your project's SDK Key const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; -// 2. Add an event to your project, adding it to your Experiment flag as a metric, then set the key here -const EVENT_KEY = 'version_presented'; +// 2. Add a Targeted Delivery to your project, then flag key here +const TARGETED_DELIVERY_FLAG_KEY = 'product_sort'; -// 2. Uncomment each scenario 1 by 1 modifying the contents of the method +// 3. Add a Targeted Delivery to your project, then flag key here +const AB_EXPERIMENT_FLAG_KEY = 'product_version'; + +// 4. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. $test = new ForcedDecisionTests(); +$test->forcedDecisionForAFlag(); +$test->forcedDecisionForExperiment(); +$test->forcedDecisionForDeliveryRule(); +$test->getForcedDecision(); +$test->removeSingleForcedDecisions(); +$test->removeAllForcedDecisions(); -// 3. Change the current folder into the bug-bash directory if you've not already +// 5. Change the current folder into the bug-bash directory if you've not already // cd bug-bash/ -// 4. Run the following command to execute the uncommented tests above: +// 6. Run the following command to execute the uncommented tests above: // php ForcedDecision.php // https://docs.developers.optimizely.com/feature-experimentation/docs/forced-decision-methods-php class ForcedDecisionTests { + // set a forced decision for a flag + public function forcedDecisionForAFlag(): void + { + $maybeARandomFlagKey = "maybe_a_random_flag_key"; + $decisionContext = new OptimizelyDecisionContext($maybeARandomFlagKey, "some_rule_key"); + $forceDecision = new OptimizelyForcedDecision("some_variation_key"); + $this->userContext->setForcedDecision($decisionContext, $forceDecision); + + // code under test + $decision = $this->userContext->decide($maybeARandomFlagKey, [OptimizelyDecideOption::INCLUDE_REASONS]); + + $this->printDecision($decision, "Check your expected decision properties for this flag"); + } + + // set a forced decision for an ab-test experiment rule + public function forcedDecisionForExperiment(): void + { + $decisionContext = new OptimizelyDecisionContext(AB_EXPERIMENT_FLAG_KEY, "some_rule_key"); + $forceDecision = new OptimizelyForcedDecision("some_variation_key"); + $this->userContext->setForcedDecision($decisionContext, $forceDecision); + + // code under test + $decision = $this->userContext->decide(AB_EXPERIMENT_FLAG_KEY, [OptimizelyDecideOption::INCLUDE_REASONS]); + + $this->printDecision($decision, "Check your expected decision properties for this experiment rule"); + } + + // set a forced variation for a delivery rule + public function forcedDecisionForDeliveryRule(): void + { + $decisionContext = new OptimizelyDecisionContext(TARGETED_DELIVERY_FLAG_KEY, "some_rule_key"); + $forceDecision = new OptimizelyForcedDecision("some_variation_key"); + $this->userContext->setForcedDecision($decisionContext, $forceDecision); + + // code under test + $decision = $this->userContext->decide(TARGETED_DELIVERY_FLAG_KEY, [OptimizelyDecideOption::INCLUDE_REASONS]); + + $this->printDecision($decision, "Check your expected decision properties for this delivery rule"); + } + + // get forced variations + public function getForcedDecision(): void + { + $decisionContext = new OptimizelyDecisionContext(AB_EXPERIMENT_FLAG_KEY, "some_rule_key"); + $forceDecision = new OptimizelyForcedDecision("some_variation_key"); + $this->userContext->setForcedDecision($decisionContext, $forceDecision); + + $retrievedForcedDecision = $this->userContext->getForcedDecision($decisionContext); // code under test + + print ">>> $this->outputTag variationKey = $retrievedForcedDecision"; + } + + // remove forced variations + public function removeSingleForcedDecisions(): void + { + $forcedDecisionThatWillBeRemoved = new OptimizelyForcedDecision("some_variation_key"); + $forcedDecisionThatShouldBeKept = new OptimizelyForcedDecision("some_other_variation_key"); + $this->userContext->setForcedDecision( + new OptimizelyDecisionContext(AB_EXPERIMENT_FLAG_KEY, "some_rule_key"), + $forcedDecisionThatWillBeRemoved + ); + $this->userContext->setForcedDecision( + new OptimizelyDecisionContext(TARGETED_DELIVERY_FLAG_KEY, "some_rule_key"), + $forcedDecisionThatShouldBeKept + ); + + $this->userContext->removeForcedDecision($forcedDecisionThatWillBeRemoved); // code under test + $removed = $this->userContext->getForcedDecision($forcedDecisionThatWillBeRemoved); + $kept = $this->userContext->getForcedDecision($forcedDecisionThatShouldBeKept); + + // This forced decision should return null because we just removed it + print ">>> $this->outputTag Removed forced decision should be null: $removed"; + + // This forced decision should return since we did not remove it + print ">>> $this->outputTag Kept forced decision not be null = $kept"; + } + + public function removeAllForcedDecisions(): void + { + $forcedDecisionThatShouldBeRemoved = new OptimizelyForcedDecision("some_variation_key"); + $forcedDecisionThatShouldAlsoBeRemoved = new OptimizelyForcedDecision("some_other_variation_key"); + $this->userContext->setForcedDecision( + new OptimizelyDecisionContext(AB_EXPERIMENT_FLAG_KEY, "some_rule_key"), + $forcedDecisionThatShouldBeRemoved + ); + $this->userContext->setForcedDecision( + new OptimizelyDecisionContext(TARGETED_DELIVERY_FLAG_KEY, "some_rule_key"), + $forcedDecisionThatShouldAlsoBeRemoved + ); + + $this->userContext->removeAllForcedDecisions(); // code under test + $wasRemoved = $this->userContext->getForcedDecision($forcedDecisionThatShouldBeRemoved); + $alsoRemoved = $this->userContext->getForcedDecision($forcedDecisionThatShouldAlsoBeRemoved); + + // This forced decision should return null because we just removed it + print ">>> $this->outputTag Forced decision should be null since it was removed: $wasRemoved"; + + // This forced decision should return since we did not remove it + print ">>> $this->outputTag Second forced decision should also be null since it too was removed = $alsoRemoved"; + } private Optimizely $optimizelyClient; private string $userId; @@ -46,4 +155,17 @@ public function __construct() $attributes = ['eats_vegetables' => true, 'age' => 7, 'favorite_vegetable' => 'turnips']; $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); } + + private function printDecision($decision, $message): void + { + $enabled = $decision->getEnabled() ? "true" : "false"; + + print ">>> [$this->outputTag] $message: + enabled: $enabled, + flagKey: {$decision->getFlagKey()}, + ruleKey: {$decision->getRuleKey()}, + variationKey: {$decision->getVariationKey()}, + variables: " . print_r($decision->getVariables(), true) . ", + reasons: " . print_r($decision->getReasons(), true) . "\r\n"; + } } diff --git a/bug-bash/TrackEvent.php b/bug-bash/TrackEvent.php index dce4d9ce..c2fa8991 100644 --- a/bug-bash/TrackEvent.php +++ b/bug-bash/TrackEvent.php @@ -18,7 +18,7 @@ // 2. Add an event to your project, adding it to your Experiment flag as a metric, then set the key here const EVENT_KEY = 'version_presented'; -// 2. Uncomment each scenario 1 by 1 modifying the contents of the method +// 3. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. $test = new TrackEventTests(); @@ -27,10 +27,10 @@ // $test->checkConversionEventLogIsNOTDispatchedOnTrackEventForInvalidEventName(); // $test->testEventTagsShowInDispatchedEventAndAppOptimizelyCom(); -// 3. Change the current folder into the bug-bash directory if you've not already +// 4. Change the current folder into the bug-bash directory if you've not already // cd bug-bash/ -// 4. Run the following command to execute the uncommented tests above: +// 5. Run the following command to execute the uncommented tests above: // php TrackEvent.php // https://docs.developers.optimizely.com/feature-experimentation/docs/track-event-php From 01af3ee117b0bb8799d3e89ad28e77fb911ac250 Mon Sep 17 00:00:00 2001 From: Mike Chu <104384559+mikechu-optimizely@users.noreply.github.com> Date: Mon, 5 Jun 2023 20:29:50 +0000 Subject: [PATCH 33/42] Remove sensitive info --- bug-bash/Decide.php | 4 ++-- bug-bash/DecideAll.php | 2 +- bug-bash/DecideForKeys.php | 4 ++-- bug-bash/ForcedDecision.php | 18 +++++++++--------- bug-bash/TrackEvent.php | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/bug-bash/Decide.php b/bug-bash/Decide.php index 3125118c..d68ebe1c 100644 --- a/bug-bash/Decide.php +++ b/bug-bash/Decide.php @@ -14,10 +14,10 @@ use Optimizely\OptimizelyUserContext; // 1. Change this SDK key to your project's SDK Key -const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; +const SDK_KEY = ''; // 2. Change this to your flag key -const FLAG_KEY = 'product_sort'; +const FLAG_KEY = ''; // 3. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. diff --git a/bug-bash/DecideAll.php b/bug-bash/DecideAll.php index 6488e61d..92c3cffd 100644 --- a/bug-bash/DecideAll.php +++ b/bug-bash/DecideAll.php @@ -14,7 +14,7 @@ use Optimizely\OptimizelyUserContext; // 1. Change this SDK key to your project's SDK Key -const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; +const SDK_KEY = ''; // 2. Create additional flag keys in your project (2+) diff --git a/bug-bash/DecideForKeys.php b/bug-bash/DecideForKeys.php index f1f86378..b059b49a 100644 --- a/bug-bash/DecideForKeys.php +++ b/bug-bash/DecideForKeys.php @@ -14,10 +14,10 @@ use Optimizely\OptimizelyUserContext; // 1. Change this SDK key to your project's SDK Key -const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; +const SDK_KEY = ''; // 2. Check that you have 3+ flag keys in your project and add them here -const FLAG_KEYS = ['product_sort', 'marketing_banner', 'product_version']; +const FLAG_KEYS = ['', '', '']; // 3. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. diff --git a/bug-bash/ForcedDecision.php b/bug-bash/ForcedDecision.php index f1a4c4a3..9a44035d 100644 --- a/bug-bash/ForcedDecision.php +++ b/bug-bash/ForcedDecision.php @@ -13,24 +13,24 @@ use Optimizely\OptimizelyUserContext; // 1. Change this SDK key to your project's SDK Key -const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; +const SDK_KEY = ''; // 2. Add a Targeted Delivery to your project, then flag key here -const TARGETED_DELIVERY_FLAG_KEY = 'product_sort'; +const TARGETED_DELIVERY_FLAG_KEY = ''; // 3. Add a Targeted Delivery to your project, then flag key here -const AB_EXPERIMENT_FLAG_KEY = 'product_version'; +const AB_EXPERIMENT_FLAG_KEY = ''; // 4. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. $test = new ForcedDecisionTests(); $test->forcedDecisionForAFlag(); -$test->forcedDecisionForExperiment(); -$test->forcedDecisionForDeliveryRule(); -$test->getForcedDecision(); -$test->removeSingleForcedDecisions(); -$test->removeAllForcedDecisions(); +// $test->forcedDecisionForExperiment(); +// $test->forcedDecisionForDeliveryRule(); +// $test->getForcedDecision(); +// $test->removeSingleForcedDecisions(); +// $test->removeAllForcedDecisions(); // 5. Change the current folder into the bug-bash directory if you've not already // cd bug-bash/ @@ -90,7 +90,7 @@ public function getForcedDecision(): void $retrievedForcedDecision = $this->userContext->getForcedDecision($decisionContext); // code under test - print ">>> $this->outputTag variationKey = $retrievedForcedDecision"; + print ">>> $this->outputTag Get Forced Variation = $retrievedForcedDecision"; } // remove forced variations diff --git a/bug-bash/TrackEvent.php b/bug-bash/TrackEvent.php index c2fa8991..e77bb1e5 100644 --- a/bug-bash/TrackEvent.php +++ b/bug-bash/TrackEvent.php @@ -13,10 +13,10 @@ use Optimizely\OptimizelyUserContext; // 1. Change this SDK key to your project's SDK Key -const SDK_KEY = 'K4UmaV5Pk7cEh2hbcjgwe'; +const SDK_KEY = ''; // 2. Add an event to your project, adding it to your Experiment flag as a metric, then set the key here -const EVENT_KEY = 'version_presented'; +const EVENT_KEY = ''; // 3. Uncomment each scenario 1 by 1 modifying the contents of the method // to test additional scenarios. From 94d211e94766f512a622dd1c48ffb34632508250 Mon Sep 17 00:00:00 2001 From: Matjaz Pirnovar Date: Tue, 6 Jun 2023 21:40:34 +0000 Subject: [PATCH 34/42] Added second part for forced decisions - not necessary, just a advanced addition. And Optimizely config. --- bug-bash/ForcedDecisionPart2.php | 321 +++++++++++++++++++++++++++++++ bug-bash/OptiConfig.php | 112 +++++++++++ 2 files changed, 433 insertions(+) create mode 100644 bug-bash/ForcedDecisionPart2.php create mode 100644 bug-bash/OptiConfig.php diff --git a/bug-bash/ForcedDecisionPart2.php b/bug-bash/ForcedDecisionPart2.php new file mode 100644 index 00000000..b3b9dab1 --- /dev/null +++ b/bug-bash/ForcedDecisionPart2.php @@ -0,0 +1,321 @@ + expected result is variation a'.PHP_EOL; +echo ' ---------------------'.PHP_EOL; + +$user = $optimizelyClient->createUserContext($userId, array("age"=> 20)); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert('variation_a' == $decideDecision->getVariationKey()); + +echo PHP_EOL . ' Set forced decision w flag1 and variation b' . PHP_EOL; +echo ' Call decide -----> expected variation b in decide decision' . PHP_EOL; +echo ' ---------------------'; + +$context = new OptimizelyDecisionContext('flag1', null); +$decision = new OptimizelyForcedDecision('variation_b'); +$user->setForcedDecision($context, $decision); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert ('variation_b' == $decideDecision->getVariationKey()); + +echo PHP_EOL . ' Set forced decision with flag1 and variation c (invalid)' . PHP_EOL; +echo ' Call decide ----> expected variation a' . PHP_EOL; +echo ' ---------------------' . PHP_EOL; +$context = new OptimizelyDecisionContext('flag1', null); +$decision = new OptimizelyForcedDecision('variation_c'); +$user->setForcedDecision($context, $decision); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert ('variation_a' == $decideDecision->getVariationKey()); + +// E-to-D (rule key = “flag1_experiment”): +// ------------------------------------------- +// Set user context, userId any, age = 20 (bucketed) +// Call decide with flag1 ---> expected result is variation a in the decide decision +// Set forced decision w flag1 and rule key “flag1_experiment”, and variation b +// Call decide -----> expected variation b in decide decision +// Set forced decision with flag1 and rule key “flag1_experiment” and invalid variation c +// Call decide ----> expected variation a + +echo PHP_EOL . PHP_EOL . '==================================='; +echo 'E-to-D (rule key = “flag1_experiment”):'; +echo '==================================='.PHP_EOL; + +echo ' Set user context, userId any, age = 20 (bucketed)'.PHP_EOL; +echo ' Call decide with flag1 ---> expected result is variation a'.PHP_EOL; +echo ' ---------------------'.PHP_EOL; + +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert ('variation_a' == $decideDecision->getVariationKey()); + +echo PHP_EOL . ' Set forced decision with flag1 and rule flag1_experiment and variation b' . PHP_EOL; +echo ' Call decide -----> expected variation_b in decide decision' . PHP_EOL; +echo ' ---------------------'; + +$context = new OptimizelyDecisionContext('flag1', 'flag1_experiment'); +$decision = new OptimizelyForcedDecision('variation_b'); +$user->setForcedDecision($context, $decision); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert ('variation_b' == $decideDecision->getVariationKey()); + +echo PHP_EOL . ' Set forced decision with flag1 and rule flag1_experiment and variation c (Invalid)' . PHP_EOL; +echo ' Call decide -----> expected variation a in decide decision' . PHP_EOL; +echo ' ---------------------'; + +$context = new OptimizelyDecisionContext('flag1', 'flag1_experiment'); +$decision = new OptimizelyForcedDecision('variation_c'); +$user->setForcedDecision($context, $decision); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert ('variation_a' == $decideDecision->getVariationKey()); + +// D-to-D (rule key = “flag1_targeted_delivery”): +// ------------------------------------------- +// Set user context, userId any, country = “US” (bucketed) +// Call decide with flag1 ---> expected result is “on” in the decide decision +// Set forced decision w flag1 and rule key “flag1_targeted_delivery”, and variation b +// Call decide -----> expected variation b in decide decision +// Set forced decision with flag1 and rule key “flag1_targeted_delivery” and invalid variation c +// Call decide ----> expected “on” + +echo PHP_EOL . PHP_EOL . '==================================='; +echo 'D-to-D (rule key = “flag1_targeted_delivery”):'; +echo '==================================='.PHP_EOL; + +echo ' Set user context, userId any, country = US (bucketed)'.PHP_EOL; +echo ' Call decide with flag1 ---> expected result is on on'.PHP_EOL; +echo ' ---------------------'.PHP_EOL; + +$user = $optimizelyClient->createUserContext($userId, array("country"=> "US")); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert ('on' == $decideDecision->getVariationKey()); + +echo PHP_EOL . ' Set forced decision with flag1 and rule “flag1_targeted_delivery” and variation b' . PHP_EOL; +echo ' Call decide -----> expected variation_b in decide decision' . PHP_EOL; +echo ' ---------------------'; + +$context = new OptimizelyDecisionContext('flag1', 'flag1_targeted_delivery'); +$decision = new OptimizelyForcedDecision('variation_b'); +$user->setForcedDecision($context, $decision); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert ('variation_b' == $decideDecision->getVariationKey()); + +echo PHP_EOL . ' Set forced decision with flag1 and rule flag1_targeted_delivery and variation c (Invalid)' . PHP_EOL; +echo ' Call decide -----> expected on in decide decision' . PHP_EOL; +echo ' ---------------------'; + +$context = new OptimizelyDecisionContext('flag1', 'flag1_targeted_delivery'); +$decision = new OptimizelyForcedDecision('variation_c'); +$user->setForcedDecision($context, $decision); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert ('on' == $decideDecision->getVariationKey()); + + +// ================================ +// PART 2 b) Repeat above three blocks, this time user DOES NOT meet audience conditions +// ================================ + +// F-to-D (no rule key specified): +// ------------------------------------------- +// Set user context, userId any, age = 0 (not bucketed) +// Call decide with flag1 ---> expected result is “off” (everyone else) +// Set forced decision w flag1, variation b +// Call decide -----> expected variation b in decide decision + +echo PHP_EOL . PHP_EOL . '==================================='; +echo 'F-to-D (no rule key specified):'; +echo '==================================='.PHP_EOL; + +echo ' Set user context, userId any, age = 0 (not bucketed)'.PHP_EOL; +echo ' Call decide with flag1 ---> expected result is off'.PHP_EOL; +echo ' ---------------------'.PHP_EOL; + +$user = $optimizelyClient->createUserContext($userId, array("age"=> 0)); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert('off' == $decideDecision->getVariationKey()); + +echo PHP_EOL . ' Set forced decision w flag1 and variation b' . PHP_EOL; +echo ' Call decide -----> expected variation b in decide decision' . PHP_EOL; +echo ' ---------------------'; + +$context = new OptimizelyDecisionContext('flag1', null); +$decision = new OptimizelyForcedDecision('variation_b'); +$user->setForcedDecision($context, $decision); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert ('variation_b' == $decideDecision->getVariationKey()); + + +// E-to-D (rule key = “flag1_experiment”): +// ------------------------------------------- +// Set user context, userId any, age = 0 ( not bucketed) +// Call decide with flag1 ---> expected result is “off” +// Set forced decision w flag1 and rule key “flag1_experiment”, and variation b +// Call decide -----> expected variation b in decide decision + +echo PHP_EOL . PHP_EOL . '==================================='; +echo 'E-to-D (rule key = “flag1_experiment”):'; +echo '==================================='.PHP_EOL; + +echo ' Set user context, userId any, age = 0 (not bucketed)'.PHP_EOL; +echo ' Call decide with flag1 ---> expected result is off'.PHP_EOL; +echo ' ---------------------'.PHP_EOL; + +$user = $optimizelyClient->createUserContext($userId, array("age"=> 0)); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert('off' == $decideDecision->getVariationKey()); + +echo PHP_EOL . ' Set forced decision w flag1 and rule flag1_experiment and variation b' . PHP_EOL; +echo ' Call decide -----> expected variation b in decide decision' . PHP_EOL; +echo ' ---------------------'; + +$context = new OptimizelyDecisionContext('flag1', 'flag1_experiment'); +$decision = new OptimizelyForcedDecision('variation_b'); +$user->setForcedDecision($context, $decision); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert ('variation_b' == $decideDecision->getVariationKey()); + + +// D-to-D (rule key = “flag1_targeted_delivery”): +// ------------------------------------------- +// Set user context, userId any, country = “MX” (not bucketed) +// Call decide with flag1 ---> expected result is “off” +// Set forced decision w flag1 and rule key “flag1_targeted_delivery”, and variation b +// Call decide -----> expected variation b in decide decision + + +echo PHP_EOL . PHP_EOL . '==================================='; +echo 'D-to-D (rule key = flag1_targeted_delivery):'; +echo '==================================='.PHP_EOL; + +echo ' Set user context, userId any, country = MX (not bucketed)'.PHP_EOL; +echo ' Call decide with flag1 and rule flag1_targeted_delivery ---> expected result is off'.PHP_EOL; +echo ' ---------------------'.PHP_EOL; + +$user = $optimizelyClient->createUserContext($userId, array("country"=> "MX")); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert('off' == $decideDecision->getVariationKey()); + +echo PHP_EOL . ' Set forced decision w flag1 and rule flag1_targeted_delivery and variation b' . PHP_EOL; +echo ' Call decide -----> expected variation b in decide decision' . PHP_EOL; +echo ' ---------------------'; + +$context = new OptimizelyDecisionContext('flag1', 'flag1_targeted_delivery'); +$decision = new OptimizelyForcedDecision('variation_b'); +$user->setForcedDecision($context, $decision); +$decideDecision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); +echo ' VARIATION >>> ' . $decideDecision->getVariationKey() . PHP_EOL; +// ASSERT YOU GET CORRECT VARIATION +echo ' REASONS >>> ' . json_encode($decideDecision->getReasons()) . PHP_EOL; +// VERIFY REASONS ARE CORRECT +assert ('variation_b' == $decideDecision->getVariationKey()); + +// ================================ +// Part 3 +// ================================ +$user = $optimizelyClient->createUserContext($userId); + +$user->setForcedDecision(new OptimizelyDecisionContext('F1', null), + new OptimizelyForcedDecision('V1')); +$user->setForcedDecision(new OptimizelyDecisionContext('F1', 'E1'), + new OptimizelyForcedDecision('V3')); + +assert($user->getForcedDecision(new OptimizelyDecisionContext('F1', null)) == 'V1'); +assert($user->getForcedDecision(new OptimizelyDecisionContext('F1', 'E1')) == 'V3'); +$user->setForcedDecision(new OptimizelyDecisionContext('F1', null), + new OptimizelyForcedDecision('V5')); +$user->setForcedDecision(new OptimizelyDecisionContext('F1', 'E1'), + new OptimizelyForcedDecision('V5')); + +assert($user->getForcedDecision(new OptimizelyDecisionContext('F1', null)) == 'V5'); +assert($user->getForcedDecision(new OptimizelyDecisionContext('F1', 'E1')) == 'V5'); +$user->removeForcedDecision(new OptimizelyDecisionContext('F1', null)); +echo $user->getForcedDecision(new OptimizelyDecisionContext('F1', null)) == null; +assert($user->getForcedDecision(new OptimizelyDecisionContext('F1', null)) == null); +assert($user->getForcedDecision(new OptimizelyDecisionContext('F1', 'E1')) == 'V5'); + +$user->removeForcedDecision(new OptimizelyDecisionContext('F1', 'E1')); + +assert($user->getForcedDecision(new OptimizelyDecisionContext('F1', null)) == null); +assert($user->getForcedDecision(new OptimizelyDecisionContext('F1', 'E1')) == null); + +$user->removeAllForcedDecisions(); + +assert($user->getForcedDecision(new OptimizelyDecisionContext('F2', null)) == null); +assert($user->getForcedDecision(new OptimizelyDecisionContext('F2', 'E1')) == null); + + + +// ?> \ No newline at end of file diff --git a/bug-bash/OptiConfig.php b/bug-bash/OptiConfig.php new file mode 100644 index 00000000..8a610b75 --- /dev/null +++ b/bug-bash/OptiConfig.php @@ -0,0 +1,112 @@ +createUserContext('user123', ['attribute1' => 'hello']); +$decision = $user->decide('flag1', [OptimizelyDecideOption::INCLUDE_REASONS]); + +$reasons = $decision->getReasons(); +echo "[OptimizelyConfig] reasons: " . json_encode($reasons) . PHP_EOL; +echo "[OptimizelyConfig - flag key]: " . $decision->getFlagKey() . PHP_EOL; +echo "[OptimizelyConfig - rule key]: " . $decision->getFlagKey() . PHP_EOL; +echo "[OptimizelyConfig - enabled]: " . $decision->getEnabled() . PHP_EOL; +echo "[OptimizelyConfig - variation key]: " . $decision->getVariationKey() . PHP_EOL; +$variables = $decision->getVariables(); +echo "[OptimizelyConfig - variables]: " . json_encode($variables) . PHP_EOL; +echo PHP_EOL; + +$user->trackEvent('myevent'); + +echo "===========================" . PHP_EOL; +echo " OPTIMIZELY CONFIG V2 " . PHP_EOL; +echo "===========================" . PHP_EOL . PHP_EOL; + +$config = $optimizelyClient->getOptimizelyConfig(); +// get the revision +echo "[OptimizelyConfig] revision:" . $config->getRevision() . PHP_EOL; + +// get the SDK key +echo "[OptimizelyConfig] SDKKey:" . $config->getSdkKey() . PHP_EOL; + +// get the environment key +echo "[OptimizelyConfig] environmentKey:" . $config->getEnvironmentKey() . PHP_EOL; + +// all attributes +echo "[OptimizelyConfig] attributes:" . PHP_EOL; +$attributes = $config->getAttributes(); +foreach($attributes as $attribute) +{ + echo "[OptimizelyAttribute] -- (id, key) = ((" . $attribute->getId(). "), (". $attribute->getKey() . "))" . PHP_EOL; +} + +// all audiences +echo "[OptimizelyConfig] audiences:" . PHP_EOL; +$audiences = $config->getAudiences(); +foreach($audiences as $audience) +{ + echo "[OptimizelyAudience] -- (id, key, conditions) = ((" . $audience->getId(). "), (". $audience->getName() . "), (". $audience->getConditions() . "))" . PHP_EOL; +} + +// all events +echo "[OptimizelyConfig] events:" . PHP_EOL; +$events = $config->getEvents(); +foreach($events as $event) +{ + echo "[OptimizelyEvent] -- (id, key, experimentIds) = ((" . $event->getId(). "), (". $event->getKey() . "), (". $event->getExperimentIds() . "))" . PHP_EOL; +} + +// all flags +$flags = array_values((array)$config->getFeaturesMap()); +foreach ($flags as $flag) +{ + // Use experimentRules and deliverRules + $experimentRules = $flag->getExperimentRules(); + echo "------ Experiment rules -----" . PHP_EOL; + foreach ($experimentRules as $experimentRule) + { + echo "---" . PHP_EOL; + echo "[OptimizelyExperiment] - experiment rule-key = " . $experimentRule->getKey() . PHP_EOL; + echo "[OptimizelyExperiment] - experiment audiences = " . PHP_EOL;$experimentRule->getExperimentAudiences(); + // all variations + $variations = array_values((array)$experimentRule->getVariationsMap()); + foreach ($variations as $variation) + { + echo "[OptimizelyVariation] -- variation = { key: " . $variation->getKey() . ", . id: " . $variation->getId() . ", featureEnabled: " . $variation->getFeatureEnabled() . " }" . PHP_EOL; + $variables = $variation->getVariablesMap(); + foreach ($variables as $variable) + { + echo "[OptimizelyVariable] --- variable: " . $variable->getKey() . ", " . $variable->getId() . PHP_EOL; + // use variable data here. + } + // use experimentRule data here. + } + } + $deliveryRules = $flag->getDeliveryRules(); + echo "------ Delivery rules -----" . PHP_EOL; + foreach ($deliveryRules as $deliveryRule) + { + echo "---"; + echo "[OptimizelyExperiment] - delivery rule-key = " . $deliveryRule->getKey() . PHP_EOL; + echo "[OptimizelyExperiment] - delivery audiences = " . $deliveryRule->getExperimentAudiences() . PHP_EOL; + + // use delivery rule data here... + } +} +// $optimizelyClient->notificationCenter->addNotificationListener( +// NotificationType::OPTIMIZELY_CONFIG_UPDATE, +// function () { +// $newConfig = $optimizelyClient->getOptimizelyConfig(); +// echo "[OptimizelyConfig] revision = " . $newConfig ? $newConfig->getRevision() : "" . PHP_EOL; + // } +// ); + From 353aa317e4b6dedc5bf5ec2382c26f2b5ef36bec Mon Sep 17 00:00:00 2001 From: Matjaz Pirnovar Date: Thu, 8 Jun 2023 18:32:45 -0700 Subject: [PATCH 35/42] Delete ForcedDecision.php removing this file, duplicate --- bug-bash/ForcedDecision.php | 171 ------------------------------------ 1 file changed, 171 deletions(-) delete mode 100644 bug-bash/ForcedDecision.php diff --git a/bug-bash/ForcedDecision.php b/bug-bash/ForcedDecision.php deleted file mode 100644 index 9a44035d..00000000 --- a/bug-bash/ForcedDecision.php +++ /dev/null @@ -1,171 +0,0 @@ -'; - -// 2. Add a Targeted Delivery to your project, then flag key here -const TARGETED_DELIVERY_FLAG_KEY = ''; - -// 3. Add a Targeted Delivery to your project, then flag key here -const AB_EXPERIMENT_FLAG_KEY = ''; - -// 4. Uncomment each scenario 1 by 1 modifying the contents of the method -// to test additional scenarios. - -$test = new ForcedDecisionTests(); -$test->forcedDecisionForAFlag(); -// $test->forcedDecisionForExperiment(); -// $test->forcedDecisionForDeliveryRule(); -// $test->getForcedDecision(); -// $test->removeSingleForcedDecisions(); -// $test->removeAllForcedDecisions(); - -// 5. Change the current folder into the bug-bash directory if you've not already -// cd bug-bash/ - -// 6. Run the following command to execute the uncommented tests above: -// php ForcedDecision.php - -// https://docs.developers.optimizely.com/feature-experimentation/docs/forced-decision-methods-php -class ForcedDecisionTests -{ - // set a forced decision for a flag - public function forcedDecisionForAFlag(): void - { - $maybeARandomFlagKey = "maybe_a_random_flag_key"; - $decisionContext = new OptimizelyDecisionContext($maybeARandomFlagKey, "some_rule_key"); - $forceDecision = new OptimizelyForcedDecision("some_variation_key"); - $this->userContext->setForcedDecision($decisionContext, $forceDecision); - - // code under test - $decision = $this->userContext->decide($maybeARandomFlagKey, [OptimizelyDecideOption::INCLUDE_REASONS]); - - $this->printDecision($decision, "Check your expected decision properties for this flag"); - } - - // set a forced decision for an ab-test experiment rule - public function forcedDecisionForExperiment(): void - { - $decisionContext = new OptimizelyDecisionContext(AB_EXPERIMENT_FLAG_KEY, "some_rule_key"); - $forceDecision = new OptimizelyForcedDecision("some_variation_key"); - $this->userContext->setForcedDecision($decisionContext, $forceDecision); - - // code under test - $decision = $this->userContext->decide(AB_EXPERIMENT_FLAG_KEY, [OptimizelyDecideOption::INCLUDE_REASONS]); - - $this->printDecision($decision, "Check your expected decision properties for this experiment rule"); - } - - // set a forced variation for a delivery rule - public function forcedDecisionForDeliveryRule(): void - { - $decisionContext = new OptimizelyDecisionContext(TARGETED_DELIVERY_FLAG_KEY, "some_rule_key"); - $forceDecision = new OptimizelyForcedDecision("some_variation_key"); - $this->userContext->setForcedDecision($decisionContext, $forceDecision); - - // code under test - $decision = $this->userContext->decide(TARGETED_DELIVERY_FLAG_KEY, [OptimizelyDecideOption::INCLUDE_REASONS]); - - $this->printDecision($decision, "Check your expected decision properties for this delivery rule"); - } - - // get forced variations - public function getForcedDecision(): void - { - $decisionContext = new OptimizelyDecisionContext(AB_EXPERIMENT_FLAG_KEY, "some_rule_key"); - $forceDecision = new OptimizelyForcedDecision("some_variation_key"); - $this->userContext->setForcedDecision($decisionContext, $forceDecision); - - $retrievedForcedDecision = $this->userContext->getForcedDecision($decisionContext); // code under test - - print ">>> $this->outputTag Get Forced Variation = $retrievedForcedDecision"; - } - - // remove forced variations - public function removeSingleForcedDecisions(): void - { - $forcedDecisionThatWillBeRemoved = new OptimizelyForcedDecision("some_variation_key"); - $forcedDecisionThatShouldBeKept = new OptimizelyForcedDecision("some_other_variation_key"); - $this->userContext->setForcedDecision( - new OptimizelyDecisionContext(AB_EXPERIMENT_FLAG_KEY, "some_rule_key"), - $forcedDecisionThatWillBeRemoved - ); - $this->userContext->setForcedDecision( - new OptimizelyDecisionContext(TARGETED_DELIVERY_FLAG_KEY, "some_rule_key"), - $forcedDecisionThatShouldBeKept - ); - - $this->userContext->removeForcedDecision($forcedDecisionThatWillBeRemoved); // code under test - $removed = $this->userContext->getForcedDecision($forcedDecisionThatWillBeRemoved); - $kept = $this->userContext->getForcedDecision($forcedDecisionThatShouldBeKept); - - // This forced decision should return null because we just removed it - print ">>> $this->outputTag Removed forced decision should be null: $removed"; - - // This forced decision should return since we did not remove it - print ">>> $this->outputTag Kept forced decision not be null = $kept"; - } - - public function removeAllForcedDecisions(): void - { - $forcedDecisionThatShouldBeRemoved = new OptimizelyForcedDecision("some_variation_key"); - $forcedDecisionThatShouldAlsoBeRemoved = new OptimizelyForcedDecision("some_other_variation_key"); - $this->userContext->setForcedDecision( - new OptimizelyDecisionContext(AB_EXPERIMENT_FLAG_KEY, "some_rule_key"), - $forcedDecisionThatShouldBeRemoved - ); - $this->userContext->setForcedDecision( - new OptimizelyDecisionContext(TARGETED_DELIVERY_FLAG_KEY, "some_rule_key"), - $forcedDecisionThatShouldAlsoBeRemoved - ); - - $this->userContext->removeAllForcedDecisions(); // code under test - $wasRemoved = $this->userContext->getForcedDecision($forcedDecisionThatShouldBeRemoved); - $alsoRemoved = $this->userContext->getForcedDecision($forcedDecisionThatShouldAlsoBeRemoved); - - // This forced decision should return null because we just removed it - print ">>> $this->outputTag Forced decision should be null since it was removed: $wasRemoved"; - - // This forced decision should return since we did not remove it - print ">>> $this->outputTag Second forced decision should also be null since it too was removed = $alsoRemoved"; - } - - private Optimizely $optimizelyClient; - private string $userId; - private ?OptimizelyUserContext $userContext; - private string $outputTag = "Forced Decision"; - - public function __construct() - { - $this->optimizelyClient = OptimizelyFactory::createDefaultInstance(SDK_KEY); - - $this->userId = 'user-' . mt_rand(10, 99); - $attributes = ['eats_vegetables' => true, 'age' => 7, 'favorite_vegetable' => 'turnips']; - $this->userContext = $this->optimizelyClient->createUserContext($this->userId, $attributes); - } - - private function printDecision($decision, $message): void - { - $enabled = $decision->getEnabled() ? "true" : "false"; - - print ">>> [$this->outputTag] $message: - enabled: $enabled, - flagKey: {$decision->getFlagKey()}, - ruleKey: {$decision->getRuleKey()}, - variationKey: {$decision->getVariationKey()}, - variables: " . print_r($decision->getVariables(), true) . ", - reasons: " . print_r($decision->getReasons(), true) . "\r\n"; - } -} From 155dc1248d4098c95a0e0a4bab8dbd6e91638a8e Mon Sep 17 00:00:00 2001 From: Matjaz Pirnovar Date: Thu, 8 Jun 2023 18:33:06 -0700 Subject: [PATCH 36/42] Rename ForcedDecisionPart2.php to ForcedDecision.php --- bug-bash/{ForcedDecisionPart2.php => ForcedDecision.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename bug-bash/{ForcedDecisionPart2.php => ForcedDecision.php} (99%) diff --git a/bug-bash/ForcedDecisionPart2.php b/bug-bash/ForcedDecision.php similarity index 99% rename from bug-bash/ForcedDecisionPart2.php rename to bug-bash/ForcedDecision.php index b3b9dab1..916c9a86 100644 --- a/bug-bash/ForcedDecisionPart2.php +++ b/bug-bash/ForcedDecision.php @@ -318,4 +318,4 @@ -// ?> \ No newline at end of file +// ?> From df5089b4ff017c9a8ac48707b8e8cb4478addf11 Mon Sep 17 00:00:00 2001 From: Matjaz Pirnovar Date: Thu, 8 Jun 2023 18:35:59 -0700 Subject: [PATCH 37/42] Update ForcedDecision.php --- bug-bash/ForcedDecision.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bug-bash/ForcedDecision.php b/bug-bash/ForcedDecision.php index 916c9a86..13b7251b 100644 --- a/bug-bash/ForcedDecision.php +++ b/bug-bash/ForcedDecision.php @@ -9,12 +9,14 @@ use Optimizely\OptimizelyForcedDecision; use Optimizely\Decide\OptimizelyDecideOption; -$optimizelyClient = new Optimizely(null, null, null, null, null, null, null, null, "X9mZd2WDywaUL9hZXyh9A"); +// To test forced decisions please add the SDK key, flag key and any attributes from your optimizely +// project in the code below. If no errors then forced decision test should pass. + +$optimizelyClient = new Optimizely(null, null, null, null, null, null, null, null, ""); $userId = 'user' . strval(rand(0, 1000001)); -// PART 2 a) echo '==================================='; echo 'F-to-D (no rule key specified):'; echo '==================================='.PHP_EOL; From 79c7e7bebbc7bee62a3d9fc5f87565fc653c3e0b Mon Sep 17 00:00:00 2001 From: Matjaz Pirnovar Date: Thu, 8 Jun 2023 18:38:08 -0700 Subject: [PATCH 38/42] Update OptiConfig.php --- bug-bash/OptiConfig.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bug-bash/OptiConfig.php b/bug-bash/OptiConfig.php index 8a610b75..a2b76439 100644 --- a/bug-bash/OptiConfig.php +++ b/bug-bash/OptiConfig.php @@ -8,8 +8,12 @@ use Optimizely\Optimizely; use Optimizely\Decide\OptimizelyDecideOption; +// To test optimizely config simply add your SDK key and attributes in, then run the file. +// You should be able to see unpacked entities from featureMap and experimentMap +// verify them and make sure some are not missing or error + // Instantiate an Optimizely client -$sdkKey = "TbrfRLeKvLyWGusqANoeR"; +$sdkKey = ""; // $optimizelyClient = new Optimizely($sdkKey); $optimizelyClient = new Optimizely(null, null, null, null, false, null, null, null, $sdkKey); $user = $optimizelyClient->createUserContext('user123', ['attribute1' => 'hello']); From aab2a609d0000781400193890c518d20bfbceb81 Mon Sep 17 00:00:00 2001 From: Matjaz Pirnovar Date: Thu, 8 Jun 2023 18:41:18 -0700 Subject: [PATCH 39/42] Update EventBuilder.php SDK minor release bump --- src/Optimizely/Event/Builder/EventBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Optimizely/Event/Builder/EventBuilder.php b/src/Optimizely/Event/Builder/EventBuilder.php index 9bea2845..8e957bd9 100644 --- a/src/Optimizely/Event/Builder/EventBuilder.php +++ b/src/Optimizely/Event/Builder/EventBuilder.php @@ -39,7 +39,7 @@ class EventBuilder /** * @const string Version of the Optimizely PHP SDK. */ - const SDK_VERSION = '3.9.4'; + const SDK_VERSION = '3.10.0'; /** * @var string URL to send event to. From ead6580f8858909c6b00d8371b4d0152af823462 Mon Sep 17 00:00:00 2001 From: Matjaz Pirnovar Date: Thu, 8 Jun 2023 18:42:33 -0700 Subject: [PATCH 40/42] Update EventBuilderTest.php release version bump in the test to 3.10.0 --- tests/EventTests/EventBuilderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/EventTests/EventBuilderTest.php b/tests/EventTests/EventBuilderTest.php index 32867557..6ee6df2b 100644 --- a/tests/EventTests/EventBuilderTest.php +++ b/tests/EventTests/EventBuilderTest.php @@ -69,7 +69,7 @@ protected function setUp() : void ]], 'revision' => '15', 'client_name' => 'php-sdk', - 'client_version' => '3.9.4', + 'client_version' => '3.10.0', 'anonymize_ip'=> false, 'enrich_decisions' => true, ]; From 4eae743ffe5c05f4cbfff12a4d6ec519acd242e2 Mon Sep 17 00:00:00 2001 From: Matjaz Pirnovar Date: Thu, 8 Jun 2023 18:47:30 -0700 Subject: [PATCH 41/42] Update EventBuilder.php-revert --- src/Optimizely/Event/Builder/EventBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Optimizely/Event/Builder/EventBuilder.php b/src/Optimizely/Event/Builder/EventBuilder.php index 8e957bd9..9bea2845 100644 --- a/src/Optimizely/Event/Builder/EventBuilder.php +++ b/src/Optimizely/Event/Builder/EventBuilder.php @@ -39,7 +39,7 @@ class EventBuilder /** * @const string Version of the Optimizely PHP SDK. */ - const SDK_VERSION = '3.10.0'; + const SDK_VERSION = '3.9.4'; /** * @var string URL to send event to. From d714b049a3514719fb6c216d98aae801f1882446 Mon Sep 17 00:00:00 2001 From: Matjaz Pirnovar Date: Thu, 8 Jun 2023 18:48:04 -0700 Subject: [PATCH 42/42] Update EventBuilderTest.php - revert --- tests/EventTests/EventBuilderTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/EventTests/EventBuilderTest.php b/tests/EventTests/EventBuilderTest.php index 6ee6df2b..32867557 100644 --- a/tests/EventTests/EventBuilderTest.php +++ b/tests/EventTests/EventBuilderTest.php @@ -69,7 +69,7 @@ protected function setUp() : void ]], 'revision' => '15', 'client_name' => 'php-sdk', - 'client_version' => '3.10.0', + 'client_version' => '3.9.4', 'anonymize_ip'=> false, 'enrich_decisions' => true, ]; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy