|
16 | 16 | use Symfony\Bundle\MakerBundle\Security\UserClassConfiguration;
|
17 | 17 | use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator;
|
18 | 18 | use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
| 19 | +use Symfony\Component\Security\Core\User\User; |
19 | 20 |
|
20 | 21 | class UserClassBuilderTest extends TestCase
|
21 | 22 | {
|
22 | 23 | /**
|
23 | 24 | * @dataProvider getUserInterfaceTests
|
24 | 25 | */
|
25 |
| - public function testAddUserInterfaceImplementation(UserClassConfiguration $userClassConfig, string $expectedFilename) |
| 26 | + public function testAddUserInterfaceImplementation(UserClassConfiguration $userClassConfig, string $expectedFilename): void |
26 | 27 | {
|
27 |
| - $sourceFilename = __DIR__.'/fixtures/source/'.($userClassConfig->isEntity() ? 'UserEntity.php' : 'UserModel.php'); |
| 28 | + if (!interface_exists(PasswordAuthenticatedUserInterface::class)) { |
| 29 | + self::markTestSkipped('Requires Symfony >= 5.3'); |
| 30 | + } |
28 | 31 |
|
29 |
| - $manipulator = new ClassSourceManipulator( |
30 |
| - file_get_contents($sourceFilename), |
31 |
| - true |
32 |
| - ); |
| 32 | + $manipulator = $this->getClassSourceManipulator($userClassConfig); |
33 | 33 |
|
34 | 34 | $classBuilder = new UserClassBuilder();
|
35 | 35 | $classBuilder->addUserInterfaceImplementation($manipulator, $userClassConfig);
|
36 | 36 |
|
37 |
| - $expectedPath = __DIR__.'/fixtures/expected'; |
| 37 | + $expectedPath = $this->getExpectedPath($expectedFilename); |
38 | 38 |
|
39 |
| - // Can be removed when < Symfony 6 support is dropped. |
40 |
| - if (!interface_exists(PasswordAuthenticatedUserInterface::class)) { |
41 |
| - $expectedPath = sprintf('%s/legacy', $expectedPath); |
42 |
| - } |
| 39 | + self::assertStringEqualsFile($expectedPath, $manipulator->getSourceCode()); |
| 40 | + } |
43 | 41 |
|
44 |
| - $expectedPath = sprintf('%s/%s', $expectedPath, $expectedFilename); |
| 42 | + public function getUserInterfaceTests(): \Generator |
| 43 | + { |
| 44 | + yield 'entity_with_email_as_identifier' => [ |
| 45 | + new UserClassConfiguration(true, 'email', true), |
| 46 | + 'UserEntityWithEmailAsIdentifier.php', |
| 47 | + ]; |
45 | 48 |
|
46 |
| - if (!file_exists($expectedPath)) { |
47 |
| - throw new \Exception(sprintf('Expected file missing: "%s"', $expectedPath)); |
| 49 | + yield 'entity_with_password' => [ |
| 50 | + new UserClassConfiguration(true, 'userIdentifier', true), |
| 51 | + 'UserEntityWithPassword.php', |
| 52 | + ]; |
| 53 | + |
| 54 | + yield 'entity_with_user_identifier_as_identifier' => [ |
| 55 | + new UserClassConfiguration(true, 'user_identifier', true), |
| 56 | + 'UserEntityWithUser_IdentifierAsIdentifier.php', |
| 57 | + ]; |
| 58 | + |
| 59 | + yield 'entity_without_password' => [ |
| 60 | + new UserClassConfiguration(true, 'userIdentifier', false), |
| 61 | + 'UserEntityWithoutPassword.php', |
| 62 | + ]; |
| 63 | + |
| 64 | + yield 'model_with_email_as_identifier' => [ |
| 65 | + new UserClassConfiguration(false, 'email', true), |
| 66 | + 'UserModelWithEmailAsIdentifier.php', |
| 67 | + ]; |
| 68 | + |
| 69 | + yield 'model_with_password' => [ |
| 70 | + new UserClassConfiguration(false, 'userIdentifier', true), |
| 71 | + 'UserModelWithPassword.php', |
| 72 | + ]; |
| 73 | + |
| 74 | + yield 'model_without_password' => [ |
| 75 | + new UserClassConfiguration(false, 'userIdentifier', false), |
| 76 | + 'UserModelWithoutPassword.php', |
| 77 | + ]; |
| 78 | + } |
| 79 | + |
| 80 | + /** |
| 81 | + * Covers Symfony <= 5.2 UserInterface::getUsername(). |
| 82 | + * |
| 83 | + * In Symfony 5.3, getUsername was replaced with getUserIdentifier() |
| 84 | + * |
| 85 | + * @dataProvider legacyUserInterfaceGetUsernameDataProvider |
| 86 | + */ |
| 87 | + public function testLegacyUserInterfaceGetUsername(UserClassConfiguration $userClassConfig, string $expectedFilename): void |
| 88 | + { |
| 89 | + if (method_exists(User::class, 'getUserIdentifier')) { |
| 90 | + self::markTestSkipped(); |
48 | 91 | }
|
49 | 92 |
|
50 |
| - $this->assertSame(file_get_contents($expectedPath), $manipulator->getSourceCode()); |
| 93 | + $manipulator = $this->getClassSourceManipulator($userClassConfig); |
| 94 | + |
| 95 | + $classBuilder = new UserClassBuilder(); |
| 96 | + $classBuilder->addUserInterfaceImplementation($manipulator, $userClassConfig); |
| 97 | + |
| 98 | + $expectedPath = $this->getExpectedPath($expectedFilename, 'legacy_get_username'); |
| 99 | + |
| 100 | + self::assertStringEqualsFile($expectedPath, $manipulator->getSourceCode()); |
51 | 101 | }
|
52 | 102 |
|
53 |
| - public function getUserInterfaceTests() |
| 103 | + public function legacyUserInterfaceGetUsernameDataProvider(): \Generator |
54 | 104 | {
|
55 |
| - yield 'entity_email_password' => [ |
56 |
| - new UserClassConfiguration(true, 'email', true), |
57 |
| - 'UserEntityEmailWithPassword.php', |
| 105 | + yield 'entity_with_get_username' => [ |
| 106 | + new UserClassConfiguration(true, 'username', false), |
| 107 | + 'UserEntityGetUsername.php', |
58 | 108 | ];
|
59 | 109 |
|
60 |
| - yield 'entity_username_password' => [ |
61 |
| - new UserClassConfiguration(true, 'username', true), |
62 |
| - 'UserEntityUsernameWithPassword.php', |
| 110 | + yield 'model_with_get_username' => [ |
| 111 | + new UserClassConfiguration(false, 'username', false), |
| 112 | + 'UserModelGetUsername.php', |
63 | 113 | ];
|
64 | 114 |
|
65 |
| - yield 'entity_user_name_password' => [ |
66 |
| - new UserClassConfiguration(true, 'user_name', true), |
67 |
| - 'UserEntityUser_nameWithPassword.php', |
| 115 | + yield 'model_with_email_as_username' => [ |
| 116 | + new UserClassConfiguration(false, 'email', false), |
| 117 | + 'UserModelWithEmailAsUsername.php', |
68 | 118 | ];
|
| 119 | + } |
69 | 120 |
|
70 |
| - yield 'entity_username_no_password' => [ |
71 |
| - new UserClassConfiguration(true, 'username', false), |
72 |
| - 'UserEntityUsernameNoPassword.php', |
| 121 | + /** |
| 122 | + * Covers Symfony <= 5.2 UserInterface::getPassword(). |
| 123 | + * |
| 124 | + * In Symfony 5.3, getPassword was moved from UserInterface::class to the |
| 125 | + * new PasswordAuthenticatedUserInterface::class. |
| 126 | + * |
| 127 | + * @dataProvider legacyUserInterfaceGetPasswordDataProvider |
| 128 | + */ |
| 129 | + public function testLegacyUserInterfaceGetPassword(UserClassConfiguration $userClassConfig, string $expectedFilename): void |
| 130 | + { |
| 131 | + if (interface_exists(PasswordAuthenticatedUserInterface::class)) { |
| 132 | + self::markTestSkipped(); |
| 133 | + } |
| 134 | + |
| 135 | + $manipulator = $this->getClassSourceManipulator($userClassConfig); |
| 136 | + |
| 137 | + $classBuilder = new UserClassBuilder(); |
| 138 | + $classBuilder->addUserInterfaceImplementation($manipulator, $userClassConfig); |
| 139 | + |
| 140 | + $expectedPath = $this->getExpectedPath($expectedFilename, 'legacy_get_password'); |
| 141 | + |
| 142 | + self::assertStringEqualsFile($expectedPath, $manipulator->getSourceCode()); |
| 143 | + } |
| 144 | + |
| 145 | + public function legacyUserInterfaceGetPasswordDataProvider(): \Generator |
| 146 | + { |
| 147 | + yield 'entity_with_password' => [ |
| 148 | + new UserClassConfiguration(true, 'username', true), |
| 149 | + 'UserEntityWithPassword.php', |
73 | 150 | ];
|
74 | 151 |
|
75 |
| - yield 'model_email_password' => [ |
76 |
| - new UserClassConfiguration(false, 'email', true), |
77 |
| - 'UserModelEmailWithPassword.php', |
| 152 | + yield 'entity_without_password' => [ |
| 153 | + new UserClassConfiguration(true, 'username', false), |
| 154 | + 'UserEntityNoPassword.php', |
78 | 155 | ];
|
79 | 156 |
|
80 |
| - yield 'model_username_password' => [ |
| 157 | + yield 'model_with_password' => [ |
81 | 158 | new UserClassConfiguration(false, 'username', true),
|
82 |
| - 'UserModelUsernameWithPassword.php', |
| 159 | + 'UserModelWithPassword.php', |
83 | 160 | ];
|
84 | 161 |
|
85 |
| - yield 'model_username_no_password' => [ |
| 162 | + yield 'model_without_password' => [ |
86 | 163 | new UserClassConfiguration(false, 'username', false),
|
87 |
| - 'UserModelUsernameNoPassword.php', |
| 164 | + 'UserModelNoPassword.php', |
88 | 165 | ];
|
89 | 166 | }
|
| 167 | + |
| 168 | + private function getClassSourceManipulator(UserClassConfiguration $userClassConfiguration): ClassSourceManipulator |
| 169 | + { |
| 170 | + $sourceFilename = __DIR__.'/fixtures/source/'.($userClassConfiguration->isEntity() ? 'UserEntity.php' : 'UserModel.php'); |
| 171 | + |
| 172 | + return new ClassSourceManipulator( |
| 173 | + file_get_contents($sourceFilename), |
| 174 | + true |
| 175 | + ); |
| 176 | + } |
| 177 | + |
| 178 | + private function getExpectedPath(string $expectedFilename, string $subDirectory = null): string |
| 179 | + { |
| 180 | + $basePath = __DIR__.'/fixtures/expected'; |
| 181 | + |
| 182 | + $expectedPath = null === $subDirectory ? sprintf('%s/%s', $basePath, $expectedFilename) : sprintf('%s/%s/%s', $basePath, $subDirectory, $expectedFilename); |
| 183 | + |
| 184 | + if (!file_exists($expectedPath)) { |
| 185 | + throw new \Exception(sprintf('Expected file missing: "%s"', $expectedPath)); |
| 186 | + } |
| 187 | + |
| 188 | + return $expectedPath; |
| 189 | + } |
90 | 190 | }
|
0 commit comments