Skip to content

Commit 55fe98f

Browse files
committed
address more PR comments
1 parent 6849c33 commit 55fe98f

7 files changed

+44
-56
lines changed

optimizely/decision_service.py

+18-26
Original file line numberDiff line numberDiff line change
@@ -354,44 +354,36 @@ def get_variation_for_rollout(self, project_config, feature, user, options):
354354
return Decision(None, None, enums.DecisionSources.ROLLOUT), decide_reasons
355355

356356
rollout = project_config.get_rollout_from_id(feature.rolloutId)
357-
358-
if not rollout:
359-
message = 'There is no rollout of feature {}.'.format(feature.key)
360-
self.logger.debug(message)
361-
decide_reasons.append(message)
362-
return Decision(None, None, enums.DecisionSources.ROLLOUT), decide_reasons
363-
364357
rollout_rules = project_config.get_rollout_experiments(rollout)
365358

366-
if not rollout_rules:
367-
message = 'Rollout {} has no experiments.'.format(rollout.id)
359+
if not rollout or not rollout_rules:
360+
message = 'There is no rollout of feature {}.'.format(feature.key)
368361
self.logger.debug(message)
369362
decide_reasons.append(message)
370363
return Decision(None, None, enums.DecisionSources.ROLLOUT), decide_reasons
371364

372-
if rollout and len(rollout_rules) > 0:
373-
index = 0
374-
while index < len(rollout_rules):
375-
decision_response, reasons_received = self.get_variation_from_delivery_rule(project_config,
376-
feature,
377-
rollout_rules, index, user,
378-
options)
365+
index = 0
366+
while index < len(rollout_rules):
367+
decision_response, reasons_received = self.get_variation_from_delivery_rule(project_config,
368+
feature,
369+
rollout_rules, index, user,
370+
options)
379371

380-
decide_reasons += reasons_received
372+
decide_reasons += reasons_received
381373

382-
variation, skip_to_everyone_else = decision_response
374+
variation, skip_to_everyone_else = decision_response
383375

384-
if variation:
385-
rule = rollout_rules[index]
386-
feature_decision = Decision(experiment=rule, variation=variation,
387-
source=enums.DecisionSources.ROLLOUT)
376+
if variation:
377+
rule = rollout_rules[index]
378+
feature_decision = Decision(experiment=rule, variation=variation,
379+
source=enums.DecisionSources.ROLLOUT)
388380

389-
return feature_decision, decide_reasons
381+
return feature_decision, decide_reasons
390382

391-
# the last rule is special for "Everyone Else"
392-
index = len(rollout_rules) - 1 if skip_to_everyone_else else index + 1
383+
# the last rule is special for "Everyone Else"
384+
index = len(rollout_rules) - 1 if skip_to_everyone_else else index + 1
393385

394-
return Decision(None, None, enums.DecisionSources.ROLLOUT), decide_reasons
386+
return Decision(None, None, enums.DecisionSources.ROLLOUT), decide_reasons
395387

396388
def get_variation_from_experiment_rule(self, config, flag_key, rule, user, options):
397389
""" Checks for experiment rule if decision is forced and returns it.

optimizely/event/user_event_factory.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@ def create_impression_event(
4343
"""
4444

4545
if not activated_experiment and rule_type is not enums.DecisionSources.ROLLOUT:
46-
return None # TODO - we get this when event not sent. Now we allow None for activated_experiment
46+
return None
4747

4848
variation, experiment_id = None, None
4949
if activated_experiment:
5050
experiment_id = activated_experiment.id
5151

5252
if variation_id and experiment_id:
5353
variation = project_config.get_variation_from_id_by_experiment_id(experiment_id, variation_id)
54+
# need this condition when we send events involving forced decisions
5455
elif variation_id and flag_key:
5556
variation = project_config.get_flag_variation_by_id(flag_key, variation_id)
5657
event_context = user_event.EventContext(
@@ -60,11 +61,11 @@ def create_impression_event(
6061
return user_event.ImpressionEvent(
6162
event_context,
6263
user_id,
63-
activated_experiment, # TODO - check here also. that exper is used, that is not as None, - or pass empty strings etc
64+
activated_experiment,
6465
event_factory.EventFactory.build_attribute_list(user_attributes, project_config),
6566
variation,
6667
flag_key,
67-
rule_key, # TODO needs to be ampty string here - in relevnt APIs? or is variation that needs to be ampty string?
68+
rule_key,
6869
rule_type,
6970
enabled,
7071
project_config.get_bot_filtering_value(),

optimizely/optimizely.py

-1
Original file line numberDiff line numberDiff line change
@@ -1048,7 +1048,6 @@ def _decide(self, user_context, key, decide_options=None):
10481048
optimizely_decision_context = OptimizelyUserContext.OptimizelyDecisionContext(flag_key=key, rule_key=rule_key)
10491049
forced_decision_response = user_context.find_validated_forced_decision(optimizely_decision_context,
10501050
options=decide_options)
1051-
10521051
variation, decision_reasons = forced_decision_response
10531052
reasons += decision_reasons
10541053

optimizely/optimizely_user_context.py

+17-17
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def __init__(self, optimizely_client, user_id, user_attributes=None):
4646

4747
self._user_attributes = user_attributes.copy() if user_attributes else {}
4848
self.lock = threading.Lock()
49-
self.forced_decisions = {}
49+
self.forced_decisions_map = {}
5050
self.log = logger.SimpleLogger(min_level=enums.LogLevels.INFO)
5151

5252
# decision context
@@ -73,8 +73,8 @@ def _clone(self):
7373
user_context = OptimizelyUserContext(self.client, self.user_id, self.get_user_attributes())
7474

7575
with self.lock:
76-
if self.forced_decisions:
77-
user_context.forced_decisions = copy.deepcopy(self.forced_decisions)
76+
if self.forced_decisions_map:
77+
user_context.forced_decisions_map = copy.deepcopy(self.forced_decisions_map)
7878

7979
return user_context
8080

@@ -159,12 +159,12 @@ def set_forced_decision(self, decision_context, decision):
159159
Returns:
160160
True if the forced decision has been set successfully.
161161
"""
162-
if not self.client.config_manager.get_config():
162+
if not self.client or not self.client.config_manager.get_config():
163163
self.log.logger.error(OptimizelyDecisionMessage.SDK_NOT_READY)
164164
return False
165165

166166
with self.lock:
167-
self.forced_decisions[decision_context] = decision
167+
self.forced_decisions_map[decision_context] = decision
168168

169169
return True
170170

@@ -178,7 +178,7 @@ def get_forced_decision(self, decision_context):
178178
Returns:
179179
A forced_decision or None if forced decisions are not set for the parameters.
180180
"""
181-
if not self.client.config_manager.get_config():
181+
if not self.client or not self.client.config_manager.get_config():
182182
self.log.logger.error(OptimizelyDecisionMessage.SDK_NOT_READY)
183183
return None
184184

@@ -196,13 +196,13 @@ def remove_forced_decision(self, decision_context):
196196
Returns:
197197
Returns: true if the forced decision has been removed successfully.
198198
"""
199-
if not self.client.config_manager.get_config():
199+
if not self.client or not self.client.config_manager.get_config():
200200
self.log.logger.error(OptimizelyDecisionMessage.SDK_NOT_READY)
201201
return False
202202

203203
with self.lock:
204-
if decision_context in self.forced_decisions:
205-
del self.forced_decisions[decision_context]
204+
if decision_context in self.forced_decisions_map:
205+
del self.forced_decisions_map[decision_context]
206206
return True
207207

208208
return False
@@ -219,41 +219,41 @@ def remove_all_forced_decisions(self):
219219
return False
220220

221221
with self.lock:
222-
self.forced_decisions.clear()
222+
self.forced_decisions_map.clear()
223223

224224
return True
225225

226226
def find_forced_decision(self, decision_context):
227227

228228
with self.lock:
229-
if not self.forced_decisions:
229+
if not self.forced_decisions_map:
230230
return None
231231

232232
# must allow None to be returned for the Flags only case
233-
return self.forced_decisions.get(decision_context)
233+
return self.forced_decisions_map.get(decision_context)
234234

235235
def find_validated_forced_decision(self, decision_context, options):
236236

237237
reasons = []
238238

239-
forced_decision_response = self.find_forced_decision(decision_context)
239+
forced_decision = self.find_forced_decision(decision_context)
240240

241241
flag_key = decision_context.flag_key
242242
rule_key = decision_context.rule_key
243243

244-
if forced_decision_response:
245-
variation = self.client.get_flag_variation_by_key(flag_key, forced_decision_response.variation_key)
244+
if forced_decision:
245+
variation = self.client.get_flag_variation_by_key(flag_key, forced_decision.variation_key)
246246
if variation:
247247
if rule_key:
248248
user_has_forced_decision = enums.ForcedDecisionLogs \
249-
.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED.format(forced_decision_response.variation_key,
249+
.USER_HAS_FORCED_DECISION_WITH_RULE_SPECIFIED.format(forced_decision.variation_key,
250250
flag_key,
251251
rule_key,
252252
self.user_id)
253253

254254
else:
255255
user_has_forced_decision = enums.ForcedDecisionLogs \
256-
.USER_HAS_FORCED_DECISION_WITHOUT_RULE_SPECIFIED.format(forced_decision_response.variation_key,
256+
.USER_HAS_FORCED_DECISION_WITHOUT_RULE_SPECIFIED.format(forced_decision.variation_key,
257257
flag_key,
258258
self.user_id)
259259

optimizely/project_config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ def get_rollout_experiments(self, rollout):
224224
"""
225225

226226
rollout_experiments_id_map = self._generate_key_map(rollout.experiments, 'id', entities.Experiment)
227-
rollout_experiments = [exper for exper in rollout_experiments_id_map.values()]
227+
rollout_experiments = [experiment for experiment in rollout_experiments_id_map.values()]
228228

229229
return rollout_experiments
230230

tests/test_optimizely.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5067,5 +5067,5 @@ def test_invalid_flag_key(self):
50675067
"""
50685068
Tests invalid flag key in function get_flag_variation_by_key().
50695069
"""
5070-
# TODO mock function get_flag_variation_by_key?
5070+
# TODO mock function get_flag_variation_by_key
50715071
pass

tests/test_user_context.py

+3-7
Original file line numberDiff line numberDiff line change
@@ -1338,7 +1338,6 @@ def test_forced_decision_return_status__valid_datafile(self):
13381338
status = user_context.remove_all_forced_decisions()
13391339
self.assertTrue(status)
13401340

1341-
# TODO - EXAMPLE - THIS TEST IS NOW REFACTORED AND WORKS ----> FIX REMAINING THREE FAILING TESTS JUST LIKE THIS ONE (use flag "test_feature_in_experiment")
13421341
def test_should_return_valid_decision_after_setting_and_removing_forced_decision(self):
13431342
"""
13441343
Should return valid forced decision after setting and removing forced decision.
@@ -1592,10 +1591,7 @@ def test_invalid_experiment_rule_return_decision__forced_decision(self):
15921591
# self.assertEqual(decide_decision.rule_key, '211147')
15931592
# self.assertTrue(decide_decision.enabled)
15941593

1595-
# TODO - NEW UPDATED - are they supposed to be None ?
1596-
# TODO THIS DECISION IS DISABLED !!!!!! NOT WHAT TEST DOCSTRING SAYS !!!
1597-
# - CHECK W JAE IF THIS TEST IS DOING WHAT IS SUPPOSED TO - IF DOCSTRING IS CORRECT
1598-
# - SHOULD IT REALLY RETURN A VALID DECISION??? cause we get None and disabled decision.
1594+
# TODO - BELOW ARE NEW UPDATED - are they supposed to be None ?
15991595
self.assertEqual(decide_decision.variation_key, None)
16001596
self.assertEqual(decide_decision.rule_key, None)
16011597
self.assertFalse(decide_decision.enabled)
@@ -1616,7 +1612,7 @@ def test_invalid_experiment_rule_return_decision__forced_decision(self):
16161612
# 'User "test_user" bucketed into a targeting rule Everyone Else.'
16171613
# ]
16181614

1619-
# TODO - NEW UPDATED REASONS
1615+
# TODO - BELOW ARE NEW UPDATED REASONS
16201616
expected_reasons = [
16211617
'Evaluating audiences for rule 1: ["11154"].', 'Audiences for rule 1 collectively evaluated to FALSE.',
16221618
'User "test_user" does not meet audience conditions for targeting rule 1.',
@@ -1825,7 +1821,7 @@ def test_forced_decision_clone_return_valid_forced_decision(self):
18251821
user_context_2 = user_context._clone()
18261822
self.assertEqual(user_context_2.user_id, 'test_user')
18271823
self.assertEqual(user_context_2.get_user_attributes(), {})
1828-
self.assertIsNotNone(user_context_2.forced_decisions)
1824+
self.assertIsNotNone(user_context_2.forced_decisions_map)
18291825

18301826
self.assertEqual(user_context_2.get_forced_decision(context_with_flag).variation_key, 'v1')
18311827
self.assertEqual(user_context_2.get_forced_decision(context_with_rule).variation_key, 'v2')

0 commit comments

Comments
 (0)