From 7f46bfe76268172c1940a5ee1e73402fd64655b7 Mon Sep 17 00:00:00 2001 From: Evandro Myller Date: Fri, 21 Nov 2025 20:41:43 -0300 Subject: [PATCH] Use mapper test data from engine-test-data Co-authored-by: Claude --- .gitmodules | 2 +- src/Utils/Mappers.php | 4 +- tests/Engine/EngineTests/EngineTestData | 2 +- tests/Utils/MappersTest.php | 142 ++++++------------------ 4 files changed, 37 insertions(+), 113 deletions(-) diff --git a/.gitmodules b/.gitmodules index 15a9644..70b4760 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "tests/Engine/EngineTests/EngineTestData"] path = tests/Engine/EngineTests/EngineTestData url = git@github.com:Flagsmith/engine-test-data.git - tag = v3.4.1 + branch = feat/mappers/add-mapper-test-data diff --git a/src/Utils/Mappers.php b/src/Utils/Mappers.php index fa2ab60..5872f43 100644 --- a/src/Utils/Mappers.php +++ b/src/Utils/Mappers.php @@ -165,7 +165,7 @@ private static function _mapIdentityOverridesToSegments($identityOverrides) ]; $overridesKey[] = $part; } - $featuresToIdentifiers[serialize($overridesKey)][] = $identityOverride->identifier; + $featuresToIdentifiers[json_encode($overridesKey)][] = $identityOverride->identifier; } /** @var array */ @@ -187,7 +187,7 @@ private static function _mapIdentityOverridesToSegments($identityOverrides) $segment->rules = [$identifiersRule]; $segment->overrides = []; - foreach (unserialize($serializedOverridesKey) as $overrideKey) { + foreach (json_decode($serializedOverridesKey, true) as $overrideKey) { [$featureName, $enabled, $value] = $overrideKey; $featureId = $featureIDsByName[$featureName]; $feature = new FeatureContext(); diff --git a/tests/Engine/EngineTests/EngineTestData b/tests/Engine/EngineTests/EngineTestData index 839e8d5..c2748d4 160000 --- a/tests/Engine/EngineTests/EngineTestData +++ b/tests/Engine/EngineTests/EngineTestData @@ -1 +1 @@ -Subproject commit 839e8d5e5f2e9af6392062cf5e575d43c03770d4 +Subproject commit c2748d4bafe9a7fbbaed454e9362185f20b20e8b diff --git a/tests/Utils/MappersTest.php b/tests/Utils/MappersTest.php index 74ae0f3..2b77f4f 100644 --- a/tests/Utils/MappersTest.php +++ b/tests/Utils/MappersTest.php @@ -2,125 +2,49 @@ namespace FlagsmithTest\Utils; -use FlagsmithTest\ClientFixtures; -use Flagsmith\Engine\Utils\Types\Context\EnvironmentContext; -use Flagsmith\Engine\Utils\Types\Context\EvaluationContext; -use Flagsmith\Engine\Utils\Types\Context\SegmentRuleType; -use Flagsmith\Engine\Utils\Types\Context\SegmentConditionOperator; use Flagsmith\Utils\Mappers; use PHPUnit\Framework\TestCase; class MappersTest extends TestCase { - public function testMapEnvironmentDocumentToContextProducesEvaluationContext(): void + /** @return \Generator>> */ + public function extractMapperTestCases(): \Generator + { + $testCasePaths = glob(__DIR__ . '/../Engine/EngineTests/EngineTestData/mapper_test_cases/test_*.{json,jsonc}', \GLOB_BRACE); + foreach ($testCasePaths as $testCasePath) { + $testCaseJson = file_get_contents($testCasePath); + $testCase = json5_decode($testCaseJson); + + $testName = basename($testCasePath); + yield $testName => [[ + 'environment_document' => $testCase->environment_document, + 'expected_evaluation_context' => $testCase->expected_evaluation_context, + ]]; + } + } + + /** + * @dataProvider extractMapperTestCases + * @param array $case + * @return void + */ + public function testMapEnvironmentDocumentToContextMatchesTestData($case): void { // Given - $environment = ClientFixtures::getEnvironmentModel(); + $environmentDocument = $case['environment_document']; // When - $context = Mappers::mapEnvironmentDocumentToContext($environment); - - // Then - $this->assertInstanceOf(EvaluationContext::class, $context); - $this->assertEquals('B62qaMZNwfiqT76p38ggrQ', $context->environment->key); - $this->assertEquals('Test environment', $context->environment->name); - $this->assertNull($context->identity); - $this->assertCount(2, $context->segments); - - $this->assertArrayHasKey(0, $context->segments); - $this->assertEquals(1, $context->segments[0]->key); - $this->assertEquals('Test segment', $context->segments[0]->name); - $this->assertCount(1, $context->segments[0]->rules); - $this->assertEmpty($context->segments[0]->overrides); - $this->assertEquals('api', $context->segments[0]->metadata['source']); - $this->assertEquals('1', $context->segments[0]->metadata['id']); - - $this->assertEquals(SegmentRuleType::ALL, $context->segments[0]->rules[0]->type); - $this->assertEmpty($context->segments[0]->rules[0]->conditions); - $this->assertCount(1, $context->segments[0]->rules[0]->rules); - - $this->assertEquals(SegmentRuleType::ALL, $context->segments[0]->rules[0]->rules[0]->type); - $this->assertCount(1, $context->segments[0]->rules[0]->rules[0]->conditions); - $this->assertEmpty($context->segments[0]->rules[0]->rules[0]->rules); - - $this->assertEquals('foo', $context->segments[0]->rules[0]->rules[0]->conditions[0]->property); - $this->assertEquals(SegmentConditionOperator::EQUAL, $context->segments[0]->rules[0]->rules[0]->conditions[0]->operator); - $this->assertEquals('bar', $context->segments[0]->rules[0]->rules[0]->conditions[0]->value); + $actual = Mappers::mapEnvironmentDocumentToContext($environmentDocument); - $overrideKey = '2a3691c8a306223592e2e657e50c44cf126db84730e813adea6f951c502b19e8'; - $this->assertArrayHasKey($overrideKey, $context->segments); - $this->assertEquals('', $context->segments[$overrideKey]->key); - $this->assertEquals('identity_overrides', $context->segments[$overrideKey]->name); - $this->assertCount(1, $context->segments[$overrideKey]->rules); - $this->assertCount(1, $context->segments[$overrideKey]->overrides); + // Replace -INF with string "-INF" to allow JSON encoding + $serialized = serialize($actual); + $serialized = str_replace('d:-INF;', 's:4:"-INF";', $serialized); + $actual = unserialize($serialized); - $this->assertEquals(SegmentRuleType::ALL, $context->segments[$overrideKey]->rules[0]->type); - $this->assertCount(1, $context->segments[$overrideKey]->rules[0]->conditions); - $this->assertNull($context->segments[$overrideKey]->rules[0]->rules); - - $this->assertEquals('$.identity.identifier', $context->segments[$overrideKey]->rules[0]->conditions[0]->property); - $this->assertEquals(SegmentConditionOperator::IN, $context->segments[$overrideKey]->rules[0]->conditions[0]->operator); - $this->assertEquals(['overridden-id'], $context->segments[$overrideKey]->rules[0]->conditions[0]->value); - - $this->assertEquals('', $context->segments[$overrideKey]->overrides[0]->key); - $this->assertEquals('some_feature', $context->segments[$overrideKey]->overrides[0]->name); - $this->assertFalse($context->segments[$overrideKey]->overrides[0]->enabled); - $this->assertEquals('some-overridden-value', $context->segments[$overrideKey]->overrides[0]->value); - $this->assertEquals(-INF, $context->segments[$overrideKey]->overrides[0]->priority); - $this->assertNull($context->segments[$overrideKey]->overrides[0]->variants); - $this->assertEquals(['id' => 1], $context->segments[$overrideKey]->overrides[0]->metadata); - - $this->assertCount(3, $context->features); - $this->assertArrayHasKey('some_feature', $context->features); - $this->assertEquals('00000000-0000-0000-0000-000000000000', $context->features['some_feature']->key); - $this->assertEquals('some_feature', $context->features['some_feature']->name); - $this->assertTrue($context->features['some_feature']->enabled); - $this->assertEquals('some-value', $context->features['some_feature']->value); - $this->assertNull($context->features['some_feature']->priority); - $this->assertEmpty($context->features['some_feature']->variants); - $this->assertEquals(['id' => 1], $context->features['some_feature']->metadata); - - // Test multivariate feature with IDs - priority should be based on ID - $this->assertArrayHasKey('mv_feature_with_ids', $context->features); - $mvFeatureWithIds = $context->features['mv_feature_with_ids']; - $this->assertEquals('2', $mvFeatureWithIds->key); - $this->assertEquals('mv_feature_with_ids', $mvFeatureWithIds->name); - $this->assertTrue($mvFeatureWithIds->enabled); - $this->assertEquals('default_value', $mvFeatureWithIds->value); - $this->assertNull($mvFeatureWithIds->priority); - $this->assertCount(2, $mvFeatureWithIds->variants); - $this->assertEquals(['id' => 2], $mvFeatureWithIds->metadata); - - // First variant: ID=100, should have priority 100 - $this->assertEquals('variant_a', $mvFeatureWithIds->variants[0]->value); - $this->assertEquals(30.0, $mvFeatureWithIds->variants[0]->weight); - $this->assertEquals(100, $mvFeatureWithIds->variants[0]->priority); - - // Second variant: ID=200, should have priority 200 - $this->assertEquals('variant_b', $mvFeatureWithIds->variants[1]->value); - $this->assertEquals(70.0, $mvFeatureWithIds->variants[1]->weight); - $this->assertEquals(200, $mvFeatureWithIds->variants[1]->priority); - - // Test multivariate feature without IDs - priority should be based on UUID position - $this->assertArrayHasKey('mv_feature_without_ids', $context->features); - $mvFeatureWithoutIds = $context->features['mv_feature_without_ids']; - $this->assertEquals('3', $mvFeatureWithoutIds->key); - $this->assertEquals('mv_feature_without_ids', $mvFeatureWithoutIds->name); - $this->assertFalse($mvFeatureWithoutIds->enabled); - $this->assertEquals('fallback_value', $mvFeatureWithoutIds->value); - $this->assertNull($mvFeatureWithoutIds->priority); - $this->assertCount(3, $mvFeatureWithoutIds->variants); - $this->assertEquals(['id' => 3], $mvFeatureWithoutIds->metadata); - - // Variants should be ordered by UUID alphabetically - $this->assertEquals('option_y', $mvFeatureWithoutIds->variants[0]->value); - $this->assertEquals(50.0, $mvFeatureWithoutIds->variants[0]->weight); - $this->assertEquals(1, $mvFeatureWithoutIds->variants[0]->priority); // Second - $this->assertEquals('option_x', $mvFeatureWithoutIds->variants[1]->value); - $this->assertEquals(25.0, $mvFeatureWithoutIds->variants[1]->weight); - $this->assertEquals(0, $mvFeatureWithoutIds->variants[1]->priority); // First - $this->assertEquals('option_z', $mvFeatureWithoutIds->variants[2]->value); - $this->assertEquals(25.0, $mvFeatureWithoutIds->variants[2]->weight); - $this->assertEquals(2, $mvFeatureWithoutIds->variants[2]->priority); // Third + // Then + $this->assertEquals( + $case['expected_evaluation_context'], + json_decode(json_encode($actual)), + ); } }