Skip to content

Commit

Permalink
Moved to GitHub Actions and increased test coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickbussmann committed Aug 25, 2021
1 parent 5f20997 commit 61e5f98
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 82 deletions.
80 changes: 80 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: 'CI'

on:
pull_request:
push:
branches:
- 'main'

env:
COMPOSER_ROOT_VERSION: '1.99.99'

jobs:
lint:
name: 'Lint'
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v2'
- uses: 'shivammathur/setup-php@v2'
with:
php-version: '7.4'
coverage: 'none'
ini-values: 'memory_limit=-1'
tools: 'composer:v2'
- uses: 'ramsey/composer-install@v1'
- name: 'Lint the PHP source code'
run: './vendor/bin/parallel-lint src test'

coding-standards:
name: 'Coding Standards'
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v2'
- uses: 'shivammathur/setup-php@v2'
with:
php-version: '7.4'
coverage: 'none'
ini-values: 'memory_limit=-1'
tools: 'composer:v2'
- uses: 'ramsey/composer-install@v1'
- name: 'Check coding standards'
run: './vendor/bin/phpcs src --standard=psr2 -sp --colors'

unit-tests:
name: 'Unit Tests'
runs-on: 'ubuntu-latest'
continue-on-error: ${{ matrix.experimental }}
strategy:
fail-fast: false
matrix:
php-version:
- '5.6'
- '7.0'
- '7.1'
- '7.2'
- '7.3'
- '7.4'
- '8.0'
experimental:
- false
include:
- php-version: '8.1'
experimental: true
composer-options: '--ignore-platform-reqs'
steps:
- uses: 'actions/checkout@v2'
- uses: 'shivammathur/setup-php@v2'
with:
php-version: '${{ matrix.php-version }}'
coverage: 'pcov'
ini-values: 'memory_limit=-1'
tools: 'composer:v2'
- name: 'Prepare for tests'
run: 'mkdir -p build/logs'
- uses: 'ramsey/composer-install@v1'
with:
composer-options: '${{ matrix.composer-options }}'
- name: 'Run unit tests'
run: './vendor/bin/phpunit --colors=always --coverage-clover build/logs/clover.xml'
- name: 'Publish coverage report to Codecov'
uses: 'codecov/codecov-action@v1'
67 changes: 0 additions & 67 deletions .travis.yml

This file was deleted.

11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ All Notable changes to `oauth2-apple` will be documented in this file
### Security
- Nothing

## 0.2.6 - 2021-08-25

### Added
- GitHub Actions CI

### Removed
- Travis CI

### Fixed
- Fixed bug with serialization of AppleAccessToken [#29](https://github.com/patrickbussmann/oauth2-apple/pull/29) (thanks to [tjveldhuizen](https://github.com/tjveldhuizen))

## 0.2.5 - 2021-03-10

### Fixed
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"require-dev": {
"phpunit/phpunit": "^5.7 || ^6.0 || ^9.3",
"mockery/mockery": "^1.3",
"php-parallel-lint/php-parallel-lint": "^1.3",
"squizlabs/php_codesniffer": "^2.3 || ^3.0",
"ext-json": "*"
},
Expand Down
2 changes: 1 addition & 1 deletion src/Provider/Apple.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ private function getAppleKeys()
{
$response = $this->httpClient->request('GET', 'https://appleid.apple.com/auth/keys');

if ($response) {
if ($response && $response->getStatusCode() === 200) {
return JWK::parseKeySet(json_decode($response->getBody()->getContents(), true));
}

Expand Down
59 changes: 58 additions & 1 deletion test/src/Provider/AppleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use League\OAuth2\Client\Provider\Apple;
use League\OAuth2\Client\Provider\AppleResourceOwner;
use League\OAuth2\Client\Token\AccessToken;
use League\OAuth2\Client\Token\AppleAccessToken;
use League\OAuth2\Client\Tool\QueryBuilderTrait;
use PHPUnit\Framework\TestCase;
use Mockery as m;
Expand Down Expand Up @@ -164,6 +165,40 @@ public function testGetAccessToken()
]);
}

public function testGetAccessTokenFailedBecauseAppleHasError()
{
$this->expectException('Exception');
$this->expectExceptionMessage('Got no data within "id_token"!');

$provider = new TestApple([
'clientId' => 'mock.example',
'teamId' => 'mock.team.id',
'keyFileId' => 'mock.file.id',
'keyFilePath' => __DIR__ . '/../../resources/p256-private-key.p8',
'redirectUri' => 'none'
]);
$provider = m::mock($provider);

$client = m::mock(ClientInterface::class);
$client->shouldReceive('request')
->times(1)
->andReturn(new Response(500, [], 'Internal Server Error'));
$client->shouldReceive('send')
->times(1)
->andReturn(new Response(200, [], json_encode([
'access_token' => 'aad897dee58fe4f66bf220c181adaf82b.0.mrwxq.hmiE0djj1vJqoNisKmF-pA',
'token_type' => 'Bearer',
'expires_in' => 3600,
'refresh_token' => 'r4a6e8b9c50104b78bc86b0d2649353fa.0.mrwxq.54joUj40j0cpuMANRtRjfg',
'id_token' => 'abc'
])));
$provider->setHttpClient($client);

$provider->getAccessToken('authorization_code', [
'code' => 'hello-world'
]);
}

public function testFetchingOwnerDetails()
{
$provider = $this->getProvider();
Expand Down Expand Up @@ -206,6 +241,7 @@ public function testNotImplementedGetResourceOwnerDetailsUrl()
public function testCheckResponse()
{
$this->expectException('\League\OAuth2\Client\Provider\Exception\AppleAccessDeniedException');
$this->expectExceptionMessage('invalid_client');
$provider = $this->getProvider();
$class = new \ReflectionClass($provider);
$method = $class->getMethod('checkResponse');
Expand All @@ -217,7 +253,7 @@ public function testCheckResponse()
]]);
}

public function testCreationOfResourceOwner()
public function testCreationOfResourceOwnerWithName()
{
$provider = $this->getProvider();
$class = new \ReflectionClass($provider);
Expand Down Expand Up @@ -247,6 +283,27 @@ public function testCreationOfResourceOwner()
$this->assertArrayHasKey('name', $data->toArray());
}

public function testCreationOfResourceOwnerWithoutName()
{
$provider = $this->getProvider();
$class = new \ReflectionClass($provider);
$method = $class->getMethod('createResourceOwner');
$method->setAccessible(true);

/** @var AppleResourceOwner $data */
$data = $method->invokeArgs($provider, [
[],
new AccessToken([
'access_token' => 'hello',
'email' => '[email protected]',
'resource_owner_id' => '123.4.567'
])
]);
$this->assertEquals('[email protected]', $data->getEmail());
$this->assertNull($data->getLastName());
$this->assertNull($data->getFirstName());
}

public function testGetConfiguration()
{
$provider = m::mock(Apple::class)->makePartial();
Expand Down
53 changes: 40 additions & 13 deletions test/src/Token/AppleAccessTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace League\OAuth2\Client\Test\Token;

use GuzzleHttp\Psr7\Response;
use League\OAuth2\Client\Token\AppleAccessToken;
use PHPUnit\Framework\TestCase;
use Mockery as m;
Expand All @@ -20,7 +19,10 @@ public function testCreatingAccessToken()
->with('something', 'examplekey', ['RS256'])
->once()
->andReturn([
'sub' => '123.abc.123'
'sub' => '123.abc.123',
'email_verified' => true,
'email' => '[email protected]',
'is_private_email' => true
]);

$accessToken = new AppleAccessToken(['examplekey'], [
Expand All @@ -33,6 +35,21 @@ public function testCreatingAccessToken()
$this->assertEquals('something', $accessToken->getIdToken());
$this->assertEquals('123.abc.123', $accessToken->getResourceOwnerId());
$this->assertEquals('access_token', $accessToken->getToken());
$this->assertEquals('[email protected]', $accessToken->getEmail());
$this->assertTrue($accessToken->isPrivateEmail());
}

public function testCreateFailsBecauseNoIdTokenIsSet()
{
$this->expectException('\InvalidArgumentException');
$this->expectExceptionMessage('Required option not passed: "id_token"');

new AppleAccessToken(['examplekey'], [
'access_token' => 'access_token',
'token_type' => 'Bearer',
'expires_in' => 3600,
'refresh_token' => 'abc.0.def'
]);
}

public function testCreatingRefreshToken()
Expand All @@ -45,17 +62,27 @@ public function testCreatingRefreshToken()
$this->assertEquals('access_token', $refreshToken->getToken());
}

private function getClient($times)
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testCreatingAccessTokenFailsBecauseNoDecodingIsPossible()
{
$client = m::mock('GuzzleHttp\ClientInterface');
if ($times > 0) {
$client->shouldReceive('request')
->times($times)
->withArgs(['GET', 'https://appleid.apple.com/auth/keys'])
->andReturn(new Response())
;
}

return $client;
$this->expectException('\Exception');
$this->expectExceptionMessage('Got no data within "id_token"!');

$externalJWTMock = m::mock('overload:Firebase\JWT\JWT');
$externalJWTMock->shouldReceive('decode')
->with('something', 'examplekey', ['RS256'])
->once()
->andReturnNull();

new AppleAccessToken(['examplekey'], [
'access_token' => 'access_token',
'token_type' => 'Bearer',
'expires_in' => 3600,
'refresh_token' => 'abc.0.def',
'id_token' => 'something'
]);
}
}

0 comments on commit 61e5f98

Please sign in to comment.