Skip to content

Commit e7a722f

Browse files
committed
:octocat: improve tests & coverage
1 parent 6eff034 commit e7a722f

14 files changed

+362
-106
lines changed

phpunit.xml.dist

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@
4444
<php>
4545
<!-- whether the test runs on CI - set to false to allow live API tests to run -->
4646
<const name="TEST_IS_CI" value="true"/>
47-
<!-- the config directory, where .env, cacert.pem and test oauth tokens reside, relative from project root -->
48-
<const name="TEST_CFGDIR" value=".config"/>
49-
<!-- the filename of your .env file -->
47+
<!-- the filename of your .env file in the config dir [project root]/.config -->
5048
<const name="TEST_ENVFILE" value=".env_example"/>
5149
<!-- the http client factory for live api tests -->
5250
<const name="HTTP_CLIENT_FACTORY" value="chillerlan\PHPUnitHttp\GuzzleHttpClientFactory"/>

tests/Core/OAuthOptionsTest.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
/**
3+
* Class OAuthOptionsTest
4+
*
5+
* @created 10.04.2024
6+
* @author smiley <smiley@chillerlan.net>
7+
* @copyright 2024 smiley
8+
* @license MIT
9+
*/
10+
declare(strict_types=1);
11+
12+
namespace chillerlan\OAuthTest\Core;
13+
14+
use chillerlan\OAuth\OAuthOptions;
15+
use chillerlan\OAuth\Storage\OAuthStorageException;
16+
use PHPUnit\Framework\TestCase;
17+
18+
/**
19+
*
20+
*/
21+
class OAuthOptionsTest extends TestCase{
22+
23+
public function testSetStorageEncryptionKey():void{
24+
$key = '000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f';
25+
26+
$options = new OAuthOptions(['storageEncryptionKey' => $key]);
27+
28+
$this::assertSame($key, $options->storageEncryptionKey);
29+
}
30+
31+
public function testSetStorageEncryptionKeyInvalidException():void{
32+
$this->expectException(OAuthStorageException::class);
33+
$this->expectExceptionMessage('invalid encryption key');
34+
35+
new OAuthOptions(['storageEncryptionKey' => 'foo']);
36+
}
37+
38+
public function testSetFileStoragePath():void{
39+
$options = new OAuthOptions(['fileStoragePath' => __DIR__]);
40+
41+
$this::assertSame(__DIR__, $options->fileStoragePath);
42+
}
43+
44+
public function testSetFileStoragePathInvalidException():void{
45+
$this->expectException(OAuthStorageException::class);
46+
$this->expectExceptionMessage('invalid storage path "/foo"');
47+
48+
new OAuthOptions(['fileStoragePath' => '/foo']);
49+
}
50+
51+
public function testClampPKCEVerifierLength(){
52+
$options = new OAuthOptions;
53+
54+
// lower limit = 43
55+
$options->pkceVerifierLength = -42;
56+
$this::assertSame(43, $options->pkceVerifierLength);
57+
58+
// upper limit = 128
59+
$options->pkceVerifierLength = 69420;
60+
$this::assertSame(128, $options->pkceVerifierLength);
61+
}
62+
63+
}

tests/Core/UtilitiesTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
namespace chillerlan\OAuthTest\Core;
1313

1414
use chillerlan\OAuth\Core\{OAuthInterface, Utilities};
15-
use Monolog\Test\TestCase;
1615
use PHPUnit\Framework\Attributes\DataProvider;
16+
use PHPUnit\Framework\TestCase;
1717
use ReflectionClass;
1818

1919
/**

tests/Providers/Live/GuildWars2APITest.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,7 @@ protected function getProviderFQCN():string{
3232
protected function setUp():void{
3333
parent::setUp();
3434

35-
$tokenfile = $this->CFG_DIR.'/'.$this->provider->name.'.token.json';
36-
37-
$this->token = !file_exists($tokenfile)
38-
? $this->provider->storeGW2Token($this->dotEnv->GW2_TOKEN)
39-
: (new AccessToken)->fromJSON(file_get_contents($tokenfile));
35+
$this->provider->storeGW2Token($this->dotEnv->GW2_TOKEN);
4036

4137
$this->tokenname = $this->dotEnv->GW2_TOKEN_NAME;
4238
}

tests/Providers/ProviderLiveTestAbstract.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,15 @@ protected function initConfig():void{
5151
/** @var \chillerlan\OAuth\Core\OAuthInterface $providerFQCN */
5252
$providerFQCN = $this->getProviderFQCN();
5353

54-
$this->dotEnv = (new DotEnv($this->CFG_DIR, constant('TEST_ENVFILE'), false))->load();
54+
$this->dotEnv = (new DotEnv($this::CFGDIR, constant('TEST_ENVFILE'), false))->load();
5555
$this->ENV_PREFIX = $providerFQCN::IDENTIFIER;
5656
$this->TEST_USER = (string)$this->dotEnv->get($this->ENV_PREFIX.'_TESTUSER');
5757
}
5858

5959
protected function initOptions():OAuthOptions{
6060
$options = new OAuthOptions;
6161
$options->tokenAutoRefresh = true;
62-
$options->fileStoragePath = $this->CFG_DIR.'/.filestorage';
62+
$options->fileStoragePath = $this::CFGDIR.'/.filestorage';
6363

6464
if(!empty($this->ENV_PREFIX)){
6565
$options->key = ($this->dotEnv->get($this->ENV_PREFIX.'_KEY') ?? '');

tests/Providers/ProviderUnitTestAbstract.php

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace chillerlan\OAuthTest\Providers;
1313

14+
use chillerlan\OAuth\Core\AccessToken;
1415
use chillerlan\OAuth\Core\OAuthInterface;
1516
use chillerlan\OAuth\OAuthOptions;
1617
use chillerlan\OAuth\OAuthProviderFactory;
@@ -29,7 +30,6 @@
2930
use function constant;
3031
use function defined;
3132
use function ini_set;
32-
use function ltrim;
3333
use function realpath;
3434
use function sprintf;
3535

@@ -48,11 +48,11 @@ abstract class ProviderUnitTestAbstract extends TestCase{
4848

4949
protected string $HTTP_CLIENT_FACTORY = ProviderUnitTestHttpClientFactory::class;
5050

51-
protected string $CFG_DIR;
5251
protected bool $ENV_IS_CI;
5352

54-
protected const PROJECT_ROOT = __DIR__.'/../../';
55-
protected const CACERT = __DIR__.'/../cacert.pem';
53+
protected const PROJECT_ROOT = __DIR__.'/../..';
54+
protected const CFGDIR = self::PROJECT_ROOT.'/.config';
55+
protected const CACERT = self::PROJECT_ROOT.'/tests/cacert.pem';
5656

5757
protected function setUp():void{
5858
ini_set('date.timezone', 'UTC');
@@ -102,19 +102,12 @@ abstract protected function getProviderFQCN():string;
102102

103103
protected function initConfig():void{
104104

105-
foreach(['TEST_CFGDIR', 'TEST_ENVFILE'] as $constant){
105+
foreach(['TEST_ENVFILE'] as $constant){
106106
if(!defined($constant)){
107107
throw new InvalidArgumentException(sprintf('constant "%s" not set -> see phpunit.xml', $constant));
108108
}
109109
}
110110

111-
$cfgdir = constant('TEST_CFGDIR');
112-
$this->CFG_DIR = realpath($this::PROJECT_ROOT.ltrim($cfgdir, '/\\'));
113-
114-
if($this->CFG_DIR === false){
115-
throw new InvalidArgumentException(sprintf('invalid config dir "%s" (relative from project root)', $cfgdir));
116-
}
117-
118111
}
119112

120113
protected function initOptions():OAuthOptions{
@@ -186,4 +179,22 @@ protected function setMockResponse(ResponseInterface|StreamInterface $response):
186179
$this->setReflectionProperty('http', $this->getMockHttpClient($response));
187180
}
188181

182+
/**
183+
* Creates a test access token with the given parameters or a set of defaults
184+
*/
185+
protected function getTestToken(array|null $params = null):AccessToken{
186+
187+
$params ??= [
188+
'accessToken' => 'test_access_token',
189+
'accessTokenSecret' => 'test_access_token_secret',
190+
'refreshToken' => 'test_refresh_token',
191+
'expires' => 42,
192+
// patreon requires a scope set
193+
'scopes' => ['identity', 'scope1', 'scope2'],
194+
'provider' => $this->provider->name,
195+
];
196+
197+
return new AccessToken($params);
198+
}
199+
189200
}

tests/Providers/Unit/DeezerTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace chillerlan\OAuthTest\Providers\Unit;
1313

1414
use chillerlan\HTTP\Utils\QueryUtil;
15+
use chillerlan\OAuth\Core\UnauthorizedAccessException;
1516
use chillerlan\OAuth\Providers\Deezer;
1617
use chillerlan\OAuth\Providers\ProviderException;
1718
use function implode;
@@ -52,6 +53,18 @@ public function testParseTokenResponseErrorException():void{
5253
$this->invokeReflectionMethod('parseTokenResponse', [$response]);
5354
}
5455

56+
public function testParseTokenResponseUnauthorizedException():void{
57+
$this->expectException(UnauthorizedAccessException::class);
58+
$this->expectExceptionMessage('Unauthorized');
59+
60+
$response = $this->responseFactory
61+
->createResponse(401)
62+
->withBody($this->streamFactory->createStream('error_reason=Unauthorized'))
63+
;
64+
65+
$this->invokeReflectionMethod('parseTokenResponse', [$response]);
66+
}
67+
5568
public function testParseTokenResponseNoTokenException():void{
5669
$this->expectException(ProviderException::class);
5770
$this->expectExceptionMessage('token missing');

tests/Providers/Unit/FlickrTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,12 @@ protected function getProviderFQCN():string{
2222
return Flickr::class;
2323
}
2424

25+
public function testRequest():void{
26+
$this::markTestIncomplete();
27+
}
28+
29+
public function testRequestUnauthorizedException():void{
30+
$this::markTestIncomplete();
31+
}
32+
2533
}

tests/Providers/Unit/LastFMTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,16 @@ protected function getProviderFQCN():string{
2222
return LastFM::class;
2323
}
2424

25+
public function testRequest():void{
26+
$this::markTestIncomplete();
27+
}
28+
29+
public function testGetRequestAuthorizationInvalidTokenException():void{
30+
$this::markTestSkipped('N/A');
31+
}
32+
33+
public function testMeResponseInvalidContentTypeException():void{
34+
$this::markTestSkipped('N/A');
35+
}
36+
2537
}

tests/Providers/Unit/OAuth1ProviderUnitTestAbstract.php

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
namespace chillerlan\OAuthTest\Providers\Unit;
1313

14-
use chillerlan\OAuth\Core\{AccessToken, OAuth1Interface};
14+
use chillerlan\OAuth\Core\{AccessToken, OAuth1Interface, UnauthorizedAccessException};
1515
use chillerlan\HTTP\Utils\MessageUtil;
1616
use chillerlan\OAuth\Providers\ProviderException;
1717
use function str_starts_with;
@@ -78,11 +78,8 @@ public function testSendRequestTokenRequest():void{
7878
*/
7979

8080
public function testParseAccessTokenResponse():void{
81-
82-
$response = $this->responseFactory
83-
->createResponse()
84-
->withBody($this->streamFactory->createStream($this::TEST_ACCESS_TOKEN))
85-
;
81+
$body = $this->streamFactory->createStream($this::TEST_ACCESS_TOKEN);
82+
$response = $this->responseFactory->createResponse()->withBody($body);
8683

8784
/** @var \chillerlan\OAuth\Core\AccessToken $token */
8885
$token = $this->invokeReflectionMethod('parseTokenResponse', [$response]);
@@ -92,11 +89,8 @@ public function testParseAccessTokenResponse():void{
9289
}
9390

9491
public function testParseTemporaryCredentialsTokenResponse():void{
95-
96-
$response = $this->responseFactory
97-
->createResponse()
98-
->withBody($this->streamFactory->createStream($this::TEST_REQUEST_TOKEN))
99-
;
92+
$body = $this->streamFactory->createStream($this::TEST_REQUEST_TOKEN);
93+
$response = $this->responseFactory->createResponse()->withBody($body);
10094

10195
/** @var \chillerlan\OAuth\Core\AccessToken $token */
10296
$token = $this->invokeReflectionMethod('parseTokenResponse', [$response, true]);
@@ -122,6 +116,16 @@ public function testParseTokenResponseErrorException():void{
122116
$this->invokeReflectionMethod('parseTokenResponse', [$response]);
123117
}
124118

119+
public function testParseTokenResponseUnauthorizedException():void{
120+
$this->expectException(UnauthorizedAccessException::class);
121+
$this->expectExceptionMessage('Unauthorized');
122+
123+
$body = $this->streamFactory->createStream('error=Unauthorized');
124+
$response = $this->responseFactory->createResponse(401)->withBody($body);
125+
126+
$this->invokeReflectionMethod('parseTokenResponse', [$response]);
127+
}
128+
125129
public function testParseTokenResponseNoTokenException():void{
126130
$this->expectException(ProviderException::class);
127131
$this->expectExceptionMessage('invalid token');
@@ -150,7 +154,7 @@ public function testParseTokenResponseConfirmCallbackException():void{
150154
public function testGetAccessToken():void{
151155
$this->setMockResponse($this->streamFactory->createStream($this::TEST_ACCESS_TOKEN));
152156

153-
$requestToken = new AccessToken([
157+
$requestToken = $this->getTestToken([
154158
'accessToken' => 'hdk48Djdsa',
155159
'accessTokenSecret' => 'xyz4992k83j47x0b',
156160
'expires' => AccessToken::NEVER_EXPIRES,
@@ -165,7 +169,7 @@ public function testGetAccessToken():void{
165169

166170
public function testSendAccessTokenRequest():void{
167171
// we need the request token for the access token request
168-
$requestToken = new AccessToken([
172+
$requestToken = $this->getTestToken([
169173
'accessToken' => 'hdk48Djdsa',
170174
'accessTokenSecret' => 'xyz4992k83j47x0b',
171175
'expires' => AccessToken::NEVER_EXPIRES,
@@ -190,11 +194,12 @@ public function testGetAccessTokenRequestTokenMismatchException():void{
190194
$this->expectException(ProviderException::class);
191195
$this->expectExceptionMessage('request token mismatch');
192196

193-
$requestToken = new AccessToken(['accessToken' => 'hdk48Djdsa']);
197+
$requestToken = $this->getTestToken(['accessToken' => 'hdk48Djdsa']);
194198

195-
$this->provider->storeAccessToken($requestToken);
196-
197-
$this->provider->getAccessToken('nope', 'verifier');
199+
$this->provider
200+
->storeAccessToken($requestToken)
201+
->getAccessToken('nope', 'verifier')
202+
;
198203
}
199204

200205

@@ -204,7 +209,7 @@ public function testGetAccessTokenRequestTokenMismatchException():void{
204209

205210
public function testGetRequestAuthorization():void{
206211
$request = $this->requestFactory->createRequest('GET', 'https://foo.bar');
207-
$token = new AccessToken([
212+
$token = $this->getTestToken([
208213
'accessTokenSecret' => 'test_token_secret',
209214
'accessToken' => 'test_token',
210215
'expires' => AccessToken::NEVER_EXPIRES,

0 commit comments

Comments
 (0)