Skip to content

Commit

Permalink
Update unit tests and add more tests (#73)
Browse files Browse the repository at this point in the history
  • Loading branch information
aliabbasrizvi committed Aug 30, 2017
1 parent 669bca2 commit 6fdf655
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 137 deletions.
9 changes: 4 additions & 5 deletions optimizely/decision_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,18 +155,17 @@ def get_variation(self, experiment, user_id, attributes, ignore_user_profile=Fal

return None

def get_variation_for_rollout(self, rollout, user_id, attributes=None, ignore_user_profile=False):
def get_variation_for_rollout(self, rollout, user_id, attributes=None):
""" Determine which variation the user is in for a given rollout.
Returns the variation of the first experiment the user qualifies for.
Args:
rollout: Rollout for which we are getting the variation.
user_id: ID for user.
attributes: Dict representing user attributes.
ignore_user_profile: True to ignore the user profile lookup. Defaults to False.
Returns:
Variation the user should see. None if the user is not in any of the layer's experiments.
Variation the user should see. None if the user is not in any of the rollout's targeting rules.
"""

# Go through each experiment in order and try to get the variation for the user
Expand Down Expand Up @@ -249,8 +248,8 @@ def get_variation_for_feature(self, feature, user_id, attributes=None):

# Next check if user is part of a rollout
if not variation and feature.rolloutId:
rollout = self.config.get_layer_from_id(feature.rolloutId)
variation = self.get_variation_for_rollout(rollout, user_id, attributes, ignore_user_profile=True)
rollout = self.config.get_rollout_from_id(feature.rolloutId)
variation = self.get_variation_for_rollout(rollout, user_id, attributes)

return variation

Expand Down
16 changes: 8 additions & 8 deletions optimizely/project_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ def __init__(self, datafile, logger, error_handler):
self.event_key_map = self._generate_key_map(self.events, 'key', entities.Event)
self.attribute_key_map = self._generate_key_map(self.attributes, 'key', entities.Attribute)
self.audience_id_map = self._generate_key_map(self.audiences, 'id', entities.Audience)
self.layer_id_map = self._generate_key_map(self.rollouts, 'id', entities.Layer)
for layer in self.layer_id_map.values():
self.rollout_id_map = self._generate_key_map(self.rollouts, 'id', entities.Layer)
for layer in self.rollout_id_map.values():
for experiment in layer.experiments:
self.experiment_key_map[experiment['key']] = entities.Experiment(**experiment)

Expand Down Expand Up @@ -399,21 +399,21 @@ def get_feature_from_key(self, feature_key):
self.logger.log(enums.LogLevels.ERROR, 'Feature "%s" is not in datafile.' % feature_key)
return None

def get_layer_from_id(self, layer_id):
""" Get layer for the provided layer id.
def get_rollout_from_id(self, rollout_id):
""" Get rollout for the provided ID.
Args:
layer_id: ID of the layer to be fetched.
rollout_id: ID of the rollout to be fetched.
Returns:
Layer corresponding to the provided layer id.
Rollout corresponding to the provided ID.
"""
layer = self.layer_id_map.get(layer_id)
layer = self.rollout_id_map.get(rollout_id)

if layer:
return layer

self.logger.log(enums.LogLevels.ERROR, 'Layer with ID "%s" is not in datafile.' % layer_id)
self.logger.log(enums.LogLevels.ERROR, 'Rollout with ID "%s" is not in datafile.' % rollout_id)
return None

def get_variable_value_for_variation(self, variable, variation):
Expand Down
6 changes: 6 additions & 0 deletions tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ def setUp(self):
'id': '11159'
}],
'rollouts': [{
'id': '201111',
'experiments': []
}, {
'id': '211111',
'experiments': [{
'id': '211127',
Expand Down Expand Up @@ -524,6 +527,9 @@ def setUp(self):
'id': '11159'
}],
'rollouts': [{
'id': '201111',
'experiments': []
}, {
'id': '211111',
'experiments': [{
'id': '211127',
Expand Down
48 changes: 24 additions & 24 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -913,7 +913,7 @@ def test_init__with_v4_datafile(self):
'test_feature_in_group': entities.FeatureFlag('91113', 'test_feature_in_group', ['32222'], '', {}, '19228')
}

expected_layer_id_map = {
expected_rollout_id_map = {
'211111': entities.Layer('211111', [{
'key': '211112',
'status': 'Running',
Expand Down Expand Up @@ -970,7 +970,7 @@ def test_init__with_v4_datafile(self):
self.assertEqual(expected_variation_key_map, project_config.variation_key_map)
self.assertEqual(expected_variation_id_map, project_config.variation_id_map)
self.assertEqual(expected_feature_key_map, project_config.feature_key_map)
self.assertEqual(expected_layer_id_map, project_config.layer_id_map)
self.assertEqual(expected_rollout_id_map, project_config.rollout_id_map)
self.assertEqual(expected_variation_variable_usage_map, project_config.variation_variable_usage_map)

def test_get_version(self):
Expand Down Expand Up @@ -1128,27 +1128,27 @@ def test_get_group__invalid_id(self):

def test_get_feature_from_key__valid_feature_key(self):
""" Test that a valid feature is returned given a valid feature key. """
optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = optimizely_instance.config
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = opt_obj.config

expected_feature = entities.FeatureFlag('91112', 'test_feature_in_rollout', [], '211111', {})
self.assertEqual(expected_feature, project_config.get_feature_from_key('test_feature_in_rollout'))

def test_get_feature_from_key__invalid_feature_key(self):
""" Test that None is returned given an invalid feature key. """

optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = optimizely_instance.config
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = opt_obj.config

self.assertIsNone(project_config.get_feature_from_key('invalid_feature_key'))

def test_get_layer_from_id__valid_layer_id(self):
""" Test that a valid layer is returned """
def test_get_rollout_from_id__valid_rollout_id(self):
""" Test that a valid rollout is returned """

optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = optimizely_instance.config
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = opt_obj.config

expected_layer = entities.Layer('211111', [{
expected_rollout = entities.Layer('211111', [{
'id': '211127',
'key': '211127',
'status': 'Running',
Expand Down Expand Up @@ -1194,12 +1194,12 @@ def test_get_layer_from_id__valid_layer_id(self):
'id': '211149'
}]
}])
self.assertEqual(expected_layer, project_config.get_layer_from_id('211111'))
self.assertEqual(expected_rollout, project_config.get_rollout_from_id('211111'))

def test_get_variable_value_for_variation__returns_valid_value(self):
""" Test that the right value and type are returned. """
optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = optimizely_instance.config
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = opt_obj.config

variation = project_config.get_variation_from_id('test_experiment', '111128')
is_working_variable = project_config.get_variable_for_feature('test_feature_in_experiment', 'is_working')
Expand All @@ -1210,17 +1210,17 @@ def test_get_variable_value_for_variation__returns_valid_value(self):
def test_get_variable_value_for_variation__invalid_variable(self):
""" Test that an invalid variable key will return None. """

optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = optimizely_instance.config
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = opt_obj.config

variation = project_config.get_variation_from_id('test_experiment', '111128')
self.assertIsNone(project_config.get_variable_value_for_variation(None, variation))

def test_get_variable_value_for_variation__no_variables_for_variation(self):
""" Test that a variation with no variables will return None. """

optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = optimizely_instance.config
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = opt_obj.config

variation = entities.Variation('1111281', 'invalid_variation', [])
is_working_variable = project_config.get_variable_for_feature('test_feature_in_experiment', 'is_working')
Expand All @@ -1229,25 +1229,25 @@ def test_get_variable_value_for_variation__no_variables_for_variation(self):
def test_get_variable_for_feature__returns_valid_variable(self):
""" Test that the feature variable is returned. """

optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = optimizely_instance.config
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = opt_obj.config

variable = project_config.get_variable_for_feature('test_feature_in_experiment', 'is_working')
self.assertEqual(entities.Variable('127', 'is_working', 'boolean', 'true'), variable)

def test_get_variable_for_feature__invalid_feature_key(self):
""" Test that an invalid feature key will return None. """

optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = optimizely_instance.config
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = opt_obj.config

self.assertIsNone(project_config.get_variable_for_feature('invalid_feature', 'is_working'))

def test_get_variable_for_feature__invalid_variable_key(self):
""" Test that an invalid variable key will return None. """

optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = optimizely_instance.config
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
project_config = opt_obj.config

self.assertIsNone(project_config.get_variable_for_feature('test_feature_in_experiment', 'invalid_variable_key'))

Expand Down

0 comments on commit 6fdf655

Please sign in to comment.