From 76b3af7f2e13e24e3e851d3c1a2fbc7b4bc9d70b Mon Sep 17 00:00:00 2001 From: Charles Date: Wed, 10 Dec 2025 11:53:51 +0100 Subject: [PATCH] Test for AccessToken service --- tests/Service/AccessTokenServiceTest.php | 134 +++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 tests/Service/AccessTokenServiceTest.php diff --git a/tests/Service/AccessTokenServiceTest.php b/tests/Service/AccessTokenServiceTest.php new file mode 100644 index 0000000..ee7d6d9 --- /dev/null +++ b/tests/Service/AccessTokenServiceTest.php @@ -0,0 +1,134 @@ +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); + } +} \ No newline at end of file