-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUserManagerTest.php
More file actions
114 lines (93 loc) · 4.72 KB
/
Copy pathUserManagerTest.php
File metadata and controls
114 lines (93 loc) · 4.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<?php
declare(strict_types=1);
namespace App\Tests\Integration\Security;
use App\Enum\UserStatus;
use App\Repository\UserRepository;
use App\Security\UserManager;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
/**
* Tests for {@see UserManager}.
*
* Relies on the baseline `UserFixtures` (alice + bob with password
* `password`) loaded by `tests/bootstrap_integration.php`. Tests that
* exercise the "create a brand-new user" path use a non-fixture email
* (`charlie@example.test`) to avoid colliding with the baseline.
*/
final class UserManagerTest extends KernelTestCase
{
private UserManager $userManager;
private UserRepository $userRepository;
private UserPasswordHasherInterface $passwordHasher;
protected function setUp(): void
{
self::bootKernel();
$container = self::getContainer();
$this->userManager = $container->get(UserManager::class);
$this->userRepository = $container->get(UserRepository::class);
$this->passwordHasher = $container->get(UserPasswordHasherInterface::class);
}
// Tests the happy path: createUser persists a user with hashed password, name, default Approved status, and ROLE_USER.
public function testCreatesAndPersistsUserWithHashedPassword(): void
{
$user = $this->userManager->createUser('charlie@example.test', 'Charlie', 'secret');
self::assertNotNull($user->getId());
self::assertSame('charlie@example.test', $user->getEmail());
self::assertSame('Charlie', $user->getName());
self::assertSame(UserStatus::Approved, $user->getStatus());
self::assertSame(['ROLE_USER'], $user->getRoles());
self::assertNotSame('secret', $user->getPassword(), 'Password must be hashed.');
self::assertTrue(
$this->passwordHasher->isPasswordValid($user, 'secret'),
'Hashed password must verify against the original plain text.',
);
self::assertSame($user->getId(), $this->userRepository->findOneBy(['email' => 'charlie@example.test'])?->getId());
}
// Verifies that extra roles passed to createUser() are stored alongside the implicit ROLE_USER.
public function testCreateUserStoresExtraRoles(): void
{
$user = $this->userManager->createUser('admin@example.test', 'Admin', 'secret', ['ROLE_ADMIN']);
self::assertSame(['ROLE_ADMIN', 'ROLE_USER'], $user->getRoles());
}
// Ensures createUser() throws DomainException when the email matches an existing user.
public function testCreateUserRejectsDuplicateEmail(): void
{
// alice@example.test is loaded by UserFixtures in the bootstrap.
$this->expectException(\DomainException::class);
$this->expectExceptionMessage('alice@example.test');
$this->userManager->createUser('alice@example.test', 'Alice', 'other');
}
// Ensures createUser() throws InvalidArgumentException when the password is empty.
public function testCreateUserRejectsEmptyPassword(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Password must not be empty.');
$this->userManager->createUser('charlie@example.test', 'Charlie', '');
}
// Tests that changePassword() replaces the stored hash and the new password verifies (while the old one no longer does).
public function testChangePasswordReplacesTheHash(): void
{
$alice = $this->userRepository->findOneBy(['email' => 'alice@example.test']);
self::assertNotNull($alice);
$oldHash = $alice->getPassword();
$updated = $this->userManager->changePassword('alice@example.test', 'new');
self::assertSame($alice->getId(), $updated->getId());
self::assertNotSame($oldHash, $updated->getPassword());
self::assertTrue($this->passwordHasher->isPasswordValid($updated, 'new'));
self::assertFalse($this->passwordHasher->isPasswordValid($updated, 'password'));
}
// Ensures changePassword() throws DomainException when no user matches the given email.
public function testChangePasswordFailsWhenUserMissing(): void
{
$this->expectException(\DomainException::class);
$this->expectExceptionMessage('nobody@example.test');
$this->userManager->changePassword('nobody@example.test', 'whatever');
}
// Ensures changePassword() throws InvalidArgumentException when the new password is empty.
public function testChangePasswordRejectsEmptyPassword(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('Password must not be empty.');
$this->userManager->changePassword('alice@example.test', '');
}
}