Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add attributes and events support to config #339

Merged
merged 11 commits into from
Jun 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 72 additions & 2 deletions optimizely/optimizely_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,16 @@


class OptimizelyConfig(object):
def __init__(self, revision, experiments_map, features_map, datafile=None, sdk_key=None, environment_key=None):
def __init__(self, revision, experiments_map, features_map, datafile=None,
sdk_key=None, environment_key=None, attributes=None, events=None):
self.revision = revision
self.experiments_map = experiments_map
self.features_map = features_map
self._datafile = datafile
self.sdk_key = sdk_key
self.environment_key = environment_key
self.attributes = attributes or []
self.events = events or []

def get_datafile(self):
""" Get the datafile associated with OptimizelyConfig.
Expand All @@ -49,6 +52,22 @@ def get_environment_key(self):
"""
return self.environment_key

def get_attributes(self):
""" Get the attributes associated with OptimizelyConfig

returns:
A list of attributes.
"""
return self.attributes

def get_events(self):
""" Get the events associated with OptimizelyConfig

returns:
A list of events.
"""
return self.events


class OptimizelyExperiment(object):
def __init__(self, id, key, variations_map):
Expand Down Expand Up @@ -81,6 +100,19 @@ def __init__(self, id, key, variable_type, value):
self.value = value


class OptimizelyAttribute(object):
def __init__(self, id, key):
self.id = id
self.key = key


class OptimizelyEvent(object):
def __init__(self, id, key, experiment_ids):
self.id = id
self.key = key
self.experiment_ids = experiment_ids


class OptimizelyConfigService(object):
""" Class encapsulating methods to be used in creating instance of OptimizelyConfig. """

Expand All @@ -102,6 +134,8 @@ def __init__(self, project_config):
self.revision = project_config.revision
self.sdk_key = project_config.sdk_key
self.environment_key = project_config.environment_key
self.attributes = project_config.attributes
self.events = project_config.events

self._create_lookup_maps()

Expand All @@ -124,7 +158,9 @@ def get_config(self):
features_map,
self._datafile,
self.sdk_key,
self.environment_key)
self.environment_key,
self.attributes,
self.events)

def _create_lookup_maps(self):
""" Creates lookup maps to avoid redundant iteration of config objects. """
Expand Down Expand Up @@ -259,3 +295,37 @@ def _get_features_map(self, experiments_id_map):
features_map[feature['key']] = optly_feature

return features_map

def get_attributes_map(self):
""" Gets attributes map for the project config.

Returns:
dict -- Attribute key, OptimizelyAttribute map
"""

attributes_map = {}

for attribute in self.attributes:
optly_attribute = OptimizelyAttribute(
attribute['id'], attribute['key']
)
attributes_map[attribute['key']] = optly_attribute

return attributes_map

def get_events_map(self):
""" Gets events map for the project config.

Returns:
dict -- Event key, OptimizelyEvent map
"""

events_map = {}

for event in self.events:
optly_event = OptimizelyEvent(
event['id'], event['key'], event.get('experimentIds', [])
)
events_map[event['key']] = optly_event

return events_map
115 changes: 115 additions & 0 deletions tests/test_optimizely_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ def setUp(self):
self.expected_config = {
'sdk_key': None,
'environment_key': None,
'attributes': [{'key': 'test_attribute', 'id': '111094'}],
'events': [{'key': 'test_event', 'experimentIds': ['111127'], 'id': '111095'}],
'experiments_map': {
'test_experiment2': {
'variations_map': {
Expand Down Expand Up @@ -790,3 +792,116 @@ def test__get_environment_key_invalid(self):
invalid_value = 321

self.assertNotEqual(invalid_value, config.get_environment_key())

def test__get_attributes(self):
""" Test that the get_attributes returns the expected value. """

config = optimizely_config.OptimizelyConfig(
revision='101',
experiments_map={},
features_map={},
attributes=[{
'id': '123',
'key': '123'
},
{
'id': '234',
'key': '234'
}]
)

expected_value = [{
'id': '123',
'key': '123'
},
{
'id': '234',
'key': '234'
}]

self.assertEqual(expected_value, config.get_attributes())
self.assertEqual(len(config.get_attributes()), 2)

def test__get_events(self):
""" Test that the get_events returns the expected value. """

config = optimizely_config.OptimizelyConfig(
revision='101',
experiments_map={},
features_map={},
events=[{
'id': '123',
'key': '123',
'experiment_ids': {
'54321'
}
},
{
'id': '234',
'key': '234',
'experiment_ids': {
'3211', '54365'
}
}]
)

expected_value = [{
'id': '123',
'key': '123',
'experiment_ids': {
'54321'
}
},
{
'id': '234',
'key': '234',
'experiment_ids': {
'3211',
'54365'
}
}]

self.assertEqual(expected_value, config.get_events())
self.assertEqual(len(config.get_events()), 2)

def test__get_attributes_map(self):
""" Test to check get_attributes_map returns the correct value """

actual_attributes_map = self.opt_config_service.get_attributes_map()
expected_attributes = self.expected_config['attributes']

expected_attributes_map = {}

for expected_attribute in expected_attributes:
optly_attribute = optimizely_config.OptimizelyAttribute(
expected_attribute['id'], expected_attribute['key']
)
expected_attributes_map[expected_attribute['key']] = optly_attribute

for attribute in actual_attributes_map.values():
self.assertIsInstance(attribute, optimizely_config.OptimizelyAttribute)

self.assertEqual(len(expected_attributes), len(actual_attributes_map))
self.assertEqual(self.to_dict(actual_attributes_map), self.to_dict(expected_attributes_map))

def test__get_events_map(self):
""" Test to check that get_events_map returns the correct value """

actual_events_map = self.opt_config_service.get_events_map()
expected_events = self.expected_config['events']

expected_events_map = {}

for expected_event in expected_events:
optly_event = optimizely_config.OptimizelyEvent(
expected_event['id'],
expected_event['key'],
expected_event['experimentIds']
)
expected_events_map[expected_event['key']] = optly_event

for event in actual_events_map.values():
self.assertIsInstance(event, optimizely_config.OptimizelyEvent)

self.assertEqual(len(expected_events), len(actual_events_map))
self.assertEqual(self.to_dict(actual_events_map), self.to_dict(expected_events_map))