From 1fa3c3c26e75b9d649344214b0bbe5a3a48c2027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Gro=C3=9Fe?= Date: Wed, 29 Oct 2025 13:23:27 +0100 Subject: [PATCH] chore: raise phpstan to level 8 and fix null safety MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Updated phpstan.neon.dist to level 8 - Added null checks for ReflectionClass::getConstructor() calls in test files - Enhanced PluginSession to handle nullable instanceId parameter - Used PHP 8+ null coalescing throw operator for clean error handling - Improved null safety across test and source files Key improvements: - All ReflectionMethod calls now safely handle null returns - deleteInstance method properly validates required instanceId parameter - Modern PHP syntax for null safety with descriptive error messages - No breaking changes to existing functionality 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- phpstan.neon.dist | 2 +- src/PluginSession.php | 3 ++- test/PluginSessionTest.php | 12 ++++++------ test/SSOTokenTest.php | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 0e1768e..f9cafa8 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,5 @@ parameters: - level: 7 + level: 8 paths: - ./src - ./test diff --git a/src/PluginSession.php b/src/PluginSession.php index 19ec3fd..e5a2412 100644 --- a/src/PluginSession.php +++ b/src/PluginSession.php @@ -86,7 +86,8 @@ public function __construct( // delete the instance if the special sub is in the token data // exits the request if ($sso && $remoteCallHandler && $sso->isDeleteInstanceCall()) { - $this->deleteInstance($sso->getInstanceId(), $remoteCallHandler); + $instanceId = $sso->getInstanceId() ?: throw new SSOException('Instance id is required for deleteInstance'); + $this->deleteInstance($instanceId, $remoteCallHandler); } // starts the session diff --git a/test/PluginSessionTest.php b/test/PluginSessionTest.php index bfaed04..1abfa04 100644 --- a/test/PluginSessionTest.php +++ b/test/PluginSessionTest.php @@ -115,7 +115,7 @@ public function testConstructorWorksAsExpected(): void ->with($this->pluginId); $reflectedClass = new ReflectionClass($this->classname); - $constructor = $reflectedClass->getConstructor(); + $constructor = $reflectedClass->getConstructor() ?: throw new \Exception('Constructor not found'); $constructor->invoke($mock, $this->pluginId, $this->publicKey); $this->setupEnvironment($this->pluginInstanceId, null, false); @@ -143,7 +143,7 @@ public function testConstructorRejectsSpoofedPID(): void $this->expectException(SSOException::class); $reflectedClass = new ReflectionClass($this->classname); - $constructor = $reflectedClass->getConstructor(); + $constructor = $reflectedClass->getConstructor() ?: throw new \Exception('Constructor not found'); $constructor->invoke($mock, $this->pluginId, $this->publicKey); } @@ -168,7 +168,7 @@ public function testConstructorRefuseEmptyPluginId(): void $this->expectExceptionMessage('Empty plugin ID.'); $reflectedClass = new ReflectionClass($this->classname); - $constructor = $reflectedClass->getConstructor(); + $constructor = $reflectedClass->getConstructor() ?: throw new \Exception('Constructor not found'); $constructor->invoke($mock, '', $this->publicKey); } @@ -193,7 +193,7 @@ public function testConstructorRefuseEmptySecret(): void $this->expectExceptionMessage('Parameter appSecret for SSOToken is empty.'); $reflectedClass = new ReflectionClass($this->classname); - $constructor = $reflectedClass->getConstructor(); + $constructor = $reflectedClass->getConstructor() ?: throw new \Exception('Constructor not found'); $constructor->invoke($mock, $this->pluginId, ''); } @@ -218,7 +218,7 @@ public function testConstructorRefuseEmptyEnv(): void $this->expectExceptionMessage('Missing PID or JWT query parameter in Request.'); $reflectedClass = new ReflectionClass($this->classname); - $constructor = $reflectedClass->getConstructor(); + $constructor = $reflectedClass->getConstructor() ?: throw new \Exception('Constructor not found'); $constructor->invoke($mock, $this->pluginId, $this->publicKey); } @@ -243,7 +243,7 @@ public function testConstructorRefuseHavingBothJwtAndPid(): void $this->expectExceptionMessage('Tried to initialize the session with both PID and JWT provided.'); $reflectedClass = new ReflectionClass($this->classname); - $constructor = $reflectedClass->getConstructor(); + $constructor = $reflectedClass->getConstructor() ?: throw new \Exception('Constructor not found'); $constructor->invoke($mock, $this->pluginId, $this->publicKey); } diff --git a/test/SSOTokenTest.php b/test/SSOTokenTest.php index 7280932..a6fb88c 100644 --- a/test/SSOTokenTest.php +++ b/test/SSOTokenTest.php @@ -68,7 +68,7 @@ public function testConstructorRefuseEmptySecret(): void $this->expectExceptionMessage('Parameter appSecret for SSOToken is empty.'); $reflectedClass = new ReflectionClass(SSOToken::class); - $constructor = $reflectedClass->getConstructor(); + $constructor = $reflectedClass->getConstructor() ?: throw new \Exception('Constructor not found'); $constructor->invoke($mock, ' ', 'fake token'); } @@ -91,7 +91,7 @@ public function testConstructorRefuseEmptyToken(): void $this->expectExceptionMessage('Parameter tokenData for SSOToken is empty.'); $reflectedClass = new ReflectionClass(SSOToken::class); - $constructor = $reflectedClass->getConstructor(); + $constructor = $reflectedClass->getConstructor() ?: throw new \Exception('Constructor not found'); $constructor->invoke($mock, 'fake secret', ' '); }