diff --git a/lib/optimizely.rb b/lib/optimizely.rb index de1315ce..e2e23320 100644 --- a/lib/optimizely.rb +++ b/lib/optimizely.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # -# Copyright 2016-2021, Optimizely and contributors +# Copyright 2016-2022, Optimizely and contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -199,7 +199,7 @@ def decide(user_context, key, decide_options = []) experiment = nil decision_source = Optimizely::DecisionService::DECISION_SOURCES['ROLLOUT'] context = Optimizely::OptimizelyUserContext::OptimizelyDecisionContext.new(key, nil) - variation, reasons_received = user_context.find_validated_forced_decision(context) + variation, reasons_received = @decision_service.validated_forced_decision(config, context, user_context) reasons.push(*reasons_received) if variation diff --git a/lib/optimizely/decision_service.rb b/lib/optimizely/decision_service.rb index 77fe0f0c..9c04923e 100644 --- a/lib/optimizely/decision_service.rb +++ b/lib/optimizely/decision_service.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # -# Copyright 2017-2021, Optimizely and contributors +# Copyright 2017-2022, Optimizely and contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -265,7 +265,7 @@ def get_variation_from_experiment_rule(project_config, flag_key, rule, user, opt reasons = [] context = Optimizely::OptimizelyUserContext::OptimizelyDecisionContext.new(flag_key, rule['key']) - variation, forced_reasons = user.find_validated_forced_decision(context) + variation, forced_reasons = validated_forced_decision(project_config, context, user) reasons.push(*forced_reasons) return [variation['id'], reasons] if variation @@ -290,7 +290,7 @@ def get_variation_from_delivery_rule(project_config, flag_key, rules, rule_index skip_to_everyone_else = false rule = rules[rule_index] context = Optimizely::OptimizelyUserContext::OptimizelyDecisionContext.new(flag_key, rule['key']) - variation, forced_reasons = user.find_validated_forced_decision(context) + variation, forced_reasons = validated_forced_decision(project_config, context, user) reasons.push(*forced_reasons) return [variation, skip_to_everyone_else, reasons] if variation @@ -417,6 +417,28 @@ def get_forced_variation(project_config, experiment_key, user_id) [variation, decide_reasons] end + def validated_forced_decision(project_config, context, user_context) + decision = user_context.get_forced_decision(context) + flag_key = context[:flag_key] + rule_key = context[:rule_key] + variation_key = decision ? decision[:variation_key] : decision + reasons = [] + target = rule_key ? "flag (#{flag_key}), rule (#{rule_key})" : "flag (#{flag_key})" + if variation_key + variation = project_config.get_variation_from_flag(flag_key, variation_key, 'key') + if variation + reason = "Variation (#{variation_key}) is mapped to #{target} and user (#{user_context.user_id}) in the forced decision map." + reasons.push(reason) + return variation, reasons + else + reason = "Invalid variation is mapped to #{target} and user (#{user_context.user_id}) in the forced decision map." + reasons.push(reason) + end + end + + [nil, reasons] + end + private def get_whitelisted_variation_id(project_config, experiment_id, user_id) diff --git a/lib/optimizely/optimizely_user_context.rb b/lib/optimizely/optimizely_user_context.rb index 2d6f9500..04d663b6 100644 --- a/lib/optimizely/optimizely_user_context.rb +++ b/lib/optimizely/optimizely_user_context.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # -# Copyright 2020, Optimizely and contributors +# Copyright 2020-2022, Optimizely and contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ class OptimizelyUserContext attr_reader :forced_decisions attr_reader :OptimizelyDecisionContext attr_reader :OptimizelyForcedDecision + attr_reader :optimizely_client OptimizelyDecisionContext = Struct.new(:flag_key, :rule_key) OptimizelyForcedDecision = Struct.new(:variation_key) @@ -156,28 +157,6 @@ def remove_all_forced_decisions true end - def find_validated_forced_decision(context) - decision = find_forced_decision(context) - flag_key = context[:flag_key] - rule_key = context[:rule_key] - variation_key = decision ? decision[:variation_key] : decision - reasons = [] - target = rule_key ? "flag (#{flag_key}), rule (#{rule_key})" : "flag (#{flag_key})" - if variation_key - variation = @optimizely_client.get_flag_variation(flag_key, variation_key, 'key') - if variation - reason = "Variation (#{variation_key}) is mapped to #{target} and user (#{@user_id}) in the forced decision map." - reasons.push(reason) - return variation, reasons - else - reason = "Invalid variation is mapped to #{target} and user (#{@user_id}) in the forced decision map." - reasons.push(reason) - end - end - - [nil, reasons] - end - # Track an event # # @param event_key - Event key representing the event which needs to be recorded.