Skip to content

Commit d114cc6

Browse files
[AI-FSSDK] [FSSDK-12337] Add ExperimentTypes constant and targeted_delivery type
- Add ExperimentTypes class in enums.py with ab, mab, cmab, td, fr - Add 'targeted_delivery' to ExperimentType Literal in types.py - Use enums.ExperimentTypes.fr constant in injection check - Add test for type field parsing from datafile
1 parent 147b0da commit d114cc6

File tree

4 files changed

+62
-2
lines changed

4 files changed

+62
-2
lines changed

optimizely/helpers/enums.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,14 @@ class OdpManagerConfig:
229229
EVENT_TYPE: Final = 'fullstack'
230230

231231

232+
class ExperimentTypes:
233+
ab: Final = 'a/b'
234+
mab: Final = 'mab'
235+
cmab: Final = 'cmab'
236+
td: Final = 'targeted_delivery'
237+
fr: Final = 'feature_rollout'
238+
239+
232240
class OdpSegmentsCacheConfig:
233241
"""ODP Segment Cache configs."""
234242
DEFAULT_CAPACITY: Final = 10_000

optimizely/helpers/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class CmabDict(BaseEntity):
117117
trafficAllocation: int
118118

119119

120-
ExperimentType = Literal['a/b', 'mab', 'cmab', 'feature_rollout']
120+
ExperimentType = Literal['a/b', 'mab', 'cmab', 'targeted_delivery', 'feature_rollout']
121121

122122
HoldoutStatus = Literal['Draft', 'Running', 'Concluded', 'Archived']
123123

optimizely/project_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ def __init__(self, datafile: str | bytes, logger: Logger, error_handler: Any):
237237
everyone_else_variation = self._get_everyone_else_variation(feature)
238238
if everyone_else_variation is not None:
239239
for experiment in rules:
240-
if experiment.type == 'feature_rollout':
240+
if experiment.type == enums.ExperimentTypes.fr:
241241
experiment.variations.append({
242242
'id': everyone_else_variation.id,
243243
'key': everyone_else_variation.key,

tests/test_config.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1567,6 +1567,58 @@ def _build_datafile(self, experiments=None, rollouts=None, feature_flags=None):
15671567
}
15681568
return datafile
15691569

1570+
def test_experiment_type_field_parsed(self):
1571+
"""Test that the 'type' field value is preserved on Experiment after config parsing."""
1572+
datafile = self._build_datafile(
1573+
experiments=[
1574+
{
1575+
'id': 'exp_1',
1576+
'key': 'feature_rollout_exp',
1577+
'status': 'Running',
1578+
'forcedVariations': {},
1579+
'layerId': 'layer_1',
1580+
'audienceIds': [],
1581+
'trafficAllocation': [{'entityId': 'var_1', 'endOfRange': 5000}],
1582+
'variations': [{'key': 'var_1', 'id': 'var_1', 'featureEnabled': True}],
1583+
'type': 'feature_rollout',
1584+
},
1585+
],
1586+
rollouts=[
1587+
{
1588+
'id': 'rollout_1',
1589+
'experiments': [
1590+
{
1591+
'id': 'rollout_rule_1',
1592+
'key': 'rollout_rule_1',
1593+
'status': 'Running',
1594+
'forcedVariations': {},
1595+
'layerId': 'rollout_1',
1596+
'audienceIds': [],
1597+
'trafficAllocation': [{'entityId': 'everyone_var', 'endOfRange': 10000}],
1598+
'variations': [
1599+
{'key': 'everyone_var', 'id': 'everyone_var', 'featureEnabled': False}
1600+
],
1601+
}
1602+
],
1603+
}
1604+
],
1605+
feature_flags=[
1606+
{
1607+
'id': 'flag_1',
1608+
'key': 'test_flag',
1609+
'experimentIds': ['exp_1'],
1610+
'rolloutId': 'rollout_1',
1611+
'variables': [],
1612+
},
1613+
],
1614+
)
1615+
1616+
opt = optimizely.Optimizely(json.dumps(datafile))
1617+
config = opt.config_manager.get_config()
1618+
1619+
experiment = config.experiment_id_map['exp_1']
1620+
self.assertEqual(experiment.type, 'feature_rollout')
1621+
15701622
def test_experiment_type_field_none_when_missing(self):
15711623
"""Test that experiments without 'type' field have type=None."""
15721624
datafile = self._build_datafile(

0 commit comments

Comments
 (0)