Skip to content

Commit f979ec3

Browse files
authored
Merge pull request #122 from Flagsmith/fix/percentage-split-consistency
fix!: consistent split evaluations
2 parents 28f36c5 + f4da051 commit f979ec3

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

src/main/java/com/flagsmith/flagengine/segments/SegmentEvaluator.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,16 @@ public static Boolean evaluateIdentityInSegment(IdentityModel identity, SegmentM
5757
List<TraitModel> traits =
5858
overrideTraits != null ? overrideTraits : identity.getIdentityTraits();
5959

60+
String identityHashKey = identity.getDjangoId() == null ? identity.getCompositeKey()
61+
: identity.getDjangoId().toString();
62+
6063
if (segmentRules != null && segmentRules.size() > 0) {
6164
List<Boolean> segmentRuleEvaluations = segmentRules.stream().map(
6265
(rule) -> traitsMatchSegmentRule(
6366
traits,
6467
rule,
6568
segment.getId(),
66-
identity.getCompositeKey()
69+
identityHashKey
6770
)
6871
).collect(Collectors.toList());
6972

src/test/java/com/flagsmith/flagengine/unit/segments/SegmentEvaluatorTest.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,44 @@ public void testTraitExistenceConditions(SegmentConditions conditionOperator, St
103103
// The result is as we expect from the DataProvider definition
104104
Assertions.assertEquals(inSegment, expectedResult);
105105
}
106+
107+
private static Stream<Arguments> identitiesInSegmentsPercentageSplit() {
108+
return Stream.of(
109+
Arguments.of(null, "Test", Boolean.TRUE),
110+
Arguments.of(1, "Test", Boolean.FALSE));
111+
}
112+
113+
@ParameterizedTest
114+
@MethodSource("identitiesInSegmentsPercentageSplit")
115+
public void testIdentityInSegmentPercentageSplitUsesDjangoId(Integer djangoId, String identifier,
116+
Boolean expectedResult) {
117+
// Given
118+
// An identity with djangoId and identifier as defined in the DataProvider
119+
IdentityModel identityModel = new IdentityModel();
120+
identityModel.setDjangoId(djangoId);
121+
identityModel.setIdentifier(identifier);
122+
identityModel.setEnvironmentApiKey("key");
123+
124+
// And a segment with 50% percentage split
125+
SegmentConditionModel segmentCondition = new SegmentConditionModel();
126+
segmentCondition.setOperator(SegmentConditions.PERCENTAGE_SPLIT);
127+
segmentCondition.setValue("50");
128+
129+
SegmentRuleModel segmentRule = new SegmentRuleModel();
130+
segmentRule.setConditions(new ArrayList<>(Arrays.asList(segmentCondition)));
131+
segmentRule.setType(SegmentRules.ALL_RULE.getRule());
132+
133+
SegmentModel segment = new SegmentModel();
134+
segment.setId(1);
135+
segment.setName("% split");
136+
segment.setRules(new ArrayList<>(Arrays.asList(segmentRule)));
137+
138+
// When
139+
// We evaluate whether the identity is in the segment
140+
Boolean result = SegmentEvaluator.evaluateIdentityInSegment(identityModel, segment, null);
141+
142+
// Then
143+
// The result is as we expect from the DataProvider definition
144+
Assertions.assertEquals(result, expectedResult);
145+
}
106146
}

0 commit comments

Comments
 (0)