Skip to content

Commit

Permalink
Added unit tests and feature test update
Browse files Browse the repository at this point in the history
  • Loading branch information
rashidsp committed Apr 23, 2019
1 parent 105e1e4 commit 39137a7
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 16 deletions.
4 changes: 2 additions & 2 deletions optimizely/helpers/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,14 @@ class NotificationTypes(object):
TRACK notification listener has the following parameters:
str event_key, str user_id, dict attributes (can be None), event_tags (can be None), Event event
DECISION notification listener has the following parameters:
DecisionInfoTypes type, str user_id, dict attributes (can be None), dict decision_info
DecisionNotificationTypes type, str user_id, dict attributes (can be None), dict decision_info
"""
ACTIVATE = "ACTIVATE:experiment, user_id, attributes, variation, event"
DECISION = "DECISION:type, user_id, attributes, decision_info"
TRACK = "TRACK:event_key, user_id, attributes, event_tags, event"


class DecisionInfoTypes(object):
class DecisionNotificationTypes(object):
AB_TEST = "ab-test"
FEATURE = "feature"
FEATURE_TEST = 'feature-test'
Expand Down
8 changes: 4 additions & 4 deletions optimizely/optimizely.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def _get_feature_variable_for_type(self, feature_key, variable_key, variable_typ

self.notification_center.send_notifications(
enums.NotificationTypes.DECISION,
enums.DecisionInfoTypes.FEATURE_VARIABLE,
enums.DecisionNotificationTypes.FEATURE_VARIABLE,
user_id,
attributes or {},
{
Expand Down Expand Up @@ -388,9 +388,9 @@ def get_variation(self, experiment_key, user_id, attributes=None):
variation_key = variation.key

if self.config.is_feature_experiment(experiment.id):
decision_notification_type = enums.DecisionInfoTypes.FEATURE_TEST
decision_notification_type = enums.DecisionNotificationTypes.FEATURE_TEST
else:
decision_notification_type = enums.DecisionInfoTypes.AB_TEST
decision_notification_type = enums.DecisionNotificationTypes.AB_TEST

self.notification_center.send_notifications(
enums.NotificationTypes.DECISION,
Expand Down Expand Up @@ -462,7 +462,7 @@ def is_feature_enabled(self, feature_key, user_id, attributes=None):

self.notification_center.send_notifications(
enums.NotificationTypes.DECISION,
enums.DecisionInfoTypes.FEATURE,
enums.DecisionNotificationTypes.FEATURE,
user_id,
attributes or {},
{
Expand Down
7 changes: 2 additions & 5 deletions optimizely/project_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,7 @@ def __init__(self, datafile, logger, error_handler):
# Check if any of the experiments are in a group and add the group id for faster bucketing later on
for exp_id in feature.experimentIds:
# Add this experiment in experiment-feature map.
if exp_id in self.experiment_feature_map:
self.experiment_feature_map[exp_id].append(feature.key)
else:
self.experiment_feature_map[exp_id] = [feature.key]
self.experiment_feature_map[exp_id] = [feature.id]

experiment_in_feature = self.experiment_id_map[exp_id]
# Experiments in feature can only belong to one mutex group
Expand Down Expand Up @@ -622,7 +619,7 @@ def is_feature_experiment(self, experiment_id):
""" Gets the experiment ID.
Returns:
A boolean value that indicates if experiment belongs to any feature.
A boolean value that indicates if given experiment is a feature test.
"""

return experiment_id in self.experiment_feature_map
37 changes: 36 additions & 1 deletion tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,41 @@ def setUp(self, config_dict='config_dict'):
'id': '130', 'value': '4243'
}]
}]
}, {
'key': 'test_experiment2',
'status': 'Running',
'layerId': '5',
'audienceIds': [],
'id': '111133',
'forcedVariations': {},
'trafficAllocation': [{
'entityId': '122239',
'endOfRange': 5000
}, {
'entityId': '122240',
'endOfRange': 10000
}],
'variations': [{
'id': '122239',
'key': 'control',
'featureEnabled': True,
'variables': [
{
'id': '155551',
'value': '42.42'
}
]
}, {
'id': '122240',
'key': 'variation',
'featureEnabled': True,
'variables': [
{
'id': '155551',
'value': '13.37'
}
]
}]
}],
'groups': [{
'id': '19228',
Expand Down Expand Up @@ -431,7 +466,7 @@ def setUp(self, config_dict='config_dict'):
}, {
'id': '91114',
'key': 'test_feature_in_experiment_and_rollout',
'experimentIds': ['111127'],
'experimentIds': ['32223'],
'rolloutId': '211111',
'variables': [],
}]
Expand Down
18 changes: 18 additions & 0 deletions tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,11 @@ def test_init__with_v4_datafile(self):
}
}

expected_experiment_feature_map = {
'111127': [project_config.feature_flags[0]['id']],
'32222': [project_config.feature_flags[2]['id']]
}

self.assertEqual(expected_variation_variable_usage_map['28901'],
project_config.variation_variable_usage_map['28901'])
self.assertEqual(expected_group_id_map, project_config.group_id_map)
Expand All @@ -639,6 +644,7 @@ def test_init__with_v4_datafile(self):
self.assertEqual(expected_feature_key_map, project_config.feature_key_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)
self.assertEqual(expected_experiment_feature_map, project_config.experiment_feature_map)

def test_variation_has_featureEnabled_false_if_prop_undefined(self):
""" Test that featureEnabled property by default is set to False, when not given in the data file"""
Expand Down Expand Up @@ -1333,3 +1339,15 @@ def test_get_group__invalid_id(self):
self.assertRaisesRegexp(exceptions.InvalidGroupException,
enums.Errors.INVALID_GROUP_ID_ERROR,
self.project_config.get_group, '42')

def test_is_feature_experiment(self):
""" Test that a true is returned if experiment is a feature test, false otherwise. """

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

experiment = project_config.get_experiment_from_key('test_experiment2')
feature_experiment = project_config.get_experiment_from_key('test_experiment')

self.assertStrictFalse(project_config.is_feature_experiment(experiment.id))
self.assertStrictTrue(project_config.is_feature_experiment(feature_experiment.id))
2 changes: 1 addition & 1 deletion tests/test_decision_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ def test_get_variation_for_feature__returns_variation_if_user_not_in_experiment_

self.assertEqual(2, mock_audience_check.call_count)
mock_audience_check.assert_any_call(self.project_config,
self.project_config.get_experiment_from_key('test_experiment'), None,
self.project_config.get_experiment_from_key('group_exp_2'), None,
mock_decision_logging)
mock_audience_check.assert_any_call(self.project_config,
self.project_config.get_experiment_from_key('211127'), None,
Expand Down
9 changes: 6 additions & 3 deletions tests/test_optimizely.py
Original file line number Diff line number Diff line change
Expand Up @@ -1471,17 +1471,20 @@ def test_get_variation_with_experiment_in_feature(self):
""" Test that get_variation returns valid variation and broadcasts decision listener with type feature-test when
get_variation returns feature experiment variation."""

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

with mock.patch(
'optimizely.decision_service.DecisionService.get_variation',
return_value=self.project_config.get_variation_from_id('test_experiment', '111129')), \
return_value=project_config.get_variation_from_id('test_experiment', '111129')), \
mock.patch('optimizely.notification_center.NotificationCenter.send_notifications') as mock_broadcast:
self.assertEqual('variation', self.optimizely.get_variation('test_experiment', 'test_user'))
self.assertEqual('variation', opt_obj.get_variation('test_experiment', 'test_user'))

self.assertEqual(mock_broadcast.call_count, 1)

mock_broadcast.assert_called_once_with(
enums.NotificationTypes.DECISION,
'ab-test',
'feature-test',
'test_user',
{},
{
Expand Down

0 comments on commit 39137a7

Please sign in to comment.