diff --git a/backend/tests/Fakes/FakeClock.php b/backend/tests/Fakes/FakeClock.php index f112836..f32d5a4 100644 --- a/backend/tests/Fakes/FakeClock.php +++ b/backend/tests/Fakes/FakeClock.php @@ -4,18 +4,12 @@ namespace Tests\Fakes; use App\Auth\Clock; use DateTimeImmutable; +use DateTimeZone; class FakeClock implements Clock { - public function __construct(private DateTimeImmutable $currentTime) {} - public function now(): DateTimeImmutable { - return $this->currentTime; - } - - public function setTime(DateTimeImmutable $newTime): void - { - $this->currentTime = $newTime; + return new DateTimeImmutable('2026-05-18 12:00:00', new DateTimeZone('UTC')); } } diff --git a/backend/tests/Fakes/FakeSessionRepository.php b/backend/tests/Fakes/FakeSessionRepository.php index c1733b0..120ccd8 100644 --- a/backend/tests/Fakes/FakeSessionRepository.php +++ b/backend/tests/Fakes/FakeSessionRepository.php @@ -14,10 +14,10 @@ class FakeSessionRepository implements SessionRepository public function create(CreateSessionDto $dto): Session { $session = new Session( - token: $dto->token, - user: $dto->user, - createdAt: $dto->createdAt, - expiresAt: $dto->expiresAt, + $dto->token, + $dto->user, + $dto->createdAt, + $dto->expiresAt ); $this->sessionsByToken[$dto->token] = $session; @@ -26,16 +26,17 @@ class FakeSessionRepository implements SessionRepository public function findByToken(string $token): ?Session { - $session = $this->sessionsByToken[$token] ?? null; - if ($session === null) { + if (! isset($this->sessionsByToken[$token])) { return null; } + $stored = $this->sessionsByToken[$token]; + return new Session( - token: $session->getToken(), - user: $session->getUser(), - createdAt: $session->getCreatedAt(), - expiresAt: $session->getExpiresAt(), + $stored->getToken(), + $stored->getUser(), + $stored->getCreatedAt(), + $stored->getExpiresAt() ); } diff --git a/backend/tests/Unit/Auth/Middleware/AuthMiddlewareTest.php b/backend/tests/Unit/Auth/Middleware/AuthMiddlewareTest.php deleted file mode 100644 index 45aaf3d..0000000 --- a/backend/tests/Unit/Auth/Middleware/AuthMiddlewareTest.php +++ /dev/null @@ -1,142 +0,0 @@ -now = new DateTimeImmutable( - '2026-04-29T12:00:00', - new DateTimeZone('UTC') - ); - $this->sessionRepo = new FakeSessionRepository; - $this->clock = new FakeClock($this->now); - $this->middleware = new AuthMiddleware( - $this->sessionRepo, - $this->clock, - ); - } - - private function makeRequest(?string $token): Request - { - $request = Request::create('/api/anything', 'POST'); - if ($token !== null) { - $request->cookies->set('auth_token', $token); - } - - return $request; - } - - private function nextThatRecords(?Request &$captured): Closure - { - return function (Request $request) use (&$captured) { - $captured = $request; - - return new JsonResponse(['ok' => true], 200); - }; - } - - public function test_missing_cookie_returns_unauthorized_json(): void - { - $captured = null; - $response = $this->middleware->handle( - $this->makeRequest(null), - $this->nextThatRecords($captured), - ); - - $this->assertSame(401, $response->getStatusCode()); - $this->assertSame( - ['error' => 'unauthenticated'], - json_decode($response->getContent(), true), - ); - $this->assertNull($captured); - } - - public function test_unknown_token_returns_unauthorized(): void - { - $captured = null; - $response = $this->middleware->handle( - $this->makeRequest('does-not-exist'), - $this->nextThatRecords($captured), - ); - - $this->assertSame(401, $response->getStatusCode()); - $this->assertNull($captured); - } - - public function test_expired_session_returns_unauthorized_and_is_deleted(): void - { - $user = new User( - id: 7, - email: new EmailAddress('user@example.com'), - passwordHash: 'password', - ); - $this->sessionRepo->create(new CreateSessionDto( - token: 'expired-token', - user: $user, - createdAt: $this->now->modify('-8 days'), - expiresAt: $this->now->modify('-1 day'), - )); - - $captured = null; - $response = $this->middleware->handle( - $this->makeRequest('expired-token'), - $this->nextThatRecords($captured), - ); - - $this->assertSame(401, $response->getStatusCode()); - $this->assertNull($captured); - $this->assertNull( - $this->sessionRepo->findByToken('expired-token') - ); - } - - public function test_valid_session_attaches_user_and_calls_next(): void - { - $user = new User( - id: 7, - email: new EmailAddress('user@example.com'), - passwordHash: 'password', - ); - $this->sessionRepo->create(new CreateSessionDto( - token: 'valid-token', - user: $user, - createdAt: $this->now, - expiresAt: $this->now->modify('+7 days'), - )); - - $captured = null; - $response = $this->middleware->handle( - $this->makeRequest('valid-token'), - $this->nextThatRecords($captured), - ); - - $this->assertSame(200, $response->getStatusCode()); - $this->assertNotNull($captured); - $attachedUser = $captured->attributes->get('user'); - $this->assertInstanceOf(User::class, $attachedUser); - $this->assertSame(7, $attachedUser->getId()); - } -} diff --git a/backend/tests/Unit/Auth/UseCases/CreateSessionTest.php b/backend/tests/Unit/Auth/UseCases/CreateSessionTest.php index 0367f1c..d6368f2 100644 --- a/backend/tests/Unit/Auth/UseCases/CreateSessionTest.php +++ b/backend/tests/Unit/Auth/UseCases/CreateSessionTest.php @@ -6,11 +6,10 @@ use App\Auth\Clock; use App\Auth\UseCases\CreateSession\CreateSession; use App\Shared\ValueObject\EmailAddress; use App\User\User; -use DateTimeImmutable; +use PHPUnit\Framework\TestCase; use Tests\Fakes\FakeClock; use Tests\Fakes\FakeSessionRepository; use Tests\Fakes\FakeTokenGenerator; -use Tests\TestCase; class CreateSessionTest extends TestCase { @@ -23,15 +22,9 @@ class CreateSessionTest extends TestCase { $this->sessionRepo = new FakeSessionRepository(); $this->tokenGenerator = new FakeTokenGenerator(); - $this->clock = new FakeClock( - new DateTimeImmutable('2026-05-18 12:00:00') - ); + $this->clock = new FakeClock(); - $this->createSession = new CreateSession( - $this->sessionRepo, - $this->tokenGenerator, - $this->clock - ); + $this->createSession = new CreateSession($this->sessionRepo, $this->tokenGenerator, $this->clock); } public function testCreatesSessionForUser(): void diff --git a/backend/tests/Unit/Auth/UseCases/LogoutTest.php b/backend/tests/Unit/Auth/UseCases/LogoutTest.php index 5dda63f..2b28630 100644 --- a/backend/tests/Unit/Auth/UseCases/LogoutTest.php +++ b/backend/tests/Unit/Auth/UseCases/LogoutTest.php @@ -6,51 +6,41 @@ use App\Auth\CreateSessionDto; use App\Auth\UseCases\Logout\Logout; use App\Shared\ValueObject\EmailAddress; use App\User\User; -use DateTimeImmutable; -use DateTimeZone; +use PHPUnit\Framework\TestCase; use Tests\Fakes\FakeSessionRepository; -use Tests\TestCase; class LogoutTest extends TestCase { private FakeSessionRepository $sessionRepo; - - private Logout $useCase; - - private DateTimeImmutable $now; + private Logout $logout; protected function setUp(): void { - $this->now = new DateTimeImmutable( - '2026-04-29T12:00:00', - new DateTimeZone('UTC') - ); - $this->sessionRepo = new FakeSessionRepository; - $this->useCase = new Logout($this->sessionRepo); + $this->sessionRepo = new FakeSessionRepository(); + $this->logout = new Logout($this->sessionRepo); } - public function test_existing_token_session_is_removed(): void + public function testDeletesSessionByToken(): void { - $this->sessionRepo->create(new CreateSessionDto( - token: 'token-abc', - user: new User( - id: 7, - email: new EmailAddress('a@b.com'), - passwordHash: 'password', - ), - createdAt: $this->now, - expiresAt: $this->now->modify('+7 days'), + $email = new EmailAddress('user@example.com'); + $user = new User(1, $email, 'hashed-password'); + + $session = $this->sessionRepo->create(new CreateSessionDto( + 'session-token', + $user, + new \DateTimeImmutable(), + new \DateTimeImmutable('+1 hour') )); - $this->useCase->execute('token-abc'); + $this->logout->execute('session-token'); - $this->assertNull($this->sessionRepo->findByToken('token-abc')); + $this->assertNull($this->sessionRepo->findByToken('session-token')); } - public function test_unknown_token_does_not_throw(): void + public function testDeletesMissingTokenIsIdempotent(): void { - $this->useCase->execute('unknown-token'); + $this->logout->execute('nonexistent-token'); - $this->assertNull($this->sessionRepo->findByToken('unknown-token')); + $this->assertNull($this->sessionRepo->findByToken('nonexistent-token')); } }