From cd2168c8226ddd2ef2e97a36d929911bb6cc06f0 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Fri, 24 Apr 2026 13:25:17 +0300 Subject: [PATCH] test auth middleware --- .../Auth/Middleware/AuthMiddlewareTest.php | 161 ++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 tests/Unit/Auth/Middleware/AuthMiddlewareTest.php diff --git a/tests/Unit/Auth/Middleware/AuthMiddlewareTest.php b/tests/Unit/Auth/Middleware/AuthMiddlewareTest.php new file mode 100644 index 0000000..c79e6a6 --- /dev/null +++ b/tests/Unit/Auth/Middleware/AuthMiddlewareTest.php @@ -0,0 +1,161 @@ +userRepo = new FakeUserRepository(); + $this->sessionRepo = new FakeSessionRepository(); + $this->clock = new FakeClock( + new DateTimeImmutable('2025-01-01T12:00:00+00:00') + ); + $this->user = $this->userRepo->create(new CreateUserDto( + email: new EmailAddress('test@test.com'), + passwordHash: '', + )); + $this->middleware = new AuthMiddleware( + $this->sessionRepo, + $this->userRepo, + $this->clock, + ); + } + + private function makeApiRequest( + ?string $cookieToken = null + ): ServerRequestInterface { + $request = new ServerRequestFactory() + ->createServerRequest('GET', 'http://localhost/api/texts'); + if ($cookieToken !== null) { + $request = $request->withCookieParams([ + 'auth_token' => $cookieToken, + ]); + } + return $request; + } + + private function makeHtmlRequest( + ?string $cookieToken = null + ): ServerRequestInterface { + $request = new ServerRequestFactory() + ->createServerRequest('GET', 'http://localhost/home') + ->withHeader('Accept', 'text/html'); + if ($cookieToken !== null) { + $request = $request->withCookieParams([ + 'auth_token' => $cookieToken, + ]); + } + return $request; + } + + private function makeHandler(): RequestHandlerInterface + { + return new class() implements RequestHandlerInterface { + public ?ServerRequestInterface $capturedRequest = null; + + public function handle( + ServerRequestInterface $request + ): \Psr\Http\Message\ResponseInterface { + $this->capturedRequest = $request; + return new Response(200); + } + }; + } + + public function test_returns_401_json_when_cookie_missing(): void + { + $response = $this->middleware->process( + $this->makeApiRequest(), + $this->makeHandler(), + ); + + $this->assertEquals(401, $response->getStatusCode()); + $this->assertStringContainsString( + 'application/json', + $response->getHeaderLine('Content-Type') + ); + } + + public function test_returns_401_when_token_not_in_repo(): void + { + $response = $this->middleware->process( + $this->makeApiRequest('unknown-token'), + $this->makeHandler(), + ); + + $this->assertEquals(401, $response->getStatusCode()); + } + + public function test_returns_401_when_token_expired(): void + { + $this->sessionRepo->create(new CreateSessionDto( + token: 'expired-token', + userId: $this->user->getId(), + createdAt: new DateTimeImmutable('2024-12-01'), + expiresAt: new DateTimeImmutable('2024-12-08'), + )); + + $response = $this->middleware->process( + $this->makeApiRequest('expired-token'), + $this->makeHandler(), + ); + + $this->assertEquals(401, $response->getStatusCode()); + } + + public function test_attaches_user_to_request_on_success(): void + { + $this->sessionRepo->create(new CreateSessionDto( + token: 'valid-token', + userId: $this->user->getId(), + createdAt: new DateTimeImmutable('2025-01-01'), + expiresAt: new DateTimeImmutable('2025-01-08'), + )); + $handler = $this->makeHandler(); + + $this->middleware->process( + $this->makeApiRequest('valid-token'), + $handler, + ); + + $attached = $handler->capturedRequest->getAttribute('user'); + $this->assertInstanceOf(User::class, $attached); + $this->assertEquals( + 'test@test.com', + (string) $attached->getEmail() + ); + } + + public function test_redirects_to_login_when_html_unauthenticated(): void + { + $response = $this->middleware->process( + $this->makeHtmlRequest(), + $this->makeHandler(), + ); + + $this->assertEquals(302, $response->getStatusCode()); + $this->assertEquals('/login', $response->getHeaderLine('Location')); + } +}