From a5b06ef2451ef075a51063f1d3af2ae8aca5dc88 Mon Sep 17 00:00:00 2001 From: Andy Leap <104936100+andrewleap-optimizely@users.noreply.github.com> Date: Tue, 17 Jan 2023 16:10:30 -0500 Subject: [PATCH 1/9] Create .gitpod.yml --- .gitpod.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .gitpod.yml diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 00000000..c1989f42 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,12 @@ +# This configuration file was automatically generated by Gitpod. +# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml) +# and commit this file to your remote git repository to share the goodness with others. + +# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart + +tasks: + - init: | + bundle install && + gem install optimizely-sdk && + rake build && + gem install pkg/optimizely-sdk-4.0.0.gem From 783ac23c28ef936d12b87945ffb0661efb603181 Mon Sep 17 00:00:00 2001 From: Matjaz Pirnovar Date: Thu, 19 Jan 2023 14:14:09 -0800 Subject: [PATCH 2/9] Create myapp.rb --- myapp.rb | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 myapp.rb diff --git a/myapp.rb b/myapp.rb new file mode 100644 index 00000000..f7a0a44f --- /dev/null +++ b/myapp.rb @@ -0,0 +1,34 @@ +require 'optimizely' +require 'optimizely/optimizely_factory' +require "logger" + + +# Initialize an Optimizely client +optimizely_client = Optimizely::OptimizelyFactory.custom_instance('TbrfRLeKvLyWGusqANoeR', nil, nil, logger=Optimizely::SimpleLogger.new(Logger::INFO)) + +# config = optimizely_client.get_optimizely_config + +attributes = {"laptop_os" => "mac"} + +# user = optimizely_client.create_user_context('12345', attributes) # regular attributes, user context takes any user id - important when running these 3 lines I need to adjust the audience in the app (use the correct one)!!! +user = optimizely_client.create_user_context('fs-id-12', attributes) # prebuilt segments (no lists), valid user id is fs-id-12 (matches DOB) +# user = optimizely_client.create_user_context('fs-id-6', attributes) # list segment, valid use is fs-id-6 + +sleep(1) # sleep is needed for datafile to load - check this, might be an issue + +user.fetch_qualified_segments() +segments = user.qualified_segments() + +if segments + puts " >>> SEGMENTS when segmnents exist: #{segments}" +else + puts " >>> SEGMENTS when no segments: #{segments}" +end + +decide_options = [Optimizely::Decide::OptimizelyDecideOption::INCLUDE_REASONS] +decision = user.decide('flag1', decide_options) +puts "\n >>> DECISION #{decision.as_json()}" + +user.track_event("myevent") + +optimizely_client.close() From 4de93c8194aa2f6655db94cc115fd8a77e941a02 Mon Sep 17 00:00:00 2001 From: Matjaz Pirnovar Date: Thu, 19 Jan 2023 17:06:30 -0800 Subject: [PATCH 3/9] add opti config, remove sleep time --- myapp.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/myapp.rb b/myapp.rb index f7a0a44f..ffc02419 100644 --- a/myapp.rb +++ b/myapp.rb @@ -6,7 +6,7 @@ # Initialize an Optimizely client optimizely_client = Optimizely::OptimizelyFactory.custom_instance('TbrfRLeKvLyWGusqANoeR', nil, nil, logger=Optimizely::SimpleLogger.new(Logger::INFO)) -# config = optimizely_client.get_optimizely_config +config = optimizely_client.get_optimizely_config attributes = {"laptop_os" => "mac"} @@ -14,8 +14,6 @@ user = optimizely_client.create_user_context('fs-id-12', attributes) # prebuilt segments (no lists), valid user id is fs-id-12 (matches DOB) # user = optimizely_client.create_user_context('fs-id-6', attributes) # list segment, valid use is fs-id-6 -sleep(1) # sleep is needed for datafile to load - check this, might be an issue - user.fetch_qualified_segments() segments = user.qualified_segments() From f3b0a0c90663e242a76c233a04231fead8674a71 Mon Sep 17 00:00:00 2001 From: Andy Leap Date: Thu, 9 Mar 2023 21:05:21 +0000 Subject: [PATCH 4/9] add tests --- myapp.rb | 169 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 150 insertions(+), 19 deletions(-) diff --git a/myapp.rb b/myapp.rb index ffc02419..e292e624 100644 --- a/myapp.rb +++ b/myapp.rb @@ -1,32 +1,163 @@ +# frozen_string_literal: true + require 'optimizely' +require 'optimizely/optimizely_user_context' require 'optimizely/optimizely_factory' -require "logger" +require 'optimizely/helpers/sdk_settings' +require 'optimizely/decide/optimizely_decide_option' +require 'logger' + +def fetch_and_decide(user_ctx) + # ========================================= + # Fetch Qualified Segments + decide + # ========================================= + + user_ctx.fetch_qualified_segments # to test segment options add one or both as argument: ['RESET_CACHE', 'IGNORE_CACHE'] + + options = [Optimizely::Decide::OptimizelyDecideOption::INCLUDE_REASONS] + decision = user_ctx.decide('flag1', options) + puts(' >>> DECISION ', decision.as_json) + + segments = user_ctx.qualified_segments + puts(' >>> SEGMENTS: ', segments) + + return unless segments + + segments.each do |segment| + is_qualified = user.is_qualified_for(segment) + puts(' >>> IS QUALIFIED: ', is_qualified) + end +end + +def send_event(optimizely_client) + identifiers = {'fs-user-id': 'fs-id-12', 'email': 'fs-bash-x@optimizely.com'} + # valid case + optimizely_client.send_odp_event(type: 'any', identifiers: identifiers, action: 'any') -# Initialize an Optimizely client -optimizely_client = Optimizely::OptimizelyFactory.custom_instance('TbrfRLeKvLyWGusqANoeR', nil, nil, logger=Optimizely::SimpleLogger.new(Logger::INFO)) + # # test missing/empty identifiers should not be allowed + optimizely_client.send_odp_event(action: 'any', identifiers: nil, type: 'any') + optimizely_client.send_odp_event(action: 'any', identifiers: {}, type: 'any') -config = optimizely_client.get_optimizely_config + # # test missing/empty action should not be allowed + optimizely_client.send_odp_event(action: '', identifiers: identifiers, type: 'any') + optimizely_client.send_odp_event(action: nil, identifiers: identifiers, type: 'any') +end + +# ============================================ +# CONFIG TYPE 1: +# default config, minimal settings +# ============================================ + +# TEST THE FOLLOWING: +# - test creating user context with regular attributes +# - test creating user context with prebuilt segments (no odp list), should get segments back, experiment should evaluate to true, decide response should look correct +# - truth table - TBD +# - test creating user context with prebuilt segment list, should get back a list of segments, experiment should evaluate to true, decide response should look correct +# - may not need truth table test here (check) +# - add RESET_CACHE and/or IGNORE_CACHE to fetch qualified segments call and repeat +# - test send event +# - verify events on ODP event inspector +# - in send_event function uncomment lines of code that test missing identifiers and action keys, verify appropriate error is produced +# - test audience segments (see spreadsheet +# - test implicit/explicit ODP events? +# - test integrations (no ODP integration added to project, integration is on, is off) + +def config_1 + optimizely_client = Optimizely::OptimizelyFactory.custom_instance('TbrfRLeKvLyWGusqANoeR', nil, nil, Optimizely::SimpleLogger.new(Logger::DEBUG)) + + attributes = {"laptop_os": 'mac'} -attributes = {"laptop_os" => "mac"} + # CASE 1 - REGULAR ATTRIBUTES, NO ODP + user = optimizely_client.create_user_context('user123', attributes) -# user = optimizely_client.create_user_context('12345', attributes) # regular attributes, user context takes any user id - important when running these 3 lines I need to adjust the audience in the app (use the correct one)!!! -user = optimizely_client.create_user_context('fs-id-12', attributes) # prebuilt segments (no lists), valid user id is fs-id-12 (matches DOB) -# user = optimizely_client.create_user_context('fs-id-6', attributes) # list segment, valid use is fs-id-6 + # CASE 2 - PREBUILT SEGMENTS, NO LIST SEGMENTS, valid user id is fs-id-12 (matehces DOB) + # IMPORTANT: before running - make sure that in app.optimizely AB experiment you switched audience to "audience2-prebuit segment (no list)" + # user = optimizely_client.create_user_context('fs-id-12', attributes) -user.fetch_qualified_segments() -segments = user.qualified_segments() + # CASE 3 - SEGMENT LIST/ARRAY, valid user id is fs-id-6 + # IMPORTANT: before running - make sure that in app.optimizely AB experiment you switched audience to "audience3-prebuilt segment list" + # user = optimizely_client.create_user_context('fs-id-6', attributes) -if segments - puts " >>> SEGMENTS when segmnents exist: #{segments}" -else - puts " >>> SEGMENTS when no segments: #{segments}" + fetch_and_decide(user) + send_event(optimizely_client) + + optimizely_client.close end -decide_options = [Optimizely::Decide::OptimizelyDecideOption::INCLUDE_REASONS] -decision = user.decide('flag1', decide_options) -puts "\n >>> DECISION #{decision.as_json()}" +# ============================================ +# CONFIG TYPE 2: +# with ODP integration changed at app.optimizely.com - changed public key or host url +# VALID API key/HOST url- should work, INVALID KEY/URL-should get errors +# ============================================ + +# TEST THE FOLLOWING: +# - test the same as in "CONFIG TYPE 1" but use invalid API key or HOST url +# - TODO clarify with Jae what to test here !!! + +def config_2 + optimizely_client = Optimizely::OptimizelyFactory.custom_instance('TbrfRLeKvLyWGusqANoeR', nil, nil, Optimizely::SimpleLogger.new(Logger::DEBUG)) + + attributes = {"laptop_os": 'mac'} -user.track_event("myevent") + # CASE 1 - REGULAR ATTRIBUTES, NO ODP + user = optimizely_client.create_user_context('user123', attributes) + + # CASE 2 - PREBUILT SEGMENTS, NO LIST SEGMENTS, valid user id is fs-id-12 (matehces DOB) + # user = optimizely_client.create_user_context('fs-id-12', attributes) + + # CASE 3 - SEGMENT LIST/ARRAY, valid user id is fs-id-6 + # user = optimizely_client.create_user_context('fs-id-6', attributes) + + fetch_and_decide(user) + send_event(optimizely_client) + + optimizely_client.close +end + +# ============================================ +# CONFIG TYPE 3: +# with different ODP configuration options (odpdisabled, segments_cache_size etc) +# ============================================ + +# TEST THE FOLLOWING: +# same as in "CONFIG TYPE 1", but add config options to fetch qualified segments function, for example: +# - disable_odp +# - segments_cache_size +# - segments_cache_timeout_in_secs +# - odp_segments_cache +# - odp_segment_manager +# - odp_event_manager +# - odp_segment_request_timeout +# - odp_event_request_timeout +# - odp_event_flush_interval + +# Observe responses and verity the correct behavior. + +def config_3 + settings = Optimizely::Helpers::OptimizelySdkSettings.new(disable_odp: true, odp_event_request_timeout: 0) + + optimizely_client = Optimizely::OptimizelyFactory.custom_instance( + 'TbrfRLeKvLyWGusqANoeR', nil, nil, Optimizely::SimpleLogger.new(Logger::DEBUG), nil, false, nil, nil, nil, settings + ) + + attributes = {"laptop_os": 'mac'} + + # CASE 1 - REGULAR ATTRIBUTES, NO ODP + user = optimizely_client.create_user_context('user123', attributes) + + # CASE 2 - PREBUILT SEGMENTS, NO LIST SEGMENTS, valid user id is fs-id-12 (matehces DOB) + # user = optimizely_client.create_user_context('fs-id-12', attributes) + + # CASE 3 - SEGMENT LIST/ARRAY, valid user id is fs-id-6 + # user = optimizely_client.create_user_context('fs-id-6', attributes) + + fetch_and_decide(user) + send_event(optimizely_client) + + optimizely_client.close +end -optimizely_client.close() +config_1 +config_2 +config_3 From 9b2bcbfa6a23c641702db455f54d15b5fa892fc2 Mon Sep 17 00:00:00 2001 From: Andy Leap Date: Thu, 9 Mar 2023 21:14:39 +0000 Subject: [PATCH 5/9] update gitpod vs code extensions --- .gitpod.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.gitpod.yml b/.gitpod.yml index c1989f42..33f095f8 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -10,3 +10,9 @@ tasks: gem install optimizely-sdk && rake build && gem install pkg/optimizely-sdk-4.0.0.gem + +vscode: + extensions: + - rebornix.ruby@0.28.1 + - castwide.solargraph@0.24.0 + - wingrunr21.vscode-ruby@0.28.0 From ec8762f3d925afc4ca2bb6ea03ad34c765d606d8 Mon Sep 17 00:00:00 2001 From: Andy Leap Date: Thu, 9 Mar 2023 21:36:41 +0000 Subject: [PATCH 6/9] add type hints --- myapp.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/myapp.rb b/myapp.rb index e292e624..53fe4bec 100644 --- a/myapp.rb +++ b/myapp.rb @@ -7,6 +7,7 @@ require 'optimizely/decide/optimizely_decide_option' require 'logger' +# @param user_ctx [Optimizely::OptimizelyUserContext] def fetch_and_decide(user_ctx) # ========================================= # Fetch Qualified Segments + decide @@ -29,6 +30,7 @@ def fetch_and_decide(user_ctx) end end +# @param optimizely_client [Optimizely::Project] def send_event(optimizely_client) identifiers = {'fs-user-id': 'fs-id-12', 'email': 'fs-bash-x@optimizely.com'} From 95a6ce173e8ab449a7dcc9a5031e4fee74cd63b0 Mon Sep 17 00:00:00 2001 From: Andy Leap Date: Thu, 9 Mar 2023 21:36:54 +0000 Subject: [PATCH 7/9] gitpod change --- .gitpod.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.yml b/.gitpod.yml index 33f095f8..74e213c5 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -5,7 +5,7 @@ # Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart tasks: - - init: | + - before: | bundle install && gem install optimizely-sdk && rake build && From aad524c5c123b3838cd71e287eea8fbf1f1cc457 Mon Sep 17 00:00:00 2001 From: Andy Leap Date: Thu, 9 Mar 2023 21:46:42 +0000 Subject: [PATCH 8/9] gitpod changes --- .gitpod.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.gitpod.yml b/.gitpod.yml index 74e213c5..03a95aef 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -5,11 +5,14 @@ # Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart tasks: - - before: | - bundle install && - gem install optimizely-sdk && - rake build && - gem install pkg/optimizely-sdk-4.0.0.gem + - init: | + ( + set -e + bundle install + gem install optimizely-sdk + rake build + gem install pkg/optimizely-sdk-4.0.0.gem + ) vscode: extensions: From 24a89912c386efd3d47db455cbb216f130e830d8 Mon Sep 17 00:00:00 2001 From: Andy Leap Date: Wed, 29 Mar 2023 19:39:12 +0000 Subject: [PATCH 9/9] update version in gitpod.yml --- .gitpod.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitpod.yml b/.gitpod.yml index 03a95aef..feefd42d 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -11,7 +11,7 @@ tasks: bundle install gem install optimizely-sdk rake build - gem install pkg/optimizely-sdk-4.0.0.gem + gem install pkg/optimizely-sdk-4.0.1.gem ) vscode: