Skip to content

Commit aa906d5

Browse files
committed
resolves conflicts
2 parents 55bfc69 + b2a4883 commit aa906d5

13 files changed

+318
-111
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 2.0.3
2+
June 25th, 2018
3+
4+
### Bug Fixes
5+
Fixes [#109](https://github.com/optimizely/ruby-sdk/issues/109)
6+
17
## 2.0.2
28
June 19th, 2018
39

lib/optimizely/decision_service.rb

+3-5
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
require_relative './bucketer'
1919

2020
module Optimizely
21-
RESERVED_ATTRIBUTE_KEY_BUCKETING_ID = "\$opt_bucketing_id"
22-
2321
class DecisionService
2422
# Optimizely's decision service that determines into which variation of an experiment a user will be allocated.
2523
#
@@ -368,9 +366,9 @@ def get_bucketing_id(user_id, attributes)
368366
bucketing_id = user_id
369367

370368
# If the bucketing ID key is defined in attributes, then use that in place of the userID
371-
if attributes && attributes[RESERVED_ATTRIBUTE_KEY_BUCKETING_ID].is_a?(String)
372-
unless attributes[RESERVED_ATTRIBUTE_KEY_BUCKETING_ID].empty?
373-
bucketing_id = attributes[RESERVED_ATTRIBUTE_KEY_BUCKETING_ID]
369+
if attributes && attributes[Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BUCKETING_ID']].is_a?(String)
370+
unless attributes[Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BUCKETING_ID']].empty?
371+
bucketing_id = attributes[Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BUCKETING_ID']]
374372
@config.logger.log(Logger::DEBUG, "Setting the bucketing ID '#{bucketing_id}'")
375373
end
376374
end

lib/optimizely/event_builder.rb

+27-27
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
require 'securerandom'
2323

2424
module Optimizely
25-
RESERVED_ATTRIBUTE_KEY_BUCKETING_ID_EVENT_PARAM_KEY = 'optimizely_bucketing_id'
26-
2725
class Event
2826
# Representation of an event which can be sent to the Optimizely logging endpoint.
2927

@@ -58,6 +56,13 @@ def initialize(config, logger)
5856

5957
private
6058

59+
def bot_filtering
60+
# Get bot filtering bool
61+
#
62+
# Returns 'botFiltering' value in the datafile.
63+
@config.bot_filtering
64+
end
65+
6166
def get_common_params(user_id, attributes)
6267
# Get params which are used in both conversion and impression events.
6368
#
@@ -69,33 +74,28 @@ def get_common_params(user_id, attributes)
6974
visitor_attributes = []
7075

7176
attributes&.keys&.each do |attribute_key|
72-
# Omit null attribute value
77+
# Omit null attribute values
7378
attribute_value = attributes[attribute_key]
74-
next if attribute_value.nil?
75-
76-
if attribute_key.eql? RESERVED_ATTRIBUTE_KEY_BUCKETING_ID
77-
# TODO: (Copied from PHP-SDK) (Alda): the type for bucketing ID attribute may change so
78-
# that custom attributes are not overloaded
79-
feature = {
80-
entity_id: RESERVED_ATTRIBUTE_KEY_BUCKETING_ID,
81-
key: RESERVED_ATTRIBUTE_KEY_BUCKETING_ID_EVENT_PARAM_KEY,
82-
type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
83-
value: attribute_value
84-
}
85-
else
86-
# Skip attributes not in the datafile
87-
attribute_id = @config.get_attribute_id(attribute_key)
88-
next unless attribute_id
89-
90-
feature = {
91-
entity_id: attribute_id,
92-
key: attribute_key,
93-
type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
94-
value: attribute_value
95-
}
96-
79+
unless attribute_value.nil?
80+
attribute_id = @config.get_attribute_id attribute_key
81+
if attribute_id
82+
visitor_attributes.push(
83+
entity_id: attribute_id,
84+
key: attribute_key,
85+
type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
86+
value: attribute_value
87+
)
88+
end
9789
end
98-
visitor_attributes.push(feature)
90+
end
91+
# Append Bot Filtering Attribute
92+
if bot_filtering == true || bot_filtering == false
93+
visitor_attributes.push(
94+
entity_id: Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BOT_FILTERING'],
95+
key: Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BOT_FILTERING'],
96+
type: CUSTOM_ATTRIBUTE_FEATURE_TYPE,
97+
value: bot_filtering
98+
)
9999
end
100100

101101
common_params = {

lib/optimizely/helpers/constants.rb

+6
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,12 @@ module Constants
315315
'VARIABLE_KEY' => 'Variable key',
316316
'VARIABLE_TYPE' => 'Variable type'
317317
}.freeze
318+
319+
CONTROL_ATTRIBUTES = {
320+
'BOT_FILTERING' => '$opt_bot_filtering',
321+
'BUCKETING_ID' => '$opt_bucketing_id',
322+
'USER_AGENT' => '$opt_user_agent'
323+
}.freeze
318324
end
319325
end
320326
end

lib/optimizely/notification_center.rb

+15-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# frozen_string_literal: true
22

33
#
4-
# Copyright 2017, Optimizely and contributors
4+
# Copyright 2017-2018, Optimizely and contributors
55
#
66
# Licensed under the Apache License, Version 2.0 (the "License");
77
# you may not use this file except in compliance with the License.
@@ -84,19 +84,31 @@ def remove_notification_listener(notification_id)
8484
false
8585
end
8686

87+
# @deprecated Use {#clear_notification_listeners} instead.
88+
def clear_notifications(notification_type)
89+
@logger.log Logger::WARN, "'clear_notifications' is deprecated. Call 'clear_notification_listeners' instead."
90+
clear_notification_listeners(notification_type)
91+
end
92+
8793
# Removes notifications for a certain notification type
8894
#
8995
# @param notification_type - one of the constants in NOTIFICATION_TYPES
9096

91-
def clear_notifications(notification_type)
97+
def clear_notification_listeners(notification_type)
9298
return nil unless notification_type_valid?(notification_type)
9399

94100
@notifications[notification_type] = []
95101
@logger.log Logger::INFO, "All callbacks for notification type #{notification_type} have been removed."
96102
end
97103

98-
# Removes all notifications
104+
# @deprecated Use {#clear_all_notification_listeners} instead.
99105
def clean_all_notifications
106+
@logger.log Logger::WARN, "'clean_all_notifications' is deprecated. Call 'clear_all_notification_listeners' instead."
107+
clear_all_notification_listeners
108+
end
109+
110+
# Removes all notifications
111+
def clear_all_notification_listeners
100112
@notifications.each_key { |key| @notifications[key] = [] }
101113
end
102114

lib/optimizely/project_config.rb

+21-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
# limitations under the License.
1616
#
1717
require 'json'
18+
require_relative 'helpers/constants'
1819
require_relative 'helpers/validator'
1920

2021
module Optimizely
@@ -25,6 +26,7 @@ module Optimizely
2526
class ProjectConfig
2627
# Representation of the Optimizely project config.
2728
RUNNING_EXPERIMENT_STATUS = ['Running'].freeze
29+
RESERVED_ATTRIBUTE_PREFIX = '$opt_'
2830

2931
# Gets project config attributes.
3032
attr_reader :error_handler
@@ -41,6 +43,7 @@ class ProjectConfig
4143
attr_reader :project_id
4244
# Boolean - denotes if Optimizely should remove the last block of visitors' IP address before storing event data
4345
attr_reader :anonymize_ip
46+
attr_reader :bot_filtering
4447
attr_reader :revision
4548
attr_reader :rollouts
4649
attr_reader :version
@@ -87,7 +90,8 @@ def initialize(datafile, logger, error_handler)
8790
@feature_flags = config.fetch('featureFlags', [])
8891
@groups = config.fetch('groups', [])
8992
@project_id = config['projectId']
90-
@anonymize_ip = config.key? 'anonymizeIP' ? config['anonymizeIP'] : false
93+
@anonymize_ip = config.key?('anonymizeIP') ? config['anonymizeIP'] : false
94+
@bot_filtering = config['botFiltering']
9195
@revision = config['revision']
9296
@rollouts = config.fetch('rollouts', [])
9397

@@ -363,8 +367,23 @@ def set_forced_variation(experiment_key, user_id, variation_key)
363367
end
364368

365369
def get_attribute_id(attribute_key)
370+
# Get attribute ID for the provided attribute key.
371+
#
372+
# Args:
373+
# Attribute key for which attribute is to be fetched.
374+
#
375+
# Returns:
376+
# Attribute ID corresponding to the provided attribute key.
366377
attribute = @attribute_key_map[attribute_key]
367-
return attribute['id'] if attribute
378+
has_reserved_prefix = attribute_key.to_s.start_with?(RESERVED_ATTRIBUTE_PREFIX)
379+
unless attribute.nil?
380+
if has_reserved_prefix
381+
@logger.log(Logger::WARN, "Attribute '#{attribute_key}' unexpectedly has reserved prefix '#{RESERVED_ATTRIBUTE_PREFIX}'; "\
382+
'using attribute ID instead of reserved attribute name.')
383+
end
384+
return attribute['id']
385+
end
386+
return attribute_key if has_reserved_prefix
368387
@logger.log Logger::ERROR, "Attribute key '#{attribute_key}' is not in datafile."
369388
@error_handler.handle_error InvalidAttributeError
370389
nil

lib/optimizely/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@
1717
#
1818
module Optimizely
1919
CLIENT_ENGINE = 'ruby-sdk'
20-
VERSION = '2.0.2'
20+
VERSION = '2.0.3'
2121
end

spec/decision_service_spec.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
it 'should return the correct variation ID (using Bucketing ID attrbiute) for a given user for whom a variation has been forced' do
5252
user_attributes = {
5353
'browser_type' => 'firefox',
54-
OptimizelySpec::RESERVED_ATTRIBUTE_KEY_BUCKETING_ID => 'pid'
54+
Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BUCKETING_ID'] => 'pid'
5555
}
5656
config.set_forced_variation('test_experiment_with_audience', 'test_user', 'control_with_audience')
5757
expect(decision_service.get_variation('test_experiment_with_audience', 'test_user', user_attributes)).to eq('122228')
@@ -88,7 +88,7 @@
8888
it 'should return correct variation ID (using Bucketing ID attrbiute) if user ID is in whitelisted Variations and variation is valid' do
8989
user_attributes = {
9090
'browser_type' => 'firefox',
91-
OptimizelySpec::RESERVED_ATTRIBUTE_KEY_BUCKETING_ID => 'pid'
91+
Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BUCKETING_ID'] => 'pid'
9292
}
9393
expect(decision_service.get_variation('test_experiment', 'forced_user1', user_attributes)).to eq('111128')
9494
expect(spy_logger).to have_received(:log)
@@ -208,7 +208,7 @@
208208
}
209209
user_attributes = {
210210
'browser_type' => 'firefox',
211-
OptimizelySpec::RESERVED_ATTRIBUTE_KEY_BUCKETING_ID => 'pid'
211+
Optimizely::Helpers::Constants::CONTROL_ATTRIBUTES['BUCKETING_ID'] => 'pid'
212212
}
213213
expect(spy_user_profile_service).to receive(:lookup).once.and_return(nil)
214214

0 commit comments

Comments
 (0)