diff --git a/examples/treatmentsByFlagSets.php b/examples/treatmentsByFlagSets.php new file mode 100644 index 0000000..bcfb39c --- /dev/null +++ b/examples/treatmentsByFlagSets.php @@ -0,0 +1,37 @@ +getKey() + ." feat=".$i->getFeature() + ." treatment=".$i->getTreatment() + ." label=".$i->getLabel() + ." cn=".$i->getChangeNumber() + ." #attrs=".(($a == null) ? 0 : count($a))."\n"; + } +} + +$factory = Factory::withConfig([ + 'transfer' => [ + 'address' => '../../splitd/splitd.sock', + 'type' => 'unix-stream', + ], + 'logging' => [ + 'level' => \Psr\Log\LogLevel::INFO, + ], + 'utils' => [ + 'impressionListener' => new CustomListener(), + ], +]); + +$client = $factory->client(); +print_r($client->getTreatmentsByFlagSets("key", null, ["server_side", "backend"], ['age' => 22])); +print_r($client->getTreatmentsWithConfigByFlagSets("key", null, ["server_side", "backend"], ['age' => 22])); diff --git a/src/Client.php b/src/Client.php index ad78951..6fbcd99 100644 --- a/src/Client.php +++ b/src/Client.php @@ -218,6 +218,68 @@ public function getTreatmentsWithConfigByFlagSet( } } + public function getTreatmentsByFlagSets( + string $key, + ?string $bucketingKey, + array $flagSets, + ?array $attributes + ): array { + try { + $id = $this->tracer->makeId(); + $method = Tracer::METHOD_GET_TREATMENTS_BY_FLAG_SETS; + $this->tracer->trace(TEF::forStart($method, $id, $this->tracer->includeArgs() ? func_get_args() : [])); + // @TODO implement cache for this method + + $this->tracer->trace(TEF::forRPCStart($method, $id)); + $results = $this->lm->getTreatmentsByFlagSets($key, $bucketingKey, $flagSets, $attributes); + $this->tracer->trace(TEF::forRPCEnd($method, $id)); + foreach ($results as $feature => $result) { + list($treatment, $ilData) = $result; + $toReturn[$feature] = $treatment; + $this->handleListener($key, $bucketingKey, $feature, $attributes, $treatment, $ilData); + } + $this->cache->setMany($key, $attributes, $toReturn); + return $toReturn; + } catch (\Exception $exc) { + $this->tracer->trace(TEF::forException($method, $id, $exc)); + $this->logger->error($exc); + return array(); + } finally { + $this->tracer->trace(TEF::forEnd($method, $id)); + } + } + + public function getTreatmentsWithConfigByFlagSets( + string $key, + ?string $bucketingKey, + array $flagSets, + ?array $attributes = null + ): array { + try { + $id = $this->tracer->makeId(); + $method = Tracer::METHOD_GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS; + $this->tracer->trace(TEF::forStart($method, $id, $this->tracer->includeArgs() ? func_get_args() : [])); + // @TODO implement cache for this method + + $this->tracer->trace(TEF::forRPCStart($method, $id)); + $results = $this->lm->getTreatmentsWithConfigByFlagSets($key, $bucketingKey, $flagSets, $attributes); + $this->tracer->trace(TEF::forRPCEnd($method, $id)); + foreach ($results as $feature => $result) { + list($treatment, $ilData, $config) = $result; + $toReturn[$feature] = ['treatment' => $treatment, 'config' => $config]; + $this->handleListener($key, $bucketingKey, $feature, $attributes, $treatment, $ilData); + } + $this->cache->setMany($key, $attributes, $toReturn); + return $toReturn; + } catch (\Exception $exc) { + $this->tracer->trace(TEF::forException($method, $id, $exc)); + $this->logger->error($exc); + return array(); + } finally { + $this->tracer->trace(TEF::forEnd($method, $id)); + } + } + public function track(string $key, string $trafficType, string $eventType, ?float $value = null, ?array $properties = null): bool { try { diff --git a/src/ClientInterface.php b/src/ClientInterface.php index d8358fa..4627be2 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -15,5 +15,12 @@ function getTreatmentsWithConfigByFlagSet( string $flagSet, ?array $attributes ): array; + function getTreatmentsByFlagSets(string $key, ?string $bucketingKey, array $flagSets, ?array $attributes): array; + function getTreatmentsWithConfigByFlagSets( + string $key, + ?string $bucketingKey, + array $flagSets, + ?array $attributes + ): array; function track(string $key, string $trafficType, string $eventType, ?float $value = null, ?array $properties = null): bool; } diff --git a/src/Fallback/AlwaysControlClient.php b/src/Fallback/AlwaysControlClient.php index b7f1ad8..97ed6f0 100644 --- a/src/Fallback/AlwaysControlClient.php +++ b/src/Fallback/AlwaysControlClient.php @@ -16,7 +16,7 @@ public function getTreatmentWithConfig(string $key, ?string $bucketingKey, strin return ['treatment' => 'control', 'config' => null]; } - public function getTreatments(string $key, ?string $bucketingKey, array $features, ?array $attributes): array + public function getTreatments(string $key, ?string $bucketingKey, array $features, ?array $attributes): array { return array_reduce($features, function ($carry, $item) { $carry[$item] = "control"; @@ -24,7 +24,7 @@ public function getTreatments(string $key, ?string $bucketingKey, array $featur }, []); } - public function getTreatmentsWithConfig(string $key, ?string $bucketingKey, array $features, ?array $attributes): array + public function getTreatmentsWithConfig(string $key, ?string $bucketingKey, array $features, ?array $attributes): array { return array_reduce($features, function ($carry, $item) { $carry[$item] = ['treatment' => 'control', 'config' => null]; @@ -32,12 +32,22 @@ public function getTreatmentsWithConfig(string $key, ?string $bucketingKey, arr }, []); } - public function getTreatmentsByFlagSet(string $key, $bucketingKey, string $flagSet, $attributes): array + public function getTreatmentsByFlagSet(string $key, $bucketingKey, string $flagSet, $attributes): array { return array(); } - public function getTreatmentsWithConfigByFlagSet(string $key, $bucketingKey, string $flagSet, $attributes): array + public function getTreatmentsWithConfigByFlagSet(string $key, $bucketingKey, string $flagSet, $attributes): array + { + return array(); + } + + public function getTreatmentsByFlagSets(string $key, $bucketingKey, array $flagSets, $attributes): array + { + return array(); + } + + public function getTreatmentsWithConfigByFlagSets(string $key, $bucketingKey, array $flagSets, $attributes): array { return array(); } diff --git a/src/Link/Consumer/Manager.php b/src/Link/Consumer/Manager.php index 3be0518..a3341b8 100644 --- a/src/Link/Consumer/Manager.php +++ b/src/Link/Consumer/Manager.php @@ -17,6 +17,13 @@ function getTreatmentsWithConfigByFlagSet( string $flagSet, ?array $attributes ): array; + function getTreatmentsByFlagSets(string $key, ?string $bucketingKey, array $flagSets, ?array $attributes): array; + function getTreatmentsWithConfigByFlagSets( + string $key, + ?string $bucketingKey, + array $flagSet, + ?array $attributes + ): array; function track(string $key, string $trafficType, string $eventType, ?float $value, ?array $properties): bool; function splitNames(): array; function split(string $splitName): ?SplitView; diff --git a/src/Link/Consumer/V1Manager.php b/src/Link/Consumer/V1Manager.php index d3d5195..02a8ab6 100644 --- a/src/Link/Consumer/V1Manager.php +++ b/src/Link/Consumer/V1Manager.php @@ -117,7 +117,6 @@ public function getTreatmentsByFlagSet( return $results; } - public function getTreatmentsWithConfigByFlagSet( string $key, ?string $bucketingKey, @@ -140,6 +139,49 @@ public function getTreatmentsWithConfigByFlagSet( return $results; } + public function getTreatmentsByFlagSets( + string $key, + ?string $bucketingKey, + array $flagSets, + ?array $attributes): array + { + $response = Protocol\V1\TreatmentsByFlagSetResponse::fromRaw( + $this->rpcWithReconnect(RPC::forTreatmentsByFlagSets($key, $bucketingKey, $flagSets, $attributes)) + ); + $response->ensureSuccess(); + + $results = []; + + foreach ($response->getEvaluationResults() as $feature => $evalResult) { + $results[$feature] = $evalResult == null + ? ["control", null, null] + : [$evalResult->getTreatment(), $evalResult->getImpressionListenerdata(), $evalResult->getConfig()]; + } + + return $results; + } + + public function getTreatmentsWithConfigByFlagSets( + string $key, + ?string $bucketingKey, + array $flagSets, + ?array $attributes + ): array { + $response = Protocol\V1\TreatmentsByFlagSetResponse::fromRaw( + $this->rpcWithReconnect(RPC::forTreatmentsWithConfigByFlagSets($key, $bucketingKey, $flagSets, $attributes)) + ); + $response->ensureSuccess(); + + $results = []; + + foreach ($response->getEvaluationResults() as $feature => $evalResult) { + $results[$feature] = $evalResult == null + ? ["control", null, null] + : [$evalResult->getTreatment(), $evalResult->getImpressionListenerdata(), $evalResult->getConfig()]; + } + + return $results; + } public function track(string $key, string $trafficType, string $eventType, ?float $value, ?array $properties): bool { diff --git a/src/Link/Protocol/V1/OpCode.php b/src/Link/Protocol/V1/OpCode.php index d65d3a5..404946e 100644 --- a/src/Link/Protocol/V1/OpCode.php +++ b/src/Link/Protocol/V1/OpCode.php @@ -28,6 +28,8 @@ class OpCode extends Enum private const TreatmentsWithConfig = 0x14; private const TreatmentsByFlagSet = 0x15; private const TreatmentsWithConfigByFlagSet = 0x16; + private const TreatmentsByFlagSets = 0x17; + private const TreatmentsWithConfigByFlagSets = 0x18; private const Track = 0x80; diff --git a/src/Link/Protocol/V1/RPC.php b/src/Link/Protocol/V1/RPC.php index c2a08ff..ad57339 100644 --- a/src/Link/Protocol/V1/RPC.php +++ b/src/Link/Protocol/V1/RPC.php @@ -85,6 +85,24 @@ public static function forTreatmentsWithConfigByFlagSet( return self::_forTreatmentsByFlagSet($key, $bucketingKey, $flagSet, $attributes, true); } + public static function forTreatmentsByFlagSets( + string $key, + ?string $bucketingKey, + array $flagSets, + ?array $attributes): RPC + { + return self::_forTreatmentsByFlagSets($key, $bucketingKey, $flagSets, $attributes, false); + } + + public static function forTreatmentsWithConfigByFlagSets( + string $key, + ?string $bucketingKey, + array $flagSets, + ?array $attributes): RPC + { + return self::_forTreatmentsByFlagSets($key, $bucketingKey, $flagSets, $attributes, true); + } + public static function forTrack( string $key, string $trafficType, @@ -175,4 +193,23 @@ public static function _forTreatmentsByFlagSet( ] ); } + + public static function _forTreatmentsByFlagSets( + string $k, + ?string $bk, + array $f, + ?array $a, + bool $includeConfig): RPC + { + return new RPC( + Version::V1(), + $includeConfig ? OpCode::TreatmentsWithConfigByFlagSets() : OpCode::TreatmentsByFlagSets(), + [ + TreatmentsByFlagSetsArgs::KEY()->getValue() => $k, + TreatmentsByFlagSetsArgs::BUCKETING_KEY()->getValue() => $bk, + TreatmentsByFlagSetsArgs::FLAG_SETS()->getValue() => $f, + TreatmentsByFlagSetsArgs::ATTRIBUTES()->getValue() => ($a != null && count($a) > 0) ? $a : null, + ] + ); + } } diff --git a/src/Link/Protocol/V1/TreatmentsByFlagSetsArgs.php b/src/Link/Protocol/V1/TreatmentsByFlagSetsArgs.php new file mode 100644 index 0000000..226a792 --- /dev/null +++ b/src/Link/Protocol/V1/TreatmentsByFlagSetsArgs.php @@ -0,0 +1,23 @@ +createMock(Manager::class); + $manager->expects($this->once())->method('getTreatmentsByFlagSets') + ->with('someKey', 'someBuck', ['set_1', 'set_2'], ['someAttr' => 123]) + ->willReturn([ + 'someFeature1' => ['on', null, null], + 'someFeature2' => ['off', null, null], + 'someFeature3' => ['n/a', null, null], + ]); + + $client = new Client($manager, $this->logger, null); + $this->assertEquals( + ['someFeature1' => 'on', 'someFeature2' => 'off', 'someFeature3' => 'n/a'], + $client->getTreatmentsByFlagSets('someKey', 'someBuck', ['set_1', 'set_2'], ['someAttr' => 123]) + ); + } + + public function testGetTreatmentsByFlagSetsWithImpListener() + { + $manager = $this->createMock(Manager::class); + $manager->expects($this->once())->method('getTreatmentsByFlagSets') + ->with('someKey', 'someBuck', ['set_1', 'set_2'], ['someAttr' => 123]) + ->willReturn([ + 'someFeature1' => ['on', new ImpressionListenerData('lab1', 123, 123456), null], + 'someFeature2' => ['off', new ImpressionListenerData('lab1', 124, 123457), null], + 'someFeature3' => ['n/a', new ImpressionListenerData('lab1', 125, 123458), null], + ]); + + $ilMock = $this->createMock(ImpressionListener::class); + $ilMock->expects($this->exactly(3)) + ->method('accept') + ->withConsecutive( + [new Impression('someKey', 'someBuck', 'someFeature1', 'on', 'lab1', 123, 123456), ['someAttr' => 123]], + [new Impression('someKey', 'someBuck', 'someFeature2', 'off', 'lab1', 124, 123457), ['someAttr' => 123]], + [new Impression('someKey', 'someBuck', 'someFeature3', 'n/a', 'lab1', 125, 123458), ['someAttr' => 123]] + ); + + $client = new Client($manager, $this->logger, $ilMock); + $this->assertEquals( + ['someFeature1' => 'on', 'someFeature2' => 'off', 'someFeature3' => 'n/a'], + $client->getTreatmentsByFlagSets('someKey', 'someBuck', ['set_1', 'set_2'], ['someAttr' => 123]) + ); + } + + public function testGetTreatmentsWithConfigByFlagSetsAndListener() + { + $manager = $this->createMock(Manager::class); + $manager->expects($this->once())->method('getTreatmentsWithConfigByFlagSets') + ->with('someKey', 'someBuck', ['set_1', 'set_2'], ['someAttr' => 123]) + ->willReturn([ + 'someFeature1' => ['on', new ImpressionListenerData('lab1', 123, 123456), null], + 'someFeature2' => ['off', new ImpressionListenerData('lab1', 124, 123457), null], + 'someFeature3' => ['n/a', new ImpressionListenerData('lab1', 125, 123458), '{"a": 2}'], + ]); + + $ilMock = $this->createMock(ImpressionListener::class); + $ilMock->expects($this->exactly(3)) + ->method('accept') + ->withConsecutive( + [new Impression('someKey', 'someBuck', 'someFeature1', 'on', 'lab1', 123, 123456), ['someAttr' => 123]], + [new Impression('someKey', 'someBuck', 'someFeature2', 'off', 'lab1', 124, 123457), ['someAttr' => 123]], + [new Impression('someKey', 'someBuck', 'someFeature3', 'n/a', 'lab1', 125, 123458), ['someAttr' => 123]] + ); + + $client = new Client($manager, $this->logger, $ilMock); + $this->assertEquals( + [ + 'someFeature1' => ['treatment' => 'on', 'config' => null], + 'someFeature2' => ['treatment' => 'off', 'config' => null], + 'someFeature3' => ['treatment' => 'n/a', 'config' => '{"a": 2}'] + ], + $client->getTreatmentsWithConfigByFlagSets('someKey', 'someBuck', ['set_1', 'set_2'], ['someAttr' => 123]) + ); + } + public function testGetTreatmentExceptionReturnsControl() { $manager = $this->createMock(Manager::class); @@ -378,6 +453,20 @@ public function testGetTreatmentsByFlagSetExceptionReturnsControl() ); } + public function testGetTreatmentsByFlagSetsExceptionReturnsControl() + { + $manager = $this->createMock(Manager::class); + $manager->expects($this->once())->method('getTreatmentsByFlagSets') + ->with('someKey', 'someBuck', ['set_1', 'set_2'], ['someAttr' => 123]) + ->will($this->throwException(new \Exception("abc"))); + + $client = new Client($manager, $this->logger, null); + $this->assertEquals( + [], + $client->getTreatmentsByFlagSets('someKey', 'someBuck', ['set_1', 'set_2'], ['someAttr' => 123]) + ); + } + public function testGetTreatmentListenerErrorReturnsOk() { $manager = $this->createMock(Manager::class); diff --git a/tests/Fallback/AwaysControlClientTest.php b/tests/Fallback/AwaysControlClientTest.php index 05849a3..4c82b33 100644 --- a/tests/Fallback/AwaysControlClientTest.php +++ b/tests/Fallback/AwaysControlClientTest.php @@ -27,13 +27,20 @@ public function testGetTreatments() $this->assertEquals([], $c->getTreatments("key", null, [], null)); } - public function testGetTreatmentsByFlagSets() + public function testGetTreatmentsByFlagSet() { $c = new AlwaysControlClient(); $this->assertEquals([], $c->getTreatmentsByFlagSet("key", null, "someFlagSet", null)); $this->assertEquals([], $c->getTreatmentsWithConfigByFlagSet("key", null, "someFlagSet", null)); } + public function testGetTreatmentsByFlagSets() + { + $c = new AlwaysControlClient(); + $this->assertEquals([], $c->getTreatmentsByFlagSets("key", null, ['set_1', 'set_2'], null)); + $this->assertEquals([], $c->getTreatmentsWithConfigByFlagSets("key", null, ['set_1', 'set_2'], null)); + } + public function testTrack() { $c = new AlwaysControlClient(); diff --git a/tests/Link/Consumer/V1ManagerTest.php b/tests/Link/Consumer/V1ManagerTest.php index 337dc54..be5655b 100644 --- a/tests/Link/Consumer/V1ManagerTest.php +++ b/tests/Link/Consumer/V1ManagerTest.php @@ -30,7 +30,7 @@ public function setUp(): void public function testHappyExchangeNoImpListener(): void { $connMock = $this->createMock(RawConnection::class); - $connMock->expects($this->exactly(7)) + $connMock->expects($this->exactly(9)) ->method('sendMessage') ->withConsecutive( ['serializedRegister'], @@ -39,9 +39,11 @@ public function testHappyExchangeNoImpListener(): void ['serializedTreatmentWithConfig'], ['serializedTreatmentsWithConfig'], ['serializedTreatmentsByFlagSet'], - ['serializedTreatmentsWithConfigByFlagSet'] + ['serializedTreatmentsWithConfigByFlagSet'], + ['serializedTreatmentsByFlagSets'], + ['serializedTreatmentsWithConfigByFlagSets'] ); - $connMock->expects($this->exactly(7)) + $connMock->expects($this->exactly(9)) ->method('readMessage') ->willReturnOnConsecutiveCalls( 'serializedRegisterResp', @@ -50,14 +52,16 @@ public function testHappyExchangeNoImpListener(): void 'serilaizedTreatmentWithConfigResp', 'serializedTreatmentsWithConfigResp', 'serializedTreatmentsByFlagSetResp', - 'serializedTreatmentsWithConfigByFlagSetResp' + 'serializedTreatmentsWithConfigByFlagSetResp', + 'serializedTreatmentsByFlagSetsResp', + 'serializedTreatmentsWithConfigByFlagSetsResp', ); $connFactoryMock = $this->createMock(ConnectionFactory::class); $connFactoryMock->expects($this->once())->method('create')->willReturn($connMock); $serializerMock = $this->createMock(Serializer::class); - $serializerMock->expects($this->exactly(7)) + $serializerMock->expects($this->exactly(9)) ->method('serialize') ->withConsecutive( [RPC::forRegister('someId', new RegisterFlags(false))], @@ -67,6 +71,8 @@ public function testHappyExchangeNoImpListener(): void [RPC::forTreatmentsWithConfig("k", "b", ["f1", "f2", "f3"], ["a" => 1])], [RPC::forTreatmentsByFlagSet("k", "b", "s", ["a" => 1])], [RPC::forTreatmentsWithConfigByFlagSet("k", "b", "s", ["a" => 1])], + [RPC::forTreatmentsByFlagSets("k", "b", ["s1", "s2"], ["a" => 1])], + [RPC::forTreatmentsWithConfigByFlagSets("k", "b", ["s1", "s2"], ["a" => 1])], ) ->willReturnOnConsecutiveCalls( 'serializedRegister', @@ -75,10 +81,12 @@ public function testHappyExchangeNoImpListener(): void 'serializedTreatmentWithConfig', 'serializedTreatmentsWithConfig', 'serializedTreatmentsByFlagSet', - 'serializedTreatmentsWithConfigByFlagSet' + 'serializedTreatmentsWithConfigByFlagSet', + 'serializedTreatmentsByFlagSets', + 'serializedTreatmentsWithConfigByFlagSets' ); - $serializerMock->expects($this->exactly(7)) + $serializerMock->expects($this->exactly(9)) ->method('deserialize') ->withConsecutive( ['serializedRegisterResp'], @@ -87,7 +95,9 @@ public function testHappyExchangeNoImpListener(): void ['serilaizedTreatmentWithConfigResp'], ['serializedTreatmentsWithConfigResp'], ['serializedTreatmentsByFlagSetResp'], - ['serializedTreatmentsWithConfigByFlagSetResp'] + ['serializedTreatmentsWithConfigByFlagSetResp'], + ['serializedTreatmentsByFlagSetsResp'], + ['serializedTreatmentsWithConfigByFlagSetsResp'] ) ->willReturnOnConsecutiveCalls( ['s' => 0x01], @@ -96,6 +106,8 @@ public function testHappyExchangeNoImpListener(): void ['s' => 0x01, 'p' => ['t' => 'on', 'c' => '{"a": 1}']], ['s' => 0x01, 'p' => ['r' => [['t' => 'on'], ['t' => 'on'], ['t' => 'off', 'c' => '{"a": 2}']]]], ['s' => 0x01, 'p' => ['r' => ['f1' => ['t' => 'on'], 'f2' => ['t' => 'on'], 'f3' => ['t' => 'off', 'c' => '{"a": 2}']]]], + ['s' => 0x01, 'p' => ['r' => ['f1' => ['t' => 'on'], 'f2' => ['t' => 'on'], 'f3' => ['t' => 'off', 'c' => '{"a": 2}']]]], + ['s' => 0x01, 'p' => ['r' => ['f1' => ['t' => 'on'], 'f2' => ['t' => 'on'], 'f3' => ['t' => 'off', 'c' => '{"a": 2}']]]], ['s' => 0x01, 'p' => ['r' => ['f1' => ['t' => 'on'], 'f2' => ['t' => 'on'], 'f3' => ['t' => 'off', 'c' => '{"a": 2}']]]] ); @@ -121,6 +133,14 @@ public function testHappyExchangeNoImpListener(): void ['f1' => ['on', null, null], 'f2' => ['on', null, null], 'f3' => ['off', null, '{"a": 2}']], $v1Manager->getTreatmentsWithConfigByFlagSet('k', 'b', "s", ['a' => 1]) ); + $this->assertEquals( + ['f1' => ['on', null, null], 'f2' => ['on', null, null], 'f3' => ['off', null, '{"a": 2}']], + $v1Manager->getTreatmentsByFlagSets('k', 'b', ["s1", "s2"], ['a' => 1]) + ); + $this->assertEquals( + ['f1' => ['on', null, null], 'f2' => ['on', null, null], 'f3' => ['off', null, '{"a": 2}']], + $v1Manager->getTreatmentsWithConfigByFlagSets('k', 'b', ["s1", "s2"], ['a' => 1]) + ); } public function testHappyExchangeWithImpListener(): void diff --git a/tests/Link/Protocol/V1/RPCTest.php b/tests/Link/Protocol/V1/RPCTest.php index 1f271c3..1cbcfbf 100644 --- a/tests/Link/Protocol/V1/RPCTest.php +++ b/tests/Link/Protocol/V1/RPCTest.php @@ -3,6 +3,7 @@ namespace SplitIO\Test\Link\Protocol\V1; use SplitIO\ThinSdk\Link\Protocol\V1\TreatmentsByFlagSetArgs; +use SplitIO\ThinSdk\Link\Protocol\V1\TreatmentsByFlagSetsArgs; use SplitIO\ThinSdk\Link\Protocol\Version; use SplitIO\ThinSdk\Link\Protocol\V1\RPC; use SplitIO\ThinSdk\Link\Protocol\V1\OpCode; @@ -91,4 +92,41 @@ public function testTreatmentsWithConfigByFlagSetRPC(): void ); } + public function testTreatmentsByFlagSetsRPC(): void + { + $dt = new \DateTime('now'); + $rpc = RPC::forTreatmentsByFlagSets('key1', 'buck', ['set_1', 'set_2'], ['a' => 'sarasa', 'b' => 2, 'c' => ['q', 'w'], 'd' => $dt]); + $this->assertEquals(OpCode::TreatmentsByFlagSets(), $rpc->getOpCode()); + $this->assertEquals(Version::V1(), $rpc->getVersion()); + $this->assertEquals('key1', $rpc->getArgs()[TreatmentsByFlagSetsArgs::KEY()->getValue()]); + $this->assertEquals('buck', $rpc->getArgs()[TreatmentsByFlagSetsArgs::BUCKETING_KEY()->getValue()]); + $this->assertEquals(['set_1', 'set_2'], $rpc->getArgs()[TreatmentsByFlagSetsArgs::FLAG_SETS()->getValue()]); + $this->assertEquals('sarasa', $rpc->getArgs()[TreatmentsByFlagSetsArgs::ATTRIBUTES()->getValue()]['a']); + $this->assertEquals(2, $rpc->getArgs()[TreatmentsByFlagSetsArgs::ATTRIBUTES()->getValue()]['b']); + $this->assertEquals(['q', 'w'], $rpc->getArgs()[TreatmentsByFlagSetsArgs::ATTRIBUTES()->getValue()]['c']); + $this->assertEquals($dt, $rpc->getArgs()[TreatmentsByFlagSetsArgs::ATTRIBUTES()->getValue()]['d']); + $this->assertEquals( + ['v' => 1, 'o' => 0x17, 'a' => ['key1', 'buck', ['set_1', 'set_2'], ['a' => 'sarasa', 'b' => 2, 'c' => ['q', 'w'], 'd' => $dt]]], + $rpc->getSerializable() + ); + } + + public function testTreatmentsWithConfigByFlagSetsRPC(): void + { + $dt = new \DateTime('now'); + $rpc = RPC::forTreatmentsWithConfigByFlagSets('key1', 'buck', ['set_1', 'set_2'], ['a' => 'sarasa', 'b' => 2, 'c' => ['q', 'w'], 'd' => $dt]); + $this->assertEquals(OpCode::TreatmentsWithConfigByFlagSets(), $rpc->getOpCode()); + $this->assertEquals(Version::V1(), $rpc->getVersion()); + $this->assertEquals('key1', $rpc->getArgs()[TreatmentsByFlagSetsArgs::KEY()->getValue()]); + $this->assertEquals('buck', $rpc->getArgs()[TreatmentsByFlagSetsArgs::BUCKETING_KEY()->getValue()]); + $this->assertEquals(['set_1', 'set_2'], $rpc->getArgs()[TreatmentsByFlagSetsArgs::FLAG_SETS()->getValue()]); + $this->assertEquals('sarasa', $rpc->getArgs()[TreatmentsByFlagSetsArgs::ATTRIBUTES()->getValue()]['a']); + $this->assertEquals(2, $rpc->getArgs()[TreatmentsByFlagSetsArgs::ATTRIBUTES()->getValue()]['b']); + $this->assertEquals(['q', 'w'], $rpc->getArgs()[TreatmentsByFlagSetsArgs::ATTRIBUTES()->getValue()]['c']); + $this->assertEquals($dt, $rpc->getArgs()[TreatmentsByFlagSetsArgs::ATTRIBUTES()->getValue()]['d']); + $this->assertEquals( + ['v' => 1, 'o' => 0x18, 'a' => ['key1', 'buck', ['set_1', 'set_2'], ['a' => 'sarasa', 'b' => 2, 'c' => ['q', 'w'], 'd' => $dt]]], + $rpc->getSerializable() + ); + } }