Skip to content

Commit 3f12e5f

Browse files
authored
fix: Incorrect TARGETING_MATCH reasons (#258)
1 parent fa37c6c commit 3f12e5f

File tree

2 files changed

+78
-20
lines changed

2 files changed

+78
-20
lines changed

flag_engine/segments/evaluator.py

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
from flag_engine.utils.types import SupportsStr, get_casting_function
2828

2929

30+
class FeatureContextWithSegmentName(typing.TypedDict):
31+
feature_context: FeatureContext
32+
segment_name: str
33+
34+
3035
def get_evaluation_result(context: EvaluationContext) -> EvaluationResult:
3136
"""
3237
Get the evaluation result for a given context.
@@ -35,7 +40,10 @@ def get_evaluation_result(context: EvaluationContext) -> EvaluationResult:
3540
:return: EvaluationResult containing the context, flags, and segments
3641
"""
3742
segments: list[SegmentResult] = []
38-
segment_feature_contexts: dict[SupportsStr, FeatureContext] = {}
43+
flags: list[FlagResult] = []
44+
45+
segment_feature_contexts: dict[SupportsStr, FeatureContextWithSegmentName] = {}
46+
3947
for segment_context in (context.get("segments") or {}).values():
4048
if not is_context_in_segment(context, segment_context):
4149
continue
@@ -56,35 +64,44 @@ def get_evaluation_result(context: EvaluationContext) -> EvaluationResult:
5664
"priority",
5765
constants.DEFAULT_PRIORITY,
5866
)
59-
< segment_feature_contexts[feature_key].get(
67+
< (segment_feature_contexts[feature_key]["feature_context"]).get(
6068
"priority",
6169
constants.DEFAULT_PRIORITY,
6270
)
6371
):
64-
segment_feature_contexts[feature_key] = override_feature_context
72+
segment_feature_contexts[feature_key] = (
73+
FeatureContextWithSegmentName(
74+
feature_context=override_feature_context,
75+
segment_name=segment_context["name"],
76+
)
77+
)
6578

66-
identity_key = get_context_value(context, "$.identity.key")
67-
flags: list[FlagResult] = [
68-
(
69-
{
70-
"enabled": segment_feature_context["enabled"],
71-
"feature_key": segment_feature_context["feature_key"],
72-
"name": segment_feature_context["name"],
73-
"reason": f"TARGETING_MATCH; segment={segment_context['name']}",
74-
"value": segment_feature_context.get("value"),
75-
}
76-
if (
77-
segment_feature_context := segment_feature_contexts.get(
78-
feature_context["feature_key"],
79-
)
79+
identity_key = (
80+
identity_context["key"]
81+
if (identity_context := context.get("identity"))
82+
else None
83+
)
84+
for feature_context in (context.get("features") or {}).values():
85+
if feature_context_with_segment_name := segment_feature_contexts.get(
86+
feature_context["feature_key"],
87+
):
88+
feature_context = feature_context_with_segment_name["feature_context"]
89+
flags.append(
90+
{
91+
"enabled": feature_context["enabled"],
92+
"feature_key": feature_context["feature_key"],
93+
"name": feature_context["name"],
94+
"reason": f"TARGETING_MATCH; segment={feature_context_with_segment_name['segment_name']}",
95+
"value": feature_context.get("value"),
96+
}
8097
)
81-
else get_flag_result_from_feature_context(
98+
continue
99+
flags.append(
100+
get_flag_result_from_feature_context(
82101
feature_context=feature_context,
83102
key=identity_key,
84103
)
85104
)
86-
for feature_context in (context.get("features") or {}).values()
87-
]
88105

89106
return {
90107
"context": context,

tests/unit/test_engine.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,13 @@ def test_get_evaluation_result__segment_override__no_priority__returns_expected(
250250
"enabled": False,
251251
"value": None,
252252
},
253+
"feature_2": {
254+
"key": "2",
255+
"feature_key": "2",
256+
"name": "feature_2",
257+
"enabled": False,
258+
"value": None,
259+
},
253260
},
254261
"segments": {
255262
"1": {
@@ -297,6 +304,32 @@ def test_get_evaluation_result__segment_override__no_priority__returns_expected(
297304
}
298305
],
299306
},
307+
"3": {
308+
"key": "3",
309+
"name": "another_segment",
310+
"rules": [
311+
{
312+
"type": "ALL",
313+
"conditions": [
314+
{
315+
"property": "$.identity.identifier",
316+
"operator": "EQUAL",
317+
"value": "identity_2",
318+
}
319+
],
320+
"rules": [],
321+
}
322+
],
323+
"overrides": [
324+
{
325+
"key": "5",
326+
"feature_key": "2",
327+
"name": "feature_2",
328+
"enabled": False,
329+
"value": "moose",
330+
}
331+
],
332+
},
300333
},
301334
}
302335

@@ -314,9 +347,17 @@ def test_get_evaluation_result__segment_override__no_priority__returns_expected(
314347
"reason": "TARGETING_MATCH; segment=segment_with_override_priority",
315348
"value": "overridden_with_priority",
316349
},
350+
{
351+
"enabled": False,
352+
"feature_key": "2",
353+
"name": "feature_2",
354+
"reason": "TARGETING_MATCH; segment=another_segment",
355+
"value": "moose",
356+
},
317357
],
318358
"segments": [
319359
{"key": "1", "name": "segment_without_override_priority"},
320360
{"key": "2", "name": "segment_with_override_priority"},
361+
{"key": "3", "name": "another_segment"},
321362
],
322363
}

0 commit comments

Comments
 (0)