Rabbi_Gerzi/backend/tests/Unit/Auth/UseCases/AuthenticateUserTest.php
Yisroel Baum 57c75f64c4
test: add failing authenticate user test
Red phase: write AuthenticateUserTest with cases for valid credentials, empty email/password (null and empty string), unknown email, wrong password, and fresh instance guarantee. Fakes included.
2026-05-17 09:45:22 +03:00

126 lines
3.8 KiB
PHP

<?php
namespace Tests\Unit\Auth\UseCases;
use App\Auth\UseCases\AuthenticateUser\AuthenticateUser;
use App\Auth\UseCases\AuthenticateUser\AuthenticateUserRequest;
use App\Exceptions\BadRequestException;
use App\Exceptions\UnauthorizedException;
use App\Shared\ValueObject\EmailAddress;
use App\User\CreateUserDto;
use PHPUnit\Framework\TestCase;
use Tests\Fakes\FakePasswordHasher;
use Tests\Fakes\FakeUserRepository;
class AuthenticateUserTest extends TestCase
{
private FakeUserRepository $userRepo;
private FakePasswordHasher $hasher;
private AuthenticateUser $useCase;
protected function setUp(): void
{
$this->userRepo = new FakeUserRepository();
$this->hasher = new FakePasswordHasher();
$this->useCase = new AuthenticateUser(
$this->userRepo,
$this->hasher,
);
$this->userRepo->create(new CreateUserDto(
email: new EmailAddress('user@example.com'),
passwordHash: $this->hasher->hash('correct-password'),
));
}
public function testAuthenticatesWithValidCredentials(): void
{
$user = $this->useCase->execute(new AuthenticateUserRequest(
email: 'user@example.com',
password: 'correct-password',
));
$this->assertSame('user@example.com', $user->getEmail()->value());
}
public function testThrowsBadRequestWhenEmailIsEmpty(): void
{
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('email is required');
$this->useCase->execute(new AuthenticateUserRequest(
email: '',
password: 'some-password',
));
}
public function testThrowsBadRequestWhenPasswordIsEmpty(): void
{
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('password is required');
$this->useCase->execute(new AuthenticateUserRequest(
email: 'user@example.com',
password: '',
));
}
public function testThrowsBadRequestWhenEmailIsNull(): void
{
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('email is required');
$this->useCase->execute(new AuthenticateUserRequest(
email: null,
password: 'some-password',
));
}
public function testThrowsBadRequestWhenPasswordIsNull(): void
{
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('password is required');
$this->useCase->execute(new AuthenticateUserRequest(
email: 'user@example.com',
password: null,
));
}
public function testThrowsUnauthorizedForUnknownEmail(): void
{
$this->expectException(UnauthorizedException::class);
$this->expectExceptionMessage('invalid credentials');
$this->useCase->execute(new AuthenticateUserRequest(
email: 'unknown@example.com',
password: 'some-password',
));
}
public function testThrowsUnauthorizedForWrongPassword(): void
{
$this->expectException(UnauthorizedException::class);
$this->expectExceptionMessage('invalid credentials');
$this->useCase->execute(new AuthenticateUserRequest(
email: 'user@example.com',
password: 'wrong-password',
));
}
public function testReturnsNewInstanceOnEachCall(): void
{
$user1 = $this->useCase->execute(new AuthenticateUserRequest(
email: 'user@example.com',
password: 'correct-password',
));
$user2 = $this->useCase->execute(new AuthenticateUserRequest(
email: 'user@example.com',
password: 'correct-password',
));
$this->assertNotSame($user1, $user2);
}
}