Module: Optimizely::Audience

Defined in:
lib/optimizely/audience.rb

Class Method Summary collapse

Class Method Details

.user_meets_audience_conditions?(config, experiment, attributes, logger, logging_hash = nil, logging_key = nil) ⇒ Boolean



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/optimizely/audience.rb', line 27

def user_meets_audience_conditions?(config, experiment, attributes, logger, logging_hash = nil, logging_key = nil)
  # Determine for given experiment/rollout rule if user satisfies the audience conditions.
  #
  # config - Representation of the Optimizely project config.
  # experiment - Experiment/Rollout rule in which user is to be bucketed.
  # attributes - Hash representing user attributes which will be used in determining if
  #              the audience conditions are met.
  # logger - Provides a logger instance.
  # logging_hash - Optional string representing logs hash inside Helpers::Constants.
  #                This defaults to 'EXPERIMENT_AUDIENCE_EVALUATION_LOGS'.
  # logging_key - Optional string to be logged as an identifier of experiment under evaluation.
  #               This defaults to experiment['key'].
  #
  # Returns boolean representing if user satisfies audience conditions for the audiences or not.
  logging_hash ||= 'EXPERIMENT_AUDIENCE_EVALUATION_LOGS'
  logging_key ||= experiment['key']

  logs_hash = Object.const_get "Optimizely::Helpers::Constants::#{logging_hash}"

  audience_conditions = experiment['audienceConditions'] || experiment['audienceIds']

  logger.log(
    Logger::DEBUG,
    format(
      logs_hash['EVALUATING_AUDIENCES_COMBINED'],
      logging_key,
      audience_conditions
    )
  )

  # Return true if there are no audiences
  if audience_conditions.empty?
    logger.log(
      Logger::INFO,
      format(
        logs_hash['AUDIENCE_EVALUATION_RESULT_COMBINED'],
        logging_key,
        'TRUE'
      )
    )
    return true
  end

  attributes ||= {}

  custom_attr_condition_evaluator = CustomAttributeConditionEvaluator.new(attributes, logger)

  evaluate_custom_attr = lambda do |condition|
    return custom_attr_condition_evaluator.evaluate(condition)
  end

  evaluate_audience = lambda do |audience_id|
    audience = config.get_audience_from_id(audience_id)
    return nil unless audience

    audience_conditions = audience['conditions']
    logger.log(
      Logger::DEBUG,
      format(
        logs_hash['EVALUATING_AUDIENCE'],
        audience_id,
        audience_conditions
      )
    )

    audience_conditions = JSON.parse(audience_conditions) if audience_conditions.is_a?(String)
    result = ConditionTreeEvaluator.evaluate(audience_conditions, evaluate_custom_attr)
    result_str = result.nil? ? 'UNKNOWN' : result.to_s.upcase
    logger.log(
      Logger::DEBUG,
      format(logs_hash['AUDIENCE_EVALUATION_RESULT'], audience_id, result_str)
    )
    result
  end

  eval_result = ConditionTreeEvaluator.evaluate(audience_conditions, evaluate_audience)

  eval_result ||= false

  logger.log(
    Logger::INFO,
    format(
      logs_hash['AUDIENCE_EVALUATION_RESULT_COMBINED'],
      logging_key,
      eval_result.to_s.upcase
    )
  )

  eval_result
end