From 6b2b7bfc9200bbecef8342fd578d4ab557fc72b0 Mon Sep 17 00:00:00 2001 From: DorAshkenaziHuman Date: Sun, 2 Nov 2025 14:59:02 +0200 Subject: [PATCH 1/8] Update to PHP 7.2.5 --- CHANGELOG.md | 17 ++++++++++++ composer.json | 12 ++++----- .../V2CredentialsIntelligenceProtocolTest.php | 2 +- .../Fixtures/PerimeterxContextGoodCookie.php | 6 +---- .../PerimeterxConfigurationValidatorTest.php | 6 ++--- tests/PerimeterxCookieV3ValidatorTest.php | 21 +++++++-------- tests/PerimeterxCookieValidatorTest.php | 18 +++++-------- tests/PerimeterxDataEnrichmentTest.php | 4 +-- tests/PerimeterxFieldExtractorManagerTest.php | 4 +-- tests/PerimeterxFirstPartyClientTest.php | 2 +- .../PerimeterxOriginalTokenValidatorTest.php | 4 +-- tests/PerimeterxS2SValidatorTest.php | 26 ++++++++++--------- tests/PerimeterxUtilsTest.php | 6 ++--- 13 files changed, 67 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 941e1cb..bbcfdfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [4.0.0] - 2025-11-02 + +### Changed + +- **BREAKING CHANGE**: Updated minimum PHP version from 5.5 to 7.2.5 +- **BREAKING CHANGE**: Updated Guzzle HTTP client from ~6.0 to ^7.0 +- Updated dev dependencies: + - PHPUnit from 5.6.* to ^8.5 + - Mockery from 0.9.* to ^1.3 + - PHPLint from ^1.1 to ^2.0 + +### Notes + +- This is a major version update due to the breaking changes in minimum PHP version requirements +- Guzzle 7.x requires PHP 7.2.5 or higher +- Existing projects using this SDK must upgrade to at least PHP 7.2.5 to use this version + ## [3.10.2] - 2024-09-11 ### Fixed diff --git a/composer.json b/composer.json index 8dae19f..17e1fef 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "perimeterx/php-sdk", "description": "PerimeterX SDK for PHP", - "version" : "3.10.2", + "version" : "4.0.0", "keywords": [ "perimeterx", "websecurity", @@ -14,8 +14,8 @@ "type": "library", "require": { "mustache/mustache": "^2.11.1", - "guzzlehttp/guzzle": "~6.0", - "php": ">=5.5", + "guzzlehttp/guzzle": "^7.0", + "php": ">=7.2.5", "psr/log": "^1.0.2" }, "config": { @@ -27,9 +27,9 @@ } }, "require-dev": { - "phpunit/phpunit": "5.6.*", - "mockery/mockery": "0.9.*", - "overtrue/phplint": "^1.1" + "phpunit/phpunit": "^8.5", + "mockery/mockery": "^1.3", + "overtrue/phplint": "^2.0" }, "autoload-dev": { "psr-4": { diff --git a/tests/CredentialsIntelligence/Protocol/V2CredentialsIntelligenceProtocolTest.php b/tests/CredentialsIntelligence/Protocol/V2CredentialsIntelligenceProtocolTest.php index 65a12f9..398a26a 100644 --- a/tests/CredentialsIntelligence/Protocol/V2CredentialsIntelligenceProtocolTest.php +++ b/tests/CredentialsIntelligence/Protocol/V2CredentialsIntelligenceProtocolTest.php @@ -4,7 +4,7 @@ use Perimeterx\CredentialsIntelligence\LoginCredentialsFields; use Perimeterx\CredentialsIntelligence\Protocol\CIVersion; -class V2CredentialsIntelligenceProtocolTests extends PHPUnit_Framework_TestCase { +class V2CredentialsIntelligenceProtocolTests extends PHPUnit\Framework\TestCase { /** * @dataProvider provideCredentialsAndExpectedHashes diff --git a/tests/Fixtures/PerimeterxContextGoodCookie.php b/tests/Fixtures/PerimeterxContextGoodCookie.php index 3f58b54..e687415 100644 --- a/tests/Fixtures/PerimeterxContextGoodCookie.php +++ b/tests/Fixtures/PerimeterxContextGoodCookie.php @@ -68,8 +68,4 @@ public function setVid($val){} public function setBlockAction($val){} public function setCookieHmac($val){} public function setPassReason($val){} -} -?> - \ No newline at end of file +} \ No newline at end of file diff --git a/tests/PerimeterxConfigurationValidatorTest.php b/tests/PerimeterxConfigurationValidatorTest.php index a475d26..b56517e 100644 --- a/tests/PerimeterxConfigurationValidatorTest.php +++ b/tests/PerimeterxConfigurationValidatorTest.php @@ -3,13 +3,13 @@ use PHPUnit\Framework\TestCase; use Perimeterx\Perimeterx; -class PerimeterxConfigurationValidatorTest extends PHPUnit_Framework_TestCase +class PerimeterxConfigurationValidatorTest extends PHPUnit\Framework\TestCase { protected $params; protected $px; - protected function setUp() + protected function setUp(): void { $this->params = [ 'app_id' => 'PX_APP_ID', @@ -20,7 +20,7 @@ protected function setUp() ]; } - protected function tearDown() + protected function tearDown(): void { $reflection = new ReflectionClass($this->px); $instance = $reflection->getProperty('instance'); diff --git a/tests/PerimeterxCookieV3ValidatorTest.php b/tests/PerimeterxCookieV3ValidatorTest.php index de029dd..7917619 100644 --- a/tests/PerimeterxCookieV3ValidatorTest.php +++ b/tests/PerimeterxCookieV3ValidatorTest.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\TestCase; use Psr\Log\AbstractLogger; -class PerimeterxCookieV3ValidatorTest extends PHPUnit_Framework_TestCase +class PerimeterxCookieV3ValidatorTest extends PHPUnit\Framework\TestCase { // randomly generated fake values @@ -544,18 +544,12 @@ public function testEncryptedTokenDecryption() { // private functions private function getMockLogger($expected_level = null, $expected_message = null, $msgIndex = 0) { - $levels = ['info', 'debug', 'warning', 'error']; $logger = $this->createMock(AbstractLogger::class); - foreach ($levels as $level) { - if ($expected_level === $level) { - $logger->expects($this->at($msgIndex)) - ->method($expected_level) - ->with($this->stringContains($expected_message)); - } else { - $logger->expects($this->never()) - ->method($level); - } + if ($expected_level !== null && $expected_message !== null) { + $logger->expects($this->atLeastOnce()) + ->method($expected_level) + ->with($this->stringContains($expected_message)); } return $logger; @@ -616,7 +610,7 @@ private function getPxContext($pxCookie, $userAgent, $sensitive_route = false, $ { $pxCtx = $this->getMockBuilder(PerimeterxContext::class) ->disableOriginalConstructor() - ->setMethods(['getPxCookie', 'getUserAgent', 'getIp','isSensitiveRoute', 'getCookieOrigin', 'getPxCookies']) + ->onlyMethods(['getPxCookie', 'getUserAgent', 'getIp','isSensitiveRoute', 'getCookieOrigin', 'getPxCookies', 'getCookieVersion']) ->getMock(); $pxCtx->expects($this->any()) ->method('getPxCookie') @@ -633,6 +627,9 @@ private function getPxContext($pxCookie, $userAgent, $sensitive_route = false, $ $pxCtx->expects($this->any()) ->method("getPxCookies") ->willReturn(array('v3' => 'aaaaa')); // mocking an entry to cookies array that will trigger V3 cookie/token + $pxCtx->expects($this->any()) + ->method('getCookieVersion') + ->willReturn('V3'); return $pxCtx; } diff --git a/tests/PerimeterxCookieValidatorTest.php b/tests/PerimeterxCookieValidatorTest.php index 8e8c9b5..424d36e 100644 --- a/tests/PerimeterxCookieValidatorTest.php +++ b/tests/PerimeterxCookieValidatorTest.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\TestCase; use Psr\Log\AbstractLogger; -class PerimeterxCookieValidatorTest extends PHPUnit_Framework_TestCase +class PerimeterxCookieValidatorTest extends PHPUnit\Framework\TestCase { // randomly generated fake values @@ -599,18 +599,12 @@ private function assertPxContext($pxCtx, $decoded_cookie, $uuid, $vid, $score, $ private function getMockLogger($expected_level = null, $expected_message = null, $msgIndex = 0) { - $levels = ['debug', 'info', 'warning', 'error']; $logger = $this->createMock(AbstractLogger::class); - foreach ($levels as $level) { - if ($expected_level === $level) { - $logger->expects($this->at($msgIndex)) - ->method($expected_level) - ->with($this->stringContains($expected_message)); - } else { - $logger->expects($this->never()) - ->method($level); - } + if ($expected_level !== null && $expected_message !== null) { + $logger->expects($this->atLeastOnce()) + ->method($expected_level) + ->with($this->stringContains($expected_message)); } return $logger; @@ -650,7 +644,7 @@ private function getPxContext($pxCookie, $userAgent, $ip, $sensitive_route = fal { $pxCtx = $this->getMockBuilder(PerimeterxContext::class) ->disableOriginalConstructor() - ->setMethods(['getPxCookie', 'getUserAgent', 'getIp','isSensitiveRoute', 'getCookieOrigin']) + ->onlyMethods(['getPxCookie', 'getUserAgent', 'getIp','isSensitiveRoute', 'getCookieOrigin']) ->getMock(); $pxCtx->expects($this->any()) ->method('getPxCookie') diff --git a/tests/PerimeterxDataEnrichmentTest.php b/tests/PerimeterxDataEnrichmentTest.php index 9f23491..db2f5f1 100644 --- a/tests/PerimeterxDataEnrichmentTest.php +++ b/tests/PerimeterxDataEnrichmentTest.php @@ -8,7 +8,7 @@ use PHPUnit\Framework\TestCase; use Psr\Log\AbstractLogger; -class PerimeterxDataEnrichmentTest extends PHPUnit_Framework_TestCase { +class PerimeterxDataEnrichmentTest extends PHPUnit\Framework\TestCase { const COOKIE_KEY = '549Z5UsasvfmVS6kAR3r4ydPnQdnnW4Gcwk35hj5tatZ5B2dqjrQvMMyLAJN5de3'; public function testNoPxdeCookie() { @@ -114,7 +114,7 @@ private function getPxContext($pxCookie) { $pxCtx = $this->getMockBuilder(PerimeterxContext::class) ->disableOriginalConstructor() - ->setMethods(['getDataEnrichmentCookie']) + ->onlyMethods(['getDataEnrichmentCookie']) ->getMock(); $pxCtx->expects($this->any()) ->method('getDataEnrichmentCookie') diff --git a/tests/PerimeterxFieldExtractorManagerTest.php b/tests/PerimeterxFieldExtractorManagerTest.php index 2011d8a..fe9b573 100644 --- a/tests/PerimeterxFieldExtractorManagerTest.php +++ b/tests/PerimeterxFieldExtractorManagerTest.php @@ -5,7 +5,7 @@ use Perimeterx\CredentialsIntelligence\PerimeterxFieldExtractorManager; use Perimeterx\CredentialsIntelligence\Protocol\V1CredentialsIntelligenceProtocol; -class PerimeterxFieldExtractorManagerTest extends PHPUnit_Framework_TestCase +class PerimeterxFieldExtractorManagerTest extends PHPUnit\Framework\TestCase { const LOGIN_REQUEST_URI = "/login"; const LOGIN_REQUEST_METHOD = "POST"; @@ -32,7 +32,7 @@ class PerimeterxFieldExtractorManagerTest extends PHPUnit_Framework_TestCase */ private $fieldExtractorManager; - public function setUp() { + public function setUp(): void { $mapKey = PerimeterxFieldExtractorManager::generateMapKey(self::LOGIN_REQUEST_URI, self::LOGIN_REQUEST_METHOD); $mockExtractor = $this->createMock(PerimeterxFieldExtractor::class); $mockExtractor diff --git a/tests/PerimeterxFirstPartyClientTest.php b/tests/PerimeterxFirstPartyClientTest.php index 07f9d7b..6f39cc8 100644 --- a/tests/PerimeterxFirstPartyClientTest.php +++ b/tests/PerimeterxFirstPartyClientTest.php @@ -7,7 +7,7 @@ use PerimeterxTests\MockHttpClient; use PerimeterxTests\TestUtils; -class PerimeterxFirstPartyClientTest extends PHPUnit_Framework_TestCase { +class PerimeterxFirstPartyClientTest extends PHPUnit\Framework\TestCase { private function getTestPxConfig() { $pxConfig = [ 'app_id' => 'PX_APP_ID', diff --git a/tests/PerimeterxOriginalTokenValidatorTest.php b/tests/PerimeterxOriginalTokenValidatorTest.php index b0c814a..7d56e48 100644 --- a/tests/PerimeterxOriginalTokenValidatorTest.php +++ b/tests/PerimeterxOriginalTokenValidatorTest.php @@ -6,7 +6,7 @@ use PHPUnit\Framework\TestCase; use Psr\Log\AbstractLogger; -class PerimeterxOriginalTokenValidatorTest extends PHPUnit_Framework_TestCase +class PerimeterxOriginalTokenValidatorTest extends PHPUnit\Framework\TestCase { // randomly generated fake values const COOKIE_KEY = '549Z5UsasvfmVS6kAR3r4ydPnQdnnW4Gcwk35hj5tatZ5B2dqjrQvMMyLAJN5de3'; @@ -221,7 +221,7 @@ private function getPxContext($pxToken, $pxOriginalToken, $cookie_origin = "head { $pxCtx = $this->getMockBuilder(PerimeterxContext::class) ->disableOriginalConstructor() - ->setMethods(['getPxCookie', 'getOriginalToken', 'getCookieOrigin']) + ->onlyMethods(['getPxCookie', 'getOriginalToken', 'getCookieOrigin']) ->getMock(); $pxCtx->expects($this->any()) ->method('getPxCookie') diff --git a/tests/PerimeterxS2SValidatorTest.php b/tests/PerimeterxS2SValidatorTest.php index dbd6f34..caf8a72 100644 --- a/tests/PerimeterxS2SValidatorTest.php +++ b/tests/PerimeterxS2SValidatorTest.php @@ -6,7 +6,7 @@ use Perimeterx\PerimeterxHttpClient; use Psr\Log\AbstractLogger; -class PerimeterxS2SValidatorTest extends PHPUnit_Framework_TestCase +class PerimeterxS2SValidatorTest extends PHPUnit\Framework\TestCase { // randomly generated fake values const COOKIE_KEY = '549Z5UsasvfmVS6kAR3r4ydPnQdnnW4Gcwk35hj5tatZ5B2dqjrQvMMyLAJN5de3'; @@ -30,9 +30,14 @@ class PerimeterxS2SValidatorTest extends PHPUnit_Framework_TestCase public function testAttachPxOrigCookie() { $pxCookie = 'this is a fake cookie'; + $actualRequestBody = null; $http_client = $this->createMock(PerimeterxHttpClient::class); - $http_client->expects($spy = $this->any()) - ->method('send'); + $http_client->expects($this->once()) + ->method('send') + ->willReturnCallback(function($url, $method, $requestBody) use (&$actualRequestBody) { + $actualRequestBody = $requestBody; + return json_encode(['score' => 0, 'action' => 'c', 'uuid' => 'test']); + }); $pxCtx = $this->getPxContext($pxCookie); $pxConfig = $this->getPxConfig($this->getMockLogger('info', 'attaching px_orig_cookie to request'), $http_client); @@ -40,10 +45,7 @@ public function testAttachPxOrigCookie() { $validator = new PerimeterxS2SValidator($pxCtx, $pxConfig); $validator->verify(); - $invocations = $spy->getInvocations(); - - $last = end($invocations); - $this->assertEquals($pxCookie, $last->parameters[2]["additional"]["px_cookie_orig"]); + $this->assertEquals($pxCookie, $actualRequestBody["additional"]["px_cookie_orig"]); } /** @@ -85,7 +87,7 @@ public function testS2SErrorHttpClientThrowsException() { $this->assertEquals("s2s_error", $pxCtx->getPassReason()); $this->assertEquals("unknown_error", $pxCtx->getS2SErrorReason()); - $this->assertContains($exception_message, $pxCtx->getS2SErrorMessage()); + $this->assertStringContainsString($exception_message, $pxCtx->getS2SErrorMessage()); } /** @@ -107,7 +109,7 @@ public function testS2SError($httpClientReturnValue, $s2sErrorReason, $s2sErrorM $this->assertEquals("s2s_error", $pxCtx->getPassReason()); $this->assertEquals($s2sErrorReason, $pxCtx->getS2SErrorReason()); if (!empty($s2sErrorMessage)) { - $this->assertContains($s2sErrorMessage, $pxCtx->getS2SErrorMessage()); + $this->assertStringContainsString($s2sErrorMessage, $pxCtx->getS2SErrorMessage()); } $this->assertEquals($httpStatus, $pxCtx->getS2SErrorHttpStatus()); $this->assertEquals($httpMessage, $pxCtx->getS2SErrorHttpMessage()); @@ -184,12 +186,12 @@ private function getPxContext($pxCookie = "", { $pxCtx = $this->getMockBuilder(PerimeterxContext::class) ->disableOriginalConstructor() - ->setMethods([ + ->onlyMethods([ 'getPxCookie', 'getUserAgent', 'getIp', 'getUri', - 'getUrl', + 'getFullUrl', 'getS2SCallReason', 'getHttpMethod', 'getHttpVersion', @@ -210,7 +212,7 @@ private function getPxContext($pxCookie = "", ->method('getUri') ->willReturn($uri); $pxCtx->expects($this->any()) - ->method('getUrl') + ->method('getFullUrl') ->willReturn($url); $pxCtx->expects($this->any()) ->method('getS2SCallReason') diff --git a/tests/PerimeterxUtilsTest.php b/tests/PerimeterxUtilsTest.php index 585924c..63ae4b2 100644 --- a/tests/PerimeterxUtilsTest.php +++ b/tests/PerimeterxUtilsTest.php @@ -9,14 +9,14 @@ public static function setInputStreamName($inputStreamName) { } } -class PerimeterxUtilsTest extends PHPUnit_Framework_TestCase { +class PerimeterxUtilsTest extends PHPUnit\Framework\TestCase { const TEMP_STREAM_NAME = "file://" . __DIR__ . "/tmp.txt"; - public function setUp() { + public function setUp(): void { PerimeterxUtilsDouble::setInputStreamName(self::TEMP_STREAM_NAME); } - public function tearDown() { + public function tearDown(): void { if (file_exists(self::TEMP_STREAM_NAME)) { unlink(self::TEMP_STREAM_NAME); } From b000665c84e10ce557a29cd4df16e34cbee29a70 Mon Sep 17 00:00:00 2001 From: DorAshkenaziHuman Date: Mon, 3 Nov 2025 11:29:10 +0200 Subject: [PATCH 2/8] fix unit tests, update dependencies --- .gitignore | 3 ++- CHANGELOG.md | 16 ++++-------- composer.json | 6 ++--- tests/PerimeterxCookieValidatorTest.php | 2 +- tests/PerimeterxDataEnrichmentTest.php | 2 +- tests/PerimeterxFieldExtractorManagerTest.php | 2 +- .../PerimeterxOriginalTokenValidatorTest.php | 2 +- tests/PerimeterxS2SValidatorTest.php | 25 +++++++++---------- tests/PerimeterxUtilsTest.php | 4 +-- 9 files changed, 28 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 9c0294d..100af41 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ composer.lock dev/ build/ .vscode -tests/coverage \ No newline at end of file +tests/coverage +.phpunit.result.cache \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index bbcfdfd..6520f85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,22 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [4.0.0] - 2025-11-02 +## [4.0.0] - 2025-11-03 ### Changed -- **BREAKING CHANGE**: Updated minimum PHP version from 5.5 to 7.2.5 -- **BREAKING CHANGE**: Updated Guzzle HTTP client from ~6.0 to ^7.0 -- Updated dev dependencies: - - PHPUnit from 5.6.* to ^8.5 - - Mockery from 0.9.* to ^1.3 - - PHPLint from ^1.1 to ^2.0 +- Updated minimum PHP version from 5.5 to 7.2.5 +- Updated Guzzle HTTP client from 6.0 to 7.0 -### Notes +### Fixed -- This is a major version update due to the breaking changes in minimum PHP version requirements -- Guzzle 7.x requires PHP 7.2.5 or higher -- Existing projects using this SDK must upgrade to at least PHP 7.2.5 to use this version +- Removed `