From 5461817df23eb52d7544899a9f49a60e0ccc6b15 Mon Sep 17 00:00:00 2001 From: ozayr-zaviar Date: Thu, 10 Jun 2021 18:55:07 +0500 Subject: [PATCH 01/11] added sdk and environment key --- optimizely/optimizely_config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optimizely/optimizely_config.py b/optimizely/optimizely_config.py index 50543f85..376a090c 100644 --- a/optimizely/optimizely_config.py +++ b/optimizely/optimizely_config.py @@ -25,6 +25,7 @@ def __init__(self, revision, experiments_map, features_map, datafile=None, sdk_k self.sdk_key = sdk_key self.environment_key = environment_key + def get_datafile(self): """ Get the datafile associated with OptimizelyConfig. @@ -49,7 +50,6 @@ def get_environment_key(self): """ return self.environment_key - class OptimizelyExperiment(object): def __init__(self, id, key, variations_map): self.id = id From 41aa6f21600f3dc5e2c6c98139e47a41216ad6b0 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Thu, 3 Jun 2021 09:45:56 -0400 Subject: [PATCH 02/11] [MAINTENANCE] Remove Deprecated warnings during build - assertRaisesRegexp -> assertRaisesRegex - assertEquals -> assertEqual - isAlive() -> is_alive() - Check added to base.py to confirm attribute assertRaisesRegex for backwards compatibility to Python2.7 --- tests/test_user_context.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_user_context.py b/tests/test_user_context.py index fcffc415..9f4ab73a 100644 --- a/tests/test_user_context.py +++ b/tests/test_user_context.py @@ -1296,3 +1296,4 @@ def test_decide_experiment(self): user_context = opt_obj.create_user_context('test_user') decision = user_context.decide('test_feature_in_experiment', [DecideOption.DISABLE_DECISION_EVENT]) self.assertTrue(decision.enabled, "decision should be enabled") + From 54e2c3b0dfce0b8b9c132b9db56bb79ed5777ecf Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 15 Jun 2021 12:52:58 -0400 Subject: [PATCH 03/11] [OASIS-7757] Fix spelling of environment to fix testcases from failing --- optimizely/optimizely_config.py | 1 - 1 file changed, 1 deletion(-) diff --git a/optimizely/optimizely_config.py b/optimizely/optimizely_config.py index 376a090c..ebace9a8 100644 --- a/optimizely/optimizely_config.py +++ b/optimizely/optimizely_config.py @@ -25,7 +25,6 @@ def __init__(self, revision, experiments_map, features_map, datafile=None, sdk_k self.sdk_key = sdk_key self.environment_key = environment_key - def get_datafile(self): """ Get the datafile associated with OptimizelyConfig. From f9b6ba3a507242fb5875b58f2dca4d343ffb5b00 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Thu, 17 Jun 2021 14:26:53 -0400 Subject: [PATCH 04/11] [OASIS-7757] - Added additional test cases to test_optimizely and test_user_context. --- tests/test_optimizely.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/test_optimizely.py b/tests/test_optimizely.py index 23454342..fca37d47 100644 --- a/tests/test_optimizely.py +++ b/tests/test_optimizely.py @@ -265,6 +265,19 @@ def test_init__sdk_key_and_datafile_access_token(self): self.assertIs(type(opt_obj.config_manager), config_manager.AuthDatafilePollingConfigManager) + def test_init__invalid_default_decide_options(self): + """ + Test to confirm that default decide options passed not as a list will trigger setting + self.deafulat_decide_options as an empty list. + """ + invalid_decide_options = {"testKey": "testOption"} + + mock_client_logger = mock.MagicMock() + with mock.patch('optimizely.logger.reset_logger', return_value=mock_client_logger): + opt_obj = optimizely.Optimizely(default_decide_options=invalid_decide_options) + + self.assertEqual(opt_obj.default_decide_options, []) + def test_invalid_json_raises_schema_validation_off(self): """ Test that invalid JSON logs error if schema validation is turned off. """ From e12d9ae4858958c8012156c3eb6a3fa6f6a418d7 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jun 2021 09:30:57 -0400 Subject: [PATCH 05/11] [OASIS-7800] Updated optimizely_config with attributes and events --- optimizely/optimizely_config.py | 56 ++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/optimizely/optimizely_config.py b/optimizely/optimizely_config.py index ebace9a8..43a08735 100644 --- a/optimizely/optimizely_config.py +++ b/optimizely/optimizely_config.py @@ -13,17 +13,22 @@ import copy +from optimizely.helpers.validator import are_attributes_valid + from .project_config import ProjectConfig 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 + self.events = events def get_datafile(self): """ Get the datafile associated with OptimizelyConfig. @@ -80,6 +85,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. """ @@ -101,6 +119,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() @@ -258,3 +278,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 attributes 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 From 6e51dbb017c56ecee6613fdf446797fbc11e97b1 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Wed, 23 Jun 2021 08:25:58 -0400 Subject: [PATCH 06/11] [OASIS-7757] - update copyright years and add more testcases for sdk_key and environment_key. Move decide tests to test_user_context from test_optimizely. --- tests/test_optimizely.py | 13 ------------- tests/test_user_context.py | 2 +- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/tests/test_optimizely.py b/tests/test_optimizely.py index fca37d47..23454342 100644 --- a/tests/test_optimizely.py +++ b/tests/test_optimizely.py @@ -265,19 +265,6 @@ def test_init__sdk_key_and_datafile_access_token(self): self.assertIs(type(opt_obj.config_manager), config_manager.AuthDatafilePollingConfigManager) - def test_init__invalid_default_decide_options(self): - """ - Test to confirm that default decide options passed not as a list will trigger setting - self.deafulat_decide_options as an empty list. - """ - invalid_decide_options = {"testKey": "testOption"} - - mock_client_logger = mock.MagicMock() - with mock.patch('optimizely.logger.reset_logger', return_value=mock_client_logger): - opt_obj = optimizely.Optimizely(default_decide_options=invalid_decide_options) - - self.assertEqual(opt_obj.default_decide_options, []) - def test_invalid_json_raises_schema_validation_off(self): """ Test that invalid JSON logs error if schema validation is turned off. """ diff --git a/tests/test_user_context.py b/tests/test_user_context.py index 9f4ab73a..1620a76a 100644 --- a/tests/test_user_context.py +++ b/tests/test_user_context.py @@ -1296,4 +1296,4 @@ def test_decide_experiment(self): user_context = opt_obj.create_user_context('test_user') decision = user_context.decide('test_feature_in_experiment', [DecideOption.DISABLE_DECISION_EVENT]) self.assertTrue(decision.enabled, "decision should be enabled") - + \ No newline at end of file From 5217294040acf274f2231473b649fef1e81274c6 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Wed, 23 Jun 2021 17:22:09 -0400 Subject: [PATCH 07/11] [OASIS-7800] Updated optimizely_config with attributes and events --- optimizely/optimizely_config.py | 24 +++++++++-- tests/test_optimizely_config.py | 73 +++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+), 3 deletions(-) diff --git a/optimizely/optimizely_config.py b/optimizely/optimizely_config.py index 43a08735..3c10be4e 100644 --- a/optimizely/optimizely_config.py +++ b/optimizely/optimizely_config.py @@ -27,8 +27,8 @@ def __init__(self, revision, experiments_map, features_map, datafile=None, self._datafile = datafile self.sdk_key = sdk_key self.environment_key = environment_key - self.attributes = attributes - self.events = events + self.attributes = attributes or [] + self.events = events or [] def get_datafile(self): """ Get the datafile associated with OptimizelyConfig. @@ -54,6 +54,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 attributes. + """ + return self.events + class OptimizelyExperiment(object): def __init__(self, id, key, variations_map): self.id = id @@ -143,7 +159,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. """ diff --git a/tests/test_optimizely_config.py b/tests/test_optimizely_config.py index d86c7a74..29bd2443 100644 --- a/tests/test_optimizely_config.py +++ b/tests/test_optimizely_config.py @@ -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': { @@ -790,3 +792,74 @@ 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) From 69e460426a4d26ee356879a912ff4843e2f03bb4 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Thu, 24 Jun 2021 08:31:49 -0400 Subject: [PATCH 08/11] Run autopep8 to fix formatting issues after rebase --- optimizely/optimizely_config.py | 1 + tests/test_user_context.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/optimizely/optimizely_config.py b/optimizely/optimizely_config.py index 3c10be4e..764e9f45 100644 --- a/optimizely/optimizely_config.py +++ b/optimizely/optimizely_config.py @@ -70,6 +70,7 @@ def get_events(self): """ return self.events + class OptimizelyExperiment(object): def __init__(self, id, key, variations_map): self.id = id diff --git a/tests/test_user_context.py b/tests/test_user_context.py index 1620a76a..fcffc415 100644 --- a/tests/test_user_context.py +++ b/tests/test_user_context.py @@ -1296,4 +1296,3 @@ def test_decide_experiment(self): user_context = opt_obj.create_user_context('test_user') decision = user_context.decide('test_feature_in_experiment', [DecideOption.DISABLE_DECISION_EVENT]) self.assertTrue(decision.enabled, "decision should be enabled") - \ No newline at end of file From 5e479a06bf442040a3940c22597dc6892b14ed40 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Thu, 24 Jun 2021 12:15:03 -0400 Subject: [PATCH 09/11] [OASIS-7800] - Added test cases for attribute map and events map --- tests/test_optimizely_config.py | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/test_optimizely_config.py b/tests/test_optimizely_config.py index 29bd2443..8ff8986b 100644 --- a/tests/test_optimizely_config.py +++ b/tests/test_optimizely_config.py @@ -863,3 +863,45 @@ def test__get_events(self): 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)) From 334e07019aabf4606f5e56dd45f0bc6bd0be2f10 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Thu, 24 Jun 2021 12:21:08 -0400 Subject: [PATCH 10/11] Remove unused import from optimizely config --- optimizely/optimizely_config.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/optimizely/optimizely_config.py b/optimizely/optimizely_config.py index 764e9f45..e3e0774f 100644 --- a/optimizely/optimizely_config.py +++ b/optimizely/optimizely_config.py @@ -13,8 +13,6 @@ import copy -from optimizely.helpers.validator import are_attributes_valid - from .project_config import ProjectConfig From 54e9f3a460b0b3fc276ba09750a45c824def45ba Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Fri, 25 Jun 2021 15:59:14 -0400 Subject: [PATCH 11/11] Corrected comment wording in get functions for events. --- optimizely/optimizely_config.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/optimizely/optimizely_config.py b/optimizely/optimizely_config.py index e3e0774f..47dae824 100644 --- a/optimizely/optimizely_config.py +++ b/optimizely/optimizely_config.py @@ -64,7 +64,7 @@ def get_events(self): """ Get the events associated with OptimizelyConfig returns: - A list of attributes. + A list of events. """ return self.events @@ -314,7 +314,7 @@ def get_attributes_map(self): return attributes_map def get_events_map(self): - """ Gets attributes map for the project config. + """ Gets events map for the project config. Returns: dict -- Event key, OptimizelyEvent map