Skip to content

Commit cbb6031

Browse files
committed
fix: Implicit identity key not supported for % Split operator
1 parent ae35794 commit cbb6031

File tree

10 files changed

+25
-59
lines changed

10 files changed

+25
-59
lines changed

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
[submodule "tests/Engine/EngineTests/EngineTestData"]
22
path = tests/Engine/EngineTests/EngineTestData
33
url = [email protected]:Flagsmith/engine-test-data.git
4-
tag = v2.5.0
4+
tag = v3.2.1

composer.phar

2.84 MB
Binary file not shown.

src/Engine/Engine.php

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,25 +44,26 @@ public static function getEvaluationResult($context): EvaluationResult
4444
$evaluatedFeatures = [];
4545

4646
/** @var array<string, SegmentContext> */
47-
$matchedSegmentsByFeatureKey = [];
47+
$matchedSegmentsByFeatureName = [];
4848

4949
/** @var array<string, FlagResult> */
5050
$evaluatedFlags = [];
5151

52+
self::enrichContext($context);
53+
5254
foreach ($context->segments as $segment) {
5355
if (!self::isContextInSegment($context, $segment)) {
5456
continue;
5557
}
5658

5759
$segmentResult = new SegmentResult();
58-
$segmentResult->key = $segment->key;
5960
$segmentResult->name = $segment->name;
6061
$segmentResult->metadata = $segment->metadata;
6162
$evaluatedSegments[] = $segmentResult;
6263

6364
foreach ($segment->overrides as $overrideFeature) {
64-
$featureKey = $overrideFeature->feature_key;
65-
$evaluatedFeature = $evaluatedFeatures[$featureKey] ?? null;
65+
$featureName = $overrideFeature->name;
66+
$evaluatedFeature = $evaluatedFeatures[$featureName] ?? null;
6667
if ($evaluatedFeature) {
6768
$overrideWinsPriority =
6869
($overrideFeature->priority ?? self::WEAKEST_PRIORITY) <
@@ -72,19 +73,18 @@ public static function getEvaluationResult($context): EvaluationResult
7273
}
7374
}
7475

75-
$evaluatedFeatures[$featureKey] = $overrideFeature;
76-
$matchedSegmentsByFeatureKey[$featureKey] = $segment;
76+
$evaluatedFeatures[$featureName] = $overrideFeature;
77+
$matchedSegmentsByFeatureName[$featureName] = $segment;
7778
}
7879
}
7980

8081
foreach ($context->features as $feature) {
81-
$featureKey = $feature->feature_key;
8282
$featureName = $feature->name;
83-
$evaluatedFeature = $evaluatedFeatures[$featureKey] ?? null;
83+
$evaluatedFeature = $evaluatedFeatures[$featureName] ?? null;
8484
if ($evaluatedFeature) {
8585
$evaluatedFlags[$featureName] = self::getFlagResultFromSegmentContext(
8686
$evaluatedFeature,
87-
$matchedSegmentsByFeatureKey[$featureKey],
87+
$matchedSegmentsByFeatureName[$featureName],
8888
);
8989
continue;
9090
}
@@ -101,6 +101,20 @@ public static function getEvaluationResult($context): EvaluationResult
101101
return $result;
102102
}
103103

104+
/**
105+
* Enrich the evaluation context with derived values:
106+
* - `$.identity.key` if missing
107+
*
108+
* @param EvaluationContext $context
109+
* @return void
110+
*/
111+
private static function enrichContext(EvaluationContext $context): void
112+
{
113+
if ($context->identity !== null && $context->identity->key === null) {
114+
$context->identity->key = "{$context->environment->key}_{$context->identity->identifier}";
115+
}
116+
}
117+
104118
/**
105119
* @param EvaluationContext $context
106120
* @param SegmentContext $segment
@@ -147,7 +161,6 @@ private static function getFlagResultFromFeatureContext($feature, $splitKey)
147161
$percentageValue < $limit
148162
) {
149163
$flag = new FlagResult();
150-
$flag->feature_key = $feature->feature_key;
151164
$flag->name = $feature->name;
152165
$flag->enabled = $feature->enabled;
153166
$flag->value = $variant->value;
@@ -160,7 +173,6 @@ private static function getFlagResultFromFeatureContext($feature, $splitKey)
160173
}
161174

162175
$flag = new FlagResult();
163-
$flag->feature_key = $feature->feature_key;
164176
$flag->name = $feature->name;
165177
$flag->enabled = $feature->enabled;
166178
$flag->value = $feature->value;
@@ -177,7 +189,6 @@ private static function getFlagResultFromFeatureContext($feature, $splitKey)
177189
private static function getFlagResultFromSegmentContext($feature, $segment)
178190
{
179191
$flag = new FlagResult();
180-
$flag->feature_key = $feature->feature_key;
181192
$flag->name = $feature->name;
182193
$flag->enabled = $feature->enabled;
183194
$flag->value = $feature->value;

src/Engine/Utils/Types/Context/EvaluationContext.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ private static function _convertFeatures($jsonFeatures): array
104104
foreach ($jsonFeatures as $jsonFeature) {
105105
$feature = new FeatureContext();
106106
$feature->key = $jsonFeature->key;
107-
$feature->feature_key = (string) $jsonFeature->feature_key;
108107
$feature->name = $jsonFeature->name;
109108
$feature->enabled = $jsonFeature->enabled;
110109
$feature->value = $jsonFeature->value;

src/Engine/Utils/Types/Context/FeatureContext.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ class FeatureContext
77
/** @var string */
88
public $key;
99

10-
/** @var string */
11-
public $feature_key;
12-
1310
/** @var string */
1411
public $name;
1512

src/Engine/Utils/Types/Result/FlagResult.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44

55
class FlagResult implements \JsonSerializable
66
{
7-
/** @var string */
8-
public $feature_key;
9-
107
/** @var string */
118
public $name;
129

src/Engine/Utils/Types/Result/SegmentResult.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44

55
class SegmentResult implements \JsonSerializable
66
{
7-
/** @var string */
8-
public $key;
9-
107
/** @var string */
118
public $name;
129

src/Utils/Mappers.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ public static function mapContextAndIdentityToContext($context, $identifier, $tr
6464
{
6565
$identity = new IdentityContext();
6666
$identity->identifier = $identifier;
67-
$identity->key = "{$context->environment->key}_{$identifier}";
6867
$identity->traits = (array) $traits;
6968

7069
$context = $context->deepClone();
@@ -112,7 +111,6 @@ private static function _mapEnvironmentDocumentFeatureStatesToFeatureContexts($f
112111
foreach ($featureStates as $featureState) {
113112
$feature = new FeatureContext();
114113
$feature->key = (string) ($featureState->django_id ?? $featureState->featurestate_uuid);
115-
$feature->feature_key = (string) $featureState->feature->id;
116114
$feature->name = $featureState->feature->name;
117115
$feature->enabled = $featureState->enabled;
118116
$feature->value = $featureState->feature_state_value;
@@ -190,7 +188,6 @@ private static function _mapIdentityOverridesToSegments($identityOverrides)
190188
[$featureId, $featureName, $enabled, $value] = $overrideKey;
191189
$feature = new FeatureContext();
192190
$feature->key = ''; // Not used in identity overrides
193-
$feature->feature_key = (string) $featureId;
194191
$feature->name = $featureName;
195192
$feature->enabled = $enabled;
196193
$feature->value = $value;
Submodule EngineTestData updated 158 files

tests/Utils/MappersTest.php

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ public function testMapEnvironmentDocumentToContextProducesEvaluationContext():
6363
$this->assertEquals(['overridden-id'], $context->segments[$overrideKey]->rules[0]->conditions[0]->value);
6464

6565
$this->assertEquals('', $context->segments[$overrideKey]->overrides[0]->key);
66-
$this->assertEquals(1, $context->segments[$overrideKey]->overrides[0]->feature_key);
6766
$this->assertEquals('some_feature', $context->segments[$overrideKey]->overrides[0]->name);
6867
$this->assertFalse($context->segments[$overrideKey]->overrides[0]->enabled);
6968
$this->assertEquals('some-overridden-value', $context->segments[$overrideKey]->overrides[0]->value);
@@ -74,7 +73,6 @@ public function testMapEnvironmentDocumentToContextProducesEvaluationContext():
7473
$this->assertCount(3, $context->features);
7574
$this->assertArrayHasKey('some_feature', $context->features);
7675
$this->assertEquals('00000000-0000-0000-0000-000000000000', $context->features['some_feature']->key);
77-
$this->assertEquals('1', $context->features['some_feature']->feature_key);
7876
$this->assertEquals('some_feature', $context->features['some_feature']->name);
7977
$this->assertTrue($context->features['some_feature']->enabled);
8078
$this->assertEquals('some-value', $context->features['some_feature']->value);
@@ -86,7 +84,6 @@ public function testMapEnvironmentDocumentToContextProducesEvaluationContext():
8684
$this->assertArrayHasKey('mv_feature_with_ids', $context->features);
8785
$mvFeatureWithIds = $context->features['mv_feature_with_ids'];
8886
$this->assertEquals('2', $mvFeatureWithIds->key);
89-
$this->assertEquals('2', $mvFeatureWithIds->feature_key);
9087
$this->assertEquals('mv_feature_with_ids', $mvFeatureWithIds->name);
9188
$this->assertTrue($mvFeatureWithIds->enabled);
9289
$this->assertEquals('default_value', $mvFeatureWithIds->value);
@@ -108,7 +105,6 @@ public function testMapEnvironmentDocumentToContextProducesEvaluationContext():
108105
$this->assertArrayHasKey('mv_feature_without_ids', $context->features);
109106
$mvFeatureWithoutIds = $context->features['mv_feature_without_ids'];
110107
$this->assertEquals('3', $mvFeatureWithoutIds->key);
111-
$this->assertEquals('3', $mvFeatureWithoutIds->feature_key);
112108
$this->assertEquals('mv_feature_without_ids', $mvFeatureWithoutIds->name);
113109
$this->assertFalse($mvFeatureWithoutIds->enabled);
114110
$this->assertEquals('fallback_value', $mvFeatureWithoutIds->value);
@@ -127,32 +123,4 @@ public function testMapEnvironmentDocumentToContextProducesEvaluationContext():
127123
$this->assertEquals(25.0, $mvFeatureWithoutIds->variants[2]->weight);
128124
$this->assertEquals(2, $mvFeatureWithoutIds->variants[2]->priority); // Third
129125
}
130-
131-
public function testMapContextAndIdentityToContextProducesEvaluationContextWithIdentity(): void
132-
{
133-
// Given
134-
$originalContext = new EvaluationContext();
135-
$originalContext->environment = new EnvironmentContext();
136-
$originalContext->environment->key = 'public-env-key';
137-
138-
// When
139-
$context = Mappers::mapContextAndIdentityToContext(
140-
context: $originalContext,
141-
identifier: 'neo',
142-
traits: (object) [
143-
'chosen-pill' => 'red',
144-
'has-met-the-oracle' => true,
145-
],
146-
);
147-
148-
// Then
149-
$this->assertInstanceOf(EvaluationContext::class, $context);
150-
$this->assertNotSame($originalContext, $context);
151-
$this->assertEquals('public-env-key', $context->environment->key);
152-
$this->assertEquals('neo', $context->identity->identifier);
153-
$this->assertEquals('public-env-key_neo', $context->identity->key);
154-
$this->assertCount(2, $context->identity->traits);
155-
$this->assertEquals('red', $context->identity->traits['chosen-pill']);
156-
$this->assertTrue($context->identity->traits['has-met-the-oracle']);
157-
}
158126
}

0 commit comments

Comments
 (0)