Skip to content

Commit af05d73

Browse files
rashidspmikeproeng37
authored andcommitted
refact(API): Adds missing input validations in all API methods and validates empty user Id. (#127)
1 parent ff19d0a commit af05d73

File tree

5 files changed

+161
-71
lines changed

5 files changed

+161
-71
lines changed

lib/optimizely.rb

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,11 @@ def get_enabled_features(user_id, attributes = nil)
307307
return enabled_features
308308
end
309309

310-
return enabled_features unless Optimizely::Helpers::Validator.inputs_valid?({user_id: user_id}, @logger, Logger::ERROR)
310+
return enabled_features unless Optimizely::Helpers::Validator.inputs_valid?(
311+
{
312+
user_id: user_id
313+
}, @logger, Logger::ERROR
314+
)
311315

312316
return enabled_features unless user_inputs_valid?(attributes)
313317

@@ -448,8 +452,8 @@ def get_feature_variable_for_type(feature_flag_key, variable_key, variable_type,
448452
{
449453
feature_flag_key: feature_flag_key,
450454
variable_key: variable_key,
451-
variable_type: variable_type,
452-
user_id: user_id
455+
user_id: user_id,
456+
variable_type: variable_type
453457
},
454458
@logger, Logger::ERROR
455459
)

lib/optimizely/helpers/validator.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,22 @@ def inputs_valid?(variables, logger = NoOpLogger.new, level = Logger::ERROR)
121121
return false unless variables.respond_to?(:each) && !variables.empty?
122122

123123
is_valid = true
124+
if variables.include? :user_id
125+
# Empty str is a valid user ID.
126+
unless variables[:user_id].is_a?(String)
127+
is_valid = false
128+
logger.log(level, "#{Constants::INPUT_VARIABLES['USER_ID']} is invalid")
129+
end
130+
variables.delete :user_id
131+
end
132+
124133
variables.each do |key, value|
125134
next if value.is_a?(String) && !value.empty?
126135

127136
is_valid = false
128137
next unless logger_valid?(logger) && level
129138

130-
logger.log(level, "#{Optimizely::Helpers::Constants::INPUT_VARIABLES[key.to_s.upcase]} is invalid")
139+
logger.log(level, "#{Constants::INPUT_VARIABLES[key.to_s.upcase]} is invalid")
131140
end
132141
is_valid
133142
end

lib/optimizely/project_config.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ def set_forced_variation(experiment_key, user_id, variation_key)
329329
#
330330
# Returns a boolean value that indicates if the set completed successfully.
331331

332-
input_values = {user_id: user_id, experiment_key: experiment_key}
332+
input_values = {experiment_key: experiment_key, user_id: user_id}
333333
input_values[:variation_key] = variation_key unless variation_key.nil?
334334
return false unless Optimizely::Helpers::Validator.inputs_valid?(input_values, @logger, Logger::DEBUG)
335335

spec/project_config_spec.rb

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -859,12 +859,6 @@
859859
expect(spy_logger).to have_received(:log).with(Logger::DEBUG,
860860
'User ID is invalid')
861861
end
862-
# User ID is an empty string
863-
it 'should log a message and return nil when user_id is passed as empty string for get_forced_variation' do
864-
expect(config.get_forced_variation(@valid_experiment[:key], '')).to eq(nil)
865-
expect(spy_logger).to have_received(:log).with(Logger::DEBUG,
866-
'User ID is invalid')
867-
end
868862
# User ID is not defined in the forced variation map
869863
it 'should log a message and return nil when user is not in forced variation map' do
870864
expect(config.get_forced_variation(@valid_experiment[:key], @user_id)).to eq(nil)
@@ -905,12 +899,6 @@
905899
expect(spy_logger).to have_received(:log).with(Logger::DEBUG,
906900
'User ID is invalid')
907901
end
908-
# User ID is an empty string
909-
it 'should log a message and return false when user_id is passed as empty string' do
910-
expect(config.set_forced_variation(@valid_experiment[:key], '', @valid_variation[:key])).to eq(false)
911-
expect(spy_logger).to have_received(:log).with(Logger::DEBUG,
912-
'User ID is invalid')
913-
end
914902
# Experiment key is nil
915903
it 'should return false when experiment_key is passed as nil' do
916904
expect(config.set_forced_variation(nil, @user_id, @valid_variation[:key])).to eq(false)
@@ -961,14 +949,24 @@
961949
it 'should call inputs_valid? with the proper arguments in set_forced_variation' do
962950
expect(Optimizely::Helpers::Validator).to receive(:inputs_valid?).with(
963951
{
964-
user_id: @user_id,
965952
experiment_key: @valid_experiment[:key],
953+
user_id: @user_id,
966954
variation_key: @valid_variation[:key]
967955
}, spy_logger, Logger::DEBUG
968956
)
969957
config.set_forced_variation(@valid_experiment[:key], @user_id, @valid_variation[:key])
970958
end
971959

960+
it 'should log and return false when user ID is non string in set_forced_variation' do
961+
expect(config.set_forced_variation(@valid_experiment[:key], nil, @valid_variation[:key])).to be false
962+
expect(config.set_forced_variation(@valid_experiment[:key], 5, @valid_variation[:key])).to be false
963+
expect(config.set_forced_variation(@valid_experiment[:key], 5.5, @valid_variation[:key])).to be false
964+
expect(config.set_forced_variation(@valid_experiment[:key], true, @valid_variation[:key])).to be false
965+
expect(config.set_forced_variation(@valid_experiment[:key], {}, @valid_variation[:key])).to be false
966+
expect(config.set_forced_variation(@valid_experiment[:key], [], @valid_variation[:key])).to be false
967+
expect(spy_logger).to have_received(:log).with(Logger::DEBUG, 'User ID is invalid').exactly(6).times
968+
end
969+
972970
it 'should call inputs_valid? with the proper arguments in get_forced_variation' do
973971
expect(Optimizely::Helpers::Validator).to receive(:inputs_valid?).with(
974972
{
@@ -979,6 +977,16 @@
979977
config.get_forced_variation(@valid_experiment[:key], @user_id)
980978
end
981979

980+
it 'should log and return nil when user ID is non string in get_forced_variation' do
981+
expect(config.get_forced_variation(@valid_experiment[:key], nil)).to eq(nil)
982+
expect(config.get_forced_variation(@valid_experiment[:key], 5)).to eq(nil)
983+
expect(config.get_forced_variation(@valid_experiment[:key], 5.5)).to eq(nil)
984+
expect(config.get_forced_variation(@valid_experiment[:key], true)).to eq(nil)
985+
expect(config.get_forced_variation(@valid_experiment[:key], {})).to eq(nil)
986+
expect(config.get_forced_variation(@valid_experiment[:key], [])).to eq(nil)
987+
expect(spy_logger).to have_received(:log).with(Logger::DEBUG, 'User ID is invalid').exactly(6).times
988+
end
989+
982990
# Call set variation with different variations on one user/experiment to confirm that each set is expected.
983991
it 'should set and return expected variations when different variations are set and removed for one user/experiment' do
984992
expect(config.set_forced_variation(@valid_experiment[:key], @user_id, @valid_variation[:key])).to eq(true)

0 commit comments

Comments
 (0)