Test for AccessToken service
This commit is contained in:
parent
ec561ef0a1
commit
76b3af7f2e
|
|
@ -0,0 +1,134 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Tests\Service;
|
||||||
|
|
||||||
|
use App\Service\AccessTokenService;
|
||||||
|
use App\Service\LoggerService;
|
||||||
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
use League\Bundle\OAuth2ServerBundle\Model\AccessToken;
|
||||||
|
use PHPUnit\Framework\MockObject\MockObject;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
class AccessTokenServiceTest extends TestCase
|
||||||
|
{
|
||||||
|
private AccessTokenService $service;
|
||||||
|
|
||||||
|
// Mocks
|
||||||
|
private MockObject|EntityManagerInterface $entityManager;
|
||||||
|
private MockObject|LoggerService $loggerService;
|
||||||
|
|
||||||
|
protected function setUp(): void
|
||||||
|
{
|
||||||
|
$this->entityManager = $this->createMock(EntityManagerInterface::class);
|
||||||
|
$this->loggerService = $this->createMock(LoggerService::class);
|
||||||
|
|
||||||
|
$this->service = new AccessTokenService(
|
||||||
|
$this->entityManager,
|
||||||
|
$this->loggerService
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRevokeUserTokensSuccess(): void
|
||||||
|
{
|
||||||
|
$userIdentifier = 'test@user.com';
|
||||||
|
|
||||||
|
// 1. Create Mock Tokens
|
||||||
|
$token1 = $this->createMock(AccessToken::class);
|
||||||
|
$token1->method('getIdentifier')->willReturn('token_1');
|
||||||
|
|
||||||
|
$token2 = $this->createMock(AccessToken::class);
|
||||||
|
$token2->method('getIdentifier')->willReturn('token_2');
|
||||||
|
|
||||||
|
// 2. Mock Repository to return these tokens
|
||||||
|
$repo = $this->createMock(EntityRepository::class);
|
||||||
|
$repo->expects($this->once())
|
||||||
|
->method('findBy')
|
||||||
|
->with(['userIdentifier' => $userIdentifier, 'revoked' => false])
|
||||||
|
->willReturn([$token1, $token2]);
|
||||||
|
|
||||||
|
$this->entityManager->expects($this->once())
|
||||||
|
->method('getRepository')
|
||||||
|
->with(AccessToken::class)
|
||||||
|
->willReturn($repo);
|
||||||
|
|
||||||
|
// 3. Expect revoke() to be called on EACH token
|
||||||
|
$token1->expects($this->once())->method('revoke');
|
||||||
|
$token2->expects($this->once())->method('revoke');
|
||||||
|
|
||||||
|
// 4. Expect success logs
|
||||||
|
$this->loggerService->expects($this->exactly(2))
|
||||||
|
->method('logTokenRevocation')
|
||||||
|
->with(
|
||||||
|
'Access token revoked for user',
|
||||||
|
$this->callback(function ($context) use ($userIdentifier) {
|
||||||
|
return $context['user_identifier'] === $userIdentifier
|
||||||
|
&& in_array($context['token_id'], ['token_1', 'token_2']);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// 5. Run
|
||||||
|
$this->service->revokeUserTokens($userIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRevokeUserTokensHandlesException(): void
|
||||||
|
{
|
||||||
|
$userIdentifier = 'fail@user.com';
|
||||||
|
|
||||||
|
// 1. Create a Token that fails to revoke
|
||||||
|
$tokenBad = $this->createMock(AccessToken::class);
|
||||||
|
$tokenBad->method('getIdentifier')->willReturn('bad_token');
|
||||||
|
|
||||||
|
// Throw exception when revoke is called
|
||||||
|
$tokenBad->expects($this->once())
|
||||||
|
->method('revoke')
|
||||||
|
->willThrowException(new \Exception('DB Connection Lost'));
|
||||||
|
|
||||||
|
// 2. Create a Token that works (to prove loop continues, if applicable)
|
||||||
|
// Your code uses try-catch inside the loop, so it SHOULD continue.
|
||||||
|
$tokenGood = $this->createMock(AccessToken::class);
|
||||||
|
$tokenGood->method('getIdentifier')->willReturn('good_token');
|
||||||
|
$tokenGood->expects($this->once())->method('revoke');
|
||||||
|
|
||||||
|
// 3. Mock Repository
|
||||||
|
$repo = $this->createMock(EntityRepository::class);
|
||||||
|
$repo->method('findBy')->willReturn([$tokenBad, $tokenGood]);
|
||||||
|
$this->entityManager->method('getRepository')->willReturn($repo);
|
||||||
|
|
||||||
|
// 4. Expect Logger calls
|
||||||
|
// Expect 1 Error log
|
||||||
|
$this->loggerService->expects($this->once())
|
||||||
|
->method('logError')
|
||||||
|
->with(
|
||||||
|
'Error revoking access token: DB Connection Lost',
|
||||||
|
['user_identifier' => $userIdentifier, 'token_id' => 'bad_token']
|
||||||
|
);
|
||||||
|
|
||||||
|
// Expect 1 Success log (for the good token)
|
||||||
|
$this->loggerService->expects($this->once())
|
||||||
|
->method('logTokenRevocation')
|
||||||
|
->with(
|
||||||
|
'Access token revoked for user',
|
||||||
|
['user_identifier' => $userIdentifier, 'token_id' => 'good_token']
|
||||||
|
);
|
||||||
|
|
||||||
|
// 5. Run
|
||||||
|
$this->service->revokeUserTokens($userIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRevokeUserTokensDoesNothingIfNoneFound(): void
|
||||||
|
{
|
||||||
|
$userIdentifier = 'ghost@user.com';
|
||||||
|
|
||||||
|
$repo = $this->createMock(EntityRepository::class);
|
||||||
|
$repo->method('findBy')->willReturn([]); // Empty array
|
||||||
|
|
||||||
|
$this->entityManager->method('getRepository')->willReturn($repo);
|
||||||
|
|
||||||
|
// Expect NO logs
|
||||||
|
$this->loggerService->expects($this->never())->method('logTokenRevocation');
|
||||||
|
$this->loggerService->expects($this->never())->method('logError');
|
||||||
|
|
||||||
|
$this->service->revokeUserTokens($userIdentifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue