Skip to content

Commit ba1608f

Browse files
committed
feat: Support returning default flags for None identities
1 parent 63b546c commit ba1608f

File tree

2 files changed

+50
-4
lines changed

2 files changed

+50
-4
lines changed

flag_engine/segments/evaluator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def get_evaluation_result(context: EvaluationContext) -> EvaluationResult:
109109
segment_feature_contexts[feature_key] = override_feature_context
110110

111111
identity_key = get_context_value(context, "$.identity.key")
112-
flags: typing.List[FlagResult] = [
112+
flags: list[FlagResult] = [
113113
(
114114
{
115115
"enabled": segment_feature_context["enabled"],
@@ -140,7 +140,7 @@ def get_evaluation_result(context: EvaluationContext) -> EvaluationResult:
140140

141141
def get_flag_result_from_feature_context(
142142
feature_context: FeatureContext,
143-
key: SupportsStr,
143+
key: typing.Optional[SupportsStr],
144144
) -> FlagResult:
145145
"""
146146
Get a feature value from the feature context
@@ -150,7 +150,7 @@ def get_flag_result_from_feature_context(
150150
:param key: the key to get the value for
151151
:return: the value for the key in the feature context
152152
"""
153-
if variants := feature_context.get("variants"):
153+
if key is not None and (variants := feature_context.get("variants")):
154154
percentage_value = get_hashed_percentage_for_object_ids(
155155
[feature_context["key"], key]
156156
)

tests/unit/segments/test_segments_evaluator.py

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ def test_get_evaluation_result__identity_override__returns_expected(
984984
),
985985
),
986986
)
987-
def test_get_flag_result_from_feature_context__call_return_expected(
987+
def test_get_flag_result_from_feature_context__calls_returns_expected(
988988
percentage_value: int,
989989
expected_result: FlagResult,
990990
mocker: MockerFixture,
@@ -1031,6 +1031,52 @@ def test_get_flag_result_from_feature_context__call_return_expected(
10311031
)
10321032

10331033

1034+
def test_get_flag_result_from_feature_context__null_key__calls_returns_expected(
1035+
mocker: MockerFixture,
1036+
) -> None:
1037+
# Given
1038+
expected_feature_context_key = "2"
1039+
expected_key = None
1040+
1041+
# we mock the function which gets the percentage value for an identity to
1042+
# return a deterministic value so we know which value to expect
1043+
get_hashed_percentage_for_object_ids_mock = mocker.patch(
1044+
"flag_engine.segments.evaluator.get_hashed_percentage_for_object_ids",
1045+
)
1046+
1047+
# and have a feature context with some multivariate feature options and associated values
1048+
feature_context: FeatureContext = {
1049+
"key": expected_feature_context_key,
1050+
"feature_key": "1",
1051+
"enabled": False,
1052+
"name": "my_feature",
1053+
"value": "control",
1054+
"variants": [
1055+
{"value": "foo", "weight": 30},
1056+
{"value": "bar", "weight": 30},
1057+
],
1058+
}
1059+
1060+
# When
1061+
result = get_flag_result_from_feature_context(
1062+
feature_context=feature_context,
1063+
key=expected_key,
1064+
)
1065+
1066+
# Then
1067+
# the value of the feature state is correct based on the percentage value returned
1068+
assert result == {
1069+
"enabled": False,
1070+
"feature_key": "1",
1071+
"name": "my_feature",
1072+
"reason": "DEFAULT",
1073+
"value": "control",
1074+
}
1075+
1076+
# the function is not called as there is no key to hash against
1077+
get_hashed_percentage_for_object_ids_mock.assert_not_called()
1078+
1079+
10341080
@pytest.mark.parametrize(
10351081
"property",
10361082
[

0 commit comments

Comments
 (0)