Skip to content

Commit 02eca8a

Browse files
Moving around some code (#70)
1 parent 9f38b15 commit 02eca8a

File tree

3 files changed

+48
-29
lines changed

3 files changed

+48
-29
lines changed

CHANGELOG.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
# 1.2.1
1+
## 1.2.1
22
- Removed older feature flag parsing.
33

4-
# 1.2.0
4+
## 1.2.0
55
- Added user profile service.
66

7-
# 1.1.1
7+
## 1.1.1
88
- Updated datafile parsing to be able to handle additional fields.
99
- Deprecated Classic project support.
1010

11-
# 1.1.0
11+
## 1.1.0
1212
- Included datafile revision information in log events.
1313
- Added event tags to track API to allow users to pass in event metadata.
1414
- Deprecated the `event_value` parameter from the track method. Should use `event_tags` to pass in event value instead.

optimizely/optimizely.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ def is_feature_enabled(self, feature_key, user_id, attributes=None):
287287
Returns:
288288
True if the feature is enabled for the user. False otherwise.
289289
"""
290+
290291
if not self.is_valid:
291292
self.logger.log(enums.LogLevels.ERROR, enums.Errors.INVALID_DATAFILE.format('is_feature_enabled'))
292293
return False
@@ -312,13 +313,13 @@ def get_enabled_features(self, user_id, attributes=None):
312313
313314
Returns:
314315
A list of the keys of the features that are enabled for the user.
315-
316316
"""
317+
318+
enabled_features = []
317319
if not self.is_valid:
318320
self.logger.log(enums.LogLevels.ERROR, enums.Errors.INVALID_DATAFILE.format('get_enabled_features'))
319-
return False
321+
return enabled_features
320322

321-
enabled_features = []
322323
for feature in self.config.feature_key_map.values():
323324
if self.is_feature_enabled(feature.key, user_id, attributes):
324325
enabled_features.append(feature.key)

tests/test_optimizely.py

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ def test_activate__bucketer_returns_none(self):
251251
def test_activate__invalid_object(self):
252252
""" Test that activate logs error if Optimizely object is not created correctly. """
253253

254-
opt_obj = optimizely.Optimizely('invalid_file')
254+
opt_obj = optimizely.Optimizely('invalid_datafile')
255255

256256
with mock.patch('optimizely.logger.SimpleLogger.log') as mock_logging:
257257
self.assertIsNone(opt_obj.activate('test_experiment', 'test_user'))
@@ -538,7 +538,7 @@ def test_track__whitelisted_user_overrides_audience_check(self):
538538
def test_track__invalid_object(self):
539539
""" Test that track logs error if Optimizely object is not created correctly. """
540540

541-
opt_obj = optimizely.Optimizely('invalid_file')
541+
opt_obj = optimizely.Optimizely('invalid_datafile')
542542

543543
with mock.patch('optimizely.logger.SimpleLogger.log') as mock_logging:
544544
opt_obj.track('test_event', 'test_user')
@@ -548,7 +548,7 @@ def test_track__invalid_object(self):
548548
def test_get_variation__invalid_object(self):
549549
""" Test that get_variation logs error if Optimizely object is not created correctly. """
550550

551-
opt_obj = optimizely.Optimizely('invalid_file')
551+
opt_obj = optimizely.Optimizely('invalid_datafile')
552552

553553
with mock.patch('optimizely.logger.SimpleLogger.log') as mock_logging:
554554
self.assertIsNone(opt_obj.get_variation('test_experiment', 'test_user'))
@@ -557,34 +557,42 @@ def test_get_variation__invalid_object(self):
557557

558558
def test_is_feature_enabled__returns_false_for_invalid_feature(self):
559559
""" Test that the feature is not enabled for the user if the provided feature key is invalid. """
560-
optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
561-
project_config = optimizely_instance.config
562560

563-
with mock.patch(
564-
'optimizely.decision_service.DecisionService.get_variation_for_feature'
565-
) as mock_decision:
566-
self.assertFalse(optimizely_instance.is_feature_enabled('invalid_feature', 'user1'))
561+
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
562+
563+
with mock.patch('optimizely.decision_service.DecisionService.get_variation_for_feature') as mock_decision:
564+
self.assertFalse(opt_obj.is_feature_enabled('invalid_feature', 'user1'))
567565

568566
self.assertFalse(mock_decision.called)
569567

570568
def test_is_feature_enabled__returns_true_if_user_is_bucketed_into_a_variation(self):
571569
""" Test that the feature is not enabled for the user if the provided feature key is invalid. """
572-
optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
573-
project_config = optimizely_instance.config
570+
571+
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
572+
project_config = opt_obj.config
574573
feature = project_config.get_feature_from_key('test_feature_1')
575574

576-
with mock.patch(
577-
'optimizely.decision_service.DecisionService.get_variation_for_feature',
578-
return_value=project_config.get_variation_from_id('test_experiment', '111129')
579-
) as mock_decision:
580-
self.assertTrue(optimizely_instance.is_feature_enabled('test_feature_1', 'user1'))
575+
with mock.patch('optimizely.decision_service.DecisionService.get_variation_for_feature',
576+
return_value=project_config.get_variation_from_id('test_experiment', '111129')) as mock_decision:
577+
self.assertTrue(opt_obj.is_feature_enabled('test_feature_1', 'user1'))
581578

582579
mock_decision.assert_called_once_with(feature, 'user1', None)
583580

581+
def test_is_feature_enabled__invalid_object(self):
582+
""" Test that is_feature_enabled returns False if Optimizely object is not valid. """
583+
584+
opt_obj = optimizely.Optimizely('invalid_file')
585+
586+
with mock.patch('optimizely.logger.SimpleLogger.log') as mock_logging:
587+
self.assertFalse(opt_obj.is_feature_enabled('test_feature_1', 'user_1'))
588+
589+
mock_logging.assert_called_once_with(enums.LogLevels.ERROR,
590+
'Datafile has invalid format. Failing "is_feature_enabled".')
591+
584592
def test_get_enabled_features(self):
585593
""" Test that get_enabled_features only returns features that are enabled for the specified user. """
586-
optimizely_instance = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
587-
project_config = optimizely_instance.config
594+
595+
opt_obj = optimizely.Optimizely(json.dumps(self.config_dict_with_features))
588596

589597
def side_effect(*args, **kwargs):
590598
feature_key = args[0]
@@ -593,10 +601,9 @@ def side_effect(*args, **kwargs):
593601

594602
return False
595603

596-
with mock.patch(
597-
'optimizely.optimizely.Optimizely.is_feature_enabled',
598-
side_effect=side_effect) as mock_is_feature_enabled:
599-
received_features = optimizely_instance.get_enabled_features('user_1')
604+
with mock.patch('optimizely.optimizely.Optimizely.is_feature_enabled',
605+
side_effect=side_effect) as mock_is_feature_enabled:
606+
received_features = opt_obj.get_enabled_features('user_1')
600607

601608
expected_enabled_features = ['test_feature_1', 'test_feature_2']
602609
self.assertEqual(sorted(expected_enabled_features), sorted(received_features))
@@ -605,6 +612,17 @@ def side_effect(*args, **kwargs):
605612
mock_is_feature_enabled.assert_any_call('test_feature_in_group', 'user_1', None)
606613
mock_is_feature_enabled.assert_any_call('test_feature_in_experiment_and_rollout', 'user_1', None)
607614

615+
def test_get_enabled_features__invalid_object(self):
616+
""" Test that get_enabled_features returns empty list if Optimizely object is not valid. """
617+
618+
opt_obj = optimizely.Optimizely('invalid_file')
619+
620+
with mock.patch('optimizely.logger.SimpleLogger.log') as mock_logging:
621+
self.assertEqual([], opt_obj.get_enabled_features('user_1'))
622+
623+
mock_logging.assert_called_once_with(enums.LogLevels.ERROR,
624+
'Datafile has invalid format. Failing "get_enabled_features".')
625+
608626

609627
class OptimizelyWithExceptionTest(base.BaseTest):
610628

0 commit comments

Comments
 (0)