@@ -56,6 +56,12 @@ class ProjectConfig
56
56
attr_reader :variation_id_to_variable_usage_map
57
57
attr_reader :variation_key_map
58
58
59
+ # Hash of user IDs to a Hash
60
+ # of experiments to variations. This contains all the forced variations
61
+ # set by the user by calling setForcedVariation (it is not the same as the
62
+ # whitelisting forcedVariations data structure in the Experiments class).
63
+ attr_reader :forced_variation_map
64
+
59
65
def initialize ( datafile , logger , error_handler )
60
66
# ProjectConfig init method to fetch and set project config data
61
67
#
@@ -98,6 +104,7 @@ def initialize(datafile, logger, error_handler)
98
104
@audience_id_map = generate_key_map ( @audiences , 'id' )
99
105
@variation_id_map = { }
100
106
@variation_key_map = { }
107
+ @forced_variation_map = { }
101
108
@variation_id_to_variable_usage_map = { }
102
109
@variation_id_to_experiment_map = { }
103
110
@experiment_key_map . each do |key , exp |
@@ -246,19 +253,113 @@ def get_variation_id_from_key(experiment_key, variation_key)
246
253
nil
247
254
end
248
255
249
- def get_forced_variations ( experiment_key )
250
- # Retrieves forced variations for a given experiment Key
256
+ def get_whitelisted_variations ( experiment_key )
257
+ # Retrieves whitelisted variations for a given experiment Key
251
258
#
252
259
# experiment_key - String Key representing the experiment
253
260
#
254
- # Returns forced variations for the experiment or nil
261
+ # Returns whitelisted variations for the experiment or nil
255
262
256
263
experiment = @experiment_key_map [ experiment_key ]
257
264
return experiment [ 'forcedVariations' ] if experiment
258
265
@logger . log Logger ::ERROR , "Experiment key '#{ experiment_key } ' is not in datafile."
259
266
@error_handler . handle_error InvalidExperimentError
260
267
end
261
268
269
+ def get_forced_variation ( experiment_key , user_id )
270
+ # Gets the forced variation for the given user and experiment.
271
+ #
272
+ # experiment_key - String Key for experiment.
273
+ # user_id - String ID for user
274
+ #
275
+ # Returns Variation The variation which the given user and experiment should be forced into.
276
+
277
+ # check for nil and empty string user ID
278
+ if user_id . nil? or user_id . empty?
279
+ @logger . log ( Logger ::DEBUG , "User ID is invalid" )
280
+ return nil
281
+ end
282
+
283
+ unless @forced_variation_map . has_key? ( user_id )
284
+ @logger . log ( Logger ::DEBUG , "User '#{ user_id } ' is not in the forced variation map." )
285
+ return nil
286
+ end
287
+
288
+ experimentToVariationMap = @forced_variation_map [ user_id ]
289
+ experiment = get_experiment_from_key ( experiment_key )
290
+ experiment_id = experiment [ "id" ] if experiment
291
+ # check for nil and empty string experiment ID
292
+ if experiment_id . nil? or experiment_id . empty?
293
+ # this case is logged in get_experiment_from_key
294
+ return nil
295
+ end
296
+
297
+ unless experimentToVariationMap . has_key? ( experiment_id )
298
+ @logger . log ( Logger ::DEBUG , "No experiment '#{ experiment_key } ' mapped to user '#{ user_id } ' in the forced variation map." )
299
+ return nil
300
+ end
301
+
302
+ variation_id = experimentToVariationMap [ experiment_id ]
303
+ variation_key = ""
304
+ variation = get_variation_from_id ( experiment_key , variation_id )
305
+ variation_key = variation [ "key" ] if variation
306
+
307
+ # check if the variation exists in the datafile
308
+ if variation_key . empty?
309
+ # this case is logged in get_variation_from_id
310
+ return nil
311
+ end
312
+
313
+ @logger . log ( Logger ::DEBUG , "Variation '#{ variation_key } ' is mapped to experiment '#{ experiment_key } ' and user '#{ user_id } ' in the forced variation map" )
314
+
315
+ variation
316
+ end
317
+
318
+ def set_forced_variation ( experiment_key , user_id , variation_key )
319
+ # Sets a Hash of user IDs to a Hash of experiments to forced variations.
320
+ #
321
+ # experiment_key - String Key for experiment.
322
+ # user_id - String ID for user.
323
+ # variation_key - String Key for variation. If null, then clear the existing experiment-to-variation mapping.
324
+ #
325
+ # Returns a boolean value that indicates if the set completed successfully.
326
+
327
+ # check for null and empty string user ID
328
+ if user_id . nil? or user_id . empty?
329
+ @logger . log ( Logger ::DEBUG , "User ID is invalid" )
330
+ return false
331
+ end
332
+
333
+ experiment = get_experiment_from_key ( experiment_key )
334
+ experiment_id = experiment [ "id" ] if experiment
335
+ # check if the experiment exists in the datafile
336
+ if experiment_id . nil? or experiment_id . empty?
337
+ return false
338
+ end
339
+
340
+ # clear the forced variation if the variation key is null
341
+ if variation_key . nil? or variation_key . empty?
342
+ @forced_variation_map [ user_id ] . delete ( experiment_id ) if @forced_variation_map . has_key? ( user_id )
343
+ @logger . log ( Logger ::DEBUG , "Variation mapped to experiment '#{ experiment_key } ' has been removed for user '#{ user_id } '." )
344
+ return true
345
+ end
346
+
347
+ variation_id = get_variation_id_from_key ( experiment_key , variation_key )
348
+
349
+ # check if the variation exists in the datafile
350
+ unless variation_id
351
+ # this case is logged in get_variation_id_from_key
352
+ return false
353
+ end
354
+
355
+ unless @forced_variation_map . has_key? user_id
356
+ @forced_variation_map [ user_id ] = { }
357
+ end
358
+ @forced_variation_map [ user_id ] [ experiment_id ] = variation_id
359
+ @logger . log ( Logger ::DEBUG , "Set variation '#{ variation_id } ' for experiment '#{ experiment_id } ' and user '#{ user_id } ' in the forced variation map." )
360
+ return true
361
+ end
362
+
262
363
def get_attribute_id ( attribute_key )
263
364
attribute = @attribute_key_map [ attribute_key ]
264
365
return attribute [ 'id' ] if attribute
@@ -290,7 +391,6 @@ def variation_id_exists?(experiment_id, variation_id)
290
391
return true if variation
291
392
@logger . log Logger ::ERROR , "Variation ID '#{ variation_id } ' is not in datafile."
292
393
@error_handler . handle_error InvalidVariationError
293
- return false
294
394
end
295
395
296
396
false
0 commit comments