use FakePasswordHasher in tests to eliminate bcrypt cost
Add a trivial prefix-based PasswordHasher fake and inject it into the three test files that exercise CreateUser or AuthenticateUser. Drops the full phpunit suite from ~7.4s to ~30ms (about 224x) without losing coverage: the round-trip through hash/verify still validates that CreateUser stores something other than the plaintext and that AuthenticateUser only succeeds on a matching hash. CreateUserTest is also refactored to use a setUp method, matching the pattern already used in AuthenticateUserTest and AuthControllerTest.
This commit is contained in:
parent
632085f5b6
commit
bb6bd7cbb3
4 changed files with 76 additions and 39 deletions
|
|
@ -10,22 +10,31 @@ use App\User\UseCases\CreateUser;
|
|||
use App\User\UseCases\CreateUserRequest;
|
||||
use App\User\User;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Tests\Fakes\FakePasswordHasher;
|
||||
use Tests\Fakes\FakeUserRepository;
|
||||
|
||||
class AuthenticateUserTest extends TestCase
|
||||
{
|
||||
private FakeUserRepository $userRepo;
|
||||
private FakePasswordHasher $passwordHasher;
|
||||
private AuthenticateUser $useCase;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->userRepo = new FakeUserRepository();
|
||||
$createUser = new CreateUser($this->userRepo);
|
||||
$this->passwordHasher = new FakePasswordHasher();
|
||||
$createUser = new CreateUser(
|
||||
$this->userRepo,
|
||||
$this->passwordHasher,
|
||||
);
|
||||
$createUser->execute(new CreateUserRequest(
|
||||
email: 'test@test.com',
|
||||
password: 'password1',
|
||||
));
|
||||
$this->useCase = new AuthenticateUser($this->userRepo);
|
||||
$this->useCase = new AuthenticateUser(
|
||||
$this->userRepo,
|
||||
$this->passwordHasher,
|
||||
);
|
||||
}
|
||||
|
||||
public function test_returns_user_on_valid_credentials(): void
|
||||
|
|
|
|||
|
|
@ -6,67 +6,71 @@ use App\Exceptions\BadRequestException;
|
|||
use App\User\User;
|
||||
use App\User\UseCases\CreateUser;
|
||||
use App\User\UseCases\CreateUserRequest;
|
||||
use Tests\Fakes\FakePasswordHasher;
|
||||
use Tests\Fakes\FakeUserRepository;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CreateUserTest extends TestCase
|
||||
{
|
||||
private FakeUserRepository $userRepo;
|
||||
private FakePasswordHasher $passwordHasher;
|
||||
private CreateUser $useCase;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->userRepo = new FakeUserRepository();
|
||||
$this->passwordHasher = new FakePasswordHasher();
|
||||
$this->useCase = new CreateUser(
|
||||
$this->userRepo,
|
||||
$this->passwordHasher,
|
||||
);
|
||||
}
|
||||
|
||||
public function test_create_user(): void
|
||||
{
|
||||
$userRepo = new FakeUserRepository();
|
||||
$useCase = new CreateUser($userRepo);
|
||||
$useCase->execute(new CreateUserRequest(
|
||||
$this->useCase->execute(new CreateUserRequest(
|
||||
email: 'test@test.com',
|
||||
password: 'password1',
|
||||
));
|
||||
$user = $userRepo->find(0);
|
||||
$user = $this->userRepo->find(0);
|
||||
$this->assertInstanceOf(User::class, $user);
|
||||
$this->assertEquals('test@test.com', $user->getEmail());
|
||||
}
|
||||
|
||||
public function test_throws_if_email_is_null(): void
|
||||
{
|
||||
$userRepo = new FakeUserRepository();
|
||||
$useCase = new CreateUser($userRepo);
|
||||
|
||||
$this->expectException(BadRequestException::class);
|
||||
$this->expectExceptionMessage('email is required');
|
||||
|
||||
$useCase->execute(new CreateUserRequest(
|
||||
$this->useCase->execute(new CreateUserRequest(
|
||||
email: null,
|
||||
));
|
||||
}
|
||||
|
||||
public function test_is_admin_defaults_to_false(): void
|
||||
{
|
||||
$userRepo = new FakeUserRepository();
|
||||
$useCase = new CreateUser($userRepo);
|
||||
$useCase->execute(new CreateUserRequest(
|
||||
$this->useCase->execute(new CreateUserRequest(
|
||||
email: 'test@test.com',
|
||||
password: 'password1',
|
||||
));
|
||||
$user = $userRepo->find(0);
|
||||
$user = $this->userRepo->find(0);
|
||||
$this->assertFalse($user->isAdmin());
|
||||
}
|
||||
|
||||
public function test_is_admin_can_be_set_true(): void
|
||||
{
|
||||
$userRepo = new FakeUserRepository();
|
||||
$useCase = new CreateUser($userRepo);
|
||||
$useCase->execute(new CreateUserRequest(
|
||||
$this->useCase->execute(new CreateUserRequest(
|
||||
email: 'test@test.com',
|
||||
password: 'password1',
|
||||
isAdmin: true,
|
||||
));
|
||||
$user = $userRepo->find(0);
|
||||
$user = $this->userRepo->find(0);
|
||||
$this->assertTrue($user->isAdmin());
|
||||
}
|
||||
|
||||
public function test_throws_when_email_already_taken(): void
|
||||
{
|
||||
$userRepo = new FakeUserRepository();
|
||||
$useCase = new CreateUser($userRepo);
|
||||
$useCase->execute(new CreateUserRequest(
|
||||
$this->useCase->execute(new CreateUserRequest(
|
||||
email: 'test@test.com',
|
||||
password: 'password1',
|
||||
));
|
||||
|
|
@ -74,7 +78,7 @@ class CreateUserTest extends TestCase
|
|||
$this->expectException(BadRequestException::class);
|
||||
$this->expectExceptionMessage('email already taken');
|
||||
|
||||
$useCase->execute(new CreateUserRequest(
|
||||
$this->useCase->execute(new CreateUserRequest(
|
||||
email: 'test@test.com',
|
||||
password: 'password1',
|
||||
));
|
||||
|
|
@ -82,13 +86,10 @@ class CreateUserTest extends TestCase
|
|||
|
||||
public function test_throws_if_password_is_null(): void
|
||||
{
|
||||
$userRepo = new FakeUserRepository();
|
||||
$useCase = new CreateUser($userRepo);
|
||||
|
||||
$this->expectException(BadRequestException::class);
|
||||
$this->expectExceptionMessage('password is required');
|
||||
|
||||
$useCase->execute(new CreateUserRequest(
|
||||
$this->useCase->execute(new CreateUserRequest(
|
||||
email: 'test@test.com',
|
||||
password: null,
|
||||
));
|
||||
|
|
@ -96,15 +97,12 @@ class CreateUserTest extends TestCase
|
|||
|
||||
public function test_throws_if_password_too_short(): void
|
||||
{
|
||||
$userRepo = new FakeUserRepository();
|
||||
$useCase = new CreateUser($userRepo);
|
||||
|
||||
$this->expectException(BadRequestException::class);
|
||||
$this->expectExceptionMessage(
|
||||
'password must be at least 8 characters'
|
||||
);
|
||||
|
||||
$useCase->execute(new CreateUserRequest(
|
||||
$this->useCase->execute(new CreateUserRequest(
|
||||
email: 'test@test.com',
|
||||
password: 'short',
|
||||
));
|
||||
|
|
@ -112,16 +110,17 @@ class CreateUserTest extends TestCase
|
|||
|
||||
public function test_stores_hashed_password(): void
|
||||
{
|
||||
$userRepo = new FakeUserRepository();
|
||||
$useCase = new CreateUser($userRepo);
|
||||
$useCase->execute(new CreateUserRequest(
|
||||
$this->useCase->execute(new CreateUserRequest(
|
||||
email: 'test@test.com',
|
||||
password: 'password1',
|
||||
));
|
||||
$user = $userRepo->find(0);
|
||||
$user = $this->userRepo->find(0);
|
||||
$this->assertNotEquals('password1', $user->getPasswordHash());
|
||||
$this->assertTrue(
|
||||
password_verify('password1', $user->getPasswordHash())
|
||||
$this->passwordHasher->verify(
|
||||
'password1',
|
||||
$user->getPasswordHash()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue