feat: read BusProNet base data from the MyE&P API
This commit is contained in:
1 parent
1505f9b50b
commit
2e9328fc51
37 files changed
+2302
-148
No files matched your search
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\MyEp\Api;
|
||||
|
||||
use App\MyEp\Api\AccessTokenProvider;
|
||||
use App\MyEp\Api\ApiException;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Psr\Log\NullLogger;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\HttpClient\MockHttpClient;
|
||||
use Symfony\Component\HttpClient\Response\MockResponse;
|
||||
|
||||
class AccessTokenProviderTest extends TestCase
|
||||
{
|
||||
private const CACHE_KEY = 'myep.api.access_token';
|
||||
|
||||
public function testTokenIsReturnedFromTheTokenEndpoint(): void
|
||||
{
|
||||
$httpClient = new MockHttpClient([$this->tokenResponse('abc123')]);
|
||||
|
||||
$this->assertEquals('abc123', $this->getProviderInstance($httpClient)->getToken());
|
||||
}
|
||||
|
||||
public function testTheClientCredentialsGrantIsRequested(): void
|
||||
{
|
||||
$body = null;
|
||||
$httpClient = new MockHttpClient(function (string $method, string $url, array $options) use (&$body) {
|
||||
$this->assertEquals('POST', $method);
|
||||
$this->assertEquals('https://myep.example/token', $url);
|
||||
$body = $options['body'];
|
||||
|
||||
return $this->tokenResponse('abc123');
|
||||
});
|
||||
|
||||
$this->getProviderInstance($httpClient)->getToken();
|
||||
|
||||
$this->assertStringContainsString('grant_type=client_credentials', $body);
|
||||
$this->assertStringContainsString('scope=api', $body);
|
||||
$this->assertStringContainsString('client_secret=secret', $body);
|
||||
}
|
||||
|
||||
public function testTheTokenIsCachedRatherThanRequestedPerCall(): void
|
||||
{
|
||||
$httpClient = new MockHttpClient([$this->tokenResponse('abc123')]);
|
||||
$cache = new ArrayAdapter();
|
||||
$provider = $this->getProviderInstance($httpClient, $cache);
|
||||
|
||||
$provider->getToken();
|
||||
$provider->getToken();
|
||||
|
||||
$this->assertEquals(1, $httpClient->getRequestsCount());
|
||||
$this->assertTrue($cache->getItem(self::CACHE_KEY)->isHit());
|
||||
}
|
||||
|
||||
public function testACachedTokenIsUsedWithoutAskingForANewOne(): void
|
||||
{
|
||||
$cache = new ArrayAdapter();
|
||||
$item = $cache->getItem(self::CACHE_KEY);
|
||||
$item->set('cached-token');
|
||||
$cache->save($item);
|
||||
|
||||
$httpClient = new MockHttpClient([]);
|
||||
|
||||
$this->assertEquals('cached-token', $this->getProviderInstance($httpClient, $cache)->getToken());
|
||||
$this->assertEquals(0, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
public function testAnInvalidatedTokenIsRequestedAgain(): void
|
||||
{
|
||||
$httpClient = new MockHttpClient([$this->tokenResponse('abc123'), $this->tokenResponse('def456')]);
|
||||
$provider = $this->getProviderInstance($httpClient);
|
||||
|
||||
$provider->getToken();
|
||||
$provider->invalidate();
|
||||
|
||||
$this->assertEquals('def456', $provider->getToken());
|
||||
$this->assertEquals(2, $httpClient->getRequestsCount());
|
||||
}
|
||||
|
||||
public function testARejectedRequestFails(): void
|
||||
{
|
||||
$httpClient = new MockHttpClient([
|
||||
new MockResponse('{"error":"invalid_client"}', ['http_code' => 401]),
|
||||
]);
|
||||
|
||||
$this->expectException(ApiException::class);
|
||||
|
||||
$this->getProviderInstance($httpClient)->getToken();
|
||||
}
|
||||
|
||||
public function testAResponseWithoutATokenFails(): void
|
||||
{
|
||||
$httpClient = new MockHttpClient([new MockResponse('{"expires_in":600}')]);
|
||||
|
||||
$this->expectException(ApiException::class);
|
||||
|
||||
$this->getProviderInstance($httpClient)->getToken();
|
||||
}
|
||||
|
||||
public function testAnUnreachableTokenEndpointFails(): void
|
||||
{
|
||||
$httpClient = new MockHttpClient([new MockResponse('', ['error' => 'connection refused'])]);
|
||||
|
||||
$this->expectException(ApiException::class);
|
||||
|
||||
$this->getProviderInstance($httpClient)->getToken();
|
||||
}
|
||||
|
||||
public function testAnUnparsableResponseFails(): void
|
||||
{
|
||||
$httpClient = new MockHttpClient([new MockResponse('<html>gateway timeout</html>')]);
|
||||
|
||||
$this->expectException(ApiException::class);
|
||||
|
||||
$this->getProviderInstance($httpClient)->getToken();
|
||||
}
|
||||
|
||||
private function tokenResponse(string $token, int $expiresIn = 600): MockResponse
|
||||
{
|
||||
return new MockResponse(json_encode([
|
||||
'access_token' => $token,
|
||||
'token_type' => 'Bearer',
|
||||
'expires_in' => $expiresIn,
|
||||
]));
|
||||
}
|
||||
|
||||
private function getProviderInstance(MockHttpClient $httpClient, ?CacheItemPoolInterface $cache = null): AccessTokenProvider
|
||||
{
|
||||
return new AccessTokenProvider(
|
||||
$httpClient,
|
||||
$cache ?? new ArrayAdapter(),
|
||||
new NullLogger(),
|
||||
[
|
||||
'client_id' => 'team-app',
|
||||
'client_secret' => 'secret',
|
||||
'token_path' => 'https://myep.example/token',
|
||||
'scope' => 'api',
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user