-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #58 from plug-and-pay/feature/INTEG-238
INTEG-238: create refresh, access token and redirect url
- Loading branch information
Showing
12 changed files
with
496 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PlugAndPay\Sdk\Tests\Feature\Token; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use PlugAndPay\Sdk\Tests\Feature\ClientMock; | ||
|
||
class GetAccessTokenTest extends TestCase | ||
{ | ||
/** @test */ | ||
public function it_should_return_access_token(): void | ||
{ | ||
$client = new ClientMock(200, ['access_token' => 'token']); | ||
$response = $client->getAccessToken('code', 'codeVerifier', 'redirectUri', 123); | ||
|
||
$this->assertEquals(200, $response->status()); | ||
$this->assertEquals([ | ||
'access_token' => 'token', | ||
'code' => 'code', | ||
'codeVerifier' => 'codeVerifier', | ||
'redirectUri' => 'redirectUri', | ||
'clientId' => 123, | ||
], $response->body()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
<?php | ||
|
||
namespace PlugAndPay\Sdk\Tests\Unit; | ||
|
||
use GuzzleHttp\Client as GuzzleClient; | ||
use GuzzleHttp\Psr7\Response as GuzzleResponse; | ||
use PHPUnit\Framework\TestCase; | ||
use PlugAndPay\Sdk\Service\Client; | ||
use PlugAndPay\Sdk\Service\TokenService; | ||
|
||
class ClientTest extends TestCase | ||
{ | ||
/** @test */ | ||
public function it_should_return_random_string(): void | ||
{ | ||
$length = 10; | ||
|
||
$randomString = Client::getRandomString($length); | ||
|
||
$this->assertIsString($randomString); | ||
$this->assertEquals($length, strlen($randomString)); | ||
} | ||
|
||
/** @test */ | ||
public function it_should_return_authorization_url(): void | ||
{ | ||
$clientId = 123; | ||
$state = 'testState'; | ||
$codeVerifier = 'testVerifier'; | ||
$redirectUrl = 'https://example.com/callback'; | ||
|
||
$client = new Client(); | ||
$url = $client->generateAuthorizationUrl($clientId, $state, $codeVerifier, $redirectUrl); | ||
|
||
$this->assertStringContainsString('client_id=123', $url); | ||
$this->assertStringContainsString('state=testState', $url); | ||
$this->assertStringContainsString('redirect_uri=https%3A%2F%2Fexample.com%2Fcallback', $url); | ||
} | ||
|
||
/** @test */ | ||
public function it_should_return_credentials(): void | ||
{ | ||
$code = 'testCode'; | ||
$codeVerifier = 'testVerifier'; | ||
$redirectUrl = 'https://example.com/callback'; | ||
$clientId = 123; | ||
|
||
$mockResponse = new GuzzleResponse(200, [], json_encode(['access_token' => 'testAccessToken', 'refresh_token' => 'testRefreshToken'], JSON_THROW_ON_ERROR)); | ||
$mockGuzzleClient = $this->createMock(GuzzleClient::class); | ||
$mockGuzzleClient->method('request')->willReturn($mockResponse); | ||
|
||
$client = new Client(null, null, null, null, $mockGuzzleClient); | ||
$response = $client->getCredentials($code, $codeVerifier, $redirectUrl, $clientId); | ||
|
||
$this->assertEquals(200, $response->status()); | ||
$this->assertEquals('testAccessToken', $response->body()['access_token']); | ||
} | ||
|
||
/** @test */ | ||
public function it_should_refresh_access_token_if_needed(): void | ||
{ | ||
$mockResponse = new GuzzleResponse(200, [], json_encode(['access_token' => 'newAccessToken'], JSON_THROW_ON_ERROR)); | ||
$mockGuzzleClient = $this->createMock(GuzzleClient::class); | ||
$mockGuzzleClient->method('request')->willReturn($mockResponse); | ||
|
||
$mockTokenService = $this->createMock(TokenService::class); | ||
$mockTokenService->method('isValid')->willReturn(false); | ||
|
||
$client = new Client('expiredAccessToken', 'expiredRefreshToken', null, 123, $mockGuzzleClient, $mockTokenService); | ||
|
||
$client->refreshAccessTokenIfNeeded(); | ||
|
||
$this->assertEquals('newAccessToken', $client->getAccessToken()); | ||
} | ||
|
||
/** @test */ | ||
public function it_should_refresh_access_token(): void | ||
{ | ||
$refreshToken = 'testRefreshToken'; | ||
$clientId = 123; | ||
|
||
$mockResponse = new GuzzleResponse(200, [], json_encode(['access_token' => 'newAccessToken'])); | ||
$mockGuzzleClient = $this->createMock(GuzzleClient::class); | ||
$mockGuzzleClient->method('request')->willReturn($mockResponse); | ||
|
||
$client = new Client(null, null, null, null, $mockGuzzleClient); | ||
$response = $client->refreshAccessToken($refreshToken, $clientId); | ||
|
||
$this->assertEquals(200, $response->status()); | ||
$this->assertEquals('newAccessToken', $response->body()['access_token']); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PlugAndPay\Sdk\Tests\Unit; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use PlugAndPay\Sdk\Support\Str; | ||
|
||
class StringUtilsTest extends TestCase | ||
{ | ||
/** @test */ | ||
public function it_should_generate_correct_string_length(): void | ||
{ | ||
$this->assertEquals(40, strlen(Str::random(40))); | ||
} | ||
|
||
/** @test */ | ||
public function it_should_generate_default_string_length(): void | ||
{ | ||
$this->assertEquals(16, strlen(Str::random())); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PlugAndPay\Sdk\Tests\Unit; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use PlugAndPay\Sdk\Exception\InvalidTokenException; | ||
use PlugAndPay\Sdk\Service\TokenService; | ||
|
||
class TokenServiceTest extends TestCase | ||
{ | ||
/** @test */ | ||
public function it_should_return_true_for_valid_token(): void | ||
{ | ||
$payload = json_encode(['exp' => time() + 3600], JSON_THROW_ON_ERROR); // Token expires in 1 hour | ||
$jwt = $this->createJwt($payload); | ||
|
||
$isTokenValid = (new TokenService)->isValid($jwt); | ||
|
||
$this->assertTrue($isTokenValid); | ||
} | ||
|
||
/** @test */ | ||
public function it_should_return_false_for_invalid_token(): void | ||
{ | ||
$payload = json_encode(['exp' => time() - 3600], JSON_THROW_ON_ERROR); // Token expired 1 hour ago | ||
$jwt = $this->createJwt($payload); | ||
|
||
$isTokenValid = (new TokenService)->isValid($jwt); | ||
|
||
$this->assertFalse($isTokenValid); | ||
} | ||
|
||
/** @test */ | ||
public function it_should_throw_exception_when_jwt_structure_is_invalid(): void | ||
{ | ||
$this->expectException(InvalidTokenException::class); | ||
$this->expectExceptionMessage('Invalid JWT structure.'); | ||
|
||
(new TokenService)->isValid('invalid.jwt'); | ||
} | ||
|
||
/** @test */ | ||
public function it_should_throw_exception_when_payload_is_invalid(): void | ||
{ | ||
$this->expectException(InvalidTokenException::class); | ||
$this->expectExceptionMessage('Invalid payload JSON.'); | ||
|
||
$jwt = $this->createJwt('invalid_json'); | ||
(new TokenService)->isValid($jwt); | ||
} | ||
|
||
/** @test */ | ||
public function it_should_throw_exception_when_expiration_time_is_not_set(): void | ||
{ | ||
$this->expectException(InvalidTokenException::class); | ||
$this->expectExceptionMessage('Expiration time not set in token.'); | ||
|
||
$payload = json_encode(['data' => 'no_exp'], JSON_THROW_ON_ERROR); | ||
$jwt = $this->createJwt($payload); | ||
|
||
(new TokenService)->isValid($jwt); | ||
} | ||
|
||
private function createJwt(string $payload): string | ||
{ | ||
$header = json_encode(['alg' => 'HS256', 'typ' => 'JWT'], JSON_THROW_ON_ERROR); | ||
$base64UrlHeader = $this->base64UrlEncode($header); | ||
$base64UrlPayload = $this->base64UrlEncode($payload); | ||
$signature = 'signature'; // Mock signature for testing | ||
|
||
return $base64UrlHeader . '.' . $base64UrlPayload . '.' . $signature; | ||
} | ||
|
||
/** @test */ | ||
public function it_should_return_false_for_token_with_less_than_30_seconds_ttl(): void | ||
{ | ||
$payload = json_encode(['exp' => time() + 20], JSON_THROW_ON_ERROR); // Token expires in 20 seconds | ||
|
||
$isTokenValid = (new TokenService)->isValid($this->createJwt($payload)); | ||
|
||
$this->assertFalse($isTokenValid); | ||
} | ||
|
||
private function base64UrlEncode(string $input): string | ||
{ | ||
return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($input)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PlugAndPay\Sdk\Exception; | ||
|
||
use Exception; | ||
|
||
class InvalidTokenException extends Exception | ||
{ | ||
public function __construct($message = 'Invalid token') | ||
{ | ||
parent::__construct($message); | ||
} | ||
} |
Oops, something went wrong.