From de2f0138729be130ee1eb71ffceed949438a3206 Mon Sep 17 00:00:00 2001 From: Bilal Al-Shahwany Date: Tue, 3 Jun 2025 10:25:52 -0700 Subject: [PATCH] Updated integrations tests --- tests/client/test_input_validator.py | 17 ++++++++ tests/integration/files/splitChanges.json | 48 ++++++++++++++++++++++- tests/integration/test_client_e2e.py | 28 +++++++++++-- 3 files changed, 87 insertions(+), 6 deletions(-) diff --git a/tests/client/test_input_validator.py b/tests/client/test_input_validator.py index 2f15d038..0659ee43 100644 --- a/tests/client/test_input_validator.py +++ b/tests/client/test_input_validator.py @@ -28,6 +28,7 @@ def test_get_treatment(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=SplitStorage) storage_mock.fetch_many.return_value = {'some_feature': split_mock} rbs_storage = mocker.Mock(spec=InMemoryRuleBasedSegmentStorage) @@ -264,6 +265,7 @@ def test_get_treatment_with_config(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] def _configs(treatment): return '{"some": "property"}' if treatment == 'default_treatment' else None @@ -819,6 +821,8 @@ def test_get_treatments(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] + storage_mock = mocker.Mock(spec=SplitStorage) storage_mock.fetch_many.return_value = { 'some_feature': split_mock @@ -965,6 +969,7 @@ def test_get_treatments_with_config(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=SplitStorage) storage_mock.fetch_many.return_value = { @@ -1113,6 +1118,7 @@ def test_get_treatments_by_flag_set(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=InMemorySplitStorage) storage_mock.fetch_many.return_value = { 'some_feature': split_mock @@ -1231,6 +1237,7 @@ def test_get_treatments_by_flag_sets(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=InMemorySplitStorage) storage_mock.fetch_many.return_value = { 'some_feature': split_mock @@ -1358,6 +1365,7 @@ def _configs(treatment): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=InMemorySplitStorage) storage_mock.fetch_many.return_value = { 'some_feature': split_mock @@ -1481,6 +1489,7 @@ def _configs(treatment): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=InMemorySplitStorage) storage_mock.fetch_many.return_value = { 'some_feature': split_mock @@ -1632,6 +1641,7 @@ async def test_get_treatment(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=SplitStorage) async def fetch_many(*_): return { @@ -1889,6 +1899,7 @@ async def test_get_treatment_with_config(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] def _configs(treatment): return '{"some": "property"}' if treatment == 'default_treatment' else None @@ -2423,6 +2434,7 @@ async def test_get_treatments(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=SplitStorage) async def get(*_): return split_mock @@ -2586,6 +2598,7 @@ async def test_get_treatments_with_config(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=SplitStorage) async def get(*_): @@ -2749,6 +2762,7 @@ async def test_get_treatments_by_flag_set(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=SplitStorage) async def get(*_): return split_mock @@ -2893,6 +2907,7 @@ async def test_get_treatments_by_flag_sets(self, mocker): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=SplitStorage) async def get(*_): return split_mock @@ -3048,6 +3063,7 @@ def _configs(treatment): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=SplitStorage) async def get(*_): return split_mock @@ -3195,6 +3211,7 @@ def _configs(treatment): conditions_mock = mocker.PropertyMock() conditions_mock.return_value = [] type(split_mock).conditions = conditions_mock + type(split_mock).prerequisites = [] storage_mock = mocker.Mock(spec=SplitStorage) async def get(*_): return split_mock diff --git a/tests/integration/files/splitChanges.json b/tests/integration/files/splitChanges.json index d9ab1c24..84f7c2cd 100644 --- a/tests/integration/files/splitChanges.json +++ b/tests/integration/files/splitChanges.json @@ -23,7 +23,8 @@ "userDefinedSegmentMatcherData": null, "whitelistMatcherData": { "whitelist": [ - "whitelisted_user" + "whitelisted_user", + "user1234" ] } } @@ -394,7 +395,50 @@ "configurations": {}, "sets": [], "impressionsDisabled": false - } + }, + { + "orgId": null, + "environment": null, + "trafficTypeId": null, + "trafficTypeName": null, + "name": "prereq_feature", + "seed": 1699838640, + "status": "ACTIVE", + "killed": false, + "changeNumber": 123, + "defaultTreatment": "off_default", + "conditions": [ + { + "conditionType": "ROLLOUT", + "matcherGroup": { + "combiner": "AND", + "matchers": [ + { + "matcherType": "ALL_KEYS", + "negate": false, + "userDefinedSegmentMatcherData": null, + "whitelistMatcherData": null + } + ] + }, + "partitions": [ + { + "treatment": "on", + "size": 100 + }, + { + "treatment": "off", + "size": 0 + } + ] + } + ], + "sets": [], + "prerequisites": [ + {"n": "regex_test", "ts": ["on"]}, + {"n": "whitelist_feature", "ts": ["off"]} + ] + } ], "s": -1, "t": 1457726098069 diff --git a/tests/integration/test_client_e2e.py b/tests/integration/test_client_e2e.py index f16352e3..f50869cf 100644 --- a/tests/integration/test_client_e2e.py +++ b/tests/integration/test_client_e2e.py @@ -171,6 +171,16 @@ def _get_treatment(factory, skip_rbs=False): if not isinstance(factory._recorder._impressions_manager._strategy, StrategyNoneMode): _validate_last_impressions(client, ('rbs_feature_flag', 'mauro@split.io', 'off')) + # test prerequisites matcher + assert client.get_treatment('abc4', 'prereq_feature') == 'on' + if not isinstance(factory._recorder._impressions_manager._strategy, StrategyNoneMode): + _validate_last_impressions(client, ('prereq_feature', 'abc4', 'on')) + + # test prerequisites matcher + assert client.get_treatment('user1234', 'prereq_feature') == 'off_default' + if not isinstance(factory._recorder._impressions_manager._strategy, StrategyNoneMode): + _validate_last_impressions(client, ('prereq_feature', 'user1234', 'off_default')) + def _get_treatment_with_config(factory): """Test client.get_treatment_with_config().""" try: @@ -460,8 +470,8 @@ def _manager_methods(factory, skip_rbs=False): assert len(manager.splits()) == 7 return - assert len(manager.split_names()) == 8 - assert len(manager.splits()) == 8 + assert len(manager.split_names()) == 9 + assert len(manager.splits()) == 9 class InMemoryDebugIntegrationTests(object): """Inmemory storage-based integration tests.""" @@ -4458,6 +4468,16 @@ async def _get_treatment_async(factory, skip_rbs=False): if skip_rbs: return + + # test prerequisites matcher + assert await client.get_treatment('abc4', 'prereq_feature') == 'on' + if not isinstance(factory._recorder._impressions_manager._strategy, StrategyNoneMode): + await _validate_last_impressions_async(client, ('prereq_feature', 'abc4', 'on')) + + # test prerequisites matcher + assert await client.get_treatment('user1234', 'prereq_feature') == 'off_default' + if not isinstance(factory._recorder._impressions_manager._strategy, StrategyNoneMode): + await _validate_last_impressions_async(client, ('prereq_feature', 'user1234', 'off_default')) # test rule based segment matcher assert await client.get_treatment('bilal@split.io', 'rbs_feature_flag', {'email': 'bilal@split.io'}) == 'on' @@ -4758,5 +4778,5 @@ async def _manager_methods_async(factory, skip_rbs=False): assert len(await manager.splits()) == 7 return - assert len(await manager.split_names()) == 8 - assert len(await manager.splits()) == 8 + assert len(await manager.split_names()) == 9 + assert len(await manager.splits()) == 9