diff --git a/.github/workflows/php-tests.yml b/.github/workflows/php-tests.yml index 8c35057..52d65a9 100644 --- a/.github/workflows/php-tests.yml +++ b/.github/workflows/php-tests.yml @@ -59,7 +59,9 @@ jobs: - name: "Install PHP" uses: "shivammathur/setup-php@v2" with: - php-version: "latest" + # Use PHP 8.3 until psalm resolves issues with 8.4 + # https://github.com/vimeo/psalm/issues/11107 + php-version: "8.3" coverage: "none" - name: "Install dependencies (Composer)" diff --git a/src/Config/ConfigInterface.php b/src/Config/ConfigInterface.php index 021def6..5ac2a99 100644 --- a/src/Config/ConfigInterface.php +++ b/src/Config/ConfigInterface.php @@ -8,7 +8,7 @@ public function getProduction(): bool; public function getSameSiteStrict(): ?bool; /** @return array|null */ public function getError(): ?array; - /** @return array|null */ + /** @return array|null */ public function getScope(): ?array; /** @return array|null */ public function getProviderHint(): ?array; diff --git a/src/Exception/CallbackException.php b/src/Exception/CallbackException.php index 9142f3f..8d2efa7 100644 --- a/src/Exception/CallbackException.php +++ b/src/Exception/CallbackException.php @@ -7,11 +7,11 @@ class CallbackException extends Exception { - /** @var array */ + /** @var array */ private array $errorDetails; /** - * @param array $errorDetails + * @param array $errorDetails * @param string $message * @param int $code * @param Throwable|null $previous @@ -27,7 +27,7 @@ public function __construct( } /** - * @return array + * @return array */ public function getErrorDetails(): array { diff --git a/src/Handler/Callback.php b/src/Handler/Callback.php index 6fc2d15..da8f29e 100644 --- a/src/Handler/Callback.php +++ b/src/Handler/Callback.php @@ -262,7 +262,7 @@ public function handleCallback(): string * Uses the target URI from error details or a fallback error route. Updates the query * string with error information. Throws an exception if no error URI is available. * - * @param array $error Error details including 'target_uri', 'error', and 'error_description'. + * @param array $error Error details including 'target_uri', 'error', and 'error_description'. * @param string $errorMessage A message describing the error. * @param Throwable|null $previous Previous exception for chaining (optional). * @@ -272,6 +272,7 @@ public function handleCallback(): string */ private function sendErrorPage(array $error, string $errorMessage, ?Throwable $previous = null): string { + /** @var string $error_uri */ $error_uri = $error['target_uri'] ?? $this->config->getRoutes()['error'] ?? null; if ($error_uri) { list($pathString, $queryString) = array_pad(explode('?', (string) $error_uri, 2), 2, ''); diff --git a/src/Handler/Login.php b/src/Handler/Login.php index bc1557b..196b379 100644 --- a/src/Handler/Login.php +++ b/src/Handler/Login.php @@ -82,13 +82,16 @@ public function generateLoginUrl(): string } $redirectURI = $this->config->getRedirectURI(); + /** @var string $host */ $host = $this->helloRequest->fetchHeader('Host'); if (empty($redirectURI)) { if (isset($this->redirectURIs[$host])) { $redirectURI = $this->redirectURIs[$host]; } elseif (!empty($params['redirect_uri'])) { - $this->redirectURIs[$host] = $redirectURI = $params['redirect_uri']; + /** @var string $redirectURI */ + $redirectURI = $params['redirect_uri']; + $this->redirectURIs[$host] = $redirectURI; error_log("Hello: RedirectURI for $host => $redirectURI"); } else { error_log('Hello: Discovering API RedirectURI route ...'); @@ -97,9 +100,11 @@ public function generateLoginUrl(): string } } + /** @var string $providerHintString */ $providerHintString = $params['provider_hint']; $providerHint = $providerHintString ? array_map('trim', explode(' ', $providerHintString)) : null; + /** @var string $scopeString */ $scopeString = $params['scope']; $scope = $scopeString ? array_map('trim', explode(' ', $scopeString)) : null; @@ -120,11 +125,14 @@ public function generateLoginUrl(): string $authResponse = $this->getAuthHelper()->createAuthRequest($request); + /** @var string $targetUri */ + $targetUri = $params['target_uri']; + $this->getOIDCManager()->saveOidc(OIDC::fromArray([ 'nonce' => $authResponse['nonce'], 'code_verifier' => $authResponse['code_verifier'], 'redirect_uri' => $redirectURI, - 'target_uri' => $params['target_uri'], + 'target_uri' => $targetUri, ])); return $authResponse['url']; diff --git a/src/Handler/Logout.php b/src/Handler/Logout.php index e78f7ca..2cc420d 100644 --- a/src/Handler/Logout.php +++ b/src/Handler/Logout.php @@ -55,6 +55,7 @@ private function getAuthLib(): AuthLib */ public function generateLogoutUrl(): string { + /** @var string|null $targetUri */ $targetUri = $this->helloRequest->fetch('target_uri'); $this->getAuthLib()->clearAuthCookie(); if ($this->config->getLogoutSync()) { diff --git a/src/HelloClient.php b/src/HelloClient.php index 3da3253..8353f85 100644 --- a/src/HelloClient.php +++ b/src/HelloClient.php @@ -141,10 +141,16 @@ private function handleCallback() return $this->helloResponse->redirect($this->getCallbackHandler()->handleCallback()); } catch (CallbackException $e) { $errorDetails = $e->getErrorDetails(); + /** @var string $error */ + $error = $errorDetails['error']; + /** @var string $errorDescription */ + $errorDescription = $errorDetails['error_description']; + /** @var string $targetUri */ + $targetUri = $errorDetails['target_uri']; return $this->helloResponse->render($this->pageRenderer->renderErrorPage( - $errorDetails['error'], - $errorDetails['error_description'], - $errorDetails['target_uri'] + $error, + $errorDescription, + $targetUri )); } catch (SameSiteCallbackException $e) { return $this->helloResponse->render($this->pageRenderer->renderSameSitePage()); @@ -153,7 +159,7 @@ private function handleCallback() /** * @return mixed|string|void|null - * @throws CryptoFailedException | InvalidSecretException + * @throws CryptoFailedException | InvalidSecretException | Exception */ public function route() { diff --git a/src/HelloRequest/HelloRequest.php b/src/HelloRequest/HelloRequest.php index 2c68f2d..875efeb 100644 --- a/src/HelloRequest/HelloRequest.php +++ b/src/HelloRequest/HelloRequest.php @@ -10,10 +10,10 @@ class HelloRequest implements HelloRequestInterface * Fetch a parameter by key from either GET or POST data. * * @param string $key The key of the parameter to fetch. - * @param string|null $default Default value if the key is not found. - * @return string|null The value of the parameter or default. + * @param mixed $default Default value if the key is not found. + * @return mixed The value of the parameter or default. */ - public function fetch(string $key, ?string $default = null): ?string + public function fetch(string $key, $default = null) { // First check GET, then POST if not found. return $_GET[$key] ?? $_POST[$key] ?? $default; @@ -23,7 +23,7 @@ public function fetch(string $key, ?string $default = null): ?string * Fetch multiple parameters by keys from either GET or POST data. * * @param array $keys The keys of the parameters to fetch. - * @return array An associative array of parameters. + * @return array An associative array of parameters. */ public function fetchMultiple(array $keys): array { @@ -38,10 +38,10 @@ public function fetchMultiple(array $keys): array * Fetch a header by key from the request headers. * * @param string $key The key of the header to fetch. - * @param string|null $default Default value if the key is not found. - * @return string|null The value of the header or default. + * @param mixed|null $default Default value if the key is not found. + * @return mixed|null The value of the header or default. */ - public function fetchHeader(string $key, ?string $default = null): ?string + public function fetchHeader(string $key, $default = null) { $headers = $this->getAllHeaders(); $normalizedKey = strtolower($key); @@ -56,7 +56,7 @@ public function fetchHeader(string $key, ?string $default = null): ?string /** * Retrieve all request headers. * - * @return array An associative array of all request headers. + * @return array An associative array of all request headers. */ private function getAllHeaders(): array { diff --git a/src/HelloRequest/HelloRequestInterface.php b/src/HelloRequest/HelloRequestInterface.php index e26da27..c0c7469 100644 --- a/src/HelloRequest/HelloRequestInterface.php +++ b/src/HelloRequest/HelloRequestInterface.php @@ -8,16 +8,16 @@ interface HelloRequestInterface * Fetch a parameter by key from either GET or POST data. * * @param string $key The key of the parameter to fetch. - * @param string|null $default Default value if the key is not found. - * @return string|null The value of the parameter or default. + * @param mixed $default Default value if the key is not found. + * @return mixed The value of the parameter or default. */ - public function fetch(string $key, ?string $default = null): ?string; + public function fetch(string $key, $default = null); /** * Fetch multiple parameters by keys from either GET or POST data. * * @param array $keys The keys of the parameters to fetch. - * @return array An associative array of parameters. + * @return array An associative array of parameters. */ public function fetchMultiple(array $keys): array; @@ -25,10 +25,10 @@ public function fetchMultiple(array $keys): array; * Fetch a header by key from the request headers. * * @param string $key The key of the header to fetch. - * @param string|null $default Default value if the key is not found. - * @return string|null The value of the header or default. + * @param mixed $default Default value if the key is not found. + * @return mixed The value of the header or default. */ - public function fetchHeader(string $key, ?string $default = null): ?string; + public function fetchHeader(string $key, $default = null); /** * Fetch a cookie value by name. diff --git a/src/Type/AuthUpdates.php b/src/Type/AuthUpdates.php index 39cf4ce..c616ef1 100644 --- a/src/Type/AuthUpdates.php +++ b/src/Type/AuthUpdates.php @@ -58,9 +58,9 @@ public function offsetExists($offset): bool return isset($this->additionalProperties[$offset]); } - public function offsetGet($offset): ?string + public function offsetGet($offset): string { - return is_string($this->additionalProperties[$offset]) ? $this->additionalProperties[$offset] : null; + return is_string($this->additionalProperties[$offset]) ? $this->additionalProperties[$offset] : ''; } public function offsetSet($offset, $value): void diff --git a/src/Utils/QueryParamFetcher.php b/src/Utils/QueryParamFetcher.php index be81398..025ec1d 100644 --- a/src/Utils/QueryParamFetcher.php +++ b/src/Utils/QueryParamFetcher.php @@ -5,7 +5,7 @@ class QueryParamFetcher { /** - * @param array $keys + * @param array $keys * @return array */ public static function fetch(array $keys): array diff --git a/tests/Config/HelloConfigBuilderTest.php b/tests/Config/HelloConfigBuilderTest.php index 81d31fe..79d58ca 100644 --- a/tests/Config/HelloConfigBuilderTest.php +++ b/tests/Config/HelloConfigBuilderTest.php @@ -8,7 +8,7 @@ class HelloConfigBuilderTest extends TestCase { - public function testHelloConfigBuilderBuildsConfigCorrectly() + public function testHelloConfigBuilderBuildsConfigCorrectly(): void { // Arrange: Create the builder and set values $builder = new HelloConfigBuilder(); diff --git a/tests/Handler/AuthTest.php b/tests/Handler/AuthTest.php index b63229b..38018a7 100644 --- a/tests/Handler/AuthTest.php +++ b/tests/Handler/AuthTest.php @@ -38,8 +38,16 @@ public function testCanHandleAuth(): void ]); $result = $this->auth->handleAuth(); + /** @var string $actual_name */ + $actual_name = isset($result->toArray()['authCookie']['name']) + ? $result->toArray()['authCookie']['name'] + : ''; + /** @var string $actual_email */ + $actual_email = isset($result->toArray()['authCookie']['name']) + ? $result->toArray()['authCookie']['email'] + : ''; $this->assertTrue($result->toArray()['isLoggedIn']); - $this->assertEquals($result->toArray()['authCookie']['name'], 'Dick Hardt'); - $this->assertEquals($result->toArray()['authCookie']['email'], 'dick.hardt@hello.coop'); + $this->assertEquals('Dick Hardt', $actual_name); + $this->assertEquals('dick.hardt@hello.coop', $actual_email); } } diff --git a/tests/Handler/CallbackTest.php b/tests/Handler/CallbackTest.php index 986eec5..48e56cf 100644 --- a/tests/Handler/CallbackTest.php +++ b/tests/Handler/CallbackTest.php @@ -28,7 +28,7 @@ protected function setUp(): void $this->tokenFetcherMock->method('fetchToken')->willReturn('valid_token_id'); } - public function testHandleCallbackSuccessfulLogin() + public function testHandleCallbackSuccessfulLogin(): void { $_COOKIE['oidcName'] = $this->crypto->encrypt([ 'code_verifier' => 'test_verifier', @@ -68,7 +68,7 @@ public function testHandleCallbackSuccessfulLogin() $this->assertEquals('http://api.example.com?uri=example.com&appName=MyApp&redirectURI=https%3A%2F%2Fexample.com%2Fcallback&targetURI=%2Fdashboard&wildcard_console=true', $result); } - public function testHandleCallbackMissingCode() + public function testHandleCallbackMissingCode(): void { $_COOKIE['oidcName'] = $this->crypto->encrypt([ 'code_verifier' => 'test_verifier', @@ -86,10 +86,13 @@ public function testHandleCallbackMissingCode() ]); - $this->assertEquals('/dashboard?error=invalid_request&error_description=Missing+code+parameter', $this->callback->handleCallback()); + $this->assertEquals( + '/dashboard?error=invalid_request&error_description=Missing+code+parameter', + $this->callback->handleCallback() + ); } - public function testHandleCallbackInvalidTokenAudience() + public function testHandleCallbackInvalidTokenAudience(): void { // Set up mock behaviors $_GET = array_merge($_GET, [ diff --git a/tests/Handler/LoginTest.php b/tests/Handler/LoginTest.php index aa5f156..189a79d 100644 --- a/tests/Handler/LoginTest.php +++ b/tests/Handler/LoginTest.php @@ -36,7 +36,7 @@ protected function setUp(): void ); } - public function testGenerateLoginUrlSuccess() + public function testGenerateLoginUrlSuccess(): void { // Setup mocks $_GET = [ @@ -67,15 +67,16 @@ public function testGenerateLoginUrlSuccess() ); $query = parse_url($url, PHP_URL_QUERY); + $this->assertIsString($query); parse_str($query, $params); - $this->assertEquals($params['provider_hint'], 'google'); - $this->assertEquals($params['scope'], 'openid profile'); - $this->assertEquals($params['code_challenge_method'], 'S256'); - $this->assertEquals($params['login_hint'], 'user@example.com'); + $this->assertEquals('google', $params['provider_hint']); + $this->assertEquals('openid profile', $params['scope']); + $this->assertEquals('S256', $params['code_challenge_method']); + $this->assertEquals('user@example.com', $params['login_hint']); //$this->assertEquals('https://wallet.hello.coop/authorize?client_id=valid_client_id&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback&scope=openid&response_type=code&response_mode=query&nonce=1234&prompt=consent&code_challenge=yyhvlwTA3oVJcnTpkLV70DjqXb794Ar5Sgth12qbRsM&code_challenge_method=S256&provider_hint=google&login_hint=user%40example.com&domain_hint=example.com', $url); } - public function testGenerateLoginUrlMissingClientId() + public function testGenerateLoginUrlMissingClientId(): void { $_GET = [ 'provider_hint' => 'google', @@ -98,7 +99,7 @@ public function testGenerateLoginUrlMissingClientId() $this->login->generateLoginUrl(); } - public function testGenerateLoginUrlMissingRedirectURI() + public function testGenerateLoginUrlMissingRedirectURI(): void { $_GET = [ 'provider_hint' => 'google', diff --git a/tests/HelloClientTest.php b/tests/HelloClientTest.php index efd3a36..2d59284 100644 --- a/tests/HelloClientTest.php +++ b/tests/HelloClientTest.php @@ -14,9 +14,9 @@ class HelloClientTest extends TestCase { use ServiceMocksTrait; - /** @var MockObject|PageRendererInterface */ + /** @var MockObject & PageRendererInterface */ private $pageRendererMock; - /** @var MockObject|Callback */ + /** @var MockObject & Callback */ private $callbackMock; private HelloClient $client; @@ -40,7 +40,7 @@ protected function setUp(): void $this->pageRendererMock->method('renderErrorPage')->willReturn("error_page"); } - public function testRouteHandlesAuth() + public function testRouteHandlesAuth(): void { // Simulate $_GET parameters $_GET = ['op' => 'auth']; @@ -61,7 +61,7 @@ public function testRouteHandlesAuth() $this->assertSame('auth_response', $result); } - public function testRouteHandlesCallback() + public function testRouteHandlesCallback(): void { // Simulate $_GET parameters $_GET = ['code' => 'callback_code']; @@ -88,7 +88,7 @@ public function testRouteHandlesCallback() $this->assertSame('/dashboard', $result); } - public function testRouteHandlesCallbackException() + public function testRouteHandlesCallbackException(): void { // Simulate $_GET parameters $_GET = ['code' => 'callback_code']; diff --git a/tests/HelloRequest/HelloRequestTest.php b/tests/HelloRequest/HelloRequestTest.php index e8522d9..365085d 100644 --- a/tests/HelloRequest/HelloRequestTest.php +++ b/tests/HelloRequest/HelloRequestTest.php @@ -14,26 +14,26 @@ protected function setUp(): void $this->request = new HelloRequest(); } - public function testFetchReturnsGetParameter() + public function testFetchReturnsGetParameter(): void { $_GET['test'] = 'value'; $this->assertSame('value', $this->request->fetch('test')); } - public function testFetchReturnsPostParameterIfGetNotSet() + public function testFetchReturnsPostParameterIfGetNotSet(): void { unset($_GET['test']); $_POST['test'] = 'value'; $this->assertSame('value', $this->request->fetch('test')); } - public function testFetchReturnsDefaultIfNeitherGetNorPostIsSet() + public function testFetchReturnsDefaultIfNeitherGetNorPostIsSet(): void { unset($_GET['test'], $_POST['test']); $this->assertSame('default', $this->request->fetch('test', 'default')); } - public function testFetchMultipleReturnsCorrectValues() + public function testFetchMultipleReturnsCorrectValues(): void { $_GET = ['key1' => 'value1']; $_POST = ['key2' => 'value2']; @@ -47,28 +47,28 @@ public function testFetchMultipleReturnsCorrectValues() ], $result); } - public function testFetchHeaderReturnsHeaderValue() + public function testFetchHeaderReturnsHeaderValue(): void { $_SERVER['HTTP_TEST_HEADER'] = 'HeaderValue'; $this->assertSame('HeaderValue', $this->request->fetchHeader('Test-Header')); } - public function testFetchHeaderReturnsDefaultIfHeaderNotSet() + public function testFetchHeaderReturnsDefaultIfHeaderNotSet(): void { unset($_SERVER['HTTP_TEST_HEADER']); $this->assertSame('default', $this->request->fetchHeader('Test-Header', 'default')); } - public function testGetCookieReturnsCookieValue() + public function testGetCookieReturnsCookieValue(): void { $_COOKIE['test_cookie'] = 'cookie_value'; $this->assertSame('cookie_value', $this->request->getCookie('test_cookie')); } - public function testGetCookieReturnsNullIfCookieNotSet() + public function testGetCookieReturnsNullIfCookieNotSet(): void { unset($_COOKIE['test_cookie']); diff --git a/tests/HelloResponse/HelloResponseTest.php b/tests/HelloResponse/HelloResponseTest.php index b26e714..e999eab 100644 --- a/tests/HelloResponse/HelloResponseTest.php +++ b/tests/HelloResponse/HelloResponseTest.php @@ -17,7 +17,7 @@ protected function setUp(): void $this->response = new HelloResponse(); } - public function testSetHeader() + public function testSetHeader(): void { $headerMock = $this->getFunctionMock('HelloCoop\HelloResponse', 'header'); $headerMock->expects($this->once()) @@ -26,7 +26,7 @@ public function testSetHeader() $this->response->setHeader('Content-Type', 'application/json'); } - public function testSetHeaderWithArrayValue() + public function testSetHeaderWithArrayValue(): void { $headerMock = $this->getFunctionMock('HelloCoop\HelloResponse', 'header'); $headerMock->expects($this->once()) @@ -35,7 +35,7 @@ public function testSetHeaderWithArrayValue() $this->response->setHeader('X-Custom-Header', ['value1', 'value2']); } - public function testSetCookie() + public function testSetCookie(): void { $setCookieMock = $this->getFunctionMock('HelloCoop\HelloResponse', 'setcookie'); $setCookieMock->expects($this->once()) @@ -55,7 +55,7 @@ public function testSetCookie() $this->response->setCookie('test_cookie', 'test_value'); } - public function testDeleteCookie() + public function testDeleteCookie(): void { $setCookieMock = $this->getFunctionMock('HelloCoop\HelloResponse', 'setcookie'); $setCookieMock->expects($this->once()) @@ -70,7 +70,7 @@ public function testDeleteCookie() $this->response->deleteCookie('delete_cookie'); } - public function testRedirect() + public function testRedirect(): void { // Mock the header function $headerMock = $this->getFunctionMock('HelloCoop\HelloResponse', 'header'); diff --git a/tests/Lib/AuthHelperTest.php b/tests/Lib/AuthHelperTest.php index 5ee5e2f..360091a 100644 --- a/tests/Lib/AuthHelperTest.php +++ b/tests/Lib/AuthHelperTest.php @@ -12,7 +12,7 @@ class AuthHelperTest extends TestCase { private AuthHelper $authHelper; - /** @var MockObject|PKCE */ + /** @var MockObject & PKCE */ private $pkceMock; protected function setUp(): void @@ -78,18 +78,4 @@ public function testAddDefaultsToScopes(): void $result = $this->authHelper->createAuthRequest($config); $this->assertStringContainsString('openid', $result['url']); } - - private function mockStaticMethod($class, $method, $returnValue): void - { - $mock = $this->getMockBuilder($class) - ->disableOriginalConstructor() - ->onlyMethods([$method]) - ->getMock(); - - $mock->method($method)->willReturn($returnValue); - - $refClass = new \ReflectionClass($class); - $method = $refClass->getMethod('setMocked'); - $method->setAccessible(true); - } } diff --git a/tests/Lib/OIDCManagerTest.php b/tests/Lib/OIDCManagerTest.php index 7e887fb..6fe55ad 100644 --- a/tests/Lib/OIDCManagerTest.php +++ b/tests/Lib/OIDCManagerTest.php @@ -13,15 +13,15 @@ class OIDCManagerTest extends TestCase { - /** @var MockObject|HelloRequestInterface */ + /** @var MockObject & HelloRequestInterface */ private $helloRequestMock; - /** @var MockObject|HelloResponseInterface */ + /** @var MockObject & HelloResponseInterface */ private $helloResponseMock; - /** @var MockObject|Crypto */ + /** @var MockObject & Crypto */ private $cryptoMock; /** @var OIDCManager */ private OIDCManager $oidcManager; - /** @var MockObject|ConfigInterface */ + /** @var MockObject & ConfigInterface */ private $configMock; protected function setUp(): void diff --git a/tests/Lib/TokenParserTest.php b/tests/Lib/TokenParserTest.php index 695facf..a9f5866 100644 --- a/tests/Lib/TokenParserTest.php +++ b/tests/Lib/TokenParserTest.php @@ -7,14 +7,14 @@ class TokenParserTest extends TestCase { - protected $tokenParser; + protected TokenParser $tokenParser; protected function setUp(): void { // Initialize the PKCE instance here $this->tokenParser = new TokenParser(); } - public function testParseTokenSuccess() + public function testParseTokenSuccess(): void { $token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiZXhwIjoxNjU0MjA4ODAwfQ.sflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'; @@ -24,11 +24,12 @@ public function testParseTokenSuccess() $this->assertIsArray($result); $this->assertArrayHasKey('header', $result); $this->assertArrayHasKey('payload', $result); + $this->assertIsArray($result['payload']); $this->assertArrayHasKey('sub', $result['payload']); $this->assertArrayHasKey('exp', $result['payload']); } - public function testParseTokenInvalidJson() + public function testParseTokenInvalidJson(): void { $invalidToken = 'invalid.token.format'; @@ -38,7 +39,7 @@ public function testParseTokenInvalidJson() $this->tokenParser->parseToken($invalidToken); } - public function testParseTokenInvalidFormat() + public function testParseTokenInvalidFormat(): void { $invalidToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9'; diff --git a/tests/Traits/ServiceMocksTrait.php b/tests/Traits/ServiceMocksTrait.php index d13160f..ddb6584 100644 --- a/tests/Traits/ServiceMocksTrait.php +++ b/tests/Traits/ServiceMocksTrait.php @@ -12,22 +12,22 @@ trait ServiceMocksTrait { - /** @var MockObject|HelloRequestInterface */ + /** @var MockObject & HelloRequestInterface */ protected $helloRequestMock; - /** @var MockObject|HelloResponseInterface */ + /** @var MockObject & HelloResponseInterface */ protected $helloResponseMock; - /** @var MockObject|ConfigInterface */ + /** @var MockObject & ConfigInterface */ protected $configMock; /** @var Crypto */ protected Crypto $crypto; - /** @var MockObject|TokenFetcher */ + /** @var MockObject & TokenFetcher */ protected $tokenFetcherMock; - /** @var MockObject|TokenParser */ + /** @var MockObject & TokenParser */ protected $tokenParserMock; /** @@ -89,6 +89,12 @@ protected function setUpServiceMocks(): void $_SERVER['REQUEST_METHOD'] = 'GET'; } + /** + * @param object $object + * @param string $propertyName + * @param mixed $mock + * @return void + */ private function replaceLazyLoadedProperty(object $object, string $propertyName, $mock): void { $reflection = new \ReflectionClass($object); diff --git a/tests/Type/AuthTest.php b/tests/Type/AuthTest.php index 8d480d7..05bbf94 100644 --- a/tests/Type/AuthTest.php +++ b/tests/Type/AuthTest.php @@ -36,6 +36,8 @@ public function testAuthCookieProperties(): void $auth = new Auth(true, $authCookie); + $this->assertNotNull($auth->authCookie); + $this->assertNotNull($auth->authCookie->sub); $this->assertSame('user123', $auth->authCookie->sub); $this->assertSame('admin', $auth->authCookie->getExtraProperty('role')); } diff --git a/tests/Utils/QueryParamFetcherTest.php b/tests/Utils/QueryParamFetcherTest.php index c47e187..3d461d9 100644 --- a/tests/Utils/QueryParamFetcherTest.php +++ b/tests/Utils/QueryParamFetcherTest.php @@ -7,7 +7,9 @@ class QueryParamFetcherTest extends TestCase { + /** @var array $originalGet */ protected array $originalGet; + protected function setUp(): void { // Backup the original $_GET superglobal @@ -20,7 +22,7 @@ protected function tearDown(): void $_GET = $this->originalGet; } - public function testFetchWithExistingKeys() + public function testFetchWithExistingKeys(): void { $_GET = [ 'key1' => 'value1', @@ -35,7 +37,7 @@ public function testFetchWithExistingKeys() ], $result); } - public function testFetchWithNonExistentKeys() + public function testFetchWithNonExistentKeys(): void { $_GET = [ 'key1' => 'value1', @@ -49,7 +51,7 @@ public function testFetchWithNonExistentKeys() ], $result); } - public function testFetchWithMixedKeys() + public function testFetchWithMixedKeys(): void { $_GET = [ 'key1' => 'value1',