Skip to content

Commit dc6e704

Browse files
committed
add integration test and integration test config
1 parent ff7339f commit dc6e704

File tree

5 files changed

+467
-0
lines changed

5 files changed

+467
-0
lines changed

.github/workflows/tests.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,27 @@ jobs:
2929
- name: Run Script
3030
run: vendor/bin/phpunit
3131

32+
test_system:
33+
runs-on: ubuntu-latest
34+
strategy:
35+
matrix:
36+
php: [ "8.0", "8.1" ]
37+
name: PHP ${{matrix.php }} Unit Test
38+
steps:
39+
- uses: actions/checkout@v2
40+
- name: Setup PHP
41+
uses: shivammathur/setup-php@v2
42+
with:
43+
php-version: ${{ matrix.php }}
44+
- name: Install Dependencies
45+
uses: nick-invision/retry@v1
46+
with:
47+
timeout_minutes: 10
48+
max_attempts: 3
49+
command: composer require guzzlehttp/guzzle psr/cache
50+
- name: Run Script
51+
run: vendor/bin/phpunit -c phpunit-system.xml.dist
52+
3253
# use dockerfiles for old versions of php (setup-php times out for those).
3354
test_php55:
3455
name: "PHP 5.5 Unit Test"

phpunit-system.xml.dist

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<phpunit backupGlobals="false"
4+
backupStaticAttributes="false"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false"
11+
bootstrap="tests/bootstrap-system.php"
12+
>
13+
<testsuites>
14+
<testsuite name="PHP JSON Web Token Test Suite">
15+
<file>./tests/CachedKeySetTest.php</file>
16+
</testsuite>
17+
</testsuites>
18+
</phpunit>

phpunit.xml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<testsuites>
1414
<testsuite name="PHP JSON Web Token Test Suite">
1515
<directory>./tests</directory>
16+
<exclude>./tests/CachedKeySetTest.php</exclude>
1617
</testsuite>
1718
</testsuites>
1819
</phpunit>

tests/CachedKeySetTest.php

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
<?php
2+
3+
namespace Firebase\JWT;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Psr\Http\Client\ClientInterface;
7+
use Prophecy\Argument;
8+
9+
class CachedKeySetTest extends TestCase
10+
{
11+
private $testJwkUri = 'httpjwkuri';
12+
private $testJwkUriKey = 'jwkhttpjwkuri';
13+
private $testJwk1 = '{"keys": [{"kid":"foo","kty":"RSA","alg":"foo","n":"","e":""}]}';
14+
private $testJwk2 = '{"keys": [{"kid":"bar","kty":"RSA","alg":"bar","n":"","e":""}]}';
15+
16+
private $googleRsaUri = 'https://www.googleapis.com/oauth2/v3/certs';
17+
// private $googleEcUri = 'https://www.gstatic.com/iap/verify/public_key-jwk';
18+
19+
public function testOffsetSetThrowsException()
20+
{
21+
$this->setExpectedException(
22+
'LogicException',
23+
'Method not implemented'
24+
);
25+
26+
$cachedKeySet = new CachedKeySet(
27+
$this->testJwkUri,
28+
$this->prophesize('Psr\Http\Client\ClientInterface')->reveal(),
29+
$this->prophesize('Psr\Http\Message\RequestFactoryInterface')->reveal(),
30+
$this->prophesize('Psr\Cache\CacheItemPoolInterface')->reveal()
31+
);
32+
33+
$cachedKeySet['foo'] = 'bar';
34+
}
35+
36+
public function testOffsetUnsetThrowsException()
37+
{
38+
$this->setExpectedException(
39+
'LogicException',
40+
'Method not implemented'
41+
);
42+
43+
$cachedKeySet = new CachedKeySet(
44+
$this->testJwkUri,
45+
$this->prophesize('Psr\Http\Client\ClientInterface')->reveal(),
46+
$this->prophesize('Psr\Http\Message\RequestFactoryInterface')->reveal(),
47+
$this->prophesize('Psr\Cache\CacheItemPoolInterface')->reveal()
48+
);
49+
50+
unset($cachedKeySet['foo']);
51+
}
52+
53+
public function testOutOfBoundsThrowsException()
54+
{
55+
$this->setExpectedException(
56+
'OutOfBoundsException',
57+
'Key ID not found'
58+
);
59+
60+
$cachedKeySet = new CachedKeySet(
61+
$this->testJwkUri,
62+
$this->getMockHttpClient($this->testJwk1),
63+
$this->getMockHttpFactory(),
64+
$this->getMockEmptyCache()
65+
);
66+
67+
// keyID doesn't exist
68+
$cachedKeySet['bar'];
69+
}
70+
71+
public function testWithExistingKeyId()
72+
{
73+
$cachedKeySet = new CachedKeySet(
74+
$this->testJwkUri,
75+
$this->getMockHttpClient($this->testJwk1),
76+
$this->getMockHttpFactory(),
77+
$this->getMockEmptyCache()
78+
);
79+
$this->assertInstanceOf('Firebase\JWT\Key', $cachedKeySet['foo']);
80+
$this->assertEquals('foo', $cachedKeySet['foo']->getAlgorithm());
81+
}
82+
83+
public function testKeyIdIsCached()
84+
{
85+
$cacheItem = $this->prophesize('Psr\Cache\CacheItemInterface');
86+
$cacheItem->isHit()
87+
->willReturn(true);
88+
$cacheItem->get()
89+
->willReturn(JWK::parseKeySet(json_decode($this->testJwk1, true)));
90+
91+
$cache = $this->prophesize('Psr\Cache\CacheItemPoolInterface');
92+
$cache->getItem($this->testJwkUriKey)
93+
->willReturn($cacheItem->reveal());
94+
$cache->save(Argument::any())
95+
->willReturn(true);
96+
97+
$cachedKeySet = new CachedKeySet(
98+
$this->testJwkUri,
99+
$this->prophesize('Psr\Http\Client\ClientInterface')->reveal(),
100+
$this->prophesize('Psr\Http\Message\RequestFactoryInterface')->reveal(),
101+
$cache->reveal()
102+
);
103+
$this->assertInstanceOf('Firebase\JWT\Key', $cachedKeySet['foo']);
104+
$this->assertEquals('foo', $cachedKeySet['foo']->getAlgorithm());
105+
}
106+
107+
public function testCachedKeyIdRefresh()
108+
{
109+
$cacheItem = $this->prophesize('Psr\Cache\CacheItemInterface');
110+
$cacheItem->isHit()
111+
->shouldBeCalledOnce()
112+
->willReturn(true);
113+
$cacheItem->get()
114+
->shouldBeCalledOnce()
115+
->willReturn(JWK::parseKeySet(json_decode($this->testJwk1, true)));
116+
$cacheItem->set(Argument::any())
117+
->shouldBeCalledOnce()
118+
->willReturn(true);
119+
120+
$cache = $this->prophesize('Psr\Cache\CacheItemPoolInterface');
121+
$cache->getItem($this->testJwkUriKey)
122+
->shouldBeCalledOnce()
123+
->willReturn($cacheItem->reveal());
124+
$cache->save(Argument::any())
125+
->shouldBeCalledOnce()
126+
->willReturn(true);
127+
128+
$cachedKeySet = new CachedKeySet(
129+
$this->testJwkUri,
130+
$this->getMockHttpClient($this->testJwk2), // updated JWK
131+
$this->getMockHttpFactory(),
132+
$cache->reveal()
133+
);
134+
$this->assertInstanceOf('Firebase\JWT\Key', $cachedKeySet['foo']);
135+
$this->assertEquals('foo', $cachedKeySet['foo']->getAlgorithm());
136+
137+
$this->assertInstanceOf('Firebase\JWT\Key', $cachedKeySet['bar']);
138+
$this->assertEquals('bar', $cachedKeySet['bar']->getAlgorithm());
139+
}
140+
141+
private function getMockHttpClient($testJwk)
142+
{
143+
$body = $this->prophesize('Psr\Http\Message\StreamInterface');
144+
$body->__toString()
145+
->shouldBeCalledOnce()
146+
->willReturn($testJwk);
147+
148+
$response = $this->prophesize('Psr\Http\Message\ResponseInterface');
149+
$response->getBody()
150+
->shouldBeCalledOnce()
151+
->willReturn($body->reveal());
152+
153+
$http = $this->prophesize('Psr\Http\Client\ClientInterface');
154+
$http->sendRequest(Argument::any())
155+
->shouldBeCalledOnce()
156+
->willReturn($response->reveal());
157+
158+
return $http->reveal();
159+
}
160+
161+
private function getMockHttpFactory()
162+
{
163+
$request = $this->prophesize('Psr\Http\Message\RequestInterface');
164+
$factory = $this->prophesize('Psr\Http\Message\RequestFactoryInterface');
165+
$factory->createRequest('get', $this->testJwkUri)
166+
->shouldBeCalledOnce()
167+
->willReturn($request->reveal());
168+
169+
return $factory->reveal();
170+
}
171+
172+
private function getMockEmptyCache()
173+
{
174+
$cacheItem = $this->prophesize('Psr\Cache\CacheItemInterface');
175+
$cacheItem->isHit()
176+
->shouldBeCalledOnce()
177+
->willReturn(false);
178+
$cacheItem->set(Argument::any())
179+
->willReturn(true);
180+
181+
$cache = $this->prophesize('Psr\Cache\CacheItemPoolInterface');
182+
$cache->getItem($this->testJwkUriKey)
183+
->shouldBeCalledOnce()
184+
->willReturn($cacheItem->reveal());
185+
$cache->save(Argument::any())
186+
->willReturn(true);
187+
188+
return $cache->reveal();
189+
}
190+
191+
public function testCacheItemWithExpiresAfter()
192+
{
193+
$expiresAfter = 10;
194+
$cacheItem = $this->prophesize('Psr\Cache\CacheItemInterface');
195+
$cacheItem->isHit()
196+
->shouldBeCalledOnce()
197+
->willReturn(false);
198+
$cacheItem->set(Argument::any())
199+
->shouldBeCalledOnce();
200+
$cacheItem->expiresAfter($expiresAfter)
201+
->shouldBeCalledOnce();
202+
203+
$cache = $this->prophesize('Psr\Cache\CacheItemPoolInterface');
204+
$cache->getItem($this->testJwkUriKey)
205+
->shouldBeCalledOnce()
206+
->willReturn($cacheItem->reveal());
207+
$cache->save(Argument::any())
208+
->shouldBeCalledOnce();
209+
210+
$cachedKeySet = new CachedKeySet(
211+
$this->testJwkUri,
212+
$this->getMockHttpClient($this->testJwk1),
213+
$this->getMockHttpFactory(),
214+
$cache->reveal(),
215+
$expiresAfter
216+
);
217+
$this->assertInstanceOf('Firebase\JWT\Key', $cachedKeySet['foo']);
218+
$this->assertEquals('foo', $cachedKeySet['foo']->getAlgorithm());
219+
}
220+
221+
public function testFullIntegration()
222+
{
223+
if (!class_exists(TestMemoryCacheItemPool::class)) {
224+
$this->markTestSkipped('Use phpunit-system.xml.dist to run this tests');
225+
}
226+
227+
$cache = new TestMemoryCacheItemPool();
228+
$http = new \GuzzleHttp\Client();
229+
$factory = new \GuzzleHttp\Psr7\HttpFactory();
230+
231+
$cachedKeySet = new CachedKeySet(
232+
$this->googleRsaUri,
233+
$http,
234+
$factory,
235+
$cache
236+
);
237+
238+
$this->assertArrayHasKey('182e450a35a2081faa1d9ae1d2d75a0f23d91df8', $cachedKeySet);
239+
}
240+
241+
/*
242+
* For compatibility with PHPUnit 4.8 and PHP < 5.6
243+
*/
244+
public function setExpectedException($exceptionName, $message = '', $code = null)
245+
{
246+
if (method_exists($this, 'expectException')) {
247+
$this->expectException($exceptionName);
248+
if ($message) {
249+
$this->expectExceptionMessage($message);
250+
}
251+
} else {
252+
parent::setExpectedException($exceptionName, $message, $code);
253+
}
254+
}
255+
}

0 commit comments

Comments
 (0)