From d1291e0691b5fd77bc8340257b336bec5ca0701e Mon Sep 17 00:00:00 2001 From: Neil Kakkar Date: Wed, 10 Jan 2024 12:46:48 +0000 Subject: [PATCH] add tests --- lib/Client.php | 13 +++-- lib/Consumer/LibCurl.php | 4 +- test/PostHogTest.php | 88 ++++++++++++++++++++++++++++++++ test/assests/MockedResponses.php | 50 ++++++++++++++++++ 4 files changed, 148 insertions(+), 7 deletions(-) diff --git a/lib/Client.php b/lib/Client.php index e8e4780..afc6c96 100644 --- a/lib/Client.php +++ b/lib/Client.php @@ -74,7 +74,7 @@ public function __construct( $this->apiKey = $apiKey; $this->personalAPIKey = $personalAPIKey; $Consumer = self::CONSUMERS[$options["consumer"] ?? "lib_curl"]; - $this->consumer = new $Consumer($apiKey, $options); + $this->consumer = new $Consumer($apiKey, $options, $httpClient); $this->httpClient = $httpClient !== null ? $httpClient : new HttpClient( $options['host'] ?? "app.posthog.com", $options['ssl'] ?? true, @@ -114,17 +114,18 @@ public function capture(array $message) $message["properties"]['$groups'] = $message['$groups']; } + $extraProperties = []; if (array_key_exists("send_feature_flags", $message) && $message["send_feature_flags"]) { $flags = $this->fetchFeatureVariants($message["distinct_id"], $message["groups"]); // Add all feature variants to event foreach ($flags as $flagKey => $flagValue) { - $message["properties"][sprintf('$feature/%s', $flagKey)] = $flagValue; + $extraProperties[sprintf('$feature/%s', $flagKey)] = $flagValue; } // Add all feature flag keys that aren't false to $active_feature_flags // decide v2 does this automatically, but we need it for when we upgrade to v3 - $message["properties"]['$active_feature_flags'] = array_keys(array_filter($flags, function ($flagValue) { + $extraProperties = array_keys(array_filter($flags, function ($flagValue) { return $flagValue !== false; })); } elseif (count($this->featureFlags) != 0) { @@ -133,13 +134,15 @@ public function capture(array $message) // Add all feature variants to event foreach ($flags as $flagKey => $flagValue) { - $message["properties"][sprintf('$feature/%s', $flagKey)] = $flagValue; + $extraProperties[sprintf('$feature/%s', $flagKey)] = $flagValue; } - $message["properties"]['$active_feature_flags'] = array_keys(array_filter($flags, function ($flagValue) { + $extraProperties['$active_feature_flags'] = array_keys(array_filter($flags, function ($flagValue) { return $flagValue !== false; })); } + $message["properties"] = array_merge($extraProperties, $message["properties"]); + return $this->consumer->capture($message); } diff --git a/lib/Consumer/LibCurl.php b/lib/Consumer/LibCurl.php index 64bb657..e925086 100644 --- a/lib/Consumer/LibCurl.php +++ b/lib/Consumer/LibCurl.php @@ -21,10 +21,10 @@ class LibCurl extends QueueConsumer * number "max_queue_size" - the max size of messages to enqueue * number "batch_size" - how many messages to send in a single request */ - public function __construct($apiKey, $options = []) + public function __construct($apiKey, $options = [], ?HttpClient $httpClient = null) { parent::__construct($apiKey, $options); - $this->httpClient = new HttpClient( + $this->httpClient = $httpClient !== null ? $httpClient : new HttpClient( $this->host, $this->ssl(), $this->maximum_backoff_duration, diff --git a/test/PostHogTest.php b/test/PostHogTest.php index 02cba0b..b0153e7 100644 --- a/test/PostHogTest.php +++ b/test/PostHogTest.php @@ -9,6 +9,9 @@ use PHPUnit\Framework\TestCase; use PostHog\Client; use PostHog\PostHog; +use PostHog\Test\Assets\MockedResponses; +use SlopeIt\ClockMock\ClockMock; + class PostHogTest extends TestCase { @@ -104,6 +107,91 @@ public function testCaptureWithSendFeatureFlagsOption(): void ); } + public function testCaptureWithLocalSendFlags(): void + { + $this->http_client = new MockedHttpClient(host: "app.posthog.com", flagEndpointResponse: MockedResponses::LOCAL_EVALUATION_MULTIPLE_REQUEST); + $this->client = new Client( + self::FAKE_API_KEY, + [ + "debug" => true, + ], + $this->http_client, + "test" + ); + PostHog::init(null, null, $this->client); + + ClockMock::executeAtFrozenDateTime(new \DateTime('2022-05-01'), function () { + $this->assertTrue( + PostHog::capture( + array( + "distinctId" => "john", + "event" => "Module PHP Event", + ) + ) + ); + + PostHog::flush(); + + $this->assertEquals( + $this->http_client->calls, + array( + 0 => array( + "path" => "/api/feature_flag/local_evaluation?token=random_key", + "payload" => null, + ), + 1 => array( + "path" => "/batch/", + "payload" => '{"batch":[{"event":"Module PHP Event","properties":{"$feature\/true-flag":true,"$active_feature_flags":["true-flag"],"$lib":"posthog-php","$lib_version":"3.0.3","$lib_consumer":"LibCurl"},"library":"posthog-php","library_version":"3.0.3","library_consumer":"LibCurl","distinct_id":"john","groups":[],"timestamp":"2022-05-01T00:00:00+00:00","type":"capture"}],"api_key":"random_key"}', + ), + ) + ); + }); + } + + public function testCaptureWithLocalSendFlagsNoOverrides(): void + { + $this->http_client = new MockedHttpClient(host: "app.posthog.com", flagEndpointResponse: MockedResponses::LOCAL_EVALUATION_MULTIPLE_REQUEST); + $this->client = new Client( + self::FAKE_API_KEY, + [ + "debug" => true, + ], + $this->http_client, + "test" + ); + PostHog::init(null, null, $this->client); + + ClockMock::executeAtFrozenDateTime(new \DateTime('2022-05-01'), function () { + $this->assertTrue( + PostHog::capture( + array( + "distinctId" => "john", + "event" => "Module PHP Event", + "properties" => array( + "\$feature/true-flag" => "random-override" + ) + ) + ) + ); + + PostHog::flush(); + + $this->assertEquals( + $this->http_client->calls, + array( + 0 => array( + "path" => "/api/feature_flag/local_evaluation?token=random_key", + "payload" => null, + ), + 1 => array( + "path" => "/batch/", + "payload" => '{"batch":[{"event":"Module PHP Event","properties":{"$feature\/true-flag":"random-override","$active_feature_flags":["true-flag"],"$lib":"posthog-php","$lib_version":"3.0.3","$lib_consumer":"LibCurl"},"library":"posthog-php","library_version":"3.0.3","library_consumer":"LibCurl","distinct_id":"john","groups":[],"timestamp":"2022-05-01T00:00:00+00:00","type":"capture"}],"api_key":"random_key"}', + ), + ) + ); + }); + } + public function testIdentify(): void { self::assertTrue( diff --git a/test/assests/MockedResponses.php b/test/assests/MockedResponses.php index 7f27e1a..11905c1 100644 --- a/test/assests/MockedResponses.php +++ b/test/assests/MockedResponses.php @@ -68,6 +68,56 @@ class MockedResponses ], ]; + public const LOCAL_EVALUATION_MULTIPLE_REQUEST = [ + 'count' => 2, + 'next' => null, + 'previous' => null, + 'flags' => [ + [ + "id" => 1, + "name" => "", + "key" => "person-flag", + "filters" => [ + "groups" => [ + [ + "properties" => [ + [ + "key" => "region", + "value" => ["USA"], + "operator" => "exact", + "type" => "person" + ] + ], + "rollout_percentage" => 100 + ] + ] + ], + "deleted" => false, + "active" => true, + "is_simple_flag" => true, + "rollout_percentage" => null + ], + [ + "id" => 2, + "name" => "", + "key" => "true-flag", + "filters" => [ + "groups" => [ + [ + "properties" => [ + ], + "rollout_percentage" => 100 + ] + ] + ], + "deleted" => false, + "active" => true, + "is_simple_flag" => true, + "rollout_percentage" => null + ] + ], + ]; + public const LOCAL_EVALUATION_WITH_NO_ROLLOUT_REQUEST = [ 'count' => 1, 'next' => null,