diff --git a/splitio/models/splits.py b/splitio/models/splits.py index 92a277c4..47e69284 100644 --- a/splitio/models/splits.py +++ b/splitio/models/splits.py @@ -10,7 +10,7 @@ SplitView = namedtuple( 'SplitView', - ['name', 'traffic_type', 'killed', 'treatments', 'change_number', 'configs', 'default_treatment', 'sets', 'impressions_disabled'] + ['name', 'traffic_type', 'killed', 'treatments', 'change_number', 'configs', 'default_treatment', 'sets', 'impressions_disabled', 'prerequisites'] ) _DEFAULT_CONDITIONS_TEMPLATE = { @@ -40,7 +40,28 @@ "label": "targeting rule type unsupported by sdk" } +class Prerequisites(object): + """Prerequisites.""" + def __init__(self, feature_flag_name, treatments): + self._feature_flag_name = feature_flag_name + self._treatments = treatments + + @property + def feature_flag_name(self): + """Return featur eflag name.""" + return self._feature_flag_name + @property + def treatments(self): + """Return treatments.""" + return self._treatments + + def to_json(self): + to_return = [] + for feature_flag_name in self._feature_flag_name: + to_return.append({"n": feature_flag_name, "ts": [treatment for treatment in self._treatments]}) + + return to_return class Status(Enum): """Split status.""" @@ -74,7 +95,8 @@ def __init__( # pylint: disable=too-many-arguments traffic_allocation_seed=None, configurations=None, sets=None, - impressions_disabled=None + impressions_disabled=None, + prerequisites = None ): """ Class constructor. @@ -99,6 +121,8 @@ def __init__( # pylint: disable=too-many-arguments :type sets: list :pram impressions_disabled: track impressions flag :type impressions_disabled: boolean + :pram prerequisites: prerequisites + :type prerequisites: List of Preqreuisites """ self._name = name self._seed = seed @@ -129,6 +153,7 @@ def __init__( # pylint: disable=too-many-arguments self._configurations = configurations self._sets = set(sets) if sets is not None else set() self._impressions_disabled = impressions_disabled if impressions_disabled is not None else False + self._prerequisites = prerequisites if prerequisites is not None else [] @property def name(self): @@ -194,6 +219,11 @@ def sets(self): def impressions_disabled(self): """Return impressions_disabled of the split.""" return self._impressions_disabled + + @property + def prerequisites(self): + """Return prerequisites of the split.""" + return self._prerequisites def get_configurations_for(self, treatment): """Return the mapping of treatments to configurations.""" @@ -224,7 +254,8 @@ def to_json(self): 'conditions': [c.to_json() for c in self.conditions], 'configurations': self._configurations, 'sets': list(self._sets), - 'impressionsDisabled': self._impressions_disabled + 'impressionsDisabled': self._impressions_disabled, + 'prerequisites': [prerequisite.to_json() for prerequisite in self._prerequisites] } def to_split_view(self): @@ -243,7 +274,8 @@ def to_split_view(self): self._configurations if self._configurations is not None else {}, self._default_treatment, list(self._sets) if self._sets is not None else [], - self._impressions_disabled + self._impressions_disabled, + self._prerequisites ) def local_kill(self, default_treatment, change_number): @@ -300,5 +332,13 @@ def from_raw(raw_split): traffic_allocation_seed=raw_split.get('trafficAllocationSeed'), configurations=raw_split.get('configurations'), sets=set(raw_split.get('sets')) if raw_split.get('sets') is not None else [], - impressions_disabled=raw_split.get('impressionsDisabled') if raw_split.get('impressionsDisabled') is not None else False + impressions_disabled=raw_split.get('impressionsDisabled') if raw_split.get('impressionsDisabled') is not None else False, + prerequisites=from_raw_prerequisites(raw_split.get('prerequisites')) if raw_split.get('prerequisites') is not None else [] ) + +def from_raw_prerequisites(raw_prerequisites): + to_return = [] + for prerequisite in raw_prerequisites: + to_return.append(Prerequisites(prerequisite['n'], prerequisite['ts'])) + + return to_return \ No newline at end of file diff --git a/tests/models/test_splits.py b/tests/models/test_splits.py index 442a18d0..472ecde9 100644 --- a/tests/models/test_splits.py +++ b/tests/models/test_splits.py @@ -11,6 +11,10 @@ class SplitTests(object): 'changeNumber': 123, 'trafficTypeName': 'user', 'name': 'some_name', + 'prerequisites': [ + { 'n': 'flag1', 'ts': ['on','v1'] }, + { 'n': 'flag2', 'ts': ['off'] } + ], 'trafficAllocation': 100, 'trafficAllocationSeed': 123456, 'seed': 321654, @@ -83,14 +87,26 @@ def test_from_raw(self): assert parsed._configurations == {'on': '{"color": "blue", "size": 13}'} assert parsed.sets == {'set1', 'set2'} assert parsed.impressions_disabled == False - + assert len(parsed.prerequisites) == 2 + flag1 = False + flag2 = False + for prerequisite in parsed.prerequisites: + if prerequisite.feature_flag_name == 'flag1': + flag1 = True + assert prerequisite.treatments == ['on','v1'] + if prerequisite.feature_flag_name == 'flag2': + flag2 = True + assert prerequisite.treatments == ['off'] + assert flag1 + assert flag2 + def test_get_segment_names(self, mocker): """Test fetching segment names.""" cond1 = mocker.Mock(spec=Condition) cond2 = mocker.Mock(spec=Condition) cond1.get_segment_names.return_value = ['segment1', 'segment2'] cond2.get_segment_names.return_value = ['segment3', 'segment4'] - split1 = splits.Split( 'some_split', 123, False, 'off', 'user', 'ACTIVE', 123, [cond1, cond2]) + split1 = splits.Split( 'some_split', 123, False, 'off', 'user', 'ACTIVE', 123, [cond1, cond2], None) assert split1.get_segment_names() == ['segment%d' % i for i in range(1, 5)] def test_to_json(self):