From e9c808d2c1c0fd4ca17190d74da60a5704662a25 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 1 May 2023 12:20:57 -0700 Subject: [PATCH 1/6] chore: drop support for 7.3 and below --- .github/workflows/tests.yml | 13 +- composer.json | 21 ++- phpstan.neon.dist | 3 - phpunit.xml.dist | 31 ++-- src/AccessToken/Verify.php | 94 +++--------- src/AuthHandler/AuthHandlerFactory.php | 4 +- src/AuthHandler/Guzzle5AuthHandler.php | 108 ------------- src/aliases.php | 4 - tests/BaseTest.php | 95 +----------- tests/Google/AccessToken/RevokeTest.php | 81 +--------- tests/Google/AccessToken/VerifyTest.php | 32 +--- tests/Google/CacheTest.php | 1 - tests/Google/ClientTest.php | 193 +++++------------------- tests/Google/Http/RESTTest.php | 2 +- tests/Google/Service/AdSenseTest.php | 2 +- tests/Google/Service/ResourceTest.php | 94 +++--------- tests/Google/Service/TasksTest.php | 2 +- tests/Google/Service/YouTubeTest.php | 2 +- tests/Google/ServiceTest.php | 16 +- tests/Google/Task/RunnerTest.php | 29 +--- 20 files changed, 127 insertions(+), 700 deletions(-) delete mode 100644 src/AuthHandler/Guzzle5AuthHandler.php diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3e81e73b4..69e190b1d 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,12 +11,12 @@ jobs: strategy: fail-fast: false matrix: - php: [ "5.6", "7.0", "7.1", "7.2", "7.3", "7.4", "8.0", "8.1", "8.2" ] + php: [ "7.4", "8.0", "8.1", "8.2" ] composer-flags: [""] include: - - php: "5.6" + - php: "7.4" composer-flags: "--prefer-lowest " - - php: "8.0" + - php: "8.2" composer-flags: "--prefer-lowest " name: PHP ${{ matrix.php }} ${{ matrix.composer-flags }}Unit Test steps: @@ -26,14 +26,11 @@ jobs: with: php-version: ${{ matrix.php }} - name: Install Dependencies - uses: nick-invision/retry@v1 + uses: nick-invision/retry@v2 with: timeout_minutes: 10 max_attempts: 3 command: composer update ${{ matrix.composer-flags }} - - if: ${{ matrix.php == '8.0' && matrix.composer-flags == '--prefer-lowest ' }} - name: Update guzzlehttp/ringphp dependency - run: composer update guzzlehttp/ringphp - name: Run Script run: vendor/bin/phpunit @@ -47,7 +44,7 @@ jobs: with: php-version: "7.3" - name: Install Dependencies - uses: nick-invision/retry@v1 + uses: nick-invision/retry@v2 with: timeout_minutes: 10 max_attempts: 3 diff --git a/composer.json b/composer.json index 9c3b7d233..3db250b74 100644 --- a/composer.json +++ b/composer.json @@ -6,25 +6,24 @@ "homepage": "http://developers.google.com/api-client-library/php", "license": "Apache-2.0", "require": { - "php": "^5.6|^7.0|^8.0", - "google/auth": "^1.10", + "php": "^7.4|^8.0", + "google/auth": "^1.26", "google/apiclient-services": "~0.200", - "firebase/php-jwt": "~2.0||~3.0||~4.0||~5.0||~6.0", - "monolog/monolog": "^1.17||^2.0||^3.0", - "phpseclib/phpseclib": "~2.0||^3.0.2", - "guzzlehttp/guzzle": "~5.3.3||~6.0||~7.0", - "guzzlehttp/psr7": "^1.8.4||^2.2.1" + "firebase/php-jwt": "~5.0||~6.0", + "monolog/monolog": "^2.0||^3.0", + "phpseclib/phpseclib": "^3.0.2", + "guzzlehttp/guzzle": "~6.0||~7.0", + "guzzlehttp/psr7": "^2.2.1" }, "require-dev": { "squizlabs/php_codesniffer": "^3.0", "symfony/dom-crawler": "~2.1", "symfony/css-selector": "~2.1", - "cache/filesystem-adapter": "^0.3.2|^1.1", + "cache/filesystem-adapter": "^1.1", "phpcompatibility/php-compatibility": "^9.2", "composer/composer": "^1.10.22", - "yoast/phpunit-polyfills": "^1.0", - "phpspec/prophecy-phpunit": "^1.1||^2.0", - "phpunit/phpunit": "^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.0" }, "suggest": { "cache/filesystem-adapter": "For caching certs and tokens (using Google\\Client::setCache)" diff --git a/phpstan.neon.dist b/phpstan.neon.dist index a70dd0e9a..dcef11342 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -3,6 +3,3 @@ parameters: level: 5 paths: - src - excludePaths: - - src/AuthHandler/Guzzle5AuthHandler.php - diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 0063e91f1..1e07db961 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,19 +1,16 @@ - - - - tests/Google - - - tests/examples - - - - - ./src - - + + + + ./src + + + + + tests/Google + + + tests/examples + + diff --git a/src/AccessToken/Verify.php b/src/AccessToken/Verify.php index 8b46ab1c8..d957908ba 100644 --- a/src/AccessToken/Verify.php +++ b/src/AccessToken/Verify.php @@ -23,6 +23,7 @@ use Exception; use ExpiredException; use Firebase\JWT\ExpiredException as ExpiredExceptionV3; +use Firebase\JWT\JWT; use Firebase\JWT\Key; use Firebase\JWT\SignatureInvalidException; use Google\Auth\Cache\MemoryCacheItemPool; @@ -31,8 +32,9 @@ use GuzzleHttp\ClientInterface; use InvalidArgumentException; use LogicException; +use phpseclib3\Crypt\AES; use phpseclib3\Crypt\PublicKeyLoader; -use phpseclib3\Crypt\RSA\PublicKey; // Firebase v2 +use phpseclib3\Math\BigInteger; use Psr\Cache\CacheItemPoolInterface; /** @@ -219,93 +221,35 @@ private function getFederatedSignOnCerts() private function getJwtService() { - $jwtClass = 'JWT'; - if (class_exists('\Firebase\JWT\JWT')) { - $jwtClass = 'Firebase\JWT\JWT'; - } - - if (property_exists($jwtClass, 'leeway') && $jwtClass::$leeway < 1) { + $jwt = new JWT(); + if ($jwt::$leeway < 1) { // Ensures JWT leeway is at least 1 // @see https://github.com/google/google-api-php-client/issues/827 - $jwtClass::$leeway = 1; + $jwt::$leeway = 1; } - // @phpstan-ignore-next-line - return new $jwtClass(); + return $jwt; } private function getPublicKey($cert) { - $bigIntClass = $this->getBigIntClass(); - $modulus = new $bigIntClass($this->jwt->urlsafeB64Decode($cert['n']), 256); - $exponent = new $bigIntClass($this->jwt->urlsafeB64Decode($cert['e']), 256); + $modulus = new BigInteger($this->jwt->urlsafeB64Decode($cert['n']), 256); + $exponent = new BigInteger($this->jwt->urlsafeB64Decode($cert['e']), 256); $component = ['n' => $modulus, 'e' => $exponent]; - if (class_exists('phpseclib3\Crypt\RSA\PublicKey')) { - /** @var PublicKey $loader */ - $loader = PublicKeyLoader::load($component); - - return $loader->toString('PKCS8'); - } - - $rsaClass = $this->getRsaClass(); - $rsa = new $rsaClass(); - $rsa->loadKey($component); - - return $rsa->getPublicKey(); - } - - private function getRsaClass() - { - if (class_exists('phpseclib3\Crypt\RSA')) { - return 'phpseclib3\Crypt\RSA'; - } - - if (class_exists('phpseclib\Crypt\RSA')) { - return 'phpseclib\Crypt\RSA'; - } + $loader = PublicKeyLoader::load($component); - return 'Crypt_RSA'; - } - - private function getBigIntClass() - { - if (class_exists('phpseclib3\Math\BigInteger')) { - return 'phpseclib3\Math\BigInteger'; - } - - if (class_exists('phpseclib\Math\BigInteger')) { - return 'phpseclib\Math\BigInteger'; - } - - return 'Math_BigInteger'; - } - - private function getOpenSslConstant() - { - if (class_exists('phpseclib3\Crypt\AES')) { - return 'phpseclib3\Crypt\AES::ENGINE_OPENSSL'; - } - - if (class_exists('phpseclib\Crypt\RSA')) { - return 'phpseclib\Crypt\RSA::MODE_OPENSSL'; - } - - if (class_exists('Crypt_RSA')) { - return 'CRYPT_RSA_MODE_OPENSSL'; - } - - throw new Exception('Cannot find RSA class'); + return $loader->toString('PKCS8'); } /** - * phpseclib calls "phpinfo" by default, which requires special - * whitelisting in the AppEngine VM environment. This function - * sets constants to bypass the need for phpseclib to check phpinfo - * - * @see phpseclib/Math/BigInteger - * @see https://github.com/GoogleCloudPlatform/getting-started-php/issues/85 - */ + * phpseclib calls "phpinfo" by default, which requires special + * whitelisting in the AppEngine VM environment. This function + * sets constants to bypass the need for phpseclib to check phpinfo + * + * @see phpseclib/Math/BigInteger + * @see https://github.com/GoogleCloudPlatform/getting-started-php/issues/85 + */ private function setPhpsecConstants() { if (filter_var(getenv('GAE_VM'), FILTER_VALIDATE_BOOLEAN)) { @@ -313,7 +257,7 @@ private function setPhpsecConstants() define('MATH_BIGINTEGER_OPENSSL_ENABLED', true); } if (!defined('CRYPT_RSA_MODE')) { - define('CRYPT_RSA_MODE', constant($this->getOpenSslConstant())); + define('CRYPT_RSA_MODE', AES::ENGINE_OPENSSL); } } } diff --git a/src/AuthHandler/AuthHandlerFactory.php b/src/AuthHandler/AuthHandlerFactory.php index 63c266165..98a0ab166 100644 --- a/src/AuthHandler/AuthHandlerFactory.php +++ b/src/AuthHandler/AuthHandlerFactory.php @@ -25,7 +25,7 @@ class AuthHandlerFactory /** * Builds out a default http handler for the installed version of guzzle. * - * @return Guzzle5AuthHandler|Guzzle6AuthHandler|Guzzle7AuthHandler + * @return Guzzle6AuthHandler|Guzzle7AuthHandler * @throws Exception */ public static function build($cache = null, array $cacheConfig = []) @@ -38,8 +38,6 @@ public static function build($cache = null, array $cacheConfig = []) } switch ($guzzleVersion) { - case 5: - return new Guzzle5AuthHandler($cache, $cacheConfig); case 6: return new Guzzle6AuthHandler($cache, $cacheConfig); case 7: diff --git a/src/AuthHandler/Guzzle5AuthHandler.php b/src/AuthHandler/Guzzle5AuthHandler.php deleted file mode 100644 index f8a76f0aa..000000000 --- a/src/AuthHandler/Guzzle5AuthHandler.php +++ /dev/null @@ -1,108 +0,0 @@ -cache = $cache; - $this->cacheConfig = $cacheConfig; - } - - public function attachCredentials( - ClientInterface $http, - CredentialsLoader $credentials, - callable $tokenCallback = null - ) { - // use the provided cache - if ($this->cache) { - $credentials = new FetchAuthTokenCache( - $credentials, - $this->cacheConfig, - $this->cache - ); - } - - return $this->attachCredentialsCache($http, $credentials, $tokenCallback); - } - - public function attachCredentialsCache( - ClientInterface $http, - FetchAuthTokenCache $credentials, - callable $tokenCallback = null - ) { - // if we end up needing to make an HTTP request to retrieve credentials, we - // can use our existing one, but we need to throw exceptions so the error - // bubbles up. - $authHttp = $this->createAuthHttp($http); - $authHttpHandler = HttpHandlerFactory::build($authHttp); - $subscriber = new AuthTokenSubscriber( - $credentials, - $authHttpHandler, - $tokenCallback - ); - - $http->setDefaultOption('auth', 'google_auth'); - $http->getEmitter()->attach($subscriber); - - return $http; - } - - public function attachToken(ClientInterface $http, array $token, array $scopes) - { - $tokenFunc = function ($scopes) use ($token) { - return $token['access_token']; - }; - - $subscriber = new ScopedAccessTokenSubscriber( - $tokenFunc, - $scopes, - $this->cacheConfig, - $this->cache - ); - - $http->setDefaultOption('auth', 'scoped'); - $http->getEmitter()->attach($subscriber); - - return $http; - } - - public function attachKey(ClientInterface $http, $key) - { - $subscriber = new SimpleSubscriber(['key' => $key]); - - $http->setDefaultOption('auth', 'simple'); - $http->getEmitter()->attach($subscriber); - - return $http; - } - - private function createAuthHttp(ClientInterface $http) - { - return new Client([ - 'base_url' => $http->getBaseUrl(), - 'defaults' => [ - 'exceptions' => true, - 'verify' => $http->getDefaultOption('verify'), - 'proxy' => $http->getDefaultOption('proxy'), - ] - ]); - } -} diff --git a/src/aliases.php b/src/aliases.php index 4419ba7e3..3224a030f 100644 --- a/src/aliases.php +++ b/src/aliases.php @@ -15,7 +15,6 @@ 'Google\\Utils\\UriTemplate' => 'Google_Utils_UriTemplate', 'Google\\AuthHandler\\Guzzle6AuthHandler' => 'Google_AuthHandler_Guzzle6AuthHandler', 'Google\\AuthHandler\\Guzzle7AuthHandler' => 'Google_AuthHandler_Guzzle7AuthHandler', - 'Google\\AuthHandler\\Guzzle5AuthHandler' => 'Google_AuthHandler_Guzzle5AuthHandler', 'Google\\AuthHandler\\AuthHandlerFactory' => 'Google_AuthHandler_AuthHandlerFactory', 'Google\\Http\\Batch' => 'Google_Http_Batch', 'Google\\Http\\MediaFileUpload' => 'Google_Http_MediaFileUpload', @@ -52,9 +51,6 @@ class Google_AccessToken_Verify extends \Google\AccessToken\Verify class Google_AuthHandler_AuthHandlerFactory extends \Google\AuthHandler\AuthHandlerFactory { } - class Google_AuthHandler_Guzzle5AuthHandler extends \Google\AuthHandler\Guzzle5AuthHandler - { - } class Google_AuthHandler_Guzzle6AuthHandler extends \Google\AuthHandler\Guzzle6AuthHandler { } diff --git a/tests/BaseTest.php b/tests/BaseTest.php index 66df1bd4b..144c7d789 100644 --- a/tests/BaseTest.php +++ b/tests/BaseTest.php @@ -24,26 +24,16 @@ use League\Flysystem\Adapter\Local; use League\Flysystem\Filesystem; use Cache\Adapter\Filesystem\FilesystemCachePool; -use Yoast\PHPUnitPolyfills\TestCases\TestCase; - -if (trait_exists('\Prophecy\PhpUnit\ProphecyTrait')) { - trait BaseTestTrait - { - use \Prophecy\PhpUnit\ProphecyTrait; - } -} else { - trait BaseTestTrait - { - } -} +use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; class BaseTest extends TestCase { + use ProphecyTrait; + private $key; private $client; - use BaseTestTrait; - public function getClient() { if (!$this->client) { @@ -74,11 +64,6 @@ private function createClient() $options['verify'] = false; } - // adjust constructor depending on guzzle version - if ($this->isGuzzle5()) { - $options = ['defaults' => $options]; - } - $httpClient = new GuzzleClient($options); $client = new Client(); @@ -219,76 +204,4 @@ protected function loadExample($example) return false; } - - protected function isGuzzle7() - { - if (!defined('\GuzzleHttp\ClientInterface::MAJOR_VERSION')) { - return false; - } - - return (7 === ClientInterface::MAJOR_VERSION); - } - - protected function isGuzzle6() - { - if (!defined('\GuzzleHttp\ClientInterface::VERSION')) { - return false; - } - $version = ClientInterface::VERSION; - - return ('6' === $version[0]); - } - - protected function isGuzzle5() - { - if (!defined('\GuzzleHttp\ClientInterface::VERSION')) { - return false; - } - - $version = ClientInterface::VERSION; - - return ('5' === $version[0]); - } - - public function onlyGuzzle6() - { - if (!$this->isGuzzle6()) { - $this->markTestSkipped('Guzzle 6 only'); - } - } - - public function onlyPhp55AndAbove() - { - if (version_compare(PHP_VERSION, '5.5', '<')) { - $this->markTestSkipped('PHP 5.5 and above only'); - } - } - - public function onlyGuzzle5() - { - if (!$this->isGuzzle5()) { - $this->markTestSkipped('Guzzle 5 only'); - } - } - - public function onlyGuzzle6Or7() - { - if (!$this->isGuzzle6() && !$this->isGuzzle7()) { - $this->markTestSkipped('Guzzle 6 or 7 only'); - } - } - - protected function getGuzzle5ResponseMock() - { - $response = $this->prophesize('GuzzleHttp\Message\ResponseInterface'); - $response->getStatusCode() - ->willReturn(200); - - $response->getHeaders()->willReturn([]); - $response->getBody()->willReturn(''); - $response->getProtocolVersion()->willReturn(''); - $response->getReasonPhrase()->willReturn(''); - - return $response; - } } diff --git a/tests/Google/AccessToken/RevokeTest.php b/tests/Google/AccessToken/RevokeTest.php index 1db83fa41..c6dd714f7 100644 --- a/tests/Google/AccessToken/RevokeTest.php +++ b/tests/Google/AccessToken/RevokeTest.php @@ -27,87 +27,8 @@ class RevokeTest extends BaseTest { - public function testRevokeAccessGuzzle5() + public function testRevokeAccess() { - $this->onlyGuzzle5(); - - $accessToken = 'ACCESS_TOKEN'; - $refreshToken = 'REFRESH_TOKEN'; - $token = ''; - - $response = $this->prophesize('GuzzleHttp\Message\ResponseInterface'); - $response->getStatusCode() - ->shouldBeCalledTimes(3) - ->willReturn(200); - - $response->getHeaders()->willReturn([]); - $response->getBody()->willReturn(''); - $response->getProtocolVersion()->willReturn(''); - $response->getReasonPhrase()->willReturn(''); - - $http = $this->prophesize('GuzzleHttp\ClientInterface'); - $http->send(Argument::type('GuzzleHttp\Message\RequestInterface')) - ->shouldBeCalledTimes(3) - ->will(function ($args) use (&$token, $response) { - $request = $args[0]; - parse_str((string) $request->getBody(), $fields); - $token = isset($fields['token']) ? $fields['token'] : null; - - return $response->reveal(); - }); - - $requestToken = null; - $request = $this->prophesize('GuzzleHttp\Message\RequestInterface'); - $request->getBody() - ->shouldBeCalledTimes(3) - ->will(function () use (&$requestToken) { - return 'token='.$requestToken; - }); - - $http->createRequest(Argument::any(), Argument::any(), Argument::any()) - ->shouldBeCalledTimes(3) - ->will(function ($args) use (&$requestToken, $request) { - $params = $args[2]; - parse_str((string) $params['body'], $fields); - $requestToken = isset($fields['token']) ? $fields['token'] : null; - - return $request; - }); - - $t = [ - 'access_token' => $accessToken, - 'created' => time(), - 'expires_in' => '3600' - ]; - - // Test with access token. - $revoke = new Revoke($http->reveal()); - $this->assertTrue($revoke->revokeToken($t)); - $this->assertEquals($accessToken, $token); - - // Test with refresh token. - $revoke = new Revoke($http->reveal()); - $t = [ - 'access_token' => $accessToken, - 'refresh_token' => $refreshToken, - 'created' => time(), - 'expires_in' => '3600' - ]; - - $this->assertTrue($revoke->revokeToken($t)); - $this->assertEquals($refreshToken, $token); - - // Test with token string. - $revoke = new Revoke($http->reveal()); - $t = $accessToken; - $this->assertTrue($revoke->revokeToken($t)); - $this->assertEquals($accessToken, $token); - } - - public function testRevokeAccessGuzzle6Or7() - { - $this->onlyGuzzle6Or7(); - $accessToken = 'ACCESS_TOKEN'; $refreshToken = 'REFRESH_TOKEN'; $token = ''; diff --git a/tests/Google/AccessToken/VerifyTest.php b/tests/Google/AccessToken/VerifyTest.php index 25a7224b2..7d37209e4 100644 --- a/tests/Google/AccessToken/VerifyTest.php +++ b/tests/Google/AccessToken/VerifyTest.php @@ -21,9 +21,11 @@ namespace Google\Tests\AccessToken; +use Firebase\JWT\JWT; use Google\AccessToken\Verify; use Google\Tests\BaseTest; use ReflectionMethod; +use phpseclib3\Crypt\AES; class VerifyTest extends BaseTest { @@ -51,7 +53,7 @@ public function testPhpsecConstants() $openSslEnable = constant('MATH_BIGINTEGER_OPENSSL_ENABLED'); $rsaMode = constant('CRYPT_RSA_MODE'); $this->assertTrue($openSslEnable); - $this->assertEquals(constant($this->getOpenSslConstant()), $rsaMode); + $this->assertEquals(AES::ENGINE_OPENSSL, $rsaMode); } /** @@ -63,7 +65,7 @@ public function testValidateIdToken() { $this->checkToken(); - $jwt = $this->getJwtService(); + $jwt = new JWT(); $client = $this->getClient(); $http = $client->getHttpClient(); $token = $client->getAccessToken(); @@ -100,7 +102,7 @@ public function testLeewayIsUnchangedWhenPassingInJwt() { $this->checkToken(); - $jwt = $this->getJwtService(); + $jwt = new JWT(); // set arbitrary leeway so we can check this later $jwt::$leeway = $leeway = 1.5; $client = $this->getClient(); @@ -133,28 +135,4 @@ public function testRetrieveCertsFromLocation() $this->assertArrayHasKey('alg', $certs['keys'][0]); $this->assertEquals('RS256', $certs['keys'][0]['alg']); } - - private function getJwtService() - { - if (class_exists('\Firebase\JWT\JWT')) { - return new \Firebase\JWT\JWT; - } - - return new \JWT; - } - - private function getOpenSslConstant() - { - if (class_exists('phpseclib3\Crypt\AES')) { - return 'phpseclib3\Crypt\AES::ENGINE_OPENSSL'; - } - - if (class_exists('phpseclib\Crypt\RSA')) { - return 'phpseclib\Crypt\RSA::MODE_OPENSSL'; - } - - if (class_exists('Crypt_RSA')) { - return 'CRYPT_RSA_MODE_OPENSSL'; - } - } } diff --git a/tests/Google/CacheTest.php b/tests/Google/CacheTest.php index e6743a45c..153b2669c 100644 --- a/tests/Google/CacheTest.php +++ b/tests/Google/CacheTest.php @@ -50,7 +50,6 @@ public function testInMemoryCache() public function testFileCache() { - $this->onlyPhp55AndAbove(); $this->checkServiceAccountCredentials(); $client = new Client(); diff --git a/tests/Google/ClientTest.php b/tests/Google/ClientTest.php index 963ea071b..2f9367b34 100644 --- a/tests/Google/ClientTest.php +++ b/tests/Google/ClientTest.php @@ -58,50 +58,31 @@ public function testSignAppKey() private function checkAuthHandler($http, $className) { - if ($this->isGuzzle6() || $this->isGuzzle7()) { - $stack = $http->getConfig('handler'); - $class = new ReflectionClass(get_class($stack)); - $property = $class->getProperty('stack'); - $property->setAccessible(true); - $middlewares = $property->getValue($stack); - $middleware = array_pop($middlewares); - - if (null === $className) { - // only the default middlewares have been added - $this->assertCount(3, $middlewares); - } else { - $authClass = sprintf('Google\Auth\Middleware\%sMiddleware', $className); - $this->assertInstanceOf($authClass, $middleware[0]); - } + $stack = $http->getConfig('handler'); + $class = new ReflectionClass(get_class($stack)); + $property = $class->getProperty('stack'); + $property->setAccessible(true); + $middlewares = $property->getValue($stack); + $middleware = array_pop($middlewares); + + if (null === $className) { + // only the default middlewares have been added + $this->assertCount(3, $middlewares); } else { - $listeners = $http->getEmitter()->listeners('before'); - - if (null === $className) { - $this->assertCount(0, $listeners); - } else { - $authClass = sprintf('Google\Auth\Subscriber\%sSubscriber', $className); - $this->assertCount(1, $listeners); - $this->assertCount(2, $listeners[0]); - $this->assertInstanceOf($authClass, $listeners[0][0]); - } + $authClass = sprintf('Google\Auth\Middleware\%sMiddleware', $className); + $this->assertInstanceOf($authClass, $middleware[0]); } } private function checkCredentials($http, $fetcherClass, $sub = null) { - if ($this->isGuzzle6() || $this->isGuzzle7()) { - $stack = $http->getConfig('handler'); - $class = new ReflectionClass(get_class($stack)); - $property = $class->getProperty('stack'); - $property->setAccessible(true); - $middlewares = $property->getValue($stack); // Works - $middleware = array_pop($middlewares); - $auth = $middleware[0]; - } else { - // access the protected $fetcher property - $listeners = $http->getEmitter()->listeners('before'); - $auth = $listeners[0][0]; - } + $stack = $http->getConfig('handler'); + $class = new ReflectionClass(get_class($stack)); + $property = $class->getProperty('stack'); + $property->setAccessible(true); + $middlewares = $property->getValue($stack); // Works + $middleware = array_pop($middlewares); + $auth = $middleware[0]; $class = new ReflectionClass(get_class($auth)); $property = $class->getProperty('fetcher'); @@ -208,8 +189,6 @@ public function testNoAuthIsNull() public function testPrepareService() { - $this->onlyGuzzle6Or7(); - $client = new Client(); $client->setScopes(["scope1", "scope2"]); $scopes = $client->prepareScopes(); @@ -327,55 +306,9 @@ public function testSetAccessTokenValidation() public function testDefaultConfigOptions() { $client = new Client(); - if ($this->isGuzzle6() || $this->isGuzzle7()) { - $this->assertArrayHasKey('http_errors', $client->getHttpClient()->getConfig()); - $this->assertArrayNotHasKey('exceptions', $client->getHttpClient()->getConfig()); - $this->assertFalse($client->getHttpClient()->getConfig()['http_errors']); - } - if ($this->isGuzzle5()) { - $this->assertArrayHasKey('exceptions', $client->getHttpClient()->getDefaultOption()); - $this->assertArrayNotHasKey('http_errors', $client->getHttpClient()->getDefaultOption()); - $this->assertFalse($client->getHttpClient()->getDefaultOption()['exceptions']); - } - } - - public function testAppEngineStreamHandlerConfig() - { - $this->onlyGuzzle5(); - - $_SERVER['SERVER_SOFTWARE'] = 'Google App Engine'; - $client = new Client(); - - // check Stream Handler is used - $http = $client->getHttpClient(); - $class = new ReflectionClass(get_class($http)); - $property = $class->getProperty('fsm'); - $property->setAccessible(true); - $fsm = $property->getValue($http); - - $class = new ReflectionClass(get_class($fsm)); - $property = $class->getProperty('handler'); - $property->setAccessible(true); - $handler = $property->getValue($fsm); - - $this->assertInstanceOf('GuzzleHttp\Ring\Client\StreamHandler', $handler); - - unset($_SERVER['SERVER_SOFTWARE']); - } - - public function testAppEngineVerifyConfig() - { - $this->onlyGuzzle5(); - - $_SERVER['SERVER_SOFTWARE'] = 'Google App Engine'; - $client = new Client(); - - $this->assertEquals( - '/etc/ca-certificates.crt', - $client->getHttpClient()->getDefaultOption('verify') - ); - - unset($_SERVER['SERVER_SOFTWARE']); + $this->assertArrayHasKey('http_errors', $client->getHttpClient()->getConfig()); + $this->assertArrayNotHasKey('exceptions', $client->getHttpClient()->getConfig()); + $this->assertFalse($client->getHttpClient()->getConfig()['http_errors']); } public function testJsonConfig() @@ -486,14 +419,7 @@ public function testRefreshTokenSetsValues() ->shouldBeCalledTimes(1) ->willReturn($token); - if ($this->isGuzzle5()) { - $response = $this->getGuzzle5ResponseMock(); - $response->getStatusCode() - ->shouldBeCalledTimes(1) - ->willReturn(200); - } else { - $response = $this->prophesize('Psr\Http\Message\ResponseInterface'); - } + $response = $this->prophesize('Psr\Http\Message\ResponseInterface'); $response->getBody() ->shouldBeCalledTimes(1) @@ -503,20 +429,9 @@ public function testRefreshTokenSetsValues() $http = $this->prophesize('GuzzleHttp\ClientInterface'); - if ($this->isGuzzle5()) { - $guzzle5Request = new \GuzzleHttp\Message\Request('POST', '/', ['body' => $token]); - $http->createRequest(Argument::any(), Argument::any(), Argument::any()) - ->shouldBeCalledTimes(1) - ->willReturn($guzzle5Request); - - $http->send(Argument::type('GuzzleHttp\Message\Request')) - ->shouldBeCalledTimes(1) - ->willReturn($response->reveal()); - } else { - $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) - ->shouldBeCalledTimes(1) - ->willReturn($response->reveal()); - } + $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) + ->shouldBeCalledTimes(1) + ->willReturn($response->reveal()); $client = $this->getClient(); $client->setHttpClient($http->reveal()); @@ -540,14 +455,7 @@ public function testRefreshTokenIsSetOnRefresh() ->shouldBeCalledTimes(1) ->willReturn($token); - if ($this->isGuzzle5()) { - $response = $this->getGuzzle5ResponseMock(); - $response->getStatusCode() - ->shouldBeCalledTimes(1) - ->willReturn(200); - } else { - $response = $this->prophesize('Psr\Http\Message\ResponseInterface'); - } + $response = $this->prophesize('Psr\Http\Message\ResponseInterface'); $response->getBody() ->shouldBeCalledTimes(1) @@ -557,19 +465,9 @@ public function testRefreshTokenIsSetOnRefresh() $http = $this->prophesize('GuzzleHttp\ClientInterface'); - if ($this->isGuzzle5()) { - $guzzle5Request = new \GuzzleHttp\Message\Request('POST', '/', ['body' => $token]); - $http->createRequest(Argument::any(), Argument::any(), Argument::any()) - ->willReturn($guzzle5Request); - - $http->send(Argument::type('GuzzleHttp\Message\Request')) - ->shouldBeCalledTimes(1) - ->willReturn($response->reveal()); - } else { - $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) - ->shouldBeCalledTimes(1) - ->willReturn($response->reveal()); - } + $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) + ->shouldBeCalledTimes(1) + ->willReturn($response->reveal()); $client = $this->getClient(); $client->setHttpClient($http->reveal()); @@ -594,13 +492,7 @@ public function testRefreshTokenIsNotSetWhenNewRefreshTokenIsReturned() $postBody->__toString() ->wilLReturn($token); - if ($this->isGuzzle5()) { - $response = $this->getGuzzle5ResponseMock(); - $response->getStatusCode() - ->willReturn(200); - } else { - $response = $this->prophesize('Psr\Http\Message\ResponseInterface'); - } + $response = $this->prophesize('Psr\Http\Message\ResponseInterface'); $response->getBody() ->willReturn($postBody->reveal()); @@ -609,18 +501,9 @@ public function testRefreshTokenIsNotSetWhenNewRefreshTokenIsReturned() $http = $this->prophesize('GuzzleHttp\ClientInterface'); - if ($this->isGuzzle5()) { - $guzzle5Request = new \GuzzleHttp\Message\Request('POST', '/', ['body' => $token]); - $http->createRequest(Argument::any(), Argument::any(), Argument::any()) - ->willReturn($guzzle5Request); - - $http->send(Argument::type('GuzzleHttp\Message\Request')) - ->willReturn($response->reveal()); - } else { - $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) - ->shouldBeCalledTimes(1) - ->willReturn($response->reveal()); - } + $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) + ->shouldBeCalledTimes(1) + ->willReturn($response->reveal()); $client = $this->getClient(); $client->setHttpClient($http->reveal()); @@ -707,7 +590,6 @@ public function testBadSubjectThrowsException() public function testTokenCallback() { - $this->onlyPhp55AndAbove(); $this->checkToken(); $client = $this->getClient(); @@ -758,7 +640,6 @@ public function testTokenCallback() public function testDefaultTokenCallback() { - $this->onlyPhp55AndAbove(); $this->checkToken(); $client = $this->getClient(); @@ -857,8 +738,6 @@ public function testCacheClientOption() public function testExecuteWithFormat() { - $this->onlyGuzzle6Or7(); - $client = new Client([ 'api_format_v2' => true ]); @@ -882,8 +761,6 @@ public function testExecuteWithFormat() public function testExecuteSetsCorrectHeaders() { - $this->onlyGuzzle6Or7(); - $client = new Client(); $guzzle = $this->prophesize('GuzzleHttp\Client'); @@ -968,8 +845,6 @@ public function testClientOptions() public function testCredentialsOptionWithCredentialsLoader() { - $this->onlyGuzzle6Or7(); - $request = null; $credentials = $this->prophesize('Google\Auth\CredentialsLoader'); $credentials->getCacheKey() diff --git a/tests/Google/Http/RESTTest.php b/tests/Google/Http/RESTTest.php index 2c73dceb6..ef44ed0a2 100644 --- a/tests/Google/Http/RESTTest.php +++ b/tests/Google/Http/RESTTest.php @@ -32,7 +32,7 @@ class RESTTest extends BaseTest */ private $rest; - public function set_up() + public function setUp(): void { $this->rest = new REST(); $this->request = new Request('GET', '/'); diff --git a/tests/Google/Service/AdSenseTest.php b/tests/Google/Service/AdSenseTest.php index 453908ced..234075aea 100644 --- a/tests/Google/Service/AdSenseTest.php +++ b/tests/Google/Service/AdSenseTest.php @@ -23,7 +23,7 @@ class AdSenseTest extends BaseTest { public $adsense; - public function set_up() + public function setUp(): void { $this->markTestSkipped('Thesse tests need to be fixed'); $this->checkToken(); diff --git a/tests/Google/Service/ResourceTest.php b/tests/Google/Service/ResourceTest.php index c2c814d4e..17000880a 100644 --- a/tests/Google/Service/ResourceTest.php +++ b/tests/Google/Service/ResourceTest.php @@ -26,13 +26,11 @@ use Google\Service\Exception as ServiceException; use Google\Service\Resource as GoogleResource; use Google\Exception as GoogleException; -use GuzzleHttp\Message\Response as Guzzle5Response; use GuzzleHttp\Psr7; use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\Stream; -use GuzzleHttp\Stream\Stream as Guzzle5Stream; use Prophecy\Argument; class TestService extends \Google\Service @@ -52,7 +50,7 @@ class ResourceTest extends BaseTest private $client; private $service; - public function set_up() + public function setUp(): void { $this->client = $this->prophesize(Client::class); @@ -231,24 +229,12 @@ public function testNoExpectedClassForAltMediaWithHttpSuccess() $http = $this->prophesize("GuzzleHttp\Client"); - if ($this->isGuzzle5()) { - $body = Guzzle5Stream::factory('thisisnotvalidjson'); - $response = new Guzzle5Response(200, [], $body); + $body = Psr7\Utils::streamFor('thisisnotvalidjson'); + $response = new Response(200, [], $body); - $http->createRequest(Argument::any(), Argument::any(), Argument::any()) - ->willReturn(new \GuzzleHttp\Message\Request('GET', '/?alt=media')); - - $http->send(Argument::type('GuzzleHttp\Message\Request')) - ->shouldBeCalledTimes(1) - ->willReturn($response); - } else { - $body = Psr7\Utils::streamFor('thisisnotvalidjson'); - $response = new Response(200, [], $body); - - $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) - ->shouldBeCalledTimes(1) - ->willReturn($response); - } + $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) + ->shouldBeCalledTimes(1) + ->willReturn($response); $client = new Client(); $client->setHttpClient($http->reveal()); @@ -284,24 +270,12 @@ public function testNoExpectedClassForAltMediaWithHttpFail() $http = $this->prophesize("GuzzleHttp\Client"); - if ($this->isGuzzle5()) { - $body = Guzzle5Stream::factory('thisisnotvalidjson'); - $response = new Guzzle5Response(400, [], $body); - - $http->createRequest(Argument::any(), Argument::any(), Argument::any()) - ->willReturn(new \GuzzleHttp\Message\Request('GET', '/?alt=media')); + $body = Psr7\Utils::streamFor('thisisnotvalidjson'); + $response = new Response(400, [], $body); - $http->send(Argument::type('GuzzleHttp\Message\Request')) - ->shouldBeCalledTimes(1) - ->willReturn($response); - } else { - $body = Psr7\Utils::streamFor('thisisnotvalidjson'); - $response = new Response(400, [], $body); - - $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) - ->shouldBeCalledTimes(1) - ->willReturn($response); - } + $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) + ->shouldBeCalledTimes(1) + ->willReturn($response); $client = new Client(); $client->setHttpClient($http->reveal()); @@ -341,24 +315,12 @@ public function testErrorResponseWithVeryLongBody() $http = $this->prophesize("GuzzleHttp\Client"); - if ($this->isGuzzle5()) { - $body = Guzzle5Stream::factory('this will be pulled into memory'); - $response = new Guzzle5Response(400, [], $body); - - $http->createRequest(Argument::any(), Argument::any(), Argument::any()) - ->willReturn(new \GuzzleHttp\Message\Request('GET', '/?alt=media')); + $body = Psr7\Utils::streamFor('this will be pulled into memory'); + $response = new Response(400, [], $body); - $http->send(Argument::type('GuzzleHttp\Message\Request')) - ->shouldBeCalledTimes(1) - ->willReturn($response); - } else { - $body = Psr7\Utils::streamFor('this will be pulled into memory'); - $response = new Response(400, [], $body); - - $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) - ->shouldBeCalledTimes(1) - ->willReturn($response); - } + $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) + ->shouldBeCalledTimes(1) + ->willReturn($response); $client = new Client(); $client->setHttpClient($http->reveal()); @@ -392,8 +354,6 @@ public function testErrorResponseWithVeryLongBody() public function testSuccessResponseWithVeryLongBody() { - $this->onlyGuzzle6Or7(); - // set the "alt" parameter to "media" $arguments = [['alt' => 'media']]; $stream = $this->prophesize(Stream::class); @@ -446,24 +406,12 @@ public function testExceptionMessage() $http = $this->prophesize("GuzzleHttp\Client"); - if ($this->isGuzzle5()) { - $body = Guzzle5Stream::factory($content); - $response = new Guzzle5Response(400, [], $body); + $body = Psr7\Utils::streamFor($content); + $response = new Response(400, [], $body); - $http->createRequest(Argument::any(), Argument::any(), Argument::any()) - ->willReturn(new \GuzzleHttp\Message\Request('GET', '/?alt=media')); - - $http->send(Argument::type('GuzzleHttp\Message\Request')) - ->shouldBeCalledTimes(1) - ->willReturn($response); - } else { - $body = Psr7\Utils::streamFor($content); - $response = new Response(400, [], $body); - - $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) - ->shouldBeCalledTimes(1) - ->willReturn($response); - } + $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) + ->shouldBeCalledTimes(1) + ->willReturn($response); $client = new Client(); $client->setHttpClient($http->reveal()); diff --git a/tests/Google/Service/TasksTest.php b/tests/Google/Service/TasksTest.php index 341b0e7ff..7e035fd57 100644 --- a/tests/Google/Service/TasksTest.php +++ b/tests/Google/Service/TasksTest.php @@ -25,7 +25,7 @@ class TasksTest extends BaseTest /** @var Tasks */ public $taskService; - public function set_up() + public function setUp(): void { $this->checkToken(); $this->taskService = new Tasks($this->getClient()); diff --git a/tests/Google/Service/YouTubeTest.php b/tests/Google/Service/YouTubeTest.php index c6e4032ee..2b08035f1 100644 --- a/tests/Google/Service/YouTubeTest.php +++ b/tests/Google/Service/YouTubeTest.php @@ -24,7 +24,7 @@ class YouTubeTest extends BaseTest { /** @var YouTube */ public $youtube; - public function set_up() + public function setUp(): void { $this->checkToken(); $this->youtube = new YouTube($this->getClient()); diff --git a/tests/Google/ServiceTest.php b/tests/Google/ServiceTest.php index 75d49bfbe..903a880a8 100644 --- a/tests/Google/ServiceTest.php +++ b/tests/Google/ServiceTest.php @@ -24,10 +24,11 @@ use Google\Model; use Google\Service; use Google\Http\Batch; -use Yoast\PHPUnitPolyfills\TestCases\TestCase; +use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; +use Prophecy\PhpUnit\ProphecyTrait; class TestModel extends Model { @@ -47,22 +48,11 @@ class TestService extends Service public $batchPath = 'batch/test'; } -if (trait_exists('\Prophecy\PhpUnit\ProphecyTrait')) { - trait ServiceTestTrait - { - use \Prophecy\PhpUnit\ProphecyTrait; - } -} else { - trait ServiceTestTrait - { - } -} - class ServiceTest extends TestCase { private static $errorMessage; - use ServiceTestTrait; + use ProphecyTrait; public function testCreateBatch() { diff --git a/tests/Google/Task/RunnerTest.php b/tests/Google/Task/RunnerTest.php index ce868158d..650ef5c75 100644 --- a/tests/Google/Task/RunnerTest.php +++ b/tests/Google/Task/RunnerTest.php @@ -24,11 +24,9 @@ use Google\Http\REST; use Google\Service\Exception as ServiceException; use Google\Task\Exception as TaskException; -use GuzzleHttp\Message\Response as Guzzle5Response; use GuzzleHttp\Psr7; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; -use GuzzleHttp\Stream\Stream as Guzzle5Stream; use Prophecy\Argument; use Exception; @@ -42,7 +40,7 @@ class RunnerTest extends BaseTest private $retryMap; private $retryConfig; - protected function set_up() + public function setUp(): void { $this->client = new Client(); } @@ -648,19 +646,9 @@ private function makeRequest() $request = new Request('GET', '/test'); $http = $this->prophesize('GuzzleHttp\ClientInterface'); - if ($this->isGuzzle5()) { - $http->createRequest(Argument::any(), Argument::any(), Argument::any()) - ->shouldBeCalledTimes($this->mockedCallsCount) - ->willReturn(new \GuzzleHttp\Message\Request('GET', '/test')); - - $http->send(Argument::type('GuzzleHttp\Message\Request')) - ->shouldBeCalledTimes($this->mockedCallsCount) - ->will([$this, 'getNextMockedCall']); - } else { - $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) - ->shouldBeCalledTimes($this->mockedCallsCount) - ->will([$this, 'getNextMockedCall']); - } + $http->send(Argument::type('Psr\Http\Message\RequestInterface'), []) + ->shouldBeCalledTimes($this->mockedCallsCount) + ->will([$this, 'getNextMockedCall']); return REST::execute($http->reveal(), $request, '', $this->retryConfig, $this->retryMap); } @@ -680,13 +668,8 @@ public function getNextMockedCall($request) throw $current; } - if ($this->isGuzzle5()) { - $stream = Guzzle5Stream::factory($current['body']); - $response = new Guzzle5Response($current['code'], $current['headers'], $stream); - } else { - $stream = Psr7\Utils::streamFor($current['body']); - $response = new Response($current['code'], $current['headers'], $stream); - } + $stream = Psr7\Utils::streamFor($current['body']); + $response = new Response($current['code'], $current['headers'], $stream); return $response; } From 4441620229ffe4d82a3d04d5f41dbd1546f87fbc Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 1 May 2023 12:23:42 -0700 Subject: [PATCH 2/6] update workflows with new PHP min --- .github/workflows/asset-release.yml | 2 +- .github/workflows/docs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/asset-release.yml b/.github/workflows/asset-release.yml index 6f86fdecf..59d5cdd56 100644 --- a/.github/workflows/asset-release.yml +++ b/.github/workflows/asset-release.yml @@ -10,7 +10,7 @@ jobs: strategy: matrix: operating-system: [ ubuntu-latest ] - php: [ "5.6", "7.0", "7.4", "8.0" ] + php: [ "7.4", "8.0", "8.2" ] name: Upload Release Assets steps: diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0c6125ad8..02d757bc1 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -18,7 +18,7 @@ jobs: max_attempts: 3 command: composer install - name: Generate and Push Documentation - uses: docker://php:7.3-cli + uses: docker://php:7.4-cli env: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} with: From de02e44e78b764125f3fdf22fa5c4c5e00dce147 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 1 May 2023 12:34:47 -0700 Subject: [PATCH 3/6] remove support for firebase/jwt 5.0 --- composer.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 3db250b74..70ca62945 100644 --- a/composer.json +++ b/composer.json @@ -9,11 +9,11 @@ "php": "^7.4|^8.0", "google/auth": "^1.26", "google/apiclient-services": "~0.200", - "firebase/php-jwt": "~5.0||~6.0", - "monolog/monolog": "^2.0||^3.0", + "firebase/php-jwt": "~6.0", + "monolog/monolog": "^2.9||^3.0", "phpseclib/phpseclib": "^3.0.2", - "guzzlehttp/guzzle": "~6.0||~7.0", - "guzzlehttp/psr7": "^2.2.1" + "guzzlehttp/guzzle": "~6.5||~7.0", + "guzzlehttp/psr7": "^1.8.4||^2.2.1" }, "require-dev": { "squizlabs/php_codesniffer": "^3.0", @@ -23,7 +23,7 @@ "phpcompatibility/php-compatibility": "^9.2", "composer/composer": "^1.10.22", "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^9.5" }, "suggest": { "cache/filesystem-adapter": "For caching certs and tokens (using Google\\Client::setCache)" From da07faa6b8986b79a6599c4ad05018f6f5c02ad8 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 1 May 2023 12:36:21 -0700 Subject: [PATCH 4/6] update sync repo settings --- .github/sync-repo-settings.yaml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index 6e411b4c9..1fa17b12f 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -5,15 +5,12 @@ branchProtectionRules: - pattern: master isAdminEnforced: true requiredStatusCheckContexts: - - 'PHP 5.6 Unit Test' - - 'PHP 5.6 --prefer-lowest Unit Test' - - 'PHP 7.0 Unit Test' - - 'PHP 7.1 Unit Test' - - 'PHP 7.2 Unit Test' - - 'PHP 7.3 Unit Test' - 'PHP 7.4 Unit Test' + - 'PHP 7.4 --prefer-lowest Unit Test' - 'PHP 8.0 Unit Test' - - 'PHP 8.0 --prefer-lowest Unit Test' + - 'PHP 8.1 Unit Test' + - 'PHP 8.2 Unit Test' + - 'PHP 8.2 --prefer-lowest Unit Test' - 'PHP Style Check' - 'cla/google' requiredApprovingReviewCount: 1 From 9fe72a5a87e615ea3501b3ed681e65059bf755a0 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Mon, 1 May 2023 12:39:14 -0700 Subject: [PATCH 5/6] update cs test php version --- .github/workflows/tests.yml | 2 +- src/Collection.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 69e190b1d..df9f1565a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -42,7 +42,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: "7.3" + php-version: "7.4" - name: Install Dependencies uses: nick-invision/retry@v2 with: diff --git a/src/Collection.php b/src/Collection.php index c164c12a2..fe2c62fec 100644 --- a/src/Collection.php +++ b/src/Collection.php @@ -81,6 +81,7 @@ public function offsetExists($offset) } /** @return mixed */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { if (!is_numeric($offset)) { From b735d18224e67e0c974b08764277bf3005650099 Mon Sep 17 00:00:00 2001 From: Brent Shaffer Date: Thu, 11 May 2023 11:56:18 -0700 Subject: [PATCH 6/6] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e623c0c7..9306b3dd8 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ For Google Cloud Platform APIs such as [Datastore][cloud-datastore], [Cloud Stor [cloud-compute]: https://github.com/googleapis/google-cloud-php-compute ## Requirements ## -* [PHP 5.6.0 or higher](https://www.php.net/) +* [PHP 7.4 or higher](https://www.php.net/) ## Developer Documentation ##