From cefcff851b70deebf93493e98f619df18d5c11cc Mon Sep 17 00:00:00 2001 From: hectorhammett Date: Thu, 6 Aug 2026 22:38:49 +0000 Subject: [PATCH 1/4] chore: monorepo preparation --- .github/CODEOWNERS | 10 ----- .github/ISSUE_TEMPLATE/bug_report.md | 36 ---------------- .github/ISSUE_TEMPLATE/feature_request.md | 21 ---------- .github/ISSUE_TEMPLATE/support_request.md | 7 ---- .github/conventional-commit-lint.yaml | 2 - .github/pull_request_template.md | 24 +++++++++++ .github/release-please.yml | 4 -- .github/release-trigger.yml | 2 - .github/workflows/lint.yml | 18 -------- .github/workflows/release.yml | 33 --------------- .github/workflows/tests.yml | 48 ---------------------- .repo-metadata.json | 7 ---- .github/CONTRIBUTING.md => CONTRIBUTING.md | 0 README.md | 6 ++- composer.json | 10 ++++- renovate.json | 6 --- 16 files changed, 38 insertions(+), 196 deletions(-) delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 .github/ISSUE_TEMPLATE/support_request.md delete mode 100644 .github/conventional-commit-lint.yaml create mode 100644 .github/pull_request_template.md delete mode 100644 .github/release-please.yml delete mode 100644 .github/release-trigger.yml delete mode 100644 .github/workflows/lint.yml delete mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/tests.yml delete mode 100644 .repo-metadata.json rename .github/CONTRIBUTING.md => CONTRIBUTING.md (100%) delete mode 100644 renovate.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index a5bc427718..0000000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,10 +0,0 @@ -# Code owners file. -# This file controls who is tagged for review for any given pull request. -# -# For syntax help see: -# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax - - -# The yoshi-php team is the default owner for anything not -# explicitly taken by someone else. -* @googleapis/cloud-sdk-php-team diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 03c1c174df..0000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve - ---- - -Thanks for stopping by to let us know something could be better! - -**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. - -Please run down the following list and make sure you've tried the usual "quick fixes": - - - Search the issues already opened: https://github.com/googleapis/google-auth-library-php/issues - - Search StackOverflow: http://stackoverflow.com/questions/tagged/google-cloud-platform+php - -If you are still having issues, please be sure to include as much information as possible: - -#### Environment details - - - OS: - - PHP version: - - Package name and version: - -#### Steps to reproduce - - 1. ... - -#### Code example - -```php -# example -``` - -Making sure to follow these steps will guarantee the quickest resolution possible. - -Thanks! diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 20d075c25b..0000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this library - ---- - -Thanks for stopping by to let us know something could be better! - -**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. - - **Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - - **Describe the solution you'd like** -A clear and concise description of what you want to happen. - - **Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - - **Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/support_request.md b/.github/ISSUE_TEMPLATE/support_request.md deleted file mode 100644 index 9958690321..0000000000 --- a/.github/ISSUE_TEMPLATE/support_request.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: Support request -about: If you have a support contract with Google, please create an issue in the Google Cloud Support console. - ---- - -**PLEASE READ**: If you have a support contract with Google, please create an issue in the [support console](https://cloud.google.com/support/) instead of filing on GitHub. This will ensure a timely response. diff --git a/.github/conventional-commit-lint.yaml b/.github/conventional-commit-lint.yaml deleted file mode 100644 index 0c96b611f7..0000000000 --- a/.github/conventional-commit-lint.yaml +++ /dev/null @@ -1,2 +0,0 @@ -always_check_pr_title: true - diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000000..9405fd1824 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,24 @@ +**PLEASE READ THIS ENTIRE MESSAGE** + +Hello, and thank you for your contribution! Please note that this repository is +a read-only split of `googleapis/google-cloud-php`. As such, we are +unable to accept pull requests to this repository. + +We welcome your pull request and would be happy to consider it for inclusion in +our library if you follow these steps: + +* Clone the parent client library repository: + +```sh +$ git clone git@github.com:googleapis/google-cloud-php.git +``` + +* Move your changes into the correct location in that library. Library code +belongs in `Auth/src`, and tests in `Auth/tests`. + +* Push the changes in a new branch to a fork, and open a new pull request +[here](https://github.com/googleapis/google-cloud-php). + +Thanks again, and we look forward to seeing your proposed change! + +The Google Cloud PHP team diff --git a/.github/release-please.yml b/.github/release-please.yml deleted file mode 100644 index 520fa5d60a..0000000000 --- a/.github/release-please.yml +++ /dev/null @@ -1,4 +0,0 @@ -releaseType: simple -handleGHRelease: true -primaryBranch: main -versionFile: VERSION diff --git a/.github/release-trigger.yml b/.github/release-trigger.yml deleted file mode 100644 index 0c81fa3148..0000000000 --- a/.github/release-trigger.yml +++ /dev/null @@ -1,2 +0,0 @@ -enabled: true -multiScmName: google-auth-library-php diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 3921698b0a..0000000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Lint -on: - push: - branches: [ main ] - pull_request: - -permissions: - contents: read -jobs: - style: - name: PHP Style Check - uses: GoogleCloudPlatform/php-tools/.github/workflows/code-standards.yml@main - - staticanalysis: - name: PHPStan Static Analysis - uses: GoogleCloudPlatform/php-tools/.github/workflows/static-analysis.yml@main - with: - autoload-file: tests/phpstan-autoload.php diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 5f35fe77ff..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Release Pre-Check -on: - pull_request: - workflow_dispatch: -permissions: - contents: read -jobs: - release-suite: - runs-on: ubuntu-latest - name: Run googleapis/google-cloud-php tests against latest version - if: github.event.pull_request.user.login == 'release-please[bot]' - steps: - - uses: actions/checkout@v7 - - name: Clone googleapis/google-cloud-php - uses: actions/checkout@master - with: - repository: googleapis/google-cloud-php - path: google-cloud-php - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: '8.2' - extensions: grpc - - name: Configure google/auth to dev-main - run: | - cd google-cloud-php - composer install -q -d dev - dev/google-cloud update-deps google/auth 'dev-main as 1.200.0' --add=dev - - name: Run google/cloud package tests - run: | - cd google-cloud-php - bash .github/run-package-tests.sh - diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index cafec3081b..0000000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,48 +0,0 @@ -name: Test Suite -on: - push: - branches: [ main ] - pull_request: - -permissions: - contents: read -jobs: - test: - strategy: - matrix: - os: [ "ubuntu-latest", "windows-latest" ] - php: [ "8.1", "8.2", "8.3", "8.4", "8.5" ] - runs-on: ${{ matrix.os }} - name: PHP ${{ matrix.php }} Unit Test${{ matrix.os == 'windows-latest' && ' on Windows' || '' }} - steps: - - uses: actions/checkout@v7 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: ${{ matrix.os == 'windows-latest' && 'gmp, php_com_dotnet' || '' }} - - name: Install Dependencies - uses: nick-invision/retry@v4 - with: - timeout_minutes: 10 - max_attempts: 3 - command: composer install - - name: Run Script - run: vendor/bin/phpunit - test_lowest: - runs-on: ubuntu-latest - name: Test Prefer Lowest - steps: - - uses: actions/checkout@v7 - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: "8.1" - - name: Install Dependencies - uses: nick-invision/retry@v4 - with: - timeout_minutes: 10 - max_attempts: 3 - command: composer update --prefer-lowest - - name: Run Script - run: vendor/bin/phpunit diff --git a/.repo-metadata.json b/.repo-metadata.json deleted file mode 100644 index 5ab504499f..0000000000 --- a/.repo-metadata.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "language": "php", - "distribution_name": "google/auth", - "release_level": "stable", - "client_documentation": "https://cloud.google.com/php/docs/reference/auth/latest", - "library_type": "CORE" -} diff --git a/.github/CONTRIBUTING.md b/CONTRIBUTING.md similarity index 100% rename from .github/CONTRIBUTING.md rename to CONTRIBUTING.md diff --git a/README.md b/README.md index a54d7210b2..6dbd64d8ba 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,10 @@ # Google Auth Library for PHP -Reference Docs +* [API documentation](https://cloud.google.com/php/docs/reference/auth/latest) + +**NOTE:** This repository is part of [Google Cloud PHP](https://github.com/googleapis/google-cloud-php). Any +support requests, bug reports, or development contributions should be directed to +that project. ## Description diff --git a/composer.json b/composer.json index 76ece53fd0..ab5c5d4936 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "type": "library", "description": "Google Auth Library for PHP", "keywords": ["google", "oauth2", "authentication"], - "homepage": "https://github.com/google/google-auth-library-php", + "homepage": "https://github.com/googleapis/google-auth-library-php", "license": "Apache-2.0", "support": { "docs": "https://cloud.google.com/php/docs/reference/auth/latest" @@ -42,5 +42,13 @@ "psr-4": { "Google\\Auth\\Tests\\": "tests" } + }, + "extra": { + "component": { + "id": "auth", + "target": "googleapis/google-auth-library-php.git", + "path": "Auth", + "entry": "README.md" + } } } diff --git a/renovate.json b/renovate.json deleted file mode 100644 index 5fcce11213..0000000000 --- a/renovate.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": [ - "config:base", - ":preserveSemverRanges" - ] -} From ce64b6ce3c27470895df3473804960ce44811457 Mon Sep 17 00:00:00 2001 From: hectorhammett Date: Mon, 10 Aug 2026 22:36:36 +0000 Subject: [PATCH 2/4] Modified the bootstrap file and moved the functions to a trait for monorepo migration --- tests/ApplicationDefaultCredentialsTest.php | 92 ++++++++++--------- .../AppIdentityCredentialsTest.php | 2 + ...alAccountAuthorizedUserCredentialsTest.php | 2 + .../ExternalAccountCredentialsTest.php | 6 +- tests/Credentials/GCECredentialsTest.php | 42 +++++---- tests/Credentials/IAMCredentialsTest.php | 2 + ...ersonatedServiceAccountCredentialsTest.php | 10 +- tests/Credentials/InsecureCredentialsTest.php | 2 + .../RegionalAccessBoundaryTraitTest.php | 18 ++-- .../ServiceAccountCredentialsTest.php | 18 ++-- ...ServiceAccountJwtAccessCredentialsTest.php | 8 +- .../UserRefreshCredentialsTest.php | 18 ++-- tests/CredentialsLoaderTest.php | 14 +-- tests/FetchAuthTokenCacheTest.php | 6 +- tests/HelperTrait.php | 41 +++++++++ tests/OAuth2Test.php | 16 ++-- tests/ObservabilityMetricsTest.php | 10 +- tests/bootstrap.php | 31 ------- 18 files changed, 196 insertions(+), 142 deletions(-) create mode 100644 tests/HelperTrait.php diff --git a/tests/ApplicationDefaultCredentialsTest.php b/tests/ApplicationDefaultCredentialsTest.php index 5158a22f34..aa3c1170c1 100644 --- a/tests/ApplicationDefaultCredentialsTest.php +++ b/tests/ApplicationDefaultCredentialsTest.php @@ -47,6 +47,8 @@ */ class ApplicationDefaultCredentialsTest extends TestCase { + use HelperTrait; + use ProphecyTrait; private $originalHome; @@ -75,7 +77,7 @@ public function testLoadsOKIfEnvSpecifiedIsValid() public function testLoadsDefaultFileIfPresentAndEnvVarIsNotSet() { - setHomeEnv(__DIR__ . '/fixtures/fixtures1'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures1'); $this->assertNotNull( ApplicationDefaultCredentials::getCredentials('a scope') ); @@ -84,11 +86,11 @@ public function testLoadsDefaultFileIfPresentAndEnvVarIsNotSet() public function testFailsIfNotOnGceAndNoDefaultFileFound() { $this->expectException(DomainException::class); + $this->skipResidencyCheck(); + $this->setHomeEnv(__DIR__ . '/not_exist_fixtures'); - skipResidencyCheck(); - setHomeEnv(__DIR__ . '/not_exist_fixtures'); // simulate not being GCE and retry attempts by returning multiple 500s - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(500), new Response(500), new Response(500) @@ -99,7 +101,7 @@ public function testFailsIfNotOnGceAndNoDefaultFileFound() public function testSuccedsIfNoDefaultFilesButIsOnGCE() { - setHomeEnv(null); + $this->setHomeEnv(null); $wantedTokens = [ 'access_token' => '1/abdef1234567890', @@ -109,7 +111,7 @@ public function testSuccedsIfNoDefaultFilesButIsOnGCE() $jsonTokens = json_encode($wantedTokens); // simulate the response from GCE. - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], Utils::streamFor($jsonTokens)), ]); @@ -122,13 +124,13 @@ public function testSuccedsIfNoDefaultFilesButIsOnGCE() public function testGceCredentials() { - setHomeEnv(null); + $this->setHomeEnv(null); $jsonTokens = json_encode(['access_token' => 'abc']); $creds = ApplicationDefaultCredentials::getCredentials( null, // $scope - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], Utils::streamFor($jsonTokens)), ]), // $httpHandler @@ -148,7 +150,7 @@ public function testGceCredentials() $creds = ApplicationDefaultCredentials::getCredentials( 'a+user+scope', // $scope - getHandler([ + $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], Utils::streamFor($jsonTokens)), ]), // $httpHandler @@ -165,7 +167,7 @@ public function testGceCredentials() public function testImpersonatedServiceAccountCredentials() { - setHomeEnv(__DIR__ . '/fixtures/fixtures5'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures5'); $creds = ApplicationDefaultCredentials::getCredentials( null, null, @@ -187,7 +189,7 @@ public function testImpersonatedServiceAccountCredentials() public function testUserRefreshCredentials() { - setHomeEnv(__DIR__ . '/fixtures/fixtures2'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures2'); $creds = ApplicationDefaultCredentials::getCredentials( null, // $scope @@ -222,7 +224,7 @@ public function testUserRefreshCredentials() public function testServiceAccountCredentials() { - setHomeEnv(__DIR__ . '/fixtures/fixtures1'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures1'); $creds = ApplicationDefaultCredentials::getCredentials( null, // $scope @@ -257,7 +259,7 @@ public function testServiceAccountCredentials() public function testDefaultScopeArray() { - setHomeEnv(__DIR__ . '/fixtures/fixtures2'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures2'); $creds = ApplicationDefaultCredentials::getCredentials( null, // $scope @@ -293,7 +295,7 @@ public function testGetMiddlewareLoadsOKIfEnvSpecifiedIsValid() public function testLGetMiddlewareoadsDefaultFileIfPresentAndEnvVarIsNotSet() { - setHomeEnv(__DIR__ . '/fixtures/fixtures1'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures1'); $this->assertNotNull(ApplicationDefaultCredentials::getMiddleware('a scope')); } @@ -301,11 +303,11 @@ public function testGetMiddlewareFailsIfNotOnGceAndNoDefaultFileFound() { $this->expectException(DomainException::class); - skipResidencyCheck(); - setHomeEnv(__DIR__ . '/not_exist_fixtures'); + $this->skipResidencyCheck(); + $this->setHomeEnv(__DIR__ . '/not_exist_fixtures'); // simulate not being GCE and retry attempts by returning multiple 500s - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(500), new Response(500), new Response(500) @@ -319,7 +321,7 @@ public function testGetMiddlewareWithCacheOptions() $keyFile = __DIR__ . '/fixtures/fixtures1/private.json'; putenv(ServiceAccountCredentials::ENV_VAR . '=' . $keyFile); - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200), ]); @@ -346,7 +348,7 @@ public function testGetMiddlewareSuccedsIfNoDefaultFilesButIsOnGCE() $jsonTokens = json_encode($wantedTokens); // simulate the response from GCE. - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], Utils::streamFor($jsonTokens)), ]); @@ -358,7 +360,7 @@ public function testOnGceCacheWithHit() { $this->expectException(DomainException::class); - setHomeEnv(__DIR__ . '/not_exist_fixtures'); + $this->setHomeEnv(__DIR__ . '/not_exist_fixtures'); $mockCacheItem = $this->prophesize('Psr\Cache\CacheItemInterface'); $mockCacheItem->isHit() @@ -382,7 +384,7 @@ public function testOnGceCacheWithHit() public function testOnGceCacheWithoutHit() { - setHomeEnv(__DIR__ . '/not_exist_fixtures'); + $this->setHomeEnv(__DIR__ . '/not_exist_fixtures'); $gceIsCalled = false; $dummyHandler = function ($request) use (&$gceIsCalled) { @@ -418,7 +420,7 @@ public function testOnGceCacheWithoutHit() public function testOnGceCacheWithOptions() { - setHomeEnv(__DIR__ . '/not_exist_fixtures'); + $this->setHomeEnv(__DIR__ . '/not_exist_fixtures'); $prefix = 'test_prefix_'; $lifetime = '70707'; @@ -475,7 +477,7 @@ public function testGetIdTokenCredentialsLoadsOKIfEnvSpecifiedIsValid() public function testGetIdTokenCredentialsLoadsDefaultFileIfPresentAndEnvVarIsNotSet() { - setHomeEnv(__DIR__ . '/fixtures/fixtures1'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures1'); $creds = ApplicationDefaultCredentials::getIdTokenCredentials($this->targetAudience); $this->assertInstanceOf(ServiceAccountCredentials::class, $creds); } @@ -485,11 +487,11 @@ public function testGetIdTokenCredentialsFailsIfNotOnGceAndNoDefaultFileFound() $this->expectException(DomainException::class); $this->expectExceptionMessage('Your default credentials were not found'); - skipResidencyCheck(); - setHomeEnv(__DIR__ . '/not_exist_fixtures'); + $this->skipResidencyCheck(); + $this->setHomeEnv(__DIR__ . '/not_exist_fixtures'); // simulate not being GCE and retry attempts by returning multiple 500s - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(500), new Response(500), new Response(500) @@ -503,7 +505,7 @@ public function testGetIdTokenCredentialsFailsIfNotOnGceAndNoDefaultFileFound() public function testGetIdTokenCredentialsWithImpersonatedServiceAccountCredentials() { - setHomeEnv(__DIR__ . '/fixtures/fixtures5'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures5'); $creds = ApplicationDefaultCredentials::getIdTokenCredentials('123@456.com'); $this->assertInstanceOf(ImpersonatedServiceAccountCredentials::class, $creds); } @@ -513,7 +515,7 @@ public function testGetIdTokenCredentialsWithCacheOptions() $keyFile = __DIR__ . '/fixtures/fixtures1/private.json'; putenv(ServiceAccountCredentials::ENV_VAR . '=' . $keyFile); - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200), ]); @@ -532,7 +534,7 @@ public function testGetIdTokenCredentialsWithCacheOptions() public function testGetIdTokenCredentialsSuccedsIfNoDefaultFilesButIsOnGCE() { - setHomeEnv(__DIR__ . '/not_exist_fixtures'); + $this->setHomeEnv(__DIR__ . '/not_exist_fixtures'); $wantedTokens = [ 'access_token' => '1/abdef1234567890', 'expires_in' => '57', @@ -541,7 +543,7 @@ public function testGetIdTokenCredentialsSuccedsIfNoDefaultFilesButIsOnGCE() $jsonTokens = json_encode($wantedTokens); // simulate the response from GCE. - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], Utils::streamFor($jsonTokens)), ]); @@ -556,7 +558,7 @@ public function testGetIdTokenCredentialsSuccedsIfNoDefaultFilesButIsOnGCE() public function testGetIdTokenCredentialsWithUserRefreshCredentials() { - setHomeEnv(__DIR__ . '/fixtures/fixtures2'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures2'); $creds = ApplicationDefaultCredentials::getIdTokenCredentials( $this->targetAudience, @@ -612,7 +614,7 @@ public function testGetCredentialsUtilizesQuotaProjectEnvVar() { $quotaProject = 'quota-project-from-env-var'; putenv(CredentialsLoader::QUOTA_PROJECT_ENV_VAR . '=' . $quotaProject); - setHomeEnv(__DIR__ . '/fixtures/fixtures1'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures1'); $credentials = ApplicationDefaultCredentials::getCredentials(); @@ -627,7 +629,7 @@ public function testGetCredentialsUtilizesQuotaProjectParameterOverEnvVar() { $quotaProject = 'quota-project-from-parameter'; putenv(CredentialsLoader::QUOTA_PROJECT_ENV_VAR . '=quota-project-from-env-var'); - setHomeEnv(__DIR__ . '/fixtures/fixtures1'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures1'); $credentials = ApplicationDefaultCredentials::getCredentials( null, // $scope @@ -665,7 +667,7 @@ public function testWithFetchAuthTokenCacheAndExplicitQuotaProject() $keyFile = __DIR__ . '/fixtures/fixtures1/private.json'; putenv(ServiceAccountCredentials::ENV_VAR . '=' . $keyFile); - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200), ]); @@ -690,7 +692,7 @@ public function testWithFetchAuthTokenCacheAndExplicitQuotaProject() public function testWithGCECredentials() { - setHomeEnv(__DIR__ . '/not_exist_fixtures'); + $this->setHomeEnv(__DIR__ . '/not_exist_fixtures'); $wantedTokens = [ 'access_token' => '1/abdef1234567890', 'expires_in' => '57', @@ -699,7 +701,7 @@ public function testWithGCECredentials() $jsonTokens = json_encode($wantedTokens); // simulate the response from GCE. - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], Utils::streamFor($jsonTokens)), ]); @@ -723,7 +725,7 @@ public function testWithGCECredentials() public function testAppEngineStandard() { $_SERVER['SERVER_SOFTWARE'] = 'Google App Engine'; - setHomeEnv(__DIR__ . '/not_exist_fixtures'); + $this->setHomeEnv(__DIR__ . '/not_exist_fixtures'); $this->assertInstanceOf( 'Google\Auth\Credentials\AppIdentityCredentials', ApplicationDefaultCredentials::getCredentials() @@ -734,8 +736,8 @@ public function testAppEngineFlexible() { $_SERVER['SERVER_SOFTWARE'] = 'Google App Engine'; putenv('GAE_INSTANCE=aef-default-20180313t154438'); - setHomeEnv(__DIR__ . '/not_exist_fixtures'); - $httpHandler = getHandler([ + $this->setHomeEnv(__DIR__ . '/not_exist_fixtures'); + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), ]); $this->assertInstanceOf( @@ -748,8 +750,8 @@ public function testAppEngineFlexibleIdToken() { $_SERVER['SERVER_SOFTWARE'] = 'Google App Engine'; putenv('GAE_INSTANCE=aef-default-20180313t154438'); - setHomeEnv(__DIR__ . '/not_exist_fixtures'); - $httpHandler = getHandler([ + $this->setHomeEnv(__DIR__ . '/not_exist_fixtures'); + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), ]); $creds = ApplicationDefaultCredentials::getIdTokenCredentials( @@ -868,12 +870,12 @@ public function testUniverseDomainInKeyFile() /** @runInSeparateProcess */ public function testUniverseDomainInGceCredentials() { - setHomeEnv(null); + $this->setHomeEnv(null); $expectedUniverseDomain = 'example-universe.com'; $creds = ApplicationDefaultCredentials::getCredentials( null, // $scope - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], Utils::streamFor($expectedUniverseDomain)), ]) // $httpHandler @@ -883,7 +885,7 @@ public function testUniverseDomainInGceCredentials() // test passing in a different universe domain overrides metadata server $creds2 = ApplicationDefaultCredentials::getCredentials( null, // $scope - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), ]), // $httpHandler null, // $cacheConfig @@ -897,7 +899,7 @@ public function testUniverseDomainInGceCredentials() // test error response returns default universe domain $creds2 = ApplicationDefaultCredentials::getCredentials( null, // $scope - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(404), ]), // $httpHandler diff --git a/tests/Credentials/AppIdentityCredentialsTest.php b/tests/Credentials/AppIdentityCredentialsTest.php index 21fdcaae7c..0811bade0f 100644 --- a/tests/Credentials/AppIdentityCredentialsTest.php +++ b/tests/Credentials/AppIdentityCredentialsTest.php @@ -17,6 +17,8 @@ namespace Google\Auth\Tests\Credentials; +use Google\Auth\Tests\HelperTrait; + use google\appengine\api\app_identity\AppIdentityService; // included from tests\mocks\AppIdentityService.php use Google\Auth\Credentials\AppIdentityCredentials; diff --git a/tests/Credentials/ExternalAccountAuthorizedUserCredentialsTest.php b/tests/Credentials/ExternalAccountAuthorizedUserCredentialsTest.php index fdba26e51a..6b69518029 100644 --- a/tests/Credentials/ExternalAccountAuthorizedUserCredentialsTest.php +++ b/tests/Credentials/ExternalAccountAuthorizedUserCredentialsTest.php @@ -18,6 +18,8 @@ namespace Google\Auth\Tests\Credentials; +use Google\Auth\Tests\HelperTrait; + use Google\Auth\Credentials\ExternalAccountAuthorizedUserCredentials; use InvalidArgumentException; use PHPUnit\Framework\TestCase; diff --git a/tests/Credentials/ExternalAccountCredentialsTest.php b/tests/Credentials/ExternalAccountCredentialsTest.php index 55a33cdf21..a176d084ab 100644 --- a/tests/Credentials/ExternalAccountCredentialsTest.php +++ b/tests/Credentials/ExternalAccountCredentialsTest.php @@ -17,6 +17,8 @@ namespace Google\Auth\Tests\Credentials; +use Google\Auth\Tests\HelperTrait; + use Google\Auth\Credentials\ExternalAccountCredentials; use Google\Auth\CredentialSource\AwsNativeSource; use Google\Auth\CredentialSource\FileSource; @@ -39,6 +41,8 @@ */ class ExternalAccountCredentialsTest extends TestCase { + use HelperTrait; + use ProphecyTrait; private $baseCreds = [ 'type' => 'external_account', @@ -651,7 +655,7 @@ public function testExecutableCredentialSourceEnvironmentVars() public function testUpdateMetadataWithRegionalAccessBoundary() { - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], '{"access_token": "source-token", "expires_in": 3600}'), new Response(200, [], '{"locations": [], "encodedLocations": "foo"}'), ]); diff --git a/tests/Credentials/GCECredentialsTest.php b/tests/Credentials/GCECredentialsTest.php index d0a74a1006..278734fef4 100644 --- a/tests/Credentials/GCECredentialsTest.php +++ b/tests/Credentials/GCECredentialsTest.php @@ -17,6 +17,8 @@ namespace Google\Auth\Tests\Credentials; +use Google\Auth\Tests\HelperTrait; + use COM; use Exception; use Google\Auth\Credentials\GCECredentials; @@ -40,11 +42,13 @@ */ class GCECredentialsTest extends BaseTest { + use HelperTrait; + use ProphecyTrait; protected function tearDown(): void { - skipResidencyCheck(false); + $this->skipResidencyCheck(false); parent::tearDown(); } @@ -82,10 +86,10 @@ public function testOnGceMetricsHeader() public function testOnGCEIsFalseOnClientErrorStatus() { - skipResidencyCheck(); + $this->skipResidencyCheck(); // simulate retry attempts by returning multiple 400s - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(400), new Response(400), new Response(400) @@ -95,10 +99,10 @@ public function testOnGCEIsFalseOnClientErrorStatus() public function testOnGCEIsFalseOnServerErrorStatus() { - skipResidencyCheck(); + $this->skipResidencyCheck(); // simulate retry attempts by returning multiple 500s - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(500), new Response(500), new Response(500) @@ -108,10 +112,10 @@ public function testOnGCEIsFalseOnServerErrorStatus() public function testOnGCEIsFalseOnNetworkError() { - skipResidencyCheck(); + $this->skipResidencyCheck(); // simulate retry attempts by returning multiple network errors - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new ConnectException('Connection refused', new Request('GET', 'test')), new ConnectException('Connection refused', new Request('GET', 'test')), new ConnectException('Connection refused', new Request('GET', 'test')), @@ -210,7 +214,7 @@ public function testOnWindowsGceWithResidency() public function testOnGCEIsFalseOnOkStatusWithoutExpectedHeader() { - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200), ]); $this->assertFalse(GCECredentials::onGCE($httpHandler)); @@ -218,7 +222,7 @@ public function testOnGCEIsFalseOnOkStatusWithoutExpectedHeader() public function testOnGCEIsOkIfGoogleIsTheFlavor() { - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), ]); $this->assertTrue(GCECredentials::onGCE($httpHandler)); @@ -247,10 +251,10 @@ public function testGetCacheKeyShouldNotBeEmpty() public function testFetchAuthTokenShouldBeEmptyIfNotOnGCE() { - skipResidencyCheck(); + $this->skipResidencyCheck(); // simulate retry attempts by returning multiple 500s - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(500), new Response(500), new Response(500) @@ -265,7 +269,7 @@ public function testFetchAuthTokenShouldFailIfResponseIsNotJson() $this->expectExceptionMessage('Invalid JSON response'); $notJson = '{"foo": , this is cannot be passed as json" "bar"}'; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], $notJson), ]); @@ -281,7 +285,7 @@ public function testFetchAuthTokenShouldReturnTokenInfo() 'token_type' => 'Bearer', ]; $jsonTokens = json_encode($wantedTokens); - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], Utils::streamFor($jsonTokens)), ]); @@ -375,7 +379,7 @@ public function testGetLastReceivedTokenIsNullByDefault() public function testGetLastReceivedTokenShouldWorkWithIdToken() { $idToken = '123asdfghjkl'; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], Utils::streamFor($idToken)), ]); @@ -391,7 +395,7 @@ public function testGetClientName() { $expected = 'foobar'; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], Utils::streamFor($expected)), new Response(200, [], Utils::streamFor('notexpected')) @@ -406,10 +410,10 @@ public function testGetClientName() public function testGetClientNameShouldBeEmptyIfNotOnGCE() { - skipResidencyCheck(); + $this->skipResidencyCheck(); // simulate retry attempts by returning multiple 500s - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(500), new Response(500), new Response(500) @@ -603,7 +607,7 @@ public function testSetIsOnGceToTrueWhenNotOnGceThrowsException() $this->expectException(ClientException::class); $this->expectExceptionMessage('408 Request Time-out'); - $httpHandler = getHandler([new Response(408)]); + $httpHandler = $this->getHandler([new Response(408)]); $creds = new GCECredentials(); $creds->setIsOnGce(true); $creds->fetchAuthToken($httpHandler); @@ -744,7 +748,7 @@ public function testGetUniverseDomainNotFoundReturnsDefault() $creds->setIsOnGce(true); // Pretend we are on GCE and mock the MDS returning a 404 for the universe domain. - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(404), ]); diff --git a/tests/Credentials/IAMCredentialsTest.php b/tests/Credentials/IAMCredentialsTest.php index ef95fd715c..8e1c5f7dc7 100644 --- a/tests/Credentials/IAMCredentialsTest.php +++ b/tests/Credentials/IAMCredentialsTest.php @@ -17,6 +17,8 @@ namespace Google\Auth\Tests\Credentials; +use Google\Auth\Tests\HelperTrait; + use Google\Auth\Credentials\IAMCredentials; use InvalidArgumentException; use PHPUnit\Framework\TestCase; diff --git a/tests/Credentials/ImpersonatedServiceAccountCredentialsTest.php b/tests/Credentials/ImpersonatedServiceAccountCredentialsTest.php index 14e5de9e1b..fd1ba4f5f4 100644 --- a/tests/Credentials/ImpersonatedServiceAccountCredentialsTest.php +++ b/tests/Credentials/ImpersonatedServiceAccountCredentialsTest.php @@ -18,6 +18,8 @@ namespace Google\Auth\Tests\Credentials; +use Google\Auth\Tests\HelperTrait; + use Google\Auth\Credentials\ExternalAccountCredentials; use Google\Auth\Credentials\ImpersonatedServiceAccountCredentials; use Google\Auth\Credentials\ServiceAccountCredentials; @@ -38,6 +40,8 @@ class ImpersonatedServiceAccountCredentialsTest extends TestCase { + use HelperTrait; + use ProphecyTrait; private const SCOPE = ['scope/1', 'scope/2']; @@ -470,7 +474,7 @@ public function testIdTokenWithAuthTokenMiddleware() $credentials = new ImpersonatedServiceAccountCredentials(null, self::USER_TO_SERVICE_ACCOUNT_JSON, $targetAudience); // this handler is for the middleware constructor, which will pass it to the ISAC to fetch tokens - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, ['Content-Type' => 'application/json'], '{"access_token":"this.is.an.access.token"}'), new Response(200, ['Content-Type' => 'application/json'], '{"token":"this.is.an.id.token"}'), ]); @@ -560,7 +564,7 @@ public function provideScopePrecedence() public function testUpdateMetadataWithRegionalAccessBoundary() { - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], '{"access_token": "source-token", "expires_in": 3600}'), new Response(200, [], '{"accessToken": "impersonated-token", "expireTime": "2026-01-01"}'), new Response(200, [], '{"locations": [], "encodedLocations": "foo"}'), @@ -588,7 +592,7 @@ public function testUpdateMetadataWithRegionalAccessBoundary() public function testUpdateMetadataWithRegionalAccessBoundarySuppressedWithUniverseDomain() { - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], '{"accessToken": "impersonated-token", "expireTime": "2026-01-01"}'), ]); diff --git a/tests/Credentials/InsecureCredentialsTest.php b/tests/Credentials/InsecureCredentialsTest.php index 62279096f9..e8b61c92b2 100644 --- a/tests/Credentials/InsecureCredentialsTest.php +++ b/tests/Credentials/InsecureCredentialsTest.php @@ -17,6 +17,8 @@ namespace Google\Auth\Tests\Credentials; +use Google\Auth\Tests\HelperTrait; + use Google\Auth\Credentials\InsecureCredentials; use PHPUnit\Framework\TestCase; diff --git a/tests/Credentials/RegionalAccessBoundaryTraitTest.php b/tests/Credentials/RegionalAccessBoundaryTraitTest.php index a42d0eb3fe..e90f747d76 100644 --- a/tests/Credentials/RegionalAccessBoundaryTraitTest.php +++ b/tests/Credentials/RegionalAccessBoundaryTraitTest.php @@ -20,6 +20,8 @@ class RegionalAccessBoundaryTraitTest extends TestCase { + use HelperTrait; + use ProphecyTrait; private RegionalAccessBoundaryTraitImpl $impl; @@ -42,7 +44,7 @@ public function testLookupRegionalAccessBoundary() { $responseBody = '{"locations": ["us-central1", "us-east1", "europe-west1", "asia-east1"], "enodedLocations": ""0xA30"}'; - $handler = getHandler([ + $handler = $this->getHandler([ new Response(200, [], $responseBody), ]); $result = $this->impl->lookupRegionalAccessBoundary($handler, 'default', ['Bearer xyz']); @@ -51,7 +53,7 @@ public function testLookupRegionalAccessBoundary() public function testLookupRegionalAccessBoundary404() { - $handler = getHandler([ + $handler = $this->getHandler([ new Response(404) ]); $result = $this->impl->lookupRegionalAccessBoundary($handler, 'default', ['Bearer xyz']); @@ -135,7 +137,7 @@ public function testRefreshRegionalAccessBoundaryWithCache() $this->impl->setCache($cache); $responseBody = '{"locations": ["us-central1", "us-east1", "europe-west1", "asia-east1"], "encodedLocations": "0xA30"}'; - $handler = getHandler([ + $handler = $this->getHandler([ new Response(200, [], $responseBody), ]); @@ -149,7 +151,7 @@ public function testRefreshRegionalAccessBoundaryWithCache() $this->assertEquals(json_decode($responseBody, true), $result1); // Second call, should return from cache - $handler = getHandler([ + $handler = $this->getHandler([ new Response(500), // This should not be called ]); $result2 = $this->impl->getRegionalAccessBoundary( @@ -189,7 +191,7 @@ public function testRefreshRegionalAccessBoundaryWithCacheAfterExpiry() // Second call, should return from HTTP call $responseBody = '{"locations": ["noncached-locations"], "encodedLocations": "0xA30"}'; - $handler = getHandler([ + $handler = $this->getHandler([ new Response(200, [], $responseBody), ]); @@ -225,7 +227,7 @@ public function testCacheLifetime() $responseBody = '{"locations": ["us-central1", "us-east1", "europe-west1", "asia-east1"], "encodedLocations": "0xA30"}'; - $handler = getHandler([ + $handler = $this->getHandler([ new Response(200, [], $responseBody) ]); // First call, should fetch and cache @@ -284,7 +286,7 @@ public function testSkipCooldownAfterExpiry() $result = $this->impl->getRegionalAccessBoundary( GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN, - getHandler([new Response(200, [], '{"encodedLocations": "0xA30"}')]), + $this->getHandler([new Response(200, [], '{"encodedLocations": "0xA30"}')]), 'default', ['authorization' => ['xyz']] ); @@ -373,7 +375,7 @@ public function provideMalformedResponseFromAllowLocationsLookup() public function testMalformedResponseFromAllowLocationsLookup(int $statusCode, string $responseBody) { $this->impl->setCache(new MemoryCacheItemPool()); - $handler = getHandler([ + $handler = $this->getHandler([ new Response($statusCode, [], $responseBody), ]); $result = $this->impl->getRegionalAccessBoundary( diff --git a/tests/Credentials/ServiceAccountCredentialsTest.php b/tests/Credentials/ServiceAccountCredentialsTest.php index 78afb51e1d..7a7ba1696e 100644 --- a/tests/Credentials/ServiceAccountCredentialsTest.php +++ b/tests/Credentials/ServiceAccountCredentialsTest.php @@ -17,6 +17,8 @@ namespace Google\Auth\Tests\Credentials; +use Google\Auth\Tests\HelperTrait; + use DomainException; use Google\Auth\ApplicationDefaultCredentials; use Google\Auth\Credentials\ServiceAccountCredentials; @@ -32,6 +34,8 @@ class ServiceAccountCredentialsTest extends TestCase { + use HelperTrait; + private function createTestJson() { return [ @@ -192,7 +196,7 @@ public function testSucceedIfFileExists() /** @runInSeparateProcess */ public function testIsNullIfFileDoesNotExist() { - setHomeEnv(__DIR__ . '/../not_exists_fixtures'); + $this->setHomeEnv(__DIR__ . '/../not_exists_fixtures'); $this->assertNull( ServiceAccountCredentials::fromWellKnownFile() ); @@ -201,7 +205,7 @@ public function testIsNullIfFileDoesNotExist() /** @runInSeparateProcess */ public function testSucceedIfFileIsPresent() { - setHomeEnv(__DIR__ . '/../fixtures/fixtures1'); + $this->setHomeEnv(__DIR__ . '/../fixtures/fixtures1'); $this->assertNotNull( ApplicationDefaultCredentials::getCredentials('a scope') ); @@ -213,7 +217,7 @@ public function testFailsOnClientErrors() $testJson = $this->createTestJson(); $scope = ['scope/1', 'scope/2']; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(400), ]); $sa = new ServiceAccountCredentials( @@ -229,7 +233,7 @@ public function testFailsOnServerErrors() $testJson = $this->createTestJson(); $scope = ['scope/1', 'scope/2']; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(500), ]); $sa = new ServiceAccountCredentials( @@ -244,7 +248,7 @@ public function testCanFetchCredsOK() $testJson = $this->createTestJson(); $testJsonText = json_encode($testJson); $scope = ['scope/1', 'scope/2']; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], Utils::streamFor($testJsonText)), ]); $sa = new ServiceAccountCredentials( @@ -261,7 +265,7 @@ public function testUpdateMetadataFunc() $scope = ['scope/1', 'scope/2']; $access_token = 'accessToken123'; $responseText = json_encode(['access_token' => $access_token]); - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], Utils::streamFor($responseText)), ]); $sa = new ServiceAccountCredentials( @@ -427,7 +431,7 @@ public function testGetQuotaProject() public function testUpdateMetadataWithRegionalAccessBoundary() { - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], '{"access_token": "source-token", "expires_in": 3600}'), new Response(200, [], '{"locations": [], "encodedLocations": "foo"}'), ]); diff --git a/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php b/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php index f3b16645aa..51f26c8c83 100644 --- a/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php +++ b/tests/Credentials/ServiceAccountJwtAccessCredentialsTest.php @@ -17,6 +17,8 @@ namespace Google\Auth\Tests\Credentials; +use Google\Auth\Tests\HelperTrait; + use Firebase\JWT\JWT; use Firebase\JWT\Key; use Google\Auth\ApplicationDefaultCredentials; @@ -31,6 +33,8 @@ class ServiceAccountJwtAccessCredentialsTest extends TestCase { + use HelperTrait; + private function createTestJson() { return [ @@ -127,7 +131,7 @@ public function testNoOpOnFetchAuthToken() ); $this->assertNotNull($sa); - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200), ]); $result = $sa->fetchAuthToken($httpHandler); // authUri has not been set @@ -555,7 +559,7 @@ public function testUpdateMetadataWithUniverseDomainAlwaysUsesJwtAccess() public function testUpdateMetadataWithRegionalAccessBoundary() { - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], '{"locations": [], "encodedLocations": "foo"}'), ]); diff --git a/tests/Credentials/UserRefreshCredentialsTest.php b/tests/Credentials/UserRefreshCredentialsTest.php index 3a360ee0ed..26dca2b39e 100644 --- a/tests/Credentials/UserRefreshCredentialsTest.php +++ b/tests/Credentials/UserRefreshCredentialsTest.php @@ -17,6 +17,8 @@ namespace Google\Auth\Tests\Credentials; +use Google\Auth\Tests\HelperTrait; + use DomainException; use Google\Auth\ApplicationDefaultCredentials; use Google\Auth\Credentials\UserRefreshCredentials; @@ -29,6 +31,8 @@ class UserRefreshCredentialsTest extends TestCase { + use HelperTrait; + private $originalHome; protected function setUp(): void @@ -40,7 +44,7 @@ protected function tearDown(): void { putenv(UserRefreshCredentials::ENV_VAR); // removes it from if ($this->originalHome != getenv('HOME')) { - setHomeEnv($this->originalHome); + $this->setHomeEnv($this->originalHome); } } @@ -179,7 +183,7 @@ public function testSucceedIfFileExists() public function testIsNullIfFileDoesNotExist() { - setHomeEnv(__DIR__ . '/../not_exist_fixtures'); + $this->setHomeEnv(__DIR__ . '/../not_exist_fixtures'); $this->assertNull( UserRefreshCredentials::fromWellKnownFile('a scope') ); @@ -187,7 +191,7 @@ public function testIsNullIfFileDoesNotExist() public function testSucceedIfFileIsPresent() { - setHomeEnv(__DIR__ . '/../fixtures/fixtures2'); + $this->setHomeEnv(__DIR__ . '/../fixtures/fixtures2'); $this->assertNotNull( ApplicationDefaultCredentials::getCredentials('a scope') ); @@ -198,7 +202,7 @@ public function testFailsOnClientErrors() $this->expectException(\GuzzleHttp\Exception\ClientException::class); $testJson = $this->createTestJson(); $scope = ['scope/1', 'scope/2']; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(400), ]); $sa = new UserRefreshCredentials( @@ -213,7 +217,7 @@ public function testFailsOnServerErrors() $this->expectException(\GuzzleHttp\Exception\ServerException::class); $testJson = $this->createTestJson(); $scope = ['scope/1', 'scope/2']; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(500), ]); $sa = new UserRefreshCredentials( @@ -228,7 +232,7 @@ public function testCanFetchCredsOK() $testJson = $this->createTestJson(); $testJsonText = json_encode($testJson); $scope = ['scope/1', 'scope/2']; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], Utils::streamFor($testJsonText)), ]); $sa = new UserRefreshCredentials( @@ -242,7 +246,7 @@ public function testCanFetchCredsOK() public function testGetGrantedScope() { $responseJson = json_encode(['scope' => 'scope/1 scope/2']); - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], Utils::streamFor($responseJson)), ]); $sa = new UserRefreshCredentials( diff --git a/tests/CredentialsLoaderTest.php b/tests/CredentialsLoaderTest.php index e9e24aff60..b6af9cfbd1 100644 --- a/tests/CredentialsLoaderTest.php +++ b/tests/CredentialsLoaderTest.php @@ -24,6 +24,8 @@ class CredentialsLoaderTest extends TestCase { + use HelperTrait; + public function testUpdateMetadataSkipsWhenAuthenticationisSet() { $creds = new TestCredentialsLoader(); @@ -35,7 +37,7 @@ public function testUpdateMetadataSkipsWhenAuthenticationisSet() /** @runInSeparateProcess */ public function testGetDefaultClientCertSource() { - setHomeEnv(__DIR__ . '/fixtures/fixtures4/valid'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures4/valid'); $callback = CredentialsLoader::getDefaultClientCertSource(); $this->assertNotNull($callback); @@ -47,7 +49,7 @@ public function testGetDefaultClientCertSource() /** @runInSeparateProcess */ public function testNonExistantDefaultClientCertSource() { - setHomeEnv(null); + $this->setHomeEnv(null); $callback = CredentialsLoader::getDefaultClientCertSource(); $this->assertNull($callback); @@ -61,7 +63,7 @@ public function testDefaultClientCertSourceInvalidJsonThrowsException() $this->expectException(UnexpectedValueException::class); $this->expectExceptionMessage('Invalid client cert source JSON'); - setHomeEnv(__DIR__ . '/fixtures/fixtures4/invalidjson'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures4/invalidjson'); CredentialsLoader::getDefaultClientCertSource(); } @@ -74,7 +76,7 @@ public function testDefaultClientCertSourceInvalidKeyThrowsException() $this->expectException(UnexpectedValueException::class); $this->expectExceptionMessage('cert source requires "cert_provider_command"'); - setHomeEnv(__DIR__ . '/fixtures/fixtures4/invalidkey'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures4/invalidkey'); CredentialsLoader::getDefaultClientCertSource(); } @@ -87,7 +89,7 @@ public function testDefaultClientCertSourceInvalidValueThrowsException() $this->expectException(UnexpectedValueException::class); $this->expectExceptionMessage('cert source expects "cert_provider_command" to be an array'); - setHomeEnv(__DIR__ . '/fixtures/fixtures4/invalidvalue'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures4/invalidvalue'); CredentialsLoader::getDefaultClientCertSource(); } @@ -115,7 +117,7 @@ public function testDefaultClientCertSourceInvalidCmdThrowsException() $this->expectException(RuntimeException::class); $this->expectExceptionMessage('"cert_provider_command" failed with a nonzero exit code'); - setHomeEnv(__DIR__ . '/fixtures/fixtures4/invalidcmd'); + $this->setHomeEnv(__DIR__ . '/fixtures/fixtures4/invalidcmd'); $callback = CredentialsLoader::getDefaultClientCertSource(); diff --git a/tests/FetchAuthTokenCacheTest.php b/tests/FetchAuthTokenCacheTest.php index caf5a8ba9a..4acc15d3c5 100644 --- a/tests/FetchAuthTokenCacheTest.php +++ b/tests/FetchAuthTokenCacheTest.php @@ -32,6 +32,8 @@ class FetchAuthTokenCacheTest extends BaseTest { + use HelperTrait; + use ProphecyTrait; private $mockFetcher; @@ -243,7 +245,7 @@ public function testUpdateMetadataWithJwtAccess() public function testUpdateMetadataWithGceCredForIdToken() { $idToken = '123asdfghjkl'; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), new Response(200, [], Utils::streamFor($idToken)), ]); @@ -282,7 +284,7 @@ public function testUpdateMetadataWithGceCredForIdToken() $this->assertEquals($metadata, $metadata2); // Ensure token for different URI is NOT cached - $metadata3 = $cachedFetcher->updateMetadata([], 'http://test-auth-uri-2', getHandler([new Response(200)])); + $metadata3 = $cachedFetcher->updateMetadata([], 'http://test-auth-uri-2', $this->getHandler([new Response(200)])); $this->assertNotEquals($metadata, $metadata3); } diff --git a/tests/HelperTrait.php b/tests/HelperTrait.php new file mode 100644 index 0000000000..5725540b17 --- /dev/null +++ b/tests/HelperTrait.php @@ -0,0 +1,41 @@ + $handler]); + + return new Guzzle7HttpHandler($client); + } + + private function setHomeEnv(?string $value): void + { + $assigment = sprintf( + "%s%s%s", + PHP_OS_FAMILY === "Windows" ? "APPDATA" : "HOME", + $value === null ? "" : "=", + (string) $value + ); + + putenv($assigment); + } + + private function skipResidencyCheck(bool $skip = true): void + { + $prop = new \ReflectionProperty( + \Google\Auth\Credentials\GCECredentials::class, + 'checkResidency' + ); + $prop->setValue(null, !$skip); + } +} diff --git a/tests/OAuth2Test.php b/tests/OAuth2Test.php index 7f28c129f7..d67938d337 100644 --- a/tests/OAuth2Test.php +++ b/tests/OAuth2Test.php @@ -32,6 +32,8 @@ class OAuth2Test extends TestCase { + use HelperTrait; + private $minimal = [ 'authorizationUri' => 'https://accounts.test.org/insecure/url', 'redirectUri' => 'https://accounts.test.org/redirect/url', @@ -895,7 +897,7 @@ public function testFailsOn400() $this->expectException(\GuzzleHttp\Exception\ClientException::class); $testConfig = $this->fetchAuthTokenMinimal; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(400), ]); $o = new OAuth2($testConfig); @@ -910,7 +912,7 @@ public function testFailsOn500() $this->expectException(\GuzzleHttp\Exception\ServerException::class); $testConfig = $this->fetchAuthTokenMinimal; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(500), ]); $o = new OAuth2($testConfig); @@ -927,7 +929,7 @@ public function testFailsOnNoContentTypeIfResponseIsNotJSON() $testConfig = $this->fetchAuthTokenMinimal; $notJson = '{"foo": , this is cannot be passed as json" "bar"}'; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], Utils::streamFor($notJson)), ]); $o = new OAuth2($testConfig); @@ -941,7 +943,7 @@ public function testFetchesJsonResponseOnNoContentTypeOK() { $testConfig = $this->fetchAuthTokenMinimal; $json = '{"foo": "bar"}'; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], Utils::streamFor($json)), ]); $o = new OAuth2($testConfig); @@ -956,7 +958,7 @@ public function testFetchesFromFormEncodedResponseOK() { $testConfig = $this->fetchAuthTokenMinimal; $json = 'foo=bar&spice=nice'; - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response( 200, ['Content-Type' => 'application/x-www-form-urlencoded'], @@ -985,7 +987,7 @@ public function testUpdatesTokenFieldsOnFetch() 'scope' => 'scope1 scope2', ]; $json = json_encode($wanted_updates); - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], Utils::streamFor($json)), ]); $o = new OAuth2($testConfig); @@ -1020,7 +1022,7 @@ public function testUpdatesTokenFieldsOnFetchMissingRefreshToken() 'id_token' => 'an_id_token', ]; $json = json_encode($wanted_updates); - $httpHandler = getHandler([ + $httpHandler = $this->getHandler([ new Response(200, [], Utils::streamFor($json)), ]); $o = new OAuth2($testConfig); diff --git a/tests/ObservabilityMetricsTest.php b/tests/ObservabilityMetricsTest.php index a9b0591022..844a2efea3 100644 --- a/tests/ObservabilityMetricsTest.php +++ b/tests/ObservabilityMetricsTest.php @@ -30,6 +30,8 @@ class ObservabilityMetricsTest extends TestCase { + use HelperTrait; + use ProphecyTrait; private static $headerKey = 'x-goog-api-client'; @@ -60,7 +62,7 @@ public function testGCECredentials($scope, $targetAudience, $requestTypeHeaderVa { $handlerCalled = false; $jsonTokens = $this->jsonTokens; - $handler = getHandler([ + $handler = $this->getHandler([ new Response(200, [GCECredentials::FLAVOR_HEADER => 'Google']), function ($request, $options) use ( $jsonTokens, @@ -122,7 +124,7 @@ public function testImpersonatedServiceAccountCredentials() $keyFile = __DIR__ . '/fixtures/fixtures5/.config/gcloud/application_default_credentials.json'; $handlerCalled = false; $responseFromIam = json_encode(['accessToken' => '1/abdef1234567890', 'expireTime' => '2024-01-01T00:00:00Z']); - $handler = getHandler([ + $handler = $this->getHandler([ $this->getExpectedRequest('imp', 'auth-request-type/at', $handlerCalled, $this->jsonTokens), $this->getExpectedRequest('imp', 'auth-request-type/at', $handlerCalled, $responseFromIam), ]); @@ -136,7 +138,7 @@ public function testImpersonatedServiceAccountCredentialsWithIdTokens() $keyFile = __DIR__ . '/fixtures/fixtures5/.config/gcloud/application_default_credentials.json'; $handlerCalled = false; $responseFromIam = json_encode(['token' => '1/abdef1234567890']); - $handler = getHandler([ + $handler = $this->getHandler([ $this->getExpectedRequest('imp', 'auth-request-type/at', $handlerCalled, $this->jsonTokens), $this->getExpectedRequest('imp', 'auth-request-type/it', $handlerCalled, $responseFromIam), ]); @@ -198,7 +200,7 @@ private function assertUpdateMetadata($cred, $handler, $credShortform, &$handler */ private function getCustomHandler($credShortform, $requestTypeHeaderValue, &$handlerCalled) { - return getHandler([ + return $this->getHandler([ $this->getExpectedRequest( $credShortform, $requestTypeHeaderValue, diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 813b21e769..5c18eee752 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -18,34 +18,3 @@ error_reporting(E_ALL); require dirname(__DIR__) . '/vendor/autoload.php'; date_default_timezone_set('UTC'); - -function getHandler(array $mockResponses = []) -{ - $mock = new \GuzzleHttp\Handler\MockHandler($mockResponses); - - $handler = \GuzzleHttp\HandlerStack::create($mock); - $client = new \GuzzleHttp\Client(['handler' => $handler]); - - return new \Google\Auth\HttpHandler\Guzzle6HttpHandler($client); -} - -function setHomeEnv(string|null $value): void -{ - $assigment = sprintf( - '%s%s%s', - PHP_OS_FAMILY === 'Windows' ? 'APPDATA' : 'HOME', - $value === null ? '' : '=', - (string) $value - ); - - putenv($assigment); -} - -function skipResidencyCheck(bool $skip = true): void -{ - $prop = new \ReflectionProperty( - \Google\Auth\Credentials\GCECredentials::class, - 'checkResidency' - ); - $prop->setValue(null, !$skip); -} From 21656417fffb877e4178c6d47e90c4e8014741d9 Mon Sep 17 00:00:00 2001 From: hectorhammett Date: Fri, 21 Aug 2026 18:17:53 +0000 Subject: [PATCH 3/4] Edit style to fit to the monorepo style rules --- phpstan.neon.dist | 2 -- src/ApplicationDefaultCredentials.php | 6 +++++- src/Cache/FileSystemCacheItemPool.php | 8 ++++++-- src/CredentialSource/AwsNativeSource.php | 4 +++- src/CredentialSource/ExecutableSource.php | 17 +++++++++++------ src/CredentialSource/FileSource.php | 4 ++-- src/CredentialSource/UrlSource.php | 4 ++-- src/Credentials/ExternalAccountCredentials.php | 3 +-- .../ImpersonatedServiceAccountCredentials.php | 3 +-- src/CredentialsLoader.php | 6 +++++- 10 files changed, 36 insertions(+), 21 deletions(-) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 95f385db43..b0b60753f2 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,5 +5,3 @@ parameters: - src featureToggles: disableRuntimeReflectionProvider: true - excludePaths: - - src/Cache/Item.php diff --git a/src/ApplicationDefaultCredentials.php b/src/ApplicationDefaultCredentials.php index daf1d744cf..fc3eca0274 100644 --- a/src/ApplicationDefaultCredentials.php +++ b/src/ApplicationDefaultCredentials.php @@ -363,7 +363,11 @@ public static function getDefaultLogger(): null|LoggerInterface // Env Var is not true if ($loggingFlag !== 'true') { if ($loggingFlag !== 'false') { - trigger_error('The ' . self::SDK_DEBUG_ENV_VAR . ' is set, but it is set to another value than false or true. Logging is disabled'); + trigger_error( + 'The ' . + self::SDK_DEBUG_ENV_VAR . + ' is set, but it is set to another value than false or true. Logging is disabled' + ); } return null; diff --git a/src/Cache/FileSystemCacheItemPool.php b/src/Cache/FileSystemCacheItemPool.php index fb8a045b2f..baf758c690 100644 --- a/src/Cache/FileSystemCacheItemPool.php +++ b/src/Cache/FileSystemCacheItemPool.php @@ -59,7 +59,9 @@ public function __construct(string $path) public function getItem(string $key): CacheItemInterface { if (!$this->validKey($key)) { - throw new InvalidArgumentException("The key '$key' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|"); + throw new InvalidArgumentException( + 'The key ' . $key . ' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|' + ); } $item = new TypedItem($key); @@ -166,7 +168,9 @@ public function clear(): bool public function deleteItem(string $key): bool { if (!$this->validKey($key)) { - throw new InvalidArgumentException("The key '$key' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|"); + throw new InvalidArgumentException( + 'The key ' . $key . ' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|' + ); } $itemPath = $this->cacheFilePath($key); diff --git a/src/CredentialSource/AwsNativeSource.php b/src/CredentialSource/AwsNativeSource.php index a22fd6bb14..1c18846afe 100644 --- a/src/CredentialSource/AwsNativeSource.php +++ b/src/CredentialSource/AwsNativeSource.php @@ -80,7 +80,9 @@ public function fetchSubjectToken(?callable $httpHandler = null): string if (!$signingVars) { if (!$this->securityCredentialsUrl) { - throw new \LogicException('Unable to get credentials from ENV, and no security credentials URL provided'); + throw new \LogicException( + 'Unable to get credentials from ENV, and no security credentials URL provided' + ); } $signingVars = self::getSigningVarsFromUrl( $httpHandler, diff --git a/src/CredentialSource/ExecutableSource.php b/src/CredentialSource/ExecutableSource.php index f6255bec99..e8f9c4ecac 100644 --- a/src/CredentialSource/ExecutableSource.php +++ b/src/CredentialSource/ExecutableSource.php @@ -167,10 +167,9 @@ public function fetchSubjectToken(?callable $httpHandler = null): string */ private function getCachedExecutableResponse(): ?array { - if ( - $this->outputFile - && file_exists($this->outputFile) - && !empty(trim($outputFileContents = (string) file_get_contents($this->outputFile))) + if ($this->outputFile && + file_exists($this->outputFile) && + !empty(trim($outputFileContents = (string) file_get_contents($this->outputFile))) ) { try { $executableResponse = $this->parseExecutableResponse($outputFileContents); @@ -219,7 +218,11 @@ private function parseExecutableResponse(string $response): array // Validate required fields for a successful response. if ($executableResponse['success']) { // Validate token type field. - $tokenTypes = [self::SAML_SUBJECT_TOKEN_TYPE, self::OIDC_SUBJECT_TOKEN_TYPE1, self::OIDC_SUBJECT_TOKEN_TYPE2]; + $tokenTypes = [ + self::SAML_SUBJECT_TOKEN_TYPE, + self::OIDC_SUBJECT_TOKEN_TYPE1, + self::OIDC_SUBJECT_TOKEN_TYPE2 + ]; if (!isset($executableResponse['token_type'])) { throw new ExecutableResponseError( 'Executable response must contain a "token_type" field when successful' @@ -263,7 +266,9 @@ private function parseExecutableResponse(string $response): array throw new ExecutableResponseError('Executable response must contain a "code" field when unsuccessful.'); } if (empty($executableResponse['message'])) { - throw new ExecutableResponseError('Executable response must contain a "message" field when unsuccessful.'); + throw new ExecutableResponseError( + 'Executable response must contain a "message" field when unsuccessful.' + ); } } diff --git a/src/CredentialSource/FileSource.php b/src/CredentialSource/FileSource.php index 2e79119b85..27c93dc075 100644 --- a/src/CredentialSource/FileSource.php +++ b/src/CredentialSource/FileSource.php @@ -33,8 +33,8 @@ class FileSource implements ExternalAccountCredentialSourceInterface /** * @param string $file The file to read the subject token from. * @param string|null $format The format of the token in the file. Can be null or "json". - * @param string|null $subjectTokenFieldName The name of the field containing the token in the file. This is required - * when format is "json". + * @param string|null $subjectTokenFieldName The name of the field containing the token in the file. + * This is required when format is "json". */ public function __construct( string $file, diff --git a/src/CredentialSource/UrlSource.php b/src/CredentialSource/UrlSource.php index d2f875ebf6..bb81d9e923 100644 --- a/src/CredentialSource/UrlSource.php +++ b/src/CredentialSource/UrlSource.php @@ -41,8 +41,8 @@ class UrlSource implements ExternalAccountCredentialSourceInterface /** * @param string $url The URL to fetch the subject token from. * @param string|null $format The format of the token in the response. Can be null or "json". - * @param string|null $subjectTokenFieldName The name of the field containing the token in the response. This is required - * when format is "json". + * @param string|null $subjectTokenFieldName The name of the field containing the token in the response. + * This is required when format is "json". * @param array|null $headers Request headers to send in with the request to the URL. */ public function __construct( diff --git a/src/Credentials/ExternalAccountCredentials.php b/src/Credentials/ExternalAccountCredentials.php index a2d1b3d8c0..7120020736 100644 --- a/src/Credentials/ExternalAccountCredentials.php +++ b/src/Credentials/ExternalAccountCredentials.php @@ -156,8 +156,7 @@ private static function buildCredentialSource(array $jsonKey): ExternalAccountCr ); } - if ( - isset($credentialSource['environment_id']) + if (isset($credentialSource['environment_id']) && 1 === preg_match('/^aws(\d+)$/', $credentialSource['environment_id'], $matches) ) { if ($matches[1] !== '1') { diff --git a/src/Credentials/ImpersonatedServiceAccountCredentials.php b/src/Credentials/ImpersonatedServiceAccountCredentials.php index ca42b99f66..a6560bf8cd 100644 --- a/src/Credentials/ImpersonatedServiceAccountCredentials.php +++ b/src/Credentials/ImpersonatedServiceAccountCredentials.php @@ -136,8 +136,7 @@ public function __construct( if (!array_key_exists('type', $jsonKey['source_credentials'])) { throw new InvalidArgumentException('json key source credentials are missing the type field'); } - if ( - $targetAudience !== null + if ($targetAudience !== null && $jsonKey['source_credentials']['type'] === 'service_account' ) { // Service account tokens MUST request a scope, and as this token is only used to impersonate diff --git a/src/CredentialsLoader.php b/src/CredentialsLoader.php index 58dcb05348..d8c2977f3f 100644 --- a/src/CredentialsLoader.php +++ b/src/CredentialsLoader.php @@ -168,7 +168,11 @@ public static function makeCredentials( if ($jsonKey['type'] == 'service_account') { // Do not pass $defaultScope to ServiceAccountCredentials - return new ServiceAccountCredentials($scope, $jsonKey, enableRegionalAccessBoundary: $enableRegionalAccessBoundary); + return new ServiceAccountCredentials( + $scope, + $jsonKey, + enableRegionalAccessBoundary: $enableRegionalAccessBoundary + ); } if ($jsonKey['type'] == 'authorized_user') { From 4ce095d6270b44e287633ee4ccaf74c6a1e7fbe5 Mon Sep 17 00:00:00 2001 From: hectorhammett Date: Fri, 21 Aug 2026 20:59:39 +0000 Subject: [PATCH 4/4] update string for thrown exception --- src/Cache/FileSystemCacheItemPool.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cache/FileSystemCacheItemPool.php b/src/Cache/FileSystemCacheItemPool.php index baf758c690..07162274ef 100644 --- a/src/Cache/FileSystemCacheItemPool.php +++ b/src/Cache/FileSystemCacheItemPool.php @@ -60,7 +60,7 @@ public function getItem(string $key): CacheItemInterface { if (!$this->validKey($key)) { throw new InvalidArgumentException( - 'The key ' . $key . ' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|' + 'The key \'' . $key . '\' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|' ); } @@ -169,7 +169,7 @@ public function deleteItem(string $key): bool { if (!$this->validKey($key)) { throw new InvalidArgumentException( - 'The key ' . $key . ' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|' + 'The key \'' . $key . '\' is not valid. The key should follow the pattern |^[a-zA-Z0-9_\.! ]+$|' ); }