buckets/tests/Entity/UserPersistenceTest.php
2026-06-17 23:49:43 +02:00

85 lines
2.8 KiB
PHP

<?php
namespace App\Tests\Entity;
use App\Entity\User;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\PasswordHasher\Hasher\NativePasswordHasher;
use Symfony\Component\PasswordHasher\Hasher\PasswordHasherFactory;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasher;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Uid\UuidV7;
final class UserPersistenceTest extends KernelTestCase
{
private EntityManagerInterface $em;
private UserPasswordHasherInterface $hasher;
protected function setUp(): void
{
self::bootKernel();
$this->em = self::getContainer()->get(EntityManagerInterface::class);
// Build the hasher directly — avoids the chicken-and-egg where
// UserPasswordHasherInterface gets compiled away before User exists.
$factory = new PasswordHasherFactory([
User::class => new NativePasswordHasher(cost: 4),
]);
$this->hasher = new UserPasswordHasher($factory);
}
public function testItPersistsAUserWithUuidIdentifierAndHashedPassword(): void
{
$hasher = $this->hasher;
$user = new User();
$user->setEmail('alice@example.com');
$user->setPassword($hasher->hashPassword($user, 'secret123'));
$this->em->persist($user);
$this->em->flush();
$id = $user->getId();
self::assertInstanceOf(UuidV7::class, $id);
$this->em->clear();
$reloaded = $this->em->find(User::class, $id);
self::assertNotNull($reloaded, 'User must be retrievable from the database after an identity-map clear.');
self::assertInstanceOf(User::class, $reloaded);
self::assertSame('alice@example.com', $reloaded->getEmail());
self::assertTrue(
$hasher->isPasswordValid($reloaded, 'secret123'),
'Stored password hash must verify against the original plain-text password.',
);
self::assertStringNotContainsString(
'secret123',
$reloaded->getPassword(),
'Plain-text password must never be stored.',
);
}
public function testEmailMustBeUnique(): void
{
$hasher = $this->hasher;
$first = new User();
$first->setEmail('bob@example.com');
$first->setPassword($hasher->hashPassword($first, 'pass1'));
$this->em->persist($first);
$this->em->flush();
$this->em->clear();
$second = new User();
$second->setEmail('bob@example.com');
$second->setPassword($hasher->hashPassword($second, 'pass2'));
$this->em->persist($second);
$this->expectException(UniqueConstraintViolationException::class);
$this->em->flush();
}
}