From ad3d9afb706b9e6d9056da229ae1dbf9adc0027f Mon Sep 17 00:00:00 2001 From: wadii Date: Mon, 20 Oct 2025 15:09:35 +0200 Subject: [PATCH] feat: get-version-from-composer-and-pass-it-in-headers --- src/Flagsmith.php | 4 +++- src/Utils/AnalyticsProcessor.php | 1 + src/Utils/UserAgent.php | 32 ++++++++++++++++++++++++++++++++ tests/AnalyticsTest.php | 15 ++++++++++++++- tests/FlagsmithClientTest.php | 29 +++++++++++++++++++++++++++++ tests/UserAgentTest.php | 18 ++++++++++++++++++ 6 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/Utils/UserAgent.php create mode 100644 tests/UserAgentTest.php diff --git a/src/Flagsmith.php b/src/Flagsmith.php index 97aade5..6509410 100644 --- a/src/Flagsmith.php +++ b/src/Flagsmith.php @@ -19,6 +19,7 @@ use Flagsmith\Utils\AnalyticsProcessor; use Flagsmith\Utils\IdentitiesGenerator; use Flagsmith\Utils\Retry; +use Flagsmith\Utils\UserAgent; use JsonException; use ValueError; use Psr\Http\Client\ClientInterface; @@ -596,7 +597,8 @@ private function call(string $method, string $uri, array $body = []) ->createRequest($method, rtrim($this->host, '/') . '/' . $uri) ->withHeader('Accept', 'application/json') ->withHeader('Content-Type', 'application/json') - ->withHeader('X-Environment-Key', $this->apiKey); + ->withHeader('X-Environment-Key', $this->apiKey) + ->withHeader('User-Agent', UserAgent::get()); if (!empty($this->customHeaders)) { foreach ($this->customHeaders as $name => $value) { diff --git a/src/Utils/AnalyticsProcessor.php b/src/Utils/AnalyticsProcessor.php index a7dae59..af2e390 100644 --- a/src/Utils/AnalyticsProcessor.php +++ b/src/Utils/AnalyticsProcessor.php @@ -67,6 +67,7 @@ public function flush() ->withHeader('Accept', 'application/json') ->withHeader('Content-Type', 'application/json') ->withHeader('X-Environment-Key', $this->environment_key) + ->withHeader('User-Agent', UserAgent::get()) ->withBody($stream); try { diff --git a/src/Utils/UserAgent.php b/src/Utils/UserAgent.php new file mode 100644 index 0000000..32bde83 --- /dev/null +++ b/src/Utils/UserAgent.php @@ -0,0 +1,32 @@ +createMock(ClientInterface::class); $analyticsProcessor = ClientFixtures::analyticsProcessor($client); $client->expects($this->once()) - ->method('sendRequest'); + ->method('sendRequest') + ->with($this->callback(function ($request) use (&$capturedRequest) { + $capturedRequest = $request; + return true; + })); $analyticsProcessor->trackFeature('my_feature'); $analyticsProcessor->flush(); + + $this->assertNotNull($capturedRequest); + $this->assertTrue($capturedRequest->hasHeader('User-Agent')); + $userAgent = $capturedRequest->getHeaderLine('User-Agent'); + $composerData = json_decode(file_get_contents(__DIR__ . '/../composer.json'), true); + $expectedVersion = $composerData['version'] ?? 'unknown'; + $expectedUserAgent = "flagsmith-php-sdk/{$expectedVersion}"; + $this->assertEquals($expectedUserAgent, $userAgent); } public function testAnalyticsProcessorFlushEarlyExitIfAnalyticsDataIsEmpty() diff --git a/tests/FlagsmithClientTest.php b/tests/FlagsmithClientTest.php index ee63f1d..ae2f3a9 100644 --- a/tests/FlagsmithClientTest.php +++ b/tests/FlagsmithClientTest.php @@ -7,6 +7,7 @@ use FlagsmithTest\Offline\FakeOfflineHandler; use GuzzleHttp\Psr7\Response; use PHPUnit\Framework\TestCase; +use Psr\Http\Client\ClientInterface; use Psr\Http\Message\StreamFactoryInterface; class FlagsmithClientTest extends TestCase @@ -441,4 +442,32 @@ public function testOfflineHandlerUsedAsFallbackForLocalEvaluation() $this->assertEquals($identityFlags->getFlag('some_feature')->enabled, true); $this->assertEquals($identityFlags->getFlag('some_feature')->value, 'some-value'); } + + public function testApiRequestsIncludeUserAgentHeader() + { + $capturedRequest = null; + $mockClient = $this->createMock(ClientInterface::class); + $mockClient->expects($this->once()) + ->method('sendRequest') + ->with($this->callback(function ($request) use (&$capturedRequest) { + $capturedRequest = $request; + return true; + })) + ->willReturn( + new Response(200, ['Content-Type' => 'application/json'], file_get_contents(__DIR__ . '/Data/flags.json')) + ); + + $flagsmith = (new Flagsmith('api_key')) + ->withClient($mockClient); + + $flagsmith->getEnvironmentFlags(); + + $this->assertNotNull($capturedRequest); + $this->assertTrue($capturedRequest->hasHeader('User-Agent')); + $userAgent = $capturedRequest->getHeaderLine('User-Agent'); + $composerData = json_decode(file_get_contents(__DIR__ . '/../composer.json'), true); + $expectedVersion = $composerData['version'] ?? 'unknown'; + $expectedUserAgent = "flagsmith-php-sdk/{$expectedVersion}"; + $this->assertEquals($expectedUserAgent, $userAgent); + } } diff --git a/tests/UserAgentTest.php b/tests/UserAgentTest.php new file mode 100644 index 0000000..b2a43d8 --- /dev/null +++ b/tests/UserAgentTest.php @@ -0,0 +1,18 @@ +assertEquals("flagsmith-php-sdk/{$expectedVersion}", $userAgent); + } +}