Skip to content

Commit fd4bcc9

Browse files
fix: Mapping identity overrides with multiple features fails (#143)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 7d5982c commit fd4bcc9

2 files changed

Lines changed: 56 additions & 1 deletion

File tree

‎src/Utils/Mappers.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ private static function _mapIdentityOverridesToSegments($identityOverrides)
149149
foreach ($identityOverrides as $identityOverride) {
150150
$identityFeatures = ((array) $identityOverride->identity_features) ?? [];
151151
// Sort by feature name to ensure consistent serialization order for $overridesKey
152-
uksort($identityFeatures, fn ($a, $b) => strcasecmp($a->feature->name, $b->feature->name));
152+
usort($identityFeatures, fn ($a, $b) => strcasecmp($a->feature->name, $b->feature->name));
153153
if (empty($identityFeatures)) {
154154
continue;
155155
}

‎tests/Utils/MappersTest.php‎

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,59 @@ public function testMapEnvironmentDocumentToContextProducesEvaluationContext():
123123
$this->assertEquals(25.0, $mvFeatureWithoutIds->variants[2]->weight);
124124
$this->assertEquals(2, $mvFeatureWithoutIds->variants[2]->priority); // Third
125125
}
126+
127+
public function testMapEnvironmentDocumentToContextMapsIdentityOverridesWithMultipleFeatures(): void
128+
{
129+
// Given
130+
$environmentDocument = json_decode(file_get_contents(__DIR__ . '/../Data/environment.json'));
131+
$environmentDocument->identity_overrides = [
132+
(object) [
133+
'identifier' => 'identity-1',
134+
'identity_features' => [
135+
self::_identityFeatureState(2, 'zeta_feature', true, 'zeta-value'),
136+
self::_identityFeatureState(1, 'alpha_feature', false, 'alpha-value'),
137+
],
138+
],
139+
(object) [
140+
'identifier' => 'identity-2',
141+
'identity_features' => [
142+
self::_identityFeatureState(1, 'alpha_feature', false, 'alpha-value'),
143+
self::_identityFeatureState(2, 'zeta_feature', true, 'zeta-value'),
144+
],
145+
],
146+
];
147+
148+
// When
149+
$context = Mappers::mapEnvironmentDocumentToContext($environmentDocument);
150+
151+
// Then
152+
$identityOverrideSegments = array_values(array_filter(
153+
$context->segments,
154+
fn ($segment) => $segment->metadata['source'] === 'identity_override',
155+
));
156+
$this->assertCount(1, $identityOverrideSegments);
157+
158+
$segment = $identityOverrideSegments[0];
159+
$this->assertEquals(['identity-1', 'identity-2'], $segment->rules[0]->conditions[0]->value);
160+
$this->assertCount(2, $segment->overrides);
161+
162+
$this->assertEquals('alpha_feature', $segment->overrides[0]->name);
163+
$this->assertFalse($segment->overrides[0]->enabled);
164+
$this->assertEquals('alpha-value', $segment->overrides[0]->value);
165+
$this->assertEquals(['id' => 1], $segment->overrides[0]->metadata);
166+
167+
$this->assertEquals('zeta_feature', $segment->overrides[1]->name);
168+
$this->assertTrue($segment->overrides[1]->enabled);
169+
$this->assertEquals('zeta-value', $segment->overrides[1]->value);
170+
$this->assertEquals(['id' => 2], $segment->overrides[1]->metadata);
171+
}
172+
173+
private static function _identityFeatureState(int $featureId, string $featureName, bool $enabled, string $value): object
174+
{
175+
return (object) [
176+
'feature' => (object) ['id' => $featureId, 'name' => $featureName, 'type' => 'STANDARD'],
177+
'feature_state_value' => $value,
178+
'enabled' => $enabled,
179+
];
180+
}
126181
}

0 commit comments

Comments
 (0)