Skip to content

Commit 241737d

Browse files
committed
Merge branch 'master' into rashid/bot_filtering
2 parents 7d0f159 + 92f4efd commit 241737d

File tree

5 files changed

+95
-27
lines changed

5 files changed

+95
-27
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@ install:
66
- bundle install
77
- bundle exec rake install
88
before_script: "rubocop"
9+
addons:
10+
srcclr: true
911
script: "rake spec"
1012
after_success: "coveralls"

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.0.2
2+
June 19th, 2018
3+
4+
- Fix: send impression event for Feature Test when Feature is disabled ([#110](https://github.com/optimizely/ruby-sdk/pull/110)).
5+
16
## 2.0.1
27
April 25th, 2018
38

lib/optimizely.rb

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -63,24 +63,24 @@ def initialize(datafile, event_dispatcher = nil, logger = nil, error_handler = n
6363
validate_instantiation_options(datafile, skip_json_validation)
6464
rescue InvalidInputError => e
6565
@is_valid = false
66-
logger = SimpleLogger.new
67-
logger.log(Logger::ERROR, e.message)
66+
@logger = SimpleLogger.new
67+
@logger.log(Logger::ERROR, e.message)
6868
return
6969
end
7070

7171
begin
7272
@config = ProjectConfig.new(datafile, @logger, @error_handler)
7373
rescue
7474
@is_valid = false
75-
logger = SimpleLogger.new
76-
logger.log(Logger::ERROR, InvalidInputError.new('datafile').message)
75+
@logger = SimpleLogger.new
76+
@logger.log(Logger::ERROR, InvalidInputError.new('datafile').message)
7777
return
7878
end
7979

8080
unless @config.parsing_succeeded?
8181
@is_valid = false
82-
logger = SimpleLogger.new
83-
logger.log(Logger::ERROR, InvalidDatafileVersionError.new.message)
82+
@logger = SimpleLogger.new
83+
@logger.log(Logger::ERROR, InvalidDatafileVersionError.new.message)
8484
return
8585
end
8686

@@ -100,8 +100,7 @@ def activate(experiment_key, user_id, attributes = nil)
100100
# Returns nil if experiment is not Running, if user is not in experiment, or if datafile is invalid.
101101

102102
unless @is_valid
103-
logger = SimpleLogger.new
104-
logger.log(Logger::ERROR, InvalidDatafileError.new('activate').message)
103+
@logger.log(Logger::ERROR, InvalidDatafileError.new('activate').message)
105104
return nil
106105
end
107106

@@ -137,8 +136,7 @@ def get_variation(experiment_key, user_id, attributes = nil)
137136
# Returns nil if experiment is not Running, if user is not in experiment, or if datafile is invalid.
138137

139138
unless @is_valid
140-
logger = SimpleLogger.new
141-
logger.log(Logger::ERROR, InvalidDatafileError.new('get_variation').message)
139+
@logger.log(Logger::ERROR, InvalidDatafileError.new('get_variation').message)
142140
return nil
143141
end
144142

@@ -200,8 +198,7 @@ def track(event_key, user_id, attributes = nil, event_tags = nil)
200198
# event_tags - Hash representing metadata associated with the event.
201199

202200
unless @is_valid
203-
logger = SimpleLogger.new
204-
logger.log(Logger::ERROR, InvalidDatafileError.new('track').message)
201+
@logger.log(Logger::ERROR, InvalidDatafileError.new('track').message)
205202
return nil
206203
end
207204

@@ -258,10 +255,8 @@ def is_feature_enabled(feature_flag_key, user_id, attributes = nil)
258255
# Returns True if the feature is enabled.
259256
# False if the feature is disabled.
260257
# False if the feature is not found.
261-
262258
unless @is_valid
263-
logger = SimpleLogger.new
264-
logger.log(Logger::ERROR, InvalidDatafileError.new('is_feature_enabled').message)
259+
@logger.log(Logger::ERROR, InvalidDatafileError.new('is_feature_enabled').message)
265260
return false
266261
end
267262

@@ -286,22 +281,23 @@ def is_feature_enabled(feature_flag_key, user_id, attributes = nil)
286281
end
287282

288283
variation = decision['variation']
289-
unless variation['featureEnabled']
290-
@logger.log(Logger::INFO,
291-
"Feature '#{feature_flag_key}' is not enabled for user '#{user_id}'.")
292-
return false
293-
end
294-
295284
if decision.source == Optimizely::DecisionService::DECISION_SOURCE_EXPERIMENT
296285
# Send event if Decision came from an experiment.
297286
send_impression(decision.experiment, variation['key'], user_id, attributes)
298287
else
299288
@logger.log(Logger::DEBUG,
300289
"The user '#{user_id}' is not being experimented on in feature '#{feature_flag_key}'.")
301290
end
302-
@logger.log(Logger::INFO, "Feature '#{feature_flag_key}' is enabled for user '#{user_id}'.")
303291

304-
true
292+
if variation['featureEnabled'] == true
293+
@logger.log(Logger::INFO,
294+
"Feature '#{feature_flag_key}' is enabled for user '#{user_id}'.")
295+
return true
296+
else
297+
@logger.log(Logger::INFO,
298+
"Feature '#{feature_flag_key}' is not enabled for user '#{user_id}'.")
299+
return false
300+
end
305301
end
306302

307303
def get_enabled_features(user_id, attributes = nil)
@@ -315,8 +311,7 @@ def get_enabled_features(user_id, attributes = nil)
315311
enabled_features = []
316312

317313
unless @is_valid
318-
logger = SimpleLogger.new
319-
logger.log(Logger::ERROR, InvalidDatafileError.new('get_enabled_features').message)
314+
@logger.log(Logger::ERROR, InvalidDatafileError.new('get_enabled_features').message)
320315
return enabled_features
321316
end
322317

@@ -343,6 +338,11 @@ def get_feature_variable_string(feature_flag_key, variable_key, user_id, attribu
343338
# Returns the string variable value.
344339
# Returns nil if the feature flag or variable are not found.
345340

341+
unless @is_valid
342+
@logger.log(Logger::ERROR, InvalidDatafileError.new('get_feature_variable_string').message)
343+
return nil
344+
end
345+
346346
variable_value = get_feature_variable_for_type(
347347
feature_flag_key,
348348
variable_key,
@@ -365,6 +365,11 @@ def get_feature_variable_boolean(feature_flag_key, variable_key, user_id, attrib
365365
# Returns the boolean variable value.
366366
# Returns nil if the feature flag or variable are not found.
367367

368+
unless @is_valid
369+
@logger.log(Logger::ERROR, InvalidDatafileError.new('get_feature_variable_boolean').message)
370+
return nil
371+
end
372+
368373
variable_value = get_feature_variable_for_type(
369374
feature_flag_key,
370375
variable_key,
@@ -387,6 +392,11 @@ def get_feature_variable_double(feature_flag_key, variable_key, user_id, attribu
387392
# Returns the double variable value.
388393
# Returns nil if the feature flag or variable are not found.
389394

395+
unless @is_valid
396+
@logger.log(Logger::ERROR, InvalidDatafileError.new('get_feature_variable_double').message)
397+
return nil
398+
end
399+
390400
variable_value = get_feature_variable_for_type(
391401
feature_flag_key,
392402
variable_key,
@@ -409,6 +419,11 @@ def get_feature_variable_integer(feature_flag_key, variable_key, user_id, attrib
409419
# Returns the integer variable value.
410420
# Returns nil if the feature flag or variable are not found.
411421

422+
unless @is_valid
423+
@logger.log(Logger::ERROR, InvalidDatafileError.new('get_feature_variable_integer').message)
424+
return nil
425+
end
426+
412427
variable_value = get_feature_variable_for_type(
413428
feature_flag_key,
414429
variable_key,

lib/optimizely/version.rb

Lines changed: 1 addition & 1 deletion
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.1'
20+
VERSION = '2.0.2'
2121
end

spec/project_spec.rb

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,8 @@ class InvalidErrorHandler; end
839839
expect(spy_logger).to have_received(:log).once.with(Logger::INFO, "Feature 'multi_variate_feature' is enabled for user 'test_user'.")
840840
end
841841

842-
it 'should return false, if the user is bucketed into a feature experiment but the featureEnabled property is false' do
842+
it 'should return false and send impression if the user is bucketed into a feature experiment but the featureEnabled property is false' do
843+
allow(project_instance.event_dispatcher).to receive(:dispatch_event).with(instance_of(Optimizely::Event))
843844
experiment_to_return = config_body['experiments'][3]
844845
variation_to_return = experiment_to_return['variations'][1]
845846
decision_to_return = Optimizely::DecisionService::Decision.new(
@@ -851,6 +852,7 @@ class InvalidErrorHandler; end
851852
allow(project_instance.decision_service).to receive(:get_variation_for_feature).and_return(decision_to_return)
852853

853854
expect(project_instance.is_feature_enabled('multi_variate_feature', 'test_user')).to be false
855+
expect(project_instance.event_dispatcher).to have_received(:dispatch_event).with(instance_of(Optimizely::Event)).once
854856
expect(spy_logger).to have_received(:log).once.with(Logger::INFO, "Feature 'multi_variate_feature' is not enabled for user 'test_user'.")
855857
end
856858
end
@@ -898,6 +900,17 @@ class InvalidErrorHandler; end
898900
user_id = 'test_user'
899901
user_attributes = {}
900902

903+
it 'should return nil when called with invalid project config' do
904+
logger = double('logger')
905+
allow(logger).to receive(:log)
906+
allow(Optimizely::SimpleLogger).to receive(:new) { logger }
907+
invalid_project = Optimizely::Project.new('invalid', nil, spy_logger)
908+
expect(invalid_project.get_feature_variable_string('string_single_variable_feature', 'string_variable', user_id, user_attributes))
909+
.to eq(nil)
910+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format.')
911+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format. Aborting get_feature_variable_string.')
912+
end
913+
901914
describe 'when the feature flag is enabled for the user' do
902915
describe 'and a variable usage instance is not found' do
903916
it 'should return the default variable value' do
@@ -1032,6 +1045,17 @@ class InvalidErrorHandler; end
10321045
user_id = 'test_user'
10331046
user_attributes = {}
10341047

1048+
it 'should return nil when called with invalid project config' do
1049+
logger = double('logger')
1050+
allow(logger).to receive(:log)
1051+
allow(Optimizely::SimpleLogger).to receive(:new) { logger }
1052+
invalid_project = Optimizely::Project.new('invalid', nil, spy_logger)
1053+
expect(invalid_project.get_feature_variable_boolean('boolean_single_variable_feature', 'boolean_variable', user_id, user_attributes))
1054+
.to eq(nil)
1055+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format.')
1056+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format. Aborting get_feature_variable_boolean.')
1057+
end
1058+
10351059
it 'should return the variable value for the variation for the user is bucketed into' do
10361060
boolean_feature = project_instance.config.feature_flag_key_map['boolean_single_variable_feature']
10371061
rollout = project_instance.config.rollout_id_map[boolean_feature['rolloutId']]
@@ -1058,6 +1082,17 @@ class InvalidErrorHandler; end
10581082
user_id = 'test_user'
10591083
user_attributes = {}
10601084

1085+
it 'should return nil when called with invalid project config' do
1086+
logger = double('logger')
1087+
allow(logger).to receive(:log)
1088+
allow(Optimizely::SimpleLogger).to receive(:new) { logger }
1089+
invalid_project = Optimizely::Project.new('invalid', nil, spy_logger)
1090+
expect(invalid_project.get_feature_variable_double('double_single_variable_feature', 'double_variable', user_id, user_attributes))
1091+
.to eq(nil)
1092+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format.')
1093+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format. Aborting get_feature_variable_double.')
1094+
end
1095+
10611096
it 'should return the variable value for the variation for the user is bucketed into' do
10621097
double_feature = project_instance.config.feature_flag_key_map['double_single_variable_feature']
10631098
experiment_to_return = project_instance.config.experiment_id_map[double_feature['experimentIds'][0]]
@@ -1085,6 +1120,17 @@ class InvalidErrorHandler; end
10851120
user_id = 'test_user'
10861121
user_attributes = {}
10871122

1123+
it 'should return nil when called with invalid project config' do
1124+
logger = double('logger')
1125+
allow(logger).to receive(:log)
1126+
allow(Optimizely::SimpleLogger).to receive(:new) { logger }
1127+
invalid_project = Optimizely::Project.new('invalid', nil, spy_logger)
1128+
expect(invalid_project.get_feature_variable_integer('integer_single_variable_feature', 'integer_variable', user_id, user_attributes))
1129+
.to eq(nil)
1130+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format.')
1131+
expect(logger).to have_received(:log).once.with(Logger::ERROR, 'Provided datafile is in an invalid format. Aborting get_feature_variable_integer.')
1132+
end
1133+
10881134
it 'should return the variable value for the variation for the user is bucketed into' do
10891135
integer_feature = project_instance.config.feature_flag_key_map['integer_single_variable_feature']
10901136
experiment_to_return = project_instance.config.experiment_id_map[integer_feature['experimentIds'][0]]

0 commit comments

Comments
 (0)