test auth controller
This commit is contained in:
parent
6c5833af5e
commit
edfe7259a3
1 changed files with 284 additions and 0 deletions
284
tests/e2e/Controllers/AuthControllerTest.php
Normal file
284
tests/e2e/Controllers/AuthControllerTest.php
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\e2e\Controllers;
|
||||
|
||||
use App\Auth\AuthController;
|
||||
use App\Auth\AuthMiddleware;
|
||||
use App\Auth\CreateSessionDto;
|
||||
use App\Auth\UseCases\CreateSession;
|
||||
use App\User\UseCases\AuthenticateUser;
|
||||
use App\User\UseCases\CreateUser;
|
||||
use App\User\UseCases\CreateUserRequest;
|
||||
use App\User\User;
|
||||
use App\ValueObjects\EmailAddress;
|
||||
use DateTimeImmutable;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Slim\Psr7\Factory\ServerRequestFactory;
|
||||
use Slim\Psr7\Factory\StreamFactory;
|
||||
use Slim\Psr7\Response;
|
||||
use Tests\Fakes\FakeClock;
|
||||
use Tests\Fakes\FakeSessionRepository;
|
||||
use Tests\Fakes\FakeTokenGenerator;
|
||||
use Tests\Fakes\FakeUserRepository;
|
||||
|
||||
class AuthControllerTest extends TestCase
|
||||
{
|
||||
private FakeUserRepository $userRepo;
|
||||
private FakeSessionRepository $sessionRepo;
|
||||
private FakeTokenGenerator $tokenGenerator;
|
||||
private FakeClock $clock;
|
||||
private CreateUser $createUser;
|
||||
private AuthenticateUser $authenticateUser;
|
||||
private CreateSession $createSession;
|
||||
private AuthController $controller;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->userRepo = new FakeUserRepository();
|
||||
$this->sessionRepo = new FakeSessionRepository();
|
||||
$this->tokenGenerator = new FakeTokenGenerator(
|
||||
['session-token-xyz']
|
||||
);
|
||||
$this->clock = new FakeClock(
|
||||
new DateTimeImmutable('2025-01-01T12:00:00+00:00')
|
||||
);
|
||||
|
||||
$this->createUser = new CreateUser($this->userRepo);
|
||||
$this->authenticateUser = new AuthenticateUser($this->userRepo);
|
||||
$this->createSession = new CreateSession(
|
||||
$this->sessionRepo,
|
||||
$this->tokenGenerator,
|
||||
$this->clock,
|
||||
);
|
||||
|
||||
$this->createUser->execute(new CreateUserRequest(
|
||||
email: 'existing@test.com',
|
||||
password: 'password1',
|
||||
));
|
||||
|
||||
$this->controller = new AuthController();
|
||||
}
|
||||
|
||||
private function makeJsonRequest(
|
||||
string $method,
|
||||
string $path,
|
||||
array $data = [],
|
||||
): ServerRequestInterface {
|
||||
$body = new StreamFactory()->createStream(json_encode($data));
|
||||
return new ServerRequestFactory()
|
||||
->createServerRequest($method, 'http://localhost' . $path)
|
||||
->withHeader('Content-Type', 'application/json')
|
||||
->withBody($body);
|
||||
}
|
||||
|
||||
public function test_login_returns_200_and_user(): void
|
||||
{
|
||||
$response = $this->controller->login(
|
||||
$this->makeJsonRequest('POST', '/api/auth/login', [
|
||||
'email' => 'existing@test.com',
|
||||
'password' => 'password1',
|
||||
]),
|
||||
new Response(),
|
||||
$this->authenticateUser,
|
||||
$this->createSession,
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$body = json_decode($response->getBody(), true);
|
||||
$this->assertEquals(
|
||||
'existing@test.com',
|
||||
$body['user']['email']
|
||||
);
|
||||
}
|
||||
|
||||
public function test_login_sets_auth_cookie(): void
|
||||
{
|
||||
$response = $this->controller->login(
|
||||
$this->makeJsonRequest('POST', '/api/auth/login', [
|
||||
'email' => 'existing@test.com',
|
||||
'password' => 'password1',
|
||||
]),
|
||||
new Response(),
|
||||
$this->authenticateUser,
|
||||
$this->createSession,
|
||||
);
|
||||
|
||||
$setCookie = $response->getHeaderLine('Set-Cookie');
|
||||
$this->assertStringContainsString(
|
||||
'auth_token=session-token-xyz',
|
||||
$setCookie
|
||||
);
|
||||
$this->assertStringContainsString('HttpOnly', $setCookie);
|
||||
$this->assertStringContainsString('SameSite=Lax', $setCookie);
|
||||
$this->assertStringContainsString('Path=/', $setCookie);
|
||||
}
|
||||
|
||||
public function test_login_creates_session(): void
|
||||
{
|
||||
$this->controller->login(
|
||||
$this->makeJsonRequest('POST', '/api/auth/login', [
|
||||
'email' => 'existing@test.com',
|
||||
'password' => 'password1',
|
||||
]),
|
||||
new Response(),
|
||||
$this->authenticateUser,
|
||||
$this->createSession,
|
||||
);
|
||||
|
||||
$this->assertNotNull(
|
||||
$this->sessionRepo->findByToken('session-token-xyz')
|
||||
);
|
||||
}
|
||||
|
||||
public function test_login_returns_401_on_wrong_password(): void
|
||||
{
|
||||
$response = $this->controller->login(
|
||||
$this->makeJsonRequest('POST', '/api/auth/login', [
|
||||
'email' => 'existing@test.com',
|
||||
'password' => 'wrongpassword',
|
||||
]),
|
||||
new Response(),
|
||||
$this->authenticateUser,
|
||||
$this->createSession,
|
||||
);
|
||||
|
||||
$this->assertEquals(401, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function test_login_returns_400_when_email_missing(): void
|
||||
{
|
||||
$response = $this->controller->login(
|
||||
$this->makeJsonRequest('POST', '/api/auth/login', [
|
||||
'password' => 'password1',
|
||||
]),
|
||||
new Response(),
|
||||
$this->authenticateUser,
|
||||
$this->createSession,
|
||||
);
|
||||
|
||||
$this->assertEquals(400, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function test_register_creates_user_and_logs_in(): void
|
||||
{
|
||||
$response = $this->controller->register(
|
||||
$this->makeJsonRequest('POST', '/api/auth/register', [
|
||||
'email' => 'new@test.com',
|
||||
'password' => 'password1',
|
||||
]),
|
||||
new Response(),
|
||||
$this->createUser,
|
||||
$this->createSession,
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$body = json_decode($response->getBody(), true);
|
||||
$this->assertEquals('new@test.com', $body['user']['email']);
|
||||
$setCookie = $response->getHeaderLine('Set-Cookie');
|
||||
$this->assertStringContainsString(
|
||||
'auth_token=session-token-xyz',
|
||||
$setCookie
|
||||
);
|
||||
}
|
||||
|
||||
public function test_register_returns_400_on_short_password(): void
|
||||
{
|
||||
$response = $this->controller->register(
|
||||
$this->makeJsonRequest('POST', '/api/auth/register', [
|
||||
'email' => 'new@test.com',
|
||||
'password' => 'short',
|
||||
]),
|
||||
new Response(),
|
||||
$this->createUser,
|
||||
$this->createSession,
|
||||
);
|
||||
|
||||
$this->assertEquals(400, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function test_register_returns_400_on_duplicate_email(): void
|
||||
{
|
||||
$response = $this->controller->register(
|
||||
$this->makeJsonRequest('POST', '/api/auth/register', [
|
||||
'email' => 'existing@test.com',
|
||||
'password' => 'password1',
|
||||
]),
|
||||
new Response(),
|
||||
$this->createUser,
|
||||
$this->createSession,
|
||||
);
|
||||
|
||||
$this->assertEquals(400, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function test_register_ignores_is_admin_in_body(): void
|
||||
{
|
||||
$this->controller->register(
|
||||
$this->makeJsonRequest('POST', '/api/auth/register', [
|
||||
'email' => 'sneaky@test.com',
|
||||
'password' => 'password1',
|
||||
'isAdmin' => true,
|
||||
]),
|
||||
new Response(),
|
||||
$this->createUser,
|
||||
$this->createSession,
|
||||
);
|
||||
|
||||
$newUser = $this->userRepo->findByEmail(
|
||||
new EmailAddress('sneaky@test.com')
|
||||
);
|
||||
$this->assertFalse($newUser->isAdmin());
|
||||
}
|
||||
|
||||
public function test_logout_deletes_session_and_clears_cookie(): void
|
||||
{
|
||||
$this->sessionRepo->create(new CreateSessionDto(
|
||||
token: 'existing-session',
|
||||
userId: 0,
|
||||
createdAt: new DateTimeImmutable('2025-01-01'),
|
||||
expiresAt: new DateTimeImmutable('2025-01-08'),
|
||||
));
|
||||
|
||||
$request = $this->makeJsonRequest(
|
||||
'POST',
|
||||
'/api/auth/logout',
|
||||
)->withCookieParams(['auth_token' => 'existing-session']);
|
||||
|
||||
$response = $this->controller->logout(
|
||||
$request,
|
||||
new Response(),
|
||||
$this->sessionRepo,
|
||||
);
|
||||
|
||||
$this->assertEquals(204, $response->getStatusCode());
|
||||
$this->assertNull(
|
||||
$this->sessionRepo->findByToken('existing-session')
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
'auth_token=;',
|
||||
$response->getHeaderLine('Set-Cookie')
|
||||
);
|
||||
}
|
||||
|
||||
public function test_me_returns_current_user(): void
|
||||
{
|
||||
$user = new User(
|
||||
id: 5,
|
||||
email: new EmailAddress('me@test.com'),
|
||||
passwordHash: '',
|
||||
isAdmin: true,
|
||||
);
|
||||
$request = new ServerRequestFactory()
|
||||
->createServerRequest('GET', 'http://localhost/api/auth/me')
|
||||
->withAttribute('user', $user);
|
||||
|
||||
$response = $this->controller->me($request, new Response());
|
||||
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$body = json_decode($response->getBody(), true);
|
||||
$this->assertEquals(5, $body['user']['id']);
|
||||
$this->assertEquals('me@test.com', $body['user']['email']);
|
||||
$this->assertTrue($body['user']['isAdmin']);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue