diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index c92f2e0..0273c68 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -10,15 +10,13 @@ permissions: contents: read jobs: - build: + validateComposer: runs-on: ubuntu-latest strategy: matrix: - operating-system: [ 'ubuntu-latest' ] - php-versions: [ '7.4', '8.0', '8.1', '8.2', '8.3', 'nightly' ] - phpunit-versions: [ 'latest' ] + php-versions: [ '7.4', '8.0', '8.1', '8.2', '8.3' ] steps: - uses: actions/checkout@v3 @@ -30,11 +28,29 @@ jobs: extensions: mbstring, intl ini-values: post_max_size=256M, max_execution_time=180 coverage: xdebug - tools: phpcs, phpunit:${{ matrix.phpunit-versions }} - name: Validate composer.json and composer.lock run: composer validate --strict + checkStyle: + + runs-on: ubuntu-latest + + strategy: + matrix: + php-versions: [ '7.4' ] + + steps: + - uses: actions/checkout@v3 + + - name: Setup PHP with PECL extension + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, intl + ini-values: post_max_size=256M, max_execution_time=180 + coverage: xdebug + - name: Cache Composer packages id: composer-cache uses: actions/cache@v3 @@ -48,7 +64,39 @@ jobs: run: composer install --prefer-dist --no-progress - name: Run PHP Code Sniffer - run: composer run-script codeStyle + run: composer run-script style + + runTests: + + runs-on: ubuntu-latest + + strategy: + matrix: + php-versions: [ '7.4', '8.0', '8.1', '8.2', '8.3' ] + + steps: + - uses: actions/checkout@v3 + + - name: Setup PHP with PECL extension + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + extensions: mbstring, intl + ini-values: post_max_size=256M, max_execution_time=180 + coverage: xdebug + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v3 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Install dependencies + run: composer install --prefer-dist --no-progress - name: Run test suite run: composer run-script test + diff --git a/.gitignore b/.gitignore index d1a1709..c9d01b6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ vendor # No composer.lock for libraries composer.lock + +# No test and cache files +.php-cs-fixer.cache diff --git a/composer.json b/composer.json index 7749f33..d9adfa1 100644 --- a/composer.json +++ b/composer.json @@ -4,16 +4,15 @@ "type": "library", "license": "GPL-3.0-or-later", "require": { - "php": "^7.3 || ^7.4 || ^8.0 || ^8.1 || ^8.2 || ^8.3", + "php": "^7.3 || ^8.0", "league/oauth2-client": "^2.6", "guzzlehttp/psr7": "^2.4", "psr/http-message": "^1.0 || ^2.0" }, "require-dev": { "roave/security-advisories": "dev-latest", - "mockery/mockery": "^1.3.5", "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "^3.0" + "friendsofphp/php-cs-fixer": "^3.64" }, "autoload": { "psr-4": { @@ -27,6 +26,6 @@ }, "scripts": { "test": "@php vendor/bin/phpunit", - "codeStyle": "@php vendor/bin/phpcs" + "style": "@php vendor/bin/php-cs-fixer fix src/ --rules=@PER-CS" } } diff --git a/phpcs.xml b/phpcs.xml deleted file mode 100644 index 9cbdf6b..0000000 --- a/phpcs.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - ./src - ./tests - - - - - - - diff --git a/src/Provider/Azure.php b/src/Provider/Azure.php index ef17112..1eb196f 100644 --- a/src/Provider/Azure.php +++ b/src/Provider/Azure.php @@ -20,7 +20,7 @@ class Azure extends AbstractProvider */ public $defaultScopes = [ 'https://outlook.office.com/SMTP.Send', - 'offline_access' + 'offline_access', ]; /** @@ -106,7 +106,7 @@ protected function checkResponse(ResponseInterface $response, $data) throw new IdentityProviderException( (isset($data['error_description']) ? $data['error_description'] : $response->getReasonPhrase()), $response->getStatusCode(), - (string)$response->getBody() + (string) $response->getBody(), ); } } @@ -134,7 +134,7 @@ public function getResourceOwnerDetailsUrl(AccessToken $token) { $uri = new Uri($this->urlResourceOwnerDetails); - return (string)Uri::withQueryValue($uri, 'access_token', (string)$token); + return (string) Uri::withQueryValue($uri, 'access_token', (string) $token); } protected function getScopeSeparator() diff --git a/src/Provider/AzureResourceOwner.php b/src/Provider/AzureResourceOwner.php index 6a4fe5f..90a71e9 100644 --- a/src/Provider/AzureResourceOwner.php +++ b/src/Provider/AzureResourceOwner.php @@ -18,7 +18,7 @@ class AzureResourceOwner implements ResourceOwnerInterface * * @param array $response */ - public function __construct(array $response = array()) + public function __construct(array $response = []) { $this->response = $response; } diff --git a/tests/src/Provider/AzureTest.php b/tests/src/Provider/AzureTest.php index 60f342e..8befa60 100644 --- a/tests/src/Provider/AzureTest.php +++ b/tests/src/Provider/AzureTest.php @@ -5,9 +5,11 @@ namespace Greew\OAuth2\Test\Client\Provider; use Greew\OAuth2\Client\Provider\Azure; +use League\OAuth2\Client\Token\AccessToken; use League\OAuth2\Client\Tool\QueryBuilderTrait; -use Mockery as m; use PHPUnit\Framework\TestCase; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamInterface; class AzureTest extends TestCase { @@ -27,7 +29,6 @@ protected function setUp(): void public function tearDown(): void { - m::close(); parent::tearDown(); } @@ -79,7 +80,7 @@ public function testSettingAuthEndpoints(): void $customAuthUrl = uniqid('', true); $customResourceOwnerUrl = uniqid('', true); $customTenantId = uniqid('', true); - $token = m::mock('League\OAuth2\Client\Token\AccessToken'); + $token = $this->createMock(AccessToken::class); $this->provider = new Azure([ 'clientId' => 'mock_client_id', @@ -87,7 +88,7 @@ public function testSettingAuthEndpoints(): void 'redirectUri' => 'none', 'tenantId' => $customTenantId, 'urlAuthorize' => $customAuthUrl, - 'urlResourceOwnerDetails' => $customResourceOwnerUrl + 'urlResourceOwnerDetails' => $customResourceOwnerUrl, ]); $authUrl = $this->provider->getAuthorizationUrl(); @@ -100,15 +101,20 @@ public function testSettingAuthEndpoints(): void public function testGetAccessToken(): void { - $response = m::mock('Psr\Http\Message\ResponseInterface'); - $response->shouldReceive('getBody')->andReturn( - '{"access_token":"mock_access_token","authentication_token":"","code":"","expires_in":3600,' . - '"refresh_token":"mock_refresh_token","scope":"","state":"","token_type":""}' - ); - $response->shouldReceive('getHeader')->andReturn(['content-type' => 'json']); - - $client = m::mock('GuzzleHttp\ClientInterface'); - $client->shouldReceive('send')->times(1)->andReturn($response); + $streamInterface = $this->createMock(StreamInterface::class); + $streamInterface + ->method('__toString') + ->willReturn('{"access_token":"mock_access_token","authentication_token":"","code":"","expires_in":3600,"refresh_token":"mock_refresh_token","scope":"","state":"","token_type":""}'); + + $response = $this->createMock(ResponseInterface::class); + $response->method('getBody')->willReturn($streamInterface); + $response->method('getHeader')->willReturn(['content-type' => 'json']); + + $client = $this->createMock('GuzzleHttp\ClientInterface'); + $client + ->expects($this->once()) + ->method('send') + ->willReturn($response); $this->provider->setHttpClient($client); $token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']); @@ -122,28 +128,32 @@ public function testGetAccessToken(): void public function testUserData(): void { - $email = uniqid('', true); - $firstname = uniqid('', true); - $lastname = uniqid('', true); - $name = uniqid('', true); $userId = rand(1000, 9999); - $urls = uniqid('', true); - - $postResponse = m::mock('Psr\Http\Message\ResponseInterface'); - $postResponse->shouldReceive('getBody')->andReturn( - '{"access_token":"mock_access_token","authentication_token":"","code":"","expires_in":3600,' . - '"refresh_token":"mock_refresh_token","scope":"","state":"","token_type":""}' - ); - $postResponse->shouldReceive('getHeader')->andReturn(['content-type' => 'json']); - - $userResponse = m::mock('Psr\Http\Message\ResponseInterface'); - $userResponse->shouldReceive('getBody')->andReturn('{"id": ' . $userId . '}'); - $userResponse->shouldReceive('getHeader')->andReturn(['content-type' => 'json']); - - $client = m::mock('GuzzleHttp\ClientInterface'); - $client->shouldReceive('send') - ->times(2) - ->andReturn($postResponse, $userResponse); + + $postResponseStreamInterface = $this->createMock(StreamInterface::class); + $postResponseStreamInterface + ->method('__toString') + ->willReturn('{"access_token":"mock_access_token","authentication_token":"","code":"","expires_in":3600,"refresh_token":"mock_refresh_token","scope":"","state":"","token_type":""}'); + + $postResponse = $this->createMock(ResponseInterface::class); + $postResponse->method('getBody')->willReturn($postResponseStreamInterface); + $postResponse->method('getHeader')->willReturn(['content-type' => 'json']); + + $userResponseStreamInterface = $this->createMock(StreamInterface::class); + $userResponseStreamInterface + ->method('__toString') + ->willReturn('{"id": ' . $userId . '}'); + + $userResponse = $this->createMock(ResponseInterface::class); + $userResponse->method('getBody')->willReturn($userResponseStreamInterface); + $userResponse->method('getHeader')->willReturn(['content-type' => 'json']); + + $client = $this->createMock('GuzzleHttp\ClientInterface'); + $client + ->expects($this->exactly(2)) + ->method('send') + ->willReturnOnConsecutiveCalls($postResponse, $userResponse); + $this->provider->setHttpClient($client); $token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']); @@ -158,17 +168,29 @@ public function testExceptionThrownWhenErrorObjectReceived(): void $this->expectException(\League\OAuth2\Client\Provider\Exception\IdentityProviderException::class); $message = uniqid('', true); - $postResponse = m::mock('Psr\Http\Message\ResponseInterface'); - $postResponse->shouldReceive('getBody')->andReturn( - '{"error": "request_token_expired", "error_description": "' . $message . '"}' - ); - $postResponse->shouldReceive('getHeader')->andReturn(['content-type' => 'json']); - $postResponse->shouldReceive('getStatusCode')->andReturn(500); - - $client = m::mock('GuzzleHttp\ClientInterface'); - $client->shouldReceive('send') - ->times(1) - ->andReturn($postResponse); + $postResponseStreamInterface = $this->createMock(StreamInterface::class); + $postResponseStreamInterface + ->method('__toString') + ->willReturn('{"error": "invalid_grant", "error_description": "' . $message . '"}'); + + $postResponse = $this->createMock(ResponseInterface::class); + $postResponse + ->method('getBody') + ->willReturn($postResponseStreamInterface); + + $postResponse + ->method('getHeader') + ->willReturn(['content-type' => 'json']); + + $postResponse + ->method('getStatusCode') + ->willReturn(400); + + $client = $this->createMock('GuzzleHttp\ClientInterface'); + $client + ->expects($this->once()) + ->method('send') + ->willReturn($postResponse); $this->provider->setHttpClient($client); $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']);