1 | <?php |
||||
2 | declare(strict_types=1); |
||||
3 | |||||
4 | /* |
||||
5 | Copyright (C) 2006-2018 David Négrier - THE CODING MACHINE |
||||
6 | |||||
7 | This program is free software; you can redistribute it and/or modify |
||||
8 | it under the terms of the GNU General Public License as published by |
||||
9 | the Free Software Foundation; either version 2 of the License, or |
||||
10 | (at your option) any later version. |
||||
11 | |||||
12 | This program is distributed in the hope that it will be useful, |
||||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
15 | GNU General Public License for more details. |
||||
16 | |||||
17 | You should have received a copy of the GNU General Public License |
||||
18 | along with this program; if not, write to the Free Software |
||||
19 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
||||
20 | */ |
||||
21 | |||||
22 | namespace TheCodingMachine\TDBM; |
||||
23 | |||||
24 | use Doctrine\Common\Cache\ArrayCache; |
||||
25 | use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException; |
||||
26 | use Doctrine\DBAL\Exception\UniqueConstraintViolationException; |
||||
27 | use Doctrine\DBAL\Platforms\MySQL57Platform; |
||||
28 | use Doctrine\DBAL\Platforms\MySqlPlatform; |
||||
29 | use Doctrine\DBAL\Platforms\OraclePlatform; |
||||
30 | use Mouf\Database\SchemaAnalyzer\SchemaAnalyzer; |
||||
31 | use Ramsey\Uuid\Uuid; |
||||
32 | use ReflectionClass; |
||||
33 | use ReflectionMethod; |
||||
34 | use ReflectionNamedType; |
||||
35 | use TheCodingMachine\TDBM\Dao\TestAlbumDao; |
||||
36 | use TheCodingMachine\TDBM\Dao\TestArticleDao; |
||||
37 | use TheCodingMachine\TDBM\Dao\TestArticleSubQueryDao; |
||||
38 | use TheCodingMachine\TDBM\Dao\TestCountryDao; |
||||
39 | use TheCodingMachine\TDBM\Dao\TestPersonDao; |
||||
40 | use TheCodingMachine\TDBM\Dao\TestRoleDao; |
||||
41 | use TheCodingMachine\TDBM\Dao\TestUserDao; |
||||
42 | use TheCodingMachine\TDBM\Fixtures\Interfaces\TestUserDaoInterface; |
||||
43 | use TheCodingMachine\TDBM\Fixtures\Interfaces\TestUserInterface; |
||||
44 | use TheCodingMachine\TDBM\Test\Dao\AlbumDao; |
||||
45 | use TheCodingMachine\TDBM\Test\Dao\AllNullableDao; |
||||
46 | use TheCodingMachine\TDBM\Test\Dao\AnimalDao; |
||||
47 | use TheCodingMachine\TDBM\Test\Dao\ArtistDao; |
||||
48 | use TheCodingMachine\TDBM\Test\Dao\BaseObjectDao; |
||||
49 | use TheCodingMachine\TDBM\Test\Dao\Bean\AccountBean; |
||||
50 | use TheCodingMachine\TDBM\Test\Dao\Bean\AlbumBean; |
||||
51 | use TheCodingMachine\TDBM\Test\Dao\Bean\AllNullableBean; |
||||
52 | use TheCodingMachine\TDBM\Test\Dao\Bean\AnimalBean; |
||||
53 | use TheCodingMachine\TDBM\Test\Dao\Bean\Article2Bean; |
||||
54 | use TheCodingMachine\TDBM\Test\Dao\Bean\ArticleBean; |
||||
55 | use TheCodingMachine\TDBM\Test\Dao\Bean\ArtistBean; |
||||
56 | use TheCodingMachine\TDBM\Test\Dao\Bean\BaseObjectBean; |
||||
57 | use TheCodingMachine\TDBM\Test\Dao\Bean\BoatBean; |
||||
58 | use TheCodingMachine\TDBM\Test\Dao\Bean\CatBean; |
||||
59 | use TheCodingMachine\TDBM\Test\Dao\Bean\CategoryBean; |
||||
60 | use TheCodingMachine\TDBM\Test\Dao\Bean\CountryBean; |
||||
61 | use TheCodingMachine\TDBM\Test\Dao\Bean\DogBean; |
||||
62 | use TheCodingMachine\TDBM\Test\Dao\Bean\FileBean; |
||||
63 | use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\ArticleBaseBean; |
||||
64 | use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\BoatBaseBean; |
||||
65 | use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\FileBaseBean; |
||||
66 | use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\UserBaseBean; |
||||
67 | use TheCodingMachine\TDBM\Test\Dao\Bean\InheritedObjectBean; |
||||
68 | use TheCodingMachine\TDBM\Test\Dao\Bean\NodeBean; |
||||
69 | use TheCodingMachine\TDBM\Test\Dao\Bean\PersonBean; |
||||
70 | use TheCodingMachine\TDBM\Test\Dao\Bean\PlayerBean; |
||||
71 | use TheCodingMachine\TDBM\Test\Dao\Bean\RefNoPrimKeyBean; |
||||
72 | use TheCodingMachine\TDBM\Test\Dao\Bean\RoleBean; |
||||
73 | use TheCodingMachine\TDBM\Test\Dao\Bean\StateBean; |
||||
74 | use TheCodingMachine\TDBM\Test\Dao\Bean\UserBean; |
||||
75 | use TheCodingMachine\TDBM\Test\Dao\BoatDao; |
||||
76 | use TheCodingMachine\TDBM\Test\Dao\CatDao; |
||||
77 | use TheCodingMachine\TDBM\Test\Dao\CategoryDao; |
||||
78 | use TheCodingMachine\TDBM\Test\Dao\CompositeFkSourceDao; |
||||
79 | use TheCodingMachine\TDBM\Test\Dao\ContactDao; |
||||
80 | use TheCodingMachine\TDBM\Test\Dao\CountryDao; |
||||
81 | use TheCodingMachine\TDBM\Test\Dao\DogDao; |
||||
82 | use TheCodingMachine\TDBM\Test\Dao\FileDao; |
||||
83 | use TheCodingMachine\TDBM\Test\Dao\Generated\UserBaseDao; |
||||
84 | use TheCodingMachine\TDBM\Test\Dao\InheritedObjectDao; |
||||
85 | use TheCodingMachine\TDBM\Test\Dao\NodeDao; |
||||
86 | use TheCodingMachine\TDBM\Test\Dao\PersonDao; |
||||
87 | use TheCodingMachine\TDBM\Test\Dao\PlayerDao; |
||||
88 | use TheCodingMachine\TDBM\Test\Dao\RefNoPrimKeyDao; |
||||
89 | use TheCodingMachine\TDBM\Test\Dao\RoleDao; |
||||
90 | use TheCodingMachine\TDBM\Test\Dao\StateDao; |
||||
91 | use TheCodingMachine\TDBM\Test\Dao\UserDao; |
||||
92 | use TheCodingMachine\TDBM\Utils\PathFinder\NoPathFoundException; |
||||
93 | use TheCodingMachine\TDBM\Utils\PathFinder\PathFinder; |
||||
94 | use TheCodingMachine\TDBM\Utils\TDBMDaoGenerator; |
||||
95 | use Symfony\Component\Process\Process; |
||||
96 | use function get_class; |
||||
97 | |||||
98 | class TDBMDaoGeneratorTest extends TDBMAbstractServiceTest |
||||
99 | { |
||||
100 | /** @var TDBMDaoGenerator $tdbmDaoGenerator */ |
||||
101 | protected $tdbmDaoGenerator; |
||||
102 | |||||
103 | private $rootPath; |
||||
104 | |||||
105 | protected function setUp(): void |
||||
106 | { |
||||
107 | parent::setUp(); |
||||
108 | $schemaManager = $this->tdbmService->getConnection()->getSchemaManager(); |
||||
109 | $schemaAnalyzer = new SchemaAnalyzer($schemaManager); |
||||
110 | $schemaLockFileDumper = new SchemaLockFileDumper($this->tdbmService->getConnection(), new ArrayCache(), Configuration::getDefaultLockFilePath()); |
||||
0 ignored issues
–
show
Deprecated Code
introduced
by
Loading history...
|
|||||
111 | $tdbmSchemaAnalyzer = new TDBMSchemaAnalyzer($this->tdbmService->getConnection(), new ArrayCache(), $schemaAnalyzer, $schemaLockFileDumper); |
||||
0 ignored issues
–
show
The class
Doctrine\Common\Cache\ArrayCache has been deprecated: Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
112 | $this->tdbmDaoGenerator = new TDBMDaoGenerator($this->getConfiguration(), $tdbmSchemaAnalyzer); |
||||
113 | $this->rootPath = __DIR__ . '/../'; |
||||
114 | //$this->tdbmDaoGenerator->setComposerFile($this->rootPath.'composer.json'); |
||||
115 | } |
||||
116 | |||||
117 | public function testGetSchemaCrashWithoutLock() |
||||
118 | { |
||||
119 | //let's delete the lock file |
||||
120 | $schemaFilePath = Configuration::getDefaultLockFilePath(); |
||||
121 | if (file_exists($schemaFilePath)) { |
||||
122 | unlink($schemaFilePath); |
||||
123 | } |
||||
124 | //let's check we cannot call get schema without a lock file |
||||
125 | $schemaAnalyzer = new SchemaAnalyzer(self::getConnection()->getSchemaManager(), new ArrayCache(), 'prefix_'); |
||||
0 ignored issues
–
show
The class
Doctrine\Common\Cache\ArrayCache has been deprecated: Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
126 | $schemaLockFileDumper = new SchemaLockFileDumper(self::getConnection(), new ArrayCache(), Configuration::getDefaultLockFilePath()); |
||||
0 ignored issues
–
show
The class
Doctrine\Common\Cache\ArrayCache has been deprecated: Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
127 | $tdbmSchemaAnalyzer = new TDBMSchemaAnalyzer(self::getConnection(), new ArrayCache(), $schemaAnalyzer, $schemaLockFileDumper); |
||||
0 ignored issues
–
show
The class
Doctrine\Common\Cache\ArrayCache has been deprecated: Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
128 | $this->expectException('TheCodingMachine\TDBM\TDBMException'); |
||||
129 | $schema1 = $tdbmSchemaAnalyzer->getSchema(true); |
||||
130 | } |
||||
131 | |||||
132 | public function testDaoGeneration(): void |
||||
133 | { |
||||
134 | // Remove all previously generated files. |
||||
135 | $this->recursiveDelete($this->rootPath . 'src/Test/Dao/'); |
||||
136 | mkdir($this->rootPath . 'src/Test/Dao/Generated', 0755, true); |
||||
137 | // Let's generate a dummy file to see it is indeed removed. |
||||
138 | $dummyFile = $this->rootPath . 'src/Test/Dao/Generated/foobar.php'; |
||||
139 | touch($dummyFile); |
||||
140 | $this->assertFileExists($dummyFile); |
||||
141 | |||||
142 | //let's delete the lock file |
||||
143 | $schemaFilePath = Configuration::getDefaultLockFilePath(); |
||||
144 | if (file_exists($schemaFilePath)) { |
||||
145 | unlink($schemaFilePath); |
||||
146 | } |
||||
147 | |||||
148 | $this->tdbmDaoGenerator->generateAllDaosAndBeans(); |
||||
149 | |||||
150 | $this->assertFileNotExists($dummyFile); |
||||
151 | |||||
152 | //Check that the lock file was generated |
||||
153 | $this->assertFileExists($schemaFilePath); |
||||
154 | |||||
155 | // Let's require all files to check they are valid PHP! |
||||
156 | // Test the daoFactory |
||||
157 | require_once $this->rootPath . 'src/Test/Dao/Generated/DaoFactory.php'; |
||||
158 | // Test the others |
||||
159 | |||||
160 | $beanDescriptors = $this->getDummyGeneratorListener()->getBeanDescriptors(); |
||||
161 | |||||
162 | foreach ($beanDescriptors as $beanDescriptor) { |
||||
163 | $daoName = $beanDescriptor->getDaoClassName(); |
||||
164 | $daoBaseName = $beanDescriptor->getBaseDaoClassName(); |
||||
165 | $beanName = $beanDescriptor->getBeanClassName(); |
||||
166 | $baseBeanName = $beanDescriptor->getBaseBeanClassName(); |
||||
167 | require_once $this->rootPath . 'src/Test/Dao/Bean/Generated/' . $baseBeanName . '.php'; |
||||
168 | require_once $this->rootPath . 'src/Test/Dao/Bean/' . $beanName . '.php'; |
||||
169 | require_once $this->rootPath . 'src/Test/Dao/Generated/' . $daoBaseName . '.php'; |
||||
170 | require_once $this->rootPath . 'src/Test/Dao/' . $daoName . '.php'; |
||||
171 | } |
||||
172 | |||||
173 | // Check that pivot tables do not generate DAOs or beans. |
||||
174 | $this->assertFalse(class_exists('TheCodingMachine\\TDBM\\Test\\Dao\\RolesRightDao')); |
||||
175 | } |
||||
176 | |||||
177 | public function testGenerationException(): void |
||||
178 | { |
||||
179 | $configuration = new Configuration('UnknownVendor\\Dao', 'UnknownVendor\\Bean', self::getConnection(), $this->getNamingStrategy()); |
||||
180 | |||||
181 | $schemaManager = $this->tdbmService->getConnection()->getSchemaManager(); |
||||
182 | $schemaAnalyzer = new SchemaAnalyzer($schemaManager); |
||||
183 | $schemaLockFileDumper = new SchemaLockFileDumper($this->tdbmService->getConnection(), new ArrayCache(), Configuration::getDefaultLockFilePath()); |
||||
0 ignored issues
–
show
The class
Doctrine\Common\Cache\ArrayCache has been deprecated: Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
184 | $tdbmSchemaAnalyzer = new TDBMSchemaAnalyzer($this->tdbmService->getConnection(), new ArrayCache(), $schemaAnalyzer, $schemaLockFileDumper); |
||||
0 ignored issues
–
show
The class
Doctrine\Common\Cache\ArrayCache has been deprecated: Deprecated without replacement in doctrine/cache 1.11. This class will be dropped in 2.0
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
185 | $tdbmDaoGenerator = new TDBMDaoGenerator($configuration, $tdbmSchemaAnalyzer); |
||||
186 | $this->rootPath = __DIR__ . '/../../../../'; |
||||
187 | //$tdbmDaoGenerator->setComposerFile($this->rootPath.'composer.json'); |
||||
188 | |||||
189 | $this->expectException(NoPathFoundException::class); |
||||
190 | $tdbmDaoGenerator->generateAllDaosAndBeans(); |
||||
191 | } |
||||
192 | |||||
193 | /** |
||||
194 | * Delete a file or recursively delete a directory. |
||||
195 | * |
||||
196 | * @param string $str Path to file or directory |
||||
197 | * @return bool |
||||
198 | */ |
||||
199 | private function recursiveDelete(string $str): bool |
||||
200 | { |
||||
201 | if (is_file($str)) { |
||||
202 | return @unlink($str); |
||||
203 | } elseif (is_dir($str)) { |
||||
204 | $scan = glob(rtrim($str, '/') . '/*'); |
||||
205 | foreach ($scan as $index => $path) { |
||||
206 | $this->recursiveDelete($path); |
||||
207 | } |
||||
208 | |||||
209 | return @rmdir($str); |
||||
210 | } |
||||
211 | return false; |
||||
212 | } |
||||
213 | |||||
214 | /** |
||||
215 | * @depends testDaoGeneration |
||||
216 | */ |
||||
217 | public function testGetBeanClassName(): void |
||||
218 | { |
||||
219 | $this->assertEquals(UserBean::class, $this->tdbmService->getBeanClassName('users')); |
||||
220 | |||||
221 | // Let's create another TDBMService to test the cache. |
||||
222 | $configuration = new Configuration('TheCodingMachine\\TDBM\\Test\\Dao\\Bean', 'TheCodingMachine\\TDBM\\Test\\Dao', self::getConnection(), $this->getNamingStrategy(), $this->getCache(), null, null, [$this->getDummyGeneratorListener()]); |
||||
223 | $configuration->setPathFinder(new PathFinder(null, dirname(__DIR__, 4))); |
||||
224 | $newTdbmService = new TDBMService($configuration); |
||||
225 | $this->assertEquals(UserBean::class, $newTdbmService->getBeanClassName('users')); |
||||
226 | } |
||||
227 | |||||
228 | /** |
||||
229 | * @depends testDaoGeneration |
||||
230 | */ |
||||
231 | public function testGeneratedGetById(): void |
||||
232 | { |
||||
233 | $contactDao = new ContactDao($this->tdbmService); |
||||
234 | $contactBean = $contactDao->getById(1); |
||||
235 | $this->assertEquals(1, $contactBean->getId()); |
||||
236 | $this->assertInstanceOf('\\DateTimeInterface', $contactBean->getCreatedAt()); |
||||
237 | |||||
238 | // FIXME: Question: que faire du paramètre stockage "UTC"???? |
||||
239 | } |
||||
240 | |||||
241 | /** |
||||
242 | * @depends testDaoGeneration |
||||
243 | */ |
||||
244 | public function testGeneratedGetByIdLazyLoaded(): void |
||||
245 | { |
||||
246 | $roleDao = new RoleDao($this->tdbmService); |
||||
247 | $roleBean = $roleDao->getById(1, true); |
||||
248 | $this->assertEquals(1, $roleBean->getId()); |
||||
249 | $this->assertInstanceOf('\\DateTimeInterface', $roleBean->getCreatedAt()); |
||||
250 | |||||
251 | $roleBean2 = $roleDao->getById(1, true); |
||||
252 | $this->assertTrue($roleBean === $roleBean2); |
||||
253 | } |
||||
254 | |||||
255 | /** |
||||
256 | * @depends testDaoGeneration |
||||
257 | */ |
||||
258 | public function testDefaultValueOnNewBean(): void |
||||
259 | { |
||||
260 | $roleBean = new RoleBean('my_role'); |
||||
261 | $this->assertEquals(1, $roleBean->getStatus()); |
||||
262 | } |
||||
263 | |||||
264 | /** |
||||
265 | * @depends testDaoGeneration |
||||
266 | */ |
||||
267 | public function testForeignKeyInBean(): void |
||||
268 | { |
||||
269 | $userDao = new UserDao($this->tdbmService); |
||||
270 | $userBean = $userDao->getById(1); |
||||
271 | $country = $userBean->getCountry(); |
||||
272 | |||||
273 | $this->assertEquals('uk', $country->getLabel()); |
||||
274 | |||||
275 | $userBean2 = $userDao->getById(1); |
||||
276 | $this->assertTrue($userBean === $userBean2); |
||||
277 | |||||
278 | $contactDao = new ContactDao($this->tdbmService); |
||||
279 | $contactBean = $contactDao->getById(1); |
||||
280 | |||||
281 | $this->assertTrue($userBean === $contactBean); |
||||
282 | } |
||||
283 | |||||
284 | /** |
||||
285 | * @depends testDaoGeneration |
||||
286 | */ |
||||
287 | public function testNewBeans(): void |
||||
288 | { |
||||
289 | $countryDao = new CountryDao($this->tdbmService); |
||||
290 | $userDao = new UserDao($this->tdbmService); |
||||
291 | $userBean = new UserBean('John Doe', '[email protected]', $countryDao->getById(2), 'john.doe'); |
||||
292 | $userBean->setOrder(1); // Let's set a "protected keyword" column. |
||||
293 | |||||
294 | $userDao->save($userBean); |
||||
295 | |||||
296 | $this->assertNull($userBean->getManager()); |
||||
297 | } |
||||
298 | |||||
299 | /** |
||||
300 | * @depends testDaoGeneration |
||||
301 | */ |
||||
302 | public function testDateTimeImmutableGetter(): void |
||||
303 | { |
||||
304 | $userDao = new UserDao($this->tdbmService); |
||||
305 | $user = $userDao->getById(1); |
||||
306 | |||||
307 | $this->assertInstanceOf('\DateTimeImmutable', $user->getCreatedAt()); |
||||
308 | } |
||||
309 | |||||
310 | /** |
||||
311 | * @depends testDaoGeneration |
||||
312 | */ |
||||
313 | public function testAssigningNewBeans(): void |
||||
314 | { |
||||
315 | $userDao = new UserDao($this->tdbmService); |
||||
316 | $countryBean = new CountryBean('Mexico'); |
||||
317 | $userBean = new UserBean('Speedy Gonzalez', '[email protected]', $countryBean, 'speedy.gonzalez'); |
||||
318 | $this->assertEquals($countryBean, $userBean->getCountry()); |
||||
319 | |||||
320 | $userDao->save($userBean); |
||||
321 | } |
||||
322 | |||||
323 | /** |
||||
324 | * @depends testAssigningNewBeans |
||||
325 | */ |
||||
326 | public function testUpdatingProtectedColumn(): void |
||||
327 | { |
||||
328 | $userDao = new UserDao($this->tdbmService); |
||||
329 | $userBean = $userDao->findOneByLogin('speedy.gonzalez'); |
||||
330 | $userBean->setOrder(2); |
||||
331 | $userDao->save($userBean); |
||||
332 | $this->assertSame(2, $userBean->getOrder()); |
||||
333 | } |
||||
334 | |||||
335 | /** |
||||
336 | * @depends testDaoGeneration |
||||
337 | */ |
||||
338 | public function testAssigningExistingRelationship(): void |
||||
339 | { |
||||
340 | $userDao = new UserDao($this->tdbmService); |
||||
341 | $user = $userDao->getById(1); |
||||
342 | $countryDao = new CountryDao($this->tdbmService); |
||||
343 | $country = $countryDao->getById(2); |
||||
344 | |||||
345 | $user->setCountry($country); |
||||
346 | $this->assertEquals(TDBMObjectStateEnum::STATE_DIRTY, $user->_getStatus()); |
||||
347 | } |
||||
348 | |||||
349 | /** |
||||
350 | * @depends testDaoGeneration |
||||
351 | */ |
||||
352 | public function testDirectReversedRelationship(): void |
||||
353 | { |
||||
354 | $countryDao = new CountryDao($this->tdbmService); |
||||
355 | $country = $countryDao->getById(1); |
||||
356 | $users = $country->getUsers(); |
||||
357 | |||||
358 | $arr = $users->toArray(); |
||||
359 | |||||
360 | $this->assertCount(1, $arr); |
||||
361 | $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $arr[0]); |
||||
362 | $this->assertEquals('jean.dupont', $arr[0]->getLogin()); |
||||
363 | |||||
364 | $newUser = new UserBean('Speedy Gonzalez', '[email protected]', $country, 'speedy.gonzalez'); |
||||
365 | $users = $country->getUsers(); |
||||
366 | |||||
367 | $arr = $users->toArray(); |
||||
368 | |||||
369 | $this->assertCount(2, $arr); |
||||
370 | $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $arr[1]); |
||||
371 | $this->assertEquals('speedy.gonzalez', $arr[1]->getLogin()); |
||||
372 | } |
||||
373 | |||||
374 | /** |
||||
375 | * @depends testDaoGeneration |
||||
376 | */ |
||||
377 | public function testDeleteInDirectReversedRelationship(): void |
||||
378 | { |
||||
379 | $countryDao = new CountryDao($this->tdbmService); |
||||
380 | $country = $countryDao->getById(1); |
||||
381 | |||||
382 | $userDao = new UserDao($this->tdbmService); |
||||
383 | $newUser = new UserBean('John Snow', '[email protected]', $country, 'john.snow'); |
||||
384 | $userDao->save($newUser); |
||||
385 | |||||
386 | $users = $country->getUsers(); |
||||
387 | |||||
388 | $arr = $users->toArray(); |
||||
389 | |||||
390 | $this->assertCount(2, $arr); |
||||
391 | |||||
392 | $userDao->delete($arr[1]); |
||||
393 | |||||
394 | $users = $country->getUsers(); |
||||
395 | $arr = $users->toArray(); |
||||
396 | $this->assertCount(1, $arr); |
||||
397 | } |
||||
398 | |||||
399 | /** |
||||
400 | * @depends testDaoGeneration |
||||
401 | */ |
||||
402 | public function testJointureGetters(): void |
||||
403 | { |
||||
404 | $roleDao = new RoleDao($this->tdbmService); |
||||
405 | $role = $roleDao->getById(1); |
||||
406 | $users = $role->getUsers(); |
||||
407 | |||||
408 | $this->assertCount(2, $users); |
||||
409 | $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $users[0]); |
||||
410 | |||||
411 | $rights = $role->getRights(); |
||||
412 | |||||
413 | $this->assertCount(2, $rights); |
||||
414 | $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\RightBean', $rights[0]); |
||||
415 | } |
||||
416 | |||||
417 | /** |
||||
418 | * @depends testDaoGeneration |
||||
419 | */ |
||||
420 | public function testNestedIterationOnAlterableResultIterator(): void |
||||
421 | { |
||||
422 | $countryDao = new CountryDao($this->tdbmService); |
||||
423 | $country = $countryDao->getById(2); |
||||
424 | |||||
425 | $count = 0; |
||||
426 | // Let's perform 2 nested calls to check that iterators do not melt. |
||||
427 | foreach ($country->getUsers() as $user) { |
||||
428 | foreach ($country->getUsers() as $user2) { |
||||
429 | $count++; |
||||
430 | } |
||||
431 | } |
||||
432 | // There are 3 users linked to country 2. |
||||
433 | $this->assertSame(9, $count); |
||||
434 | } |
||||
435 | |||||
436 | /** |
||||
437 | * @depends testDaoGeneration |
||||
438 | */ |
||||
439 | public function testNewBeanConstructor(): void |
||||
440 | { |
||||
441 | $role = new RoleBean('Newrole'); |
||||
442 | $this->assertEquals(TDBMObjectStateEnum::STATE_DETACHED, $role->_getStatus()); |
||||
443 | } |
||||
444 | |||||
445 | /** |
||||
446 | * @depends testDaoGeneration |
||||
447 | */ |
||||
448 | public function testJointureAdderOnNewBean(): void |
||||
449 | { |
||||
450 | $countryDao = new CountryDao($this->tdbmService); |
||||
451 | $country = $countryDao->getById(1); |
||||
452 | $user = new UserBean('Speedy Gonzalez', '[email protected]', $country, 'speedy.gonzalez'); |
||||
453 | $role = new RoleBean('Mouse'); |
||||
454 | $user->addRole($role); |
||||
455 | $roles = $user->getRoles(); |
||||
456 | $this->assertCount(1, $roles); |
||||
457 | $role = $roles[0]; |
||||
458 | $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\RoleBean', $role); |
||||
459 | $users = $role->getUsers(); |
||||
460 | $this->assertCount(1, $users); |
||||
461 | $this->assertEquals($user, $users[0]); |
||||
462 | |||||
463 | $role->removeUser($user); |
||||
464 | $this->assertCount(0, $role->getUsers()); |
||||
465 | $this->assertCount(0, $user->getRoles()); |
||||
466 | } |
||||
467 | |||||
468 | /** |
||||
469 | * @depends testDaoGeneration |
||||
470 | */ |
||||
471 | public function testJointureDeleteBeforeGetters(): void |
||||
472 | { |
||||
473 | $roleDao = new RoleDao($this->tdbmService); |
||||
474 | $userDao = new UserDao($this->tdbmService); |
||||
475 | $role = $roleDao->getById(1); |
||||
476 | $user = $userDao->getById(1); |
||||
477 | |||||
478 | // We call removeUser BEFORE calling getUsers |
||||
479 | // This should work as expected. |
||||
480 | $role->removeUser($user); |
||||
481 | $users = $role->getUsers(); |
||||
482 | |||||
483 | $this->assertCount(1, $users); |
||||
484 | } |
||||
485 | |||||
486 | /** |
||||
487 | * @depends testDaoGeneration |
||||
488 | */ |
||||
489 | public function testJointureMultiAdd(): void |
||||
490 | { |
||||
491 | $countryDao = new CountryDao($this->tdbmService); |
||||
492 | $country = $countryDao->getById(1); |
||||
493 | $user = new UserBean('Speedy Gonzalez', '[email protected]', $country, 'speedy.gonzalez'); |
||||
494 | $role = new RoleBean('Mouse'); |
||||
495 | $user->addRole($role); |
||||
496 | $role->addUser($user); |
||||
497 | $user->addRole($role); |
||||
498 | |||||
499 | $this->assertCount(1, $user->getRoles()); |
||||
500 | } |
||||
501 | |||||
502 | /** |
||||
503 | * Step 1: we remove the role 1 from user 1 but save role 1. |
||||
504 | * Expected result: no save done. |
||||
505 | * |
||||
506 | * @depends testDaoGeneration |
||||
507 | */ |
||||
508 | public function testJointureSave1(): void |
||||
509 | { |
||||
510 | $roleDao = new RoleDao($this->tdbmService); |
||||
511 | $role = $roleDao->getById(1); |
||||
512 | $userDao = new UserDao($this->tdbmService); |
||||
513 | $user = $userDao->getById(1); |
||||
514 | |||||
515 | $this->assertTrue($user->hasRole($role)); |
||||
516 | $this->assertTrue($role->hasUser($user)); |
||||
517 | $user->removeRole($role); |
||||
518 | $this->assertFalse($user->hasRole($role)); |
||||
519 | $this->assertFalse($role->hasUser($user)); |
||||
520 | $roleDao->save($role); |
||||
521 | |||||
522 | $this->assertEquals(TDBMObjectStateEnum::STATE_DIRTY, $user->_getStatus()); |
||||
523 | $this->assertEquals(TDBMObjectStateEnum::STATE_LOADED, $role->_getStatus()); |
||||
524 | } |
||||
525 | |||||
526 | /** |
||||
527 | * Step 2: we check that nothing was saved |
||||
528 | * Expected result: no save done. |
||||
529 | * |
||||
530 | * @depends testJointureSave1 |
||||
531 | */ |
||||
532 | public function testJointureSave2(): void |
||||
533 | { |
||||
534 | $roleDao = new RoleDao($this->tdbmService); |
||||
535 | $role = $roleDao->getById(1); |
||||
536 | $this->assertCount(2, $role->getUsers()); |
||||
537 | } |
||||
538 | |||||
539 | /** |
||||
540 | * Step 3: we remove the role 1 from user 1 and save user 1. |
||||
541 | * Expected result: save done. |
||||
542 | * |
||||
543 | * @depends testJointureSave2 |
||||
544 | */ |
||||
545 | public function testJointureSave3(): void |
||||
546 | { |
||||
547 | $roleDao = new RoleDao($this->tdbmService); |
||||
548 | $role = $roleDao->getById(1); |
||||
549 | $userDao = new UserDao($this->tdbmService); |
||||
550 | $user = $userDao->getById(1); |
||||
551 | |||||
552 | $this->assertCount(1, $user->getRoles()); |
||||
553 | $user->removeRole($role); |
||||
554 | $this->assertCount(0, $user->getRoles()); |
||||
555 | $userDao->save($user); |
||||
556 | $this->assertCount(0, $user->getRoles()); |
||||
557 | } |
||||
558 | |||||
559 | /** |
||||
560 | * Step 4: we check that save was done |
||||
561 | * Expected result: save done. |
||||
562 | * |
||||
563 | * @depends testJointureSave3 |
||||
564 | */ |
||||
565 | public function testJointureSave4(): void |
||||
566 | { |
||||
567 | $roleDao = new RoleDao($this->tdbmService); |
||||
568 | $role = $roleDao->getById(1); |
||||
569 | $this->assertCount(1, $role->getUsers()); |
||||
570 | $userDao = new UserDao($this->tdbmService); |
||||
571 | $user = $userDao->getById(1); |
||||
572 | $this->assertCount(0, $user->getRoles()); |
||||
573 | } |
||||
574 | |||||
575 | /** |
||||
576 | * Step 5: we add the role 1 from user 1 and save user 1. |
||||
577 | * Expected result: save done. |
||||
578 | * |
||||
579 | * @depends testJointureSave4 |
||||
580 | */ |
||||
581 | public function testJointureSave5(): void |
||||
582 | { |
||||
583 | $roleDao = new RoleDao($this->tdbmService); |
||||
584 | $role = $roleDao->getById(1); |
||||
585 | $userDao = new UserDao($this->tdbmService); |
||||
586 | $user = $userDao->getById(1); |
||||
587 | |||||
588 | $user->addRole($role); |
||||
589 | $this->assertCount(1, $user->getRoles()); |
||||
590 | $userDao->save($user); |
||||
591 | } |
||||
592 | |||||
593 | /** |
||||
594 | * Step 6: we check that save was done |
||||
595 | * Expected result: save done. |
||||
596 | * |
||||
597 | * @depends testJointureSave5 |
||||
598 | */ |
||||
599 | public function testJointureSave6(): void |
||||
600 | { |
||||
601 | $roleDao = new RoleDao($this->tdbmService); |
||||
602 | $role = $roleDao->getById(1); |
||||
603 | $this->assertCount(2, $role->getUsers()); |
||||
604 | $userDao = new UserDao($this->tdbmService); |
||||
605 | $user = $userDao->getById(1); |
||||
606 | $this->assertCount(1, $user->getRoles()); |
||||
607 | } |
||||
608 | |||||
609 | /** |
||||
610 | * Step 7: we add a new role to user 1 and save user 1. |
||||
611 | * Expected result: save done, including the new role. |
||||
612 | * |
||||
613 | * @depends testJointureSave6 |
||||
614 | */ |
||||
615 | public function testJointureSave7(): void |
||||
616 | { |
||||
617 | $role = new RoleBean('my new role'); |
||||
618 | $userDao = new UserDao($this->tdbmService); |
||||
619 | $user = $userDao->getById(1); |
||||
620 | |||||
621 | $user->addRole($role); |
||||
622 | $userDao->save($user); |
||||
623 | |||||
624 | $this->assertEquals(TDBMObjectStateEnum::STATE_LOADED, $role->_getStatus()); |
||||
625 | } |
||||
626 | |||||
627 | /** |
||||
628 | * Step 8: we check that save was done |
||||
629 | * Expected result: save done. |
||||
630 | * |
||||
631 | * @depends testJointureSave7 |
||||
632 | */ |
||||
633 | public function testJointureSave8(): void |
||||
634 | { |
||||
635 | $roleDao = new RoleDao($this->tdbmService); |
||||
636 | $userDao = new UserDao($this->tdbmService); |
||||
637 | $user = $userDao->getById(1); |
||||
638 | |||||
639 | $roles = $user->getRoles(); |
||||
640 | foreach ($roles as $role) { |
||||
641 | if ($role->getName() === 'my new role') { |
||||
642 | $selectedRole = $role; |
||||
643 | break; |
||||
644 | } |
||||
645 | } |
||||
646 | $this->assertNotNull($selectedRole); |
||||
647 | |||||
648 | $this->assertCount(2, $user->getRoles()); |
||||
649 | |||||
650 | // Expected: relationship removed! |
||||
651 | $roleDao->delete($selectedRole); |
||||
652 | |||||
653 | $this->assertCount(1, $user->getRoles()); |
||||
654 | } |
||||
655 | |||||
656 | /** |
||||
657 | * Step 9: Let's test the setXXX method. |
||||
658 | * |
||||
659 | * @depends testJointureSave8 |
||||
660 | */ |
||||
661 | public function testJointureSave9(): void |
||||
662 | { |
||||
663 | $roleDao = new RoleDao($this->tdbmService); |
||||
664 | $userDao = new UserDao($this->tdbmService); |
||||
665 | $user = $userDao->getById(1); |
||||
666 | |||||
667 | // At this point, user 1 is linked to role 1. |
||||
668 | // Let's bind it to role 2. |
||||
669 | $user->setRoles([$roleDao->getById(2)]); |
||||
670 | $userDao->save($user); |
||||
671 | $this->assertTrue($user->hasRole($roleDao->getById(2))); |
||||
672 | } |
||||
673 | |||||
674 | /** |
||||
675 | * Step 10: Let's check results of 9. |
||||
676 | * |
||||
677 | * @depends testJointureSave9 |
||||
678 | */ |
||||
679 | public function testJointureSave10(): void |
||||
680 | { |
||||
681 | $userDao = new UserDao($this->tdbmService); |
||||
682 | $user = $userDao->getById(1); |
||||
683 | |||||
684 | $roles = $user->getRoles(); |
||||
685 | |||||
686 | $this->assertCount(1, $roles); |
||||
687 | $this->assertEquals(2, $roles[0]->getId()); |
||||
688 | } |
||||
689 | |||||
690 | /** |
||||
691 | * Test jointure in a parent table in an inheritance relationship |
||||
692 | * |
||||
693 | * @depends testDaoGeneration |
||||
694 | */ |
||||
695 | public function testJointureInParentTable(): void |
||||
696 | { |
||||
697 | $userDao = new UserDao($this->tdbmService); |
||||
698 | $user = $userDao->getById(1); |
||||
699 | |||||
700 | $boats = $user->getBoats(); |
||||
701 | |||||
702 | $this->assertCount(1, $boats); |
||||
703 | $this->assertEquals(1, $boats[0]->getId()); |
||||
704 | } |
||||
705 | |||||
706 | /** |
||||
707 | * @depends testDaoGeneration |
||||
708 | */ |
||||
709 | public function testFindOrderBy(): void |
||||
710 | { |
||||
711 | $userDao = new TestUserDao($this->tdbmService); |
||||
712 | $users = $userDao->getUsersByAlphabeticalOrder(); |
||||
713 | |||||
714 | $this->assertCount(6, $users); |
||||
715 | $this->assertEquals('bill.shakespeare', $users[0]->getLogin()); |
||||
716 | $this->assertEquals('jean.dupont', $users[1]->getLogin()); |
||||
717 | |||||
718 | $users = $userDao->getUsersByCountryOrder(); |
||||
719 | $this->assertCount(6, $users); |
||||
720 | $countryName1 = $users[0]->getCountry()->getLabel(); |
||||
721 | for ($i = 1; $i < 6; $i++) { |
||||
722 | $countryName2 = $users[$i]->getCountry()->getLabel(); |
||||
723 | $this->assertLessThanOrEqual(0, strcmp($countryName1, $countryName2)); |
||||
724 | $countryName1 = $countryName2; |
||||
725 | } |
||||
726 | } |
||||
727 | |||||
728 | /** |
||||
729 | * @depends testDaoGeneration |
||||
730 | */ |
||||
731 | public function testFindFromSqlOrderBy(): void |
||||
732 | { |
||||
733 | $userDao = new TestUserDao($this->tdbmService); |
||||
734 | $users = $userDao->getUsersFromSqlByAlphabeticalOrder(); |
||||
735 | |||||
736 | $this->assertCount(6, $users); |
||||
737 | $this->assertEquals('bill.shakespeare', $users[0]->getLogin()); |
||||
738 | $this->assertEquals('jean.dupont', $users[1]->getLogin()); |
||||
739 | |||||
740 | $users = $userDao->getUsersFromSqlByCountryOrder(); |
||||
741 | $this->assertCount(6, $users); |
||||
742 | $countryName1 = $users[0]->getCountry()->getLabel(); |
||||
743 | for ($i = 1; $i < 6; $i++) { |
||||
744 | $countryName2 = $users[$i]->getCountry()->getLabel(); |
||||
745 | $this->assertLessThanOrEqual(0, strcmp($countryName1, $countryName2)); |
||||
746 | $countryName1 = $countryName2; |
||||
747 | } |
||||
748 | } |
||||
749 | |||||
750 | /** |
||||
751 | * @depends testDaoGeneration |
||||
752 | */ |
||||
753 | public function testFindFromSqlOrderByOnInheritedBean(): void |
||||
754 | { |
||||
755 | $articleDao = new TestArticleDao($this->tdbmService); |
||||
756 | $articles = $articleDao->getArticlesByUserLogin(); |
||||
757 | |||||
758 | foreach ($articles as $article) { |
||||
759 | var_dump($article); |
||||
760 | } |
||||
761 | $this->assertCount(0, $articles); |
||||
762 | } |
||||
763 | |||||
764 | |||||
765 | /** |
||||
766 | * @depends testDaoGeneration |
||||
767 | */ |
||||
768 | public function testFindFromSqlOrderByJoinRole(): void |
||||
769 | { |
||||
770 | $roleDao = new TestRoleDao($this->tdbmService); |
||||
771 | $roles = $roleDao->getRolesByRightCanSing('roles.name DESC'); |
||||
772 | |||||
773 | $this->assertCount(2, $roles); |
||||
774 | $this->assertEquals('Singers', $roles[0]->getName()); |
||||
775 | $this->assertEquals('Admins', $roles[1]->getName()); |
||||
776 | } |
||||
777 | |||||
778 | /** |
||||
779 | * @depends testDaoGeneration |
||||
780 | */ |
||||
781 | public function testFindFromRawSqlOrderByUserCount(): void |
||||
782 | { |
||||
783 | $countryDao = new TestCountryDao($this->tdbmService); |
||||
784 | $countries = $countryDao->getCountriesByUserCount(); |
||||
785 | |||||
786 | $nbCountries = 4; |
||||
787 | $this->assertCount($nbCountries, $countries); |
||||
788 | for ($i = 1; $i < $nbCountries; $i++) { |
||||
789 | $this->assertLessThanOrEqual($countries[$i - 1]->getUsers()->count(), $countries[$i]->getUsers()->count()); |
||||
790 | } |
||||
791 | } |
||||
792 | |||||
793 | /** |
||||
794 | * @depends testDaoGeneration |
||||
795 | */ |
||||
796 | public function testFindFromRawSqlWithUnion(): void |
||||
797 | { |
||||
798 | $countryDao = new TestCountryDao($this->tdbmService); |
||||
799 | $countries = $countryDao->getCountriesUsingUnion(); |
||||
800 | |||||
801 | $this->assertCount(2, $countries); |
||||
802 | $this->assertEquals(1, $countries[0]->getId()); |
||||
803 | } |
||||
804 | |||||
805 | /** |
||||
806 | * @depends testDaoGeneration |
||||
807 | */ |
||||
808 | public function testFindFromRawSqlWithSimpleQuery(): void |
||||
809 | { |
||||
810 | $countryDao = new TestCountryDao($this->tdbmService); |
||||
811 | $countries = $countryDao->getCountriesUsingSimpleQuery(); |
||||
812 | |||||
813 | $this->assertCount(1, $countries); |
||||
814 | $this->assertEquals(1, $countries[0]->getId()); |
||||
815 | } |
||||
816 | |||||
817 | /** |
||||
818 | * @depends testDaoGeneration |
||||
819 | */ |
||||
820 | public function testFindFromRawSqlWithDistinctQuery(): void |
||||
821 | { |
||||
822 | $countryDao = new TestCountryDao($this->tdbmService); |
||||
823 | $countries = $countryDao->getCountriesUsingDistinctQuery(); |
||||
824 | |||||
825 | $this->assertCount(1, $countries); |
||||
826 | $this->assertEquals(2, $countries[0]->getId()); |
||||
827 | } |
||||
828 | |||||
829 | /** |
||||
830 | * @depends testDaoGeneration |
||||
831 | */ |
||||
832 | public function testFindFilters(): void |
||||
833 | { |
||||
834 | $userDao = new TestUserDao($this->tdbmService); |
||||
835 | $users = $userDao->getUsersByLoginStartingWith('bill'); |
||||
836 | |||||
837 | $this->assertCount(1, $users); |
||||
838 | $this->assertEquals('bill.shakespeare', $users[0]->getLogin()); |
||||
839 | } |
||||
840 | |||||
841 | /** |
||||
842 | * @depends testDaoGeneration |
||||
843 | */ |
||||
844 | public function testFindMode(): void |
||||
845 | { |
||||
846 | $userDao = new TestUserDao($this->tdbmService); |
||||
847 | $users = $userDao->getUsersByLoginStartingWith('bill', TDBMService::MODE_CURSOR); |
||||
848 | |||||
849 | $this->expectException('TheCodingMachine\TDBM\TDBMException'); |
||||
850 | $users[0]; |
||||
851 | } |
||||
852 | |||||
853 | /** |
||||
854 | * @depends testDaoGeneration |
||||
855 | */ |
||||
856 | public function testFindAll(): void |
||||
857 | { |
||||
858 | $userDao = new TestUserDao($this->tdbmService); |
||||
859 | $users = $userDao->findAll(); |
||||
860 | |||||
861 | $this->assertCount(6, $users); |
||||
862 | } |
||||
863 | |||||
864 | /** |
||||
865 | * @depends testDaoGeneration |
||||
866 | */ |
||||
867 | public function testFindOne(): void |
||||
868 | { |
||||
869 | $userDao = new TestUserDao($this->tdbmService); |
||||
870 | $user = $userDao->getUserByLogin('bill.shakespeare'); |
||||
871 | |||||
872 | $this->assertEquals('bill.shakespeare', $user->getLogin()); |
||||
873 | } |
||||
874 | |||||
875 | /** |
||||
876 | * @depends testDaoGeneration |
||||
877 | */ |
||||
878 | public function testJsonEncodeBean(): void |
||||
879 | { |
||||
880 | $userDao = new TestUserDao($this->tdbmService); |
||||
881 | $user = $userDao->getUserByLogin('bill.shakespeare'); |
||||
882 | |||||
883 | $jsonEncoded = json_encode($user); |
||||
884 | $userDecoded = json_decode($jsonEncoded, true); |
||||
885 | |||||
886 | $this->assertEquals('bill.shakespeare', $userDecoded['login']); |
||||
887 | |||||
888 | // test serialization of dates. |
||||
889 | $this->assertTrue(is_string($userDecoded['createdAt'])); |
||||
890 | $this->assertEquals('2015-10-24', (new \DateTimeImmutable($userDecoded['createdAt']))->format('Y-m-d')); |
||||
891 | $this->assertNull($userDecoded['modifiedAt']); |
||||
892 | |||||
893 | // testing many to 1 relationships |
||||
894 | $this->assertEquals('uk', $userDecoded['country']['label']); |
||||
895 | |||||
896 | // testing many to many relationships |
||||
897 | $this->assertCount(1, $userDecoded['roles']); |
||||
898 | $this->assertArrayNotHasKey('users', $userDecoded['roles'][0]); |
||||
899 | $this->assertArrayNotHasKey('rights', $userDecoded['roles'][0]); |
||||
900 | } |
||||
901 | |||||
902 | /** |
||||
903 | * @depends testDaoGeneration |
||||
904 | */ |
||||
905 | public function testNullableForeignKey(): void |
||||
906 | { |
||||
907 | $userDao = new TestUserDao($this->tdbmService); |
||||
908 | $user = $userDao->getUserByLogin('john.smith'); |
||||
909 | |||||
910 | $this->assertNull($user->getManager()); |
||||
911 | |||||
912 | $jsonEncoded = json_encode($user); |
||||
913 | $userDecoded = json_decode($jsonEncoded, true); |
||||
914 | |||||
915 | $this->assertNull($userDecoded['manager']); |
||||
916 | } |
||||
917 | |||||
918 | /** |
||||
919 | * Test that setting (and saving) objects' references (foreign keys relations) to null is working. |
||||
920 | * |
||||
921 | * @depends testDaoGeneration |
||||
922 | */ |
||||
923 | public function testSetToNullForeignKey(): void |
||||
924 | { |
||||
925 | $userDao = new TestUserDao($this->tdbmService); |
||||
926 | $user = $userDao->getUserByLogin('john.smith'); |
||||
927 | $manager = $userDao->getUserByLogin('jean.dupont'); |
||||
928 | |||||
929 | $user->setManager($manager); |
||||
930 | $userDao->save($user); |
||||
931 | |||||
932 | $user->setManager(null); |
||||
933 | $userDao->save($user); |
||||
934 | $this->assertNull($user->getManager()); |
||||
935 | } |
||||
936 | |||||
937 | /** |
||||
938 | * @depends testDaoGeneration |
||||
939 | */ |
||||
940 | public function testQueryOnWrongTableName(): void |
||||
941 | { |
||||
942 | $userDao = new TestUserDao($this->tdbmService); |
||||
943 | $users = $userDao->getUsersWrongTableName(); |
||||
944 | $this->expectException('Mouf\Database\SchemaAnalyzer\SchemaAnalyzerTableNotFoundException'); |
||||
945 | $this->expectExceptionMessage('Could not find table \'contacts\'. Did you mean \'contact\'?'); |
||||
946 | $users->count(); |
||||
947 | } |
||||
948 | |||||
949 | /** |
||||
950 | * @depends testDaoGeneration |
||||
951 | */ |
||||
952 | /*public function testQueryNullForeignKey(): void |
||||
953 | { |
||||
954 | $userDao = new TestUserDao($this->tdbmService); |
||||
955 | $users = $userDao->getUsersByManagerId(null); |
||||
956 | $this->assertCount(3, $users); |
||||
957 | }*/ |
||||
958 | |||||
959 | /** |
||||
960 | * @depends testDaoGeneration |
||||
961 | */ |
||||
962 | public function testInnerJsonEncode(): void |
||||
963 | { |
||||
964 | $userDao = new TestUserDao($this->tdbmService); |
||||
965 | $user = $userDao->getUserByLogin('bill.shakespeare'); |
||||
966 | |||||
967 | $jsonEncoded = json_encode(['user' => $user]); |
||||
968 | $msgDecoded = json_decode($jsonEncoded, true); |
||||
969 | |||||
970 | $this->assertEquals('bill.shakespeare', $msgDecoded['user']['login']); |
||||
971 | } |
||||
972 | |||||
973 | /** |
||||
974 | * @depends testDaoGeneration |
||||
975 | */ |
||||
976 | public function testArrayJsonEncode(): void |
||||
977 | { |
||||
978 | $userDao = new TestUserDao($this->tdbmService); |
||||
979 | $users = $userDao->getUsersByLoginStartingWith('bill'); |
||||
980 | |||||
981 | $jsonEncoded = json_encode($users); |
||||
982 | $msgDecoded = json_decode($jsonEncoded, true); |
||||
983 | |||||
984 | $this->assertCount(1, $msgDecoded); |
||||
985 | } |
||||
986 | |||||
987 | /** |
||||
988 | * @depends testDaoGeneration |
||||
989 | */ |
||||
990 | public function testCursorJsonEncode(): void |
||||
991 | { |
||||
992 | $userDao = new TestUserDao($this->tdbmService); |
||||
993 | $users = $userDao->getUsersByLoginStartingWith('bill', TDBMService::MODE_CURSOR); |
||||
994 | |||||
995 | $jsonEncoded = json_encode($users); |
||||
996 | $msgDecoded = json_decode($jsonEncoded, true); |
||||
997 | |||||
998 | $this->assertCount(1, $msgDecoded); |
||||
999 | } |
||||
1000 | |||||
1001 | /** |
||||
1002 | * @depends testDaoGeneration |
||||
1003 | */ |
||||
1004 | public function testPageJsonEncode(): void |
||||
1005 | { |
||||
1006 | $userDao = new TestUserDao($this->tdbmService); |
||||
1007 | $users = $userDao->getUsersByLoginStartingWith('bill'); |
||||
1008 | |||||
1009 | $jsonEncoded = json_encode($users->take(0, 1)); |
||||
1010 | $msgDecoded = json_decode($jsonEncoded, true); |
||||
1011 | |||||
1012 | $this->assertCount(1, $msgDecoded); |
||||
1013 | } |
||||
1014 | |||||
1015 | /** |
||||
1016 | * @depends testDaoGeneration |
||||
1017 | */ |
||||
1018 | public function testInnerResultIteratorCountAfterFetch(): void |
||||
1019 | { |
||||
1020 | $userDao = new TestUserDao($this->tdbmService); |
||||
1021 | $users = $userDao->getUsersByLoginStartingWith('j')->take(0, 4); |
||||
1022 | $users->toArray(); // We force to fetch |
||||
1023 | $this->assertEquals(3, $users->count()); |
||||
1024 | } |
||||
1025 | |||||
1026 | /** |
||||
1027 | * @depends testDaoGeneration |
||||
1028 | */ |
||||
1029 | public function testFirst(): void |
||||
1030 | { |
||||
1031 | $userDao = new TestUserDao($this->tdbmService); |
||||
1032 | $users = $userDao->getUsersByLoginStartingWith('bill'); |
||||
1033 | |||||
1034 | $bill = $users->first(); |
||||
1035 | $this->assertEquals('bill.shakespeare', $bill->getLogin()); |
||||
1036 | } |
||||
1037 | |||||
1038 | /** |
||||
1039 | * @depends testDaoGeneration |
||||
1040 | */ |
||||
1041 | public function testFirstNull(): void |
||||
1042 | { |
||||
1043 | $userDao = new TestUserDao($this->tdbmService); |
||||
1044 | $users = $userDao->getUsersByLoginStartingWith('mike'); |
||||
1045 | |||||
1046 | $user = $users->first(); |
||||
1047 | $this->assertNull($user); |
||||
1048 | } |
||||
1049 | |||||
1050 | /** |
||||
1051 | * @depends testDaoGeneration |
||||
1052 | */ |
||||
1053 | public function testCloneBeanAttachedBean(): void |
||||
1054 | { |
||||
1055 | $userDao = new TestUserDao($this->tdbmService); |
||||
1056 | $user = $userDao->getUserByLogin('bill.shakespeare'); |
||||
1057 | $this->assertEquals(4, $user->getId()); |
||||
1058 | $user2 = clone $user; |
||||
1059 | $this->assertNull($user2->getId()); |
||||
1060 | $this->assertEquals('bill.shakespeare', $user2->getLogin()); |
||||
1061 | $this->assertEquals('Bill Shakespeare', $user2->getName()); |
||||
1062 | $this->assertEquals('uk', $user2->getCountry()->getLabel()); |
||||
1063 | |||||
1064 | // MANY 2 MANY must be duplicated |
||||
1065 | $this->assertEquals('Writers', $user2->getRoles()[0]->getName()); |
||||
1066 | |||||
1067 | // Let's test saving this clone |
||||
1068 | $user2->setLogin('william.shakespeare'); |
||||
1069 | $userDao->save($user2); |
||||
1070 | |||||
1071 | $user3 = $userDao->getUserByLogin('william.shakespeare'); |
||||
1072 | $this->assertTrue($user3 === $user2); |
||||
1073 | $userDao->delete($user3); |
||||
1074 | |||||
1075 | // Finally, let's test the origin user still exists! |
||||
1076 | $user4 = $userDao->getUserByLogin('bill.shakespeare'); |
||||
1077 | $this->assertEquals('bill.shakespeare', $user4->getLogin()); |
||||
1078 | } |
||||
1079 | |||||
1080 | /** |
||||
1081 | * @depends testDaoGeneration |
||||
1082 | */ |
||||
1083 | public function testCloneNewBean(): void |
||||
1084 | { |
||||
1085 | $countryDao = new CountryDao($this->tdbmService); |
||||
1086 | $roleDao = new RoleDao($this->tdbmService); |
||||
1087 | $role = $roleDao->getById(1); |
||||
1088 | |||||
1089 | $userBean = new UserBean('John Doe', '[email protected]', $countryDao->getById(2), 'john.doe'); |
||||
1090 | $userBean->addRole($role); |
||||
1091 | |||||
1092 | $user2 = clone $userBean; |
||||
1093 | |||||
1094 | $this->assertNull($user2->getId()); |
||||
1095 | $this->assertEquals('john.doe', $user2->getLogin()); |
||||
1096 | $this->assertEquals('John Doe', $user2->getName()); |
||||
1097 | $this->assertEquals('uk', $user2->getCountry()->getLabel()); |
||||
1098 | |||||
1099 | // MANY 2 MANY must be duplicated |
||||
1100 | $this->assertEquals($role->getName(), $user2->getRoles()[0]->getName()); |
||||
1101 | } |
||||
1102 | |||||
1103 | /** |
||||
1104 | * @depends testDaoGeneration |
||||
1105 | */ |
||||
1106 | public function testCascadeDelete(): void |
||||
1107 | { |
||||
1108 | $userDao = new TestUserDao($this->tdbmService); |
||||
1109 | $countryDao = new CountryDao($this->tdbmService); |
||||
1110 | |||||
1111 | $spain = new CountryBean('Spain'); |
||||
1112 | $sanchez = new UserBean('Manuel Sanchez', '[email protected]', $spain, 'manuel.sanchez'); |
||||
1113 | |||||
1114 | $countryDao->save($spain); |
||||
1115 | $userDao->save($sanchez); |
||||
1116 | |||||
1117 | $speedy2 = $userDao->getUserByLogin('manuel.sanchez'); |
||||
1118 | $this->assertTrue($sanchez === $speedy2); |
||||
1119 | |||||
1120 | $exceptionTriggered = false; |
||||
1121 | try { |
||||
1122 | $countryDao->delete($spain); |
||||
1123 | } catch (ForeignKeyConstraintViolationException $e) { |
||||
1124 | $exceptionTriggered = true; |
||||
1125 | } |
||||
1126 | $this->assertTrue($exceptionTriggered); |
||||
1127 | |||||
1128 | $countryDao->delete($spain, true); |
||||
1129 | |||||
1130 | // Let's check that speed gonzalez was removed. |
||||
1131 | $speedy3 = $userDao->getUserByLogin('manuel.sanchez'); |
||||
1132 | $this->assertNull($speedy3); |
||||
1133 | } |
||||
1134 | |||||
1135 | /** |
||||
1136 | * @depends testDaoGeneration |
||||
1137 | */ |
||||
1138 | public function testDiscardChanges(): void |
||||
1139 | { |
||||
1140 | $contactDao = new ContactDao($this->tdbmService); |
||||
1141 | $contactBean = $contactDao->getById(1); |
||||
1142 | |||||
1143 | $oldName = $contactBean->getName(); |
||||
1144 | |||||
1145 | $contactBean->setName('MyNewName'); |
||||
1146 | |||||
1147 | $contactBean->discardChanges(); |
||||
1148 | |||||
1149 | $this->assertEquals($oldName, $contactBean->getName()); |
||||
1150 | } |
||||
1151 | |||||
1152 | /** |
||||
1153 | * @depends testDaoGeneration |
||||
1154 | */ |
||||
1155 | public function testDiscardChangesOnNewBeanFails(): void |
||||
1156 | { |
||||
1157 | $person = new PersonBean('John Foo', new \DateTimeImmutable()); |
||||
1158 | $this->expectException('TheCodingMachine\TDBM\TDBMException'); |
||||
1159 | $person->discardChanges(); |
||||
1160 | } |
||||
1161 | |||||
1162 | /** |
||||
1163 | * @depends testDaoGeneration |
||||
1164 | */ |
||||
1165 | public function testDiscardChangesOnDeletedBeanFails(): void |
||||
1166 | { |
||||
1167 | $userDao = new TestUserDao($this->tdbmService); |
||||
1168 | $countryDao = new CountryDao($this->tdbmService); |
||||
1169 | |||||
1170 | $sanchez = new UserBean('Manuel Sanchez', '[email protected]', $countryDao->getById(1), 'manuel.sanchez'); |
||||
1171 | |||||
1172 | $userDao->save($sanchez); |
||||
1173 | |||||
1174 | $userDao->delete($sanchez); |
||||
1175 | |||||
1176 | $this->expectException('TheCodingMachine\TDBM\TDBMException'); |
||||
1177 | // Cannot discard changes on a bean that is already deleted. |
||||
1178 | $sanchez->discardChanges(); |
||||
1179 | } |
||||
1180 | |||||
1181 | /** |
||||
1182 | * @depends testDaoGeneration |
||||
1183 | */ |
||||
1184 | public function testUniqueIndexBasedSearch(): void |
||||
1185 | { |
||||
1186 | $userDao = new UserDao($this->tdbmService); |
||||
1187 | $user = $userDao->findOneByLogin('bill.shakespeare'); |
||||
1188 | |||||
1189 | $this->assertEquals('bill.shakespeare', $user->getLogin()); |
||||
1190 | $this->assertEquals('Bill Shakespeare', $user->getName()); |
||||
1191 | } |
||||
1192 | |||||
1193 | /** |
||||
1194 | * @depends testDaoGeneration |
||||
1195 | */ |
||||
1196 | public function testFindOneByRetunsNull(): void |
||||
1197 | { |
||||
1198 | // Let's assert that the findOneBy... methods can return null. |
||||
1199 | $userDao = new UserDao($this->tdbmService); |
||||
1200 | $userBean = $userDao->findOneByLogin('not_exist'); |
||||
1201 | |||||
1202 | $this->assertNull($userBean); |
||||
1203 | } |
||||
1204 | |||||
1205 | /** |
||||
1206 | * @depends testDaoGeneration |
||||
1207 | */ |
||||
1208 | public function testMultiColumnsIndexBasedSearch(): void |
||||
1209 | { |
||||
1210 | $countryDao = new CountryDao($this->tdbmService); |
||||
1211 | $userDao = new UserDao($this->tdbmService); |
||||
1212 | $users = $userDao->findByStatusAndCountry('on', $countryDao->getById(1)); |
||||
1213 | |||||
1214 | $this->assertEquals('jean.dupont', $users[0]->getLogin()); |
||||
1215 | } |
||||
1216 | |||||
1217 | /** |
||||
1218 | * @depends testDaoGeneration |
||||
1219 | */ |
||||
1220 | public function testPartialMultiColumnsIndexBasedSearch(): void |
||||
1221 | { |
||||
1222 | $userDao = new UserDao($this->tdbmService); |
||||
1223 | $users = $userDao->findByStatusAndCountry('on'); |
||||
1224 | |||||
1225 | $this->assertCount(2, $users); |
||||
1226 | } |
||||
1227 | |||||
1228 | /** |
||||
1229 | * @depends testDaoGeneration |
||||
1230 | */ |
||||
1231 | public function testCreationInNullableDate(): void |
||||
1232 | { |
||||
1233 | $roleDao = new RoleDao($this->tdbmService); |
||||
1234 | |||||
1235 | $role = new RoleBean('newbee'); |
||||
1236 | $roleDao->save($role); |
||||
1237 | |||||
1238 | $this->assertNull($role->getCreatedAt()); |
||||
1239 | } |
||||
1240 | |||||
1241 | /** |
||||
1242 | * @depends testDaoGeneration |
||||
1243 | */ |
||||
1244 | public function testUpdateInNullableDate(): void |
||||
1245 | { |
||||
1246 | $roleDao = new RoleDao($this->tdbmService); |
||||
1247 | |||||
1248 | $role = new RoleBean('newbee'); |
||||
1249 | $roleDao->save($role); |
||||
1250 | |||||
1251 | $role->setCreatedAt(null); |
||||
1252 | $roleDao->save($role); |
||||
1253 | $this->assertNull($role->getCreatedAt()); |
||||
1254 | } |
||||
1255 | |||||
1256 | /** |
||||
1257 | * @depends testDaoGeneration |
||||
1258 | */ |
||||
1259 | public function testFindFromSql(): void |
||||
1260 | { |
||||
1261 | $roleDao = new TestRoleDao($this->tdbmService); |
||||
1262 | |||||
1263 | $roles = $roleDao->getRolesByRightCanSing(); |
||||
1264 | $this->assertCount(2, $roles); |
||||
1265 | $this->assertInstanceOf(RoleBean::class, $roles[0]); |
||||
1266 | } |
||||
1267 | |||||
1268 | /** |
||||
1269 | * @depends testDaoGeneration |
||||
1270 | */ |
||||
1271 | public function testFindOneFromSql(): void |
||||
1272 | { |
||||
1273 | $roleDao = new TestRoleDao($this->tdbmService); |
||||
1274 | |||||
1275 | $role = $roleDao->getRoleByRightCanSingAndNameSinger(); |
||||
1276 | $this->assertInstanceOf(RoleBean::class, $role); |
||||
1277 | } |
||||
1278 | |||||
1279 | /** |
||||
1280 | * @depends testDaoGeneration |
||||
1281 | */ |
||||
1282 | public function testCreateEmptyExtendedBean(): void |
||||
1283 | { |
||||
1284 | // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/92 |
||||
1285 | |||||
1286 | $dogDao = new DogDao($this->tdbmService); |
||||
1287 | |||||
1288 | // We are not filling no field that is part of dog table. |
||||
1289 | $dog = new DogBean('Youki'); |
||||
1290 | $dog->setOrder(1); |
||||
1291 | |||||
1292 | $dogDao->save($dog); |
||||
1293 | $this->assertNull($dog->getRace()); |
||||
1294 | } |
||||
1295 | |||||
1296 | /** |
||||
1297 | * @depends testCreateEmptyExtendedBean |
||||
1298 | */ |
||||
1299 | public function testFetchEmptyExtendedBean(): void |
||||
1300 | { |
||||
1301 | // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/92 |
||||
1302 | |||||
1303 | $animalDao = new AnimalDao($this->tdbmService); |
||||
1304 | |||||
1305 | // We are not filling no field that is part of dog table. |
||||
1306 | $animalBean = $animalDao->getById(1); |
||||
1307 | |||||
1308 | $this->assertInstanceOf(DogBean::class, $animalBean); |
||||
1309 | } |
||||
1310 | |||||
1311 | /** |
||||
1312 | * @depends testDaoGeneration |
||||
1313 | */ |
||||
1314 | public function testTwoBranchesHierarchy(): void |
||||
1315 | { |
||||
1316 | // This test cases checks issue https://github.com/thecodingmachine/mouf/issues/131 |
||||
1317 | |||||
1318 | $catDao = new CatDao($this->tdbmService); |
||||
1319 | |||||
1320 | // We are not filling no field that is part of dog table. |
||||
1321 | $cat = new CatBean('Mew'); |
||||
1322 | $cat->setOrder(2); |
||||
1323 | |||||
1324 | $catDao->save($cat); |
||||
1325 | $this->assertNotNull($cat->getId()); |
||||
1326 | } |
||||
1327 | |||||
1328 | /** |
||||
1329 | * @depends testTwoBranchesHierarchy |
||||
1330 | */ |
||||
1331 | public function testFetchTwoBranchesHierarchy(): void |
||||
1332 | { |
||||
1333 | // This test cases checks issue https://github.com/thecodingmachine/mouf/issues/131 |
||||
1334 | |||||
1335 | $animalDao = new AnimalDao($this->tdbmService); |
||||
1336 | |||||
1337 | $animalBean = $animalDao->getById(2); |
||||
1338 | |||||
1339 | $this->assertInstanceOf(CatBean::class, $animalBean); |
||||
1340 | /* @var $animalBean CatBean */ |
||||
1341 | $animalBean->setCutenessLevel(999); |
||||
1342 | $animalBean->setUppercaseColumn('foobar'); |
||||
1343 | |||||
1344 | $animalDao->save($animalBean); |
||||
1345 | } |
||||
1346 | |||||
1347 | /** |
||||
1348 | * @depends testDaoGeneration |
||||
1349 | */ |
||||
1350 | public function testExceptionOnGetById(): void |
||||
1351 | { |
||||
1352 | $countryDao = new CountryDao($this->tdbmService); |
||||
1353 | $this->expectException(\TypeError::class); |
||||
1354 | $countryDao->getById(null); |
||||
1355 | } |
||||
1356 | |||||
1357 | /** |
||||
1358 | * @depends testDaoGeneration |
||||
1359 | */ |
||||
1360 | public function testDisconnectedManyToOne(): void |
||||
1361 | { |
||||
1362 | // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/99 |
||||
1363 | |||||
1364 | $country = new CountryBean('Spain'); |
||||
1365 | |||||
1366 | $user = new UserBean('John Doe', '[email protected]', $country, 'john.doe'); |
||||
1367 | |||||
1368 | $this->assertCount(1, $country->getUsers()); |
||||
1369 | $this->assertSame($user, $country->getUsers()[0]); |
||||
1370 | } |
||||
1371 | |||||
1372 | /** |
||||
1373 | * @depends testDaoGeneration |
||||
1374 | */ |
||||
1375 | public function testOrderByExternalCol(): void |
||||
1376 | { |
||||
1377 | // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/106 |
||||
1378 | |||||
1379 | $userDao = new TestUserDao($this->tdbmService); |
||||
1380 | $users = $userDao->getUsersByCountryName(); |
||||
1381 | |||||
1382 | $this->assertEquals('uk', $users[0]->getCountry()->getLabel()); |
||||
1383 | } |
||||
1384 | |||||
1385 | /** |
||||
1386 | * @depends testDaoGeneration |
||||
1387 | */ |
||||
1388 | public function testResultIteratorSort(): void |
||||
1389 | { |
||||
1390 | $userDao = new UserDao($this->tdbmService); |
||||
1391 | $users = $userDao->findAll()->withOrder('country.label DESC'); |
||||
1392 | |||||
1393 | $this->assertEquals('uk', $users[0]->getCountry()->getLabel()); |
||||
1394 | |||||
1395 | $users = $users->withOrder('country.label ASC'); |
||||
1396 | $this->assertEquals('France', $users[0]->getCountry()->getLabel()); |
||||
1397 | } |
||||
1398 | |||||
1399 | /** |
||||
1400 | * @depends testDaoGeneration |
||||
1401 | */ |
||||
1402 | public function testResultIteratorWithParameters(): void |
||||
1403 | { |
||||
1404 | $userDao = new TestUserDao($this->tdbmService); |
||||
1405 | $users = $userDao->getUsersByLoginStartingWith()->withParameters(['login' => 'bill%']); |
||||
1406 | $this->assertEquals('bill.shakespeare', $users[0]->getLogin()); |
||||
1407 | |||||
1408 | $users = $users->withParameters(['login' => 'jean%']); |
||||
1409 | $this->assertEquals('jean.dupont', $users[0]->getLogin()); |
||||
1410 | } |
||||
1411 | |||||
1412 | /** |
||||
1413 | * @depends testDaoGeneration |
||||
1414 | */ |
||||
1415 | public function testOrderByExpression(): void |
||||
1416 | { |
||||
1417 | $userDao = new TestUserDao($this->tdbmService); |
||||
1418 | $users = $userDao->getUsersByReversedCountryName(); |
||||
1419 | |||||
1420 | $this->assertEquals('Jamaica', $users[0]->getCountry()->getLabel()); |
||||
1421 | } |
||||
1422 | |||||
1423 | /** |
||||
1424 | * @depends testDaoGeneration |
||||
1425 | */ |
||||
1426 | public function testOrderByException(): void |
||||
1427 | { |
||||
1428 | $userDao = new TestUserDao($this->tdbmService); |
||||
1429 | $users = $userDao->getUsersByInvalidOrderBy(); |
||||
1430 | $this->expectException(TDBMInvalidArgumentException::class); |
||||
1431 | $user = $users[0]; |
||||
1432 | } |
||||
1433 | |||||
1434 | /** |
||||
1435 | * @depends testDaoGeneration |
||||
1436 | */ |
||||
1437 | public function testOrderByProtectedColumn(): void |
||||
1438 | { |
||||
1439 | $animalDao = new AnimalDao($this->tdbmService); |
||||
1440 | $animals = $animalDao->findAll(); |
||||
1441 | $animals = $animals->withOrder('`order` ASC'); |
||||
1442 | |||||
1443 | $this->assertInstanceOf(DogBean::class, $animals[0]); |
||||
1444 | $this->assertInstanceOf(CatBean::class, $animals[1]); |
||||
1445 | |||||
1446 | $animals = $animals->withOrder('`order` DESC'); |
||||
1447 | |||||
1448 | $this->assertInstanceOf(CatBean::class, $animals[0]); |
||||
1449 | $this->assertInstanceOf(DogBean::class, $animals[1]); |
||||
1450 | } |
||||
1451 | |||||
1452 | /** |
||||
1453 | * @depends testDaoGeneration |
||||
1454 | */ |
||||
1455 | public function testGetOnAllNullableValues(): void |
||||
1456 | { |
||||
1457 | // Tests that a get performed on a column that has only nullable fields succeeds. |
||||
1458 | $allNullable = new AllNullableBean(); |
||||
1459 | $this->assertNull($allNullable->getId()); |
||||
1460 | $this->assertNull($allNullable->getLabel()); |
||||
1461 | $this->assertNull($allNullable->getCountry()); |
||||
1462 | } |
||||
1463 | |||||
1464 | /** |
||||
1465 | * @depends testDaoGeneration |
||||
1466 | */ |
||||
1467 | public function testExceptionOnMultipleInheritance(): void |
||||
1468 | { |
||||
1469 | // Because of the sequence on the PK, we cannot set the PK to 99 at all. |
||||
1470 | $this->skipOracle(); |
||||
1471 | |||||
1472 | $connection = self::getConnection(); |
||||
1473 | self::insert($connection, 'animal', [ |
||||
1474 | 'id' => 99, 'name' => 'Snoofield', |
||||
1475 | ]); |
||||
1476 | self::insert($connection, 'dog', [ |
||||
1477 | 'id' => 99, 'race' => 'dog', |
||||
1478 | ]); |
||||
1479 | self::insert($connection, 'cat', [ |
||||
1480 | 'id' => 99, 'cuteness_level' => 0, |
||||
1481 | ]); |
||||
1482 | |||||
1483 | $catched = false; |
||||
1484 | try { |
||||
1485 | $animalDao = new AnimalDao($this->tdbmService); |
||||
1486 | $animalDao->getById(99); |
||||
1487 | } catch (TDBMInheritanceException $e) { |
||||
1488 | $catched = true; |
||||
1489 | } |
||||
1490 | $this->assertTrue($catched, 'Exception TDBMInheritanceException was not caught'); |
||||
1491 | |||||
1492 | self::delete($connection, 'cat', ['id' => 99]); |
||||
1493 | self::delete($connection, 'dog', ['id' => 99]); |
||||
1494 | self::delete($connection, 'animal', ['id' => 99]); |
||||
1495 | } |
||||
1496 | |||||
1497 | /** |
||||
1498 | * @depends testDaoGeneration |
||||
1499 | */ |
||||
1500 | public function testReferenceNotSaved(): void |
||||
1501 | { |
||||
1502 | $boatDao = new BoatDao($this->tdbmService); |
||||
1503 | |||||
1504 | $country = new CountryBean('Atlantis'); |
||||
1505 | $boat = new BoatBean($country, 'Titanic'); |
||||
1506 | |||||
1507 | $boatDao->save($boat); |
||||
1508 | $this->assertNotNull($country->getId()); |
||||
1509 | } |
||||
1510 | |||||
1511 | /** |
||||
1512 | * @depends testReferenceNotSaved |
||||
1513 | */ |
||||
1514 | public function testUniqueIndexOnForeignKeyThenScalar(): void |
||||
1515 | { |
||||
1516 | $boatDao = new BoatDao($this->tdbmService); |
||||
1517 | $countryDao = new CountryDao($this->tdbmService); |
||||
1518 | |||||
1519 | $countryBean = $countryDao->findOneByLabel('Atlantis'); |
||||
1520 | $boatBean = $boatDao->findOneByAnchorageCountryAndName($countryBean, 'Titanic'); |
||||
1521 | |||||
1522 | $this->assertNotNull($boatBean); |
||||
1523 | } |
||||
1524 | |||||
1525 | /** |
||||
1526 | * @depends testDaoGeneration |
||||
1527 | */ |
||||
1528 | public function testReferenceDeleted(): void |
||||
1529 | { |
||||
1530 | $countryDao = new CountryDao($this->tdbmService); |
||||
1531 | $boatDao = new BoatDao($this->tdbmService); |
||||
1532 | |||||
1533 | $country = new CountryBean('Bikini Bottom'); |
||||
1534 | $countryDao->save($country); |
||||
1535 | |||||
1536 | $boat = new BoatBean($country, 'Squirrel boat'); |
||||
1537 | $countryDao->delete($country); |
||||
1538 | |||||
1539 | $this->expectException(TDBMMissingReferenceException::class); |
||||
1540 | $boatDao->save($boat); |
||||
1541 | } |
||||
1542 | |||||
1543 | /** |
||||
1544 | * @depends testDaoGeneration |
||||
1545 | */ |
||||
1546 | public function testCyclicReferenceWithInheritance(): void |
||||
1547 | { |
||||
1548 | $userDao = new UserDao($this->tdbmService); |
||||
1549 | |||||
1550 | $country = new CountryBean('Norrisland'); |
||||
1551 | $user = new UserBean('Chuck Norris', '[email protected]', $country, 'chuck.norris'); |
||||
1552 | |||||
1553 | $user->setManager($user); |
||||
1554 | |||||
1555 | $this->expectException(TDBMCyclicReferenceException::class); |
||||
1556 | $userDao->save($user); |
||||
1557 | } |
||||
1558 | |||||
1559 | /** |
||||
1560 | * @depends testDaoGeneration |
||||
1561 | */ |
||||
1562 | public function testCyclicReference(): void |
||||
1563 | { |
||||
1564 | $categoryDao = new CategoryDao($this->tdbmService); |
||||
1565 | |||||
1566 | $category = new CategoryBean('Root'); |
||||
1567 | |||||
1568 | $category->setParent($category); |
||||
1569 | |||||
1570 | $this->expectException(TDBMCyclicReferenceException::class); |
||||
1571 | $categoryDao->save($category); |
||||
1572 | } |
||||
1573 | |||||
1574 | /** |
||||
1575 | * @depends testDaoGeneration |
||||
1576 | */ |
||||
1577 | public function testCorrectTypeForPrimaryKeyAfterSave(): void |
||||
1578 | { |
||||
1579 | // PosqtgreSQL does not particularly like empty inserts (i.e.: "INSERT INTO all_nullable () VALUES ()" ) |
||||
1580 | $this->onlyMySql(); |
||||
1581 | |||||
1582 | $allNullableDao = new AllNullableDao($this->tdbmService); |
||||
1583 | $allNullable = new AllNullableBean(); |
||||
1584 | $allNullableDao->save($allNullable); |
||||
1585 | $id = $allNullable->getId(); |
||||
1586 | |||||
1587 | $this->assertTrue(is_int($id)); |
||||
1588 | } |
||||
1589 | |||||
1590 | /** |
||||
1591 | * @depends testDaoGeneration |
||||
1592 | */ |
||||
1593 | public function testPSR2Compliance(): void |
||||
1594 | { |
||||
1595 | $process = new Process(['vendor/bin/php-cs-fixer', 'fix', 'src/Test/', '--dry-run', '--diff', '--diff-format=udiff', '--rules=@PSR2']); |
||||
1596 | $process->run(); |
||||
1597 | |||||
1598 | // executes after the command finishes |
||||
1599 | if (!$process->isSuccessful()) { |
||||
1600 | echo $process->getOutput(); |
||||
1601 | $this->fail('Generated code is not PSR-2 compliant'); |
||||
1602 | } |
||||
1603 | $this->assertTrue($process->isSuccessful()); |
||||
1604 | } |
||||
1605 | |||||
1606 | /** |
||||
1607 | * @depends testDaoGeneration |
||||
1608 | */ |
||||
1609 | public function testFindOneByGeneration(): void |
||||
1610 | { |
||||
1611 | $reflectionMethod = new \ReflectionMethod(UserBaseDao::class, 'findOneByLogin'); |
||||
1612 | $parameters = $reflectionMethod->getParameters(); |
||||
1613 | |||||
1614 | $this->assertCount(2, $parameters); |
||||
1615 | $this->assertSame('login', $parameters[0]->getName()); |
||||
1616 | $this->assertSame('additionalTablesFetch', $parameters[1]->getName()); |
||||
1617 | } |
||||
1618 | |||||
1619 | /** |
||||
1620 | * @depends testDaoGeneration |
||||
1621 | */ |
||||
1622 | public function testUuid(): void |
||||
1623 | { |
||||
1624 | $article = new ArticleBean('content'); |
||||
1625 | $this->assertSame('content', $article->getContent()); |
||||
1626 | $this->assertNotEmpty($article->getId()); |
||||
1627 | $uuid = Uuid::fromString($article->getId()); |
||||
1628 | $this->assertSame(1, $uuid->getVersion()); |
||||
1629 | } |
||||
1630 | |||||
1631 | /** |
||||
1632 | * @depends testDaoGeneration |
||||
1633 | */ |
||||
1634 | public function testUuidv4(): void |
||||
1635 | { |
||||
1636 | $article = new Article2Bean('content'); |
||||
1637 | $this->assertSame('content', $article->getContent()); |
||||
1638 | $this->assertNotEmpty($article->getId()); |
||||
1639 | $uuid = Uuid::fromString($article->getId()); |
||||
1640 | $this->assertSame(4, $uuid->getVersion()); |
||||
1641 | } |
||||
1642 | |||||
1643 | /** |
||||
1644 | * @depends testDaoGeneration |
||||
1645 | */ |
||||
1646 | public function testTypeHintedConstructors(): void |
||||
1647 | { |
||||
1648 | $userBaseBeanReflectionConstructor = new \ReflectionMethod(UserBaseBean::class, '__construct'); |
||||
1649 | /** @var ReflectionNamedType $nameParam */ |
||||
1650 | $nameParam = $userBaseBeanReflectionConstructor->getParameters()[0]; |
||||
1651 | |||||
1652 | $this->assertSame('string', $nameParam->getType()->getName()); |
||||
1653 | } |
||||
1654 | |||||
1655 | /** |
||||
1656 | * @depends testDaoGeneration |
||||
1657 | */ |
||||
1658 | public function testSaveTransaction(): void |
||||
1659 | { |
||||
1660 | $countryDao = new CountryDao($this->tdbmService); |
||||
1661 | |||||
1662 | $boatDao = new BoatDao($this->tdbmService); |
||||
1663 | $boatBean = $boatDao->getById(1); |
||||
1664 | $boatBean->setName('Bismark'); |
||||
1665 | |||||
1666 | $boatBean->getCountry(); |
||||
1667 | |||||
1668 | // Let's insert a row without telling TDBM to trigger an error! |
||||
1669 | self::insert($this->getConnection(), 'sailed_countries', [ |
||||
1670 | 'boat_id' => 1, |
||||
1671 | 'country_id' => 2 |
||||
1672 | ]); |
||||
1673 | |||||
1674 | $boatBean->addCountry($countryDao->getById(2)); |
||||
1675 | |||||
1676 | $this->expectException(UniqueConstraintViolationException::class); |
||||
1677 | |||||
1678 | $boatDao->save($boatBean); |
||||
1679 | } |
||||
1680 | |||||
1681 | /** |
||||
1682 | * @depends testSaveTransaction |
||||
1683 | */ |
||||
1684 | public function testSaveTransaction2(): void |
||||
1685 | { |
||||
1686 | $boatDao = new BoatDao($this->tdbmService); |
||||
1687 | $boatBean = $boatDao->getById(1); |
||||
1688 | |||||
1689 | // The name should not have been saved because the transaction of the previous test should have rollbacked. |
||||
1690 | $this->assertNotSame('Bismark', $boatBean->getName()); |
||||
1691 | } |
||||
1692 | |||||
1693 | /** |
||||
1694 | * @depends testDaoGeneration |
||||
1695 | */ |
||||
1696 | public function testForeignKeyPointingToNonPrimaryKey(): void |
||||
1697 | { |
||||
1698 | $dao = new RefNoPrimKeyDao($this->tdbmService); |
||||
1699 | $bean = $dao->getById(1); |
||||
1700 | |||||
1701 | $this->assertSame('foo', $bean->getFrom()->getTo()); |
||||
1702 | |||||
1703 | $newBean = new RefNoPrimKeyBean($bean, 'baz'); |
||||
1704 | $dao->save($newBean); |
||||
1705 | $this->assertSame('foo', $newBean->getFrom()->getTo()); |
||||
1706 | |||||
1707 | $resultSet = $bean->getRefNoPrimKey(); |
||||
1708 | $this->assertCount(2, $resultSet); |
||||
1709 | } |
||||
1710 | |||||
1711 | /** |
||||
1712 | * @depends testDaoGeneration |
||||
1713 | */ |
||||
1714 | public function testCloningUuidBean(): void |
||||
1715 | { |
||||
1716 | $article = new ArticleBean('content'); |
||||
1717 | $this->assertNotEmpty($article->getId()); |
||||
1718 | $article2 = clone $article; |
||||
1719 | $this->assertNotEmpty($article2->getId()); |
||||
1720 | $this->assertNotSame($article->getId(), $article2->getId()); |
||||
1721 | } |
||||
1722 | |||||
1723 | /** |
||||
1724 | * @depends testDaoGeneration |
||||
1725 | */ |
||||
1726 | public function testRecursiveSave(): void |
||||
1727 | { |
||||
1728 | $categoryDao = new CategoryDao($this->tdbmService); |
||||
1729 | |||||
1730 | $root1 = new CategoryBean('Root1'); |
||||
1731 | $categoryDao->save($root1); |
||||
1732 | // Root 2 is not saved yet. |
||||
1733 | $root2 = new CategoryBean('Root2'); |
||||
1734 | $intermediate = new CategoryBean('Intermediate'); |
||||
1735 | $categoryDao->save($intermediate); |
||||
1736 | |||||
1737 | // Let's switch the parent to a bean in detached state. |
||||
1738 | $intermediate->setParent($root2); |
||||
1739 | |||||
1740 | // Now, let's save a new category that references the leaf category. |
||||
1741 | $leaf = new CategoryBean('Leaf'); |
||||
1742 | $leaf->setParent($intermediate); |
||||
1743 | $categoryDao->save($leaf); |
||||
1744 | $this->assertNull($root2->getId()); |
||||
1745 | } |
||||
1746 | |||||
1747 | /** |
||||
1748 | * @depends testDaoGeneration |
||||
1749 | */ |
||||
1750 | public function testBlob(): void |
||||
1751 | { |
||||
1752 | // An issue in DBAL makes using BLOB type impossible with resources. |
||||
1753 | // See https://github.com/doctrine/dbal/issues/3290 |
||||
1754 | $this->skipOracle(); |
||||
1755 | |||||
1756 | $fp = fopen(__FILE__, 'r'); |
||||
1757 | $file = new FileBean($fp); |
||||
1758 | |||||
1759 | $fileDao = new FileDao($this->tdbmService); |
||||
1760 | |||||
1761 | $fileDao->save($file); |
||||
1762 | |||||
1763 | $loadedFile = $fileDao->getById($file->getId()); |
||||
1764 | |||||
1765 | $resource = $loadedFile->getFile(); |
||||
1766 | $result = fseek($resource, 0); |
||||
1767 | $this->assertSame(0, $result); |
||||
1768 | $this->assertIsResource($resource); |
||||
1769 | $firstLine = fgets($resource); |
||||
1770 | $this->assertSame("<?php\n", $firstLine); |
||||
1771 | } |
||||
1772 | |||||
1773 | /** |
||||
1774 | * @depends testBlob |
||||
1775 | */ |
||||
1776 | public function testReadBlob(): void |
||||
1777 | { |
||||
1778 | // An issue in DBAL makes using BLOB type impossible with resources. |
||||
1779 | // See https://github.com/doctrine/dbal/issues/3290 |
||||
1780 | $this->skipOracle(); |
||||
1781 | |||||
1782 | $fileDao = new FileDao($this->tdbmService); |
||||
1783 | $loadedFile = $fileDao->getById(1); |
||||
1784 | |||||
1785 | $resource = $loadedFile->getFile(); |
||||
1786 | $this->assertIsResource($resource); |
||||
1787 | $firstLine = fgets($resource); |
||||
1788 | $this->assertSame("<?php\n", $firstLine); |
||||
1789 | |||||
1790 | stream_get_contents($resource); |
||||
1791 | |||||
1792 | $loadedFile->setId($loadedFile->getId()); |
||||
1793 | |||||
1794 | $fileDao->save($loadedFile); |
||||
1795 | } |
||||
1796 | |||||
1797 | /** |
||||
1798 | * @depends testReadBlob |
||||
1799 | */ |
||||
1800 | public function testReadAndSaveBlob(): void |
||||
1801 | { |
||||
1802 | // An issue in DBAL makes using BLOB type impossible with resources. |
||||
1803 | // See https://github.com/doctrine/dbal/issues/3290 |
||||
1804 | $this->skipOracle(); |
||||
1805 | |||||
1806 | $fileDao = new FileDao($this->tdbmService); |
||||
1807 | $loadedFile = $fileDao->getById(1); |
||||
1808 | |||||
1809 | $resource = $loadedFile->getFile(); |
||||
1810 | |||||
1811 | $firstLine = fgets($resource); |
||||
1812 | $this->assertSame("<?php\n", $firstLine); |
||||
1813 | } |
||||
1814 | |||||
1815 | /** |
||||
1816 | * @depends testReadBlob |
||||
1817 | */ |
||||
1818 | public function testProtectedGetterSetter(): void |
||||
1819 | { |
||||
1820 | // An issue in DBAL makes using BLOB type impossible with resources. |
||||
1821 | // See https://github.com/doctrine/dbal/issues/3290 |
||||
1822 | $this->skipOracle(); |
||||
1823 | |||||
1824 | $md5Getter = new ReflectionMethod(FileBaseBean::class, 'getMd5'); |
||||
1825 | $md5Setter = new ReflectionMethod(FileBaseBean::class, 'setMd5'); |
||||
1826 | |||||
1827 | $this->assertTrue($md5Getter->isProtected()); |
||||
1828 | $this->assertTrue($md5Setter->isProtected()); |
||||
1829 | |||||
1830 | $md5Getter2 = new ReflectionMethod(FileBaseBean::class, 'getArticle'); |
||||
1831 | $md5Setter2 = new ReflectionMethod(FileBaseBean::class, 'setArticle'); |
||||
1832 | |||||
1833 | $this->assertTrue($md5Getter2->isProtected()); |
||||
1834 | $this->assertTrue($md5Setter2->isProtected()); |
||||
1835 | |||||
1836 | $oneToManyGetter = new ReflectionMethod(ArticleBaseBean::class, 'getFiles'); |
||||
1837 | $this->assertTrue($oneToManyGetter->isProtected()); |
||||
1838 | |||||
1839 | $fileDao = new FileDao($this->tdbmService); |
||||
1840 | $loadedFile = $fileDao->getById(1); |
||||
1841 | |||||
1842 | // The md5 and article columns are not JSON serialized |
||||
1843 | $this->assertSame([ |
||||
1844 | 'id' => 1, |
||||
1845 | ], $loadedFile->jsonSerialize()); |
||||
1846 | } |
||||
1847 | |||||
1848 | /** |
||||
1849 | * @depends testDaoGeneration |
||||
1850 | */ |
||||
1851 | public function testBlobResourceException(): void |
||||
1852 | { |
||||
1853 | $this->expectException(TDBMInvalidArgumentException::class); |
||||
1854 | $this->expectExceptionMessage('Invalid argument passed to \'TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\Generated\\FileBaseBean::setFile\'. Expecting a resource. Got a string.'); |
||||
1855 | new FileBean('foobar'); |
||||
1856 | } |
||||
1857 | |||||
1858 | /** |
||||
1859 | * @depends testDaoGeneration |
||||
1860 | */ |
||||
1861 | public function testFilterBag(): void |
||||
1862 | { |
||||
1863 | $userDao = new TestUserDao($this->tdbmService); |
||||
1864 | $countryDao = new CountryDao($this->tdbmService); |
||||
1865 | |||||
1866 | $country = $countryDao->getById(2); |
||||
1867 | |||||
1868 | // Let's test filter bags by bean and filter bag with many values. |
||||
1869 | $users = $userDao->getUsersByComplexFilterBag($country, ['John Doe', 'Jane Doe']); |
||||
1870 | |||||
1871 | $this->assertCount(1, $users); |
||||
1872 | $this->assertSame('John Doe', $users[0]->getName()); |
||||
1873 | } |
||||
1874 | |||||
1875 | /** |
||||
1876 | * @depends testDaoGeneration |
||||
1877 | */ |
||||
1878 | public function testDecimalIsMappedToString(): void |
||||
1879 | { |
||||
1880 | $reflectionClass = new \ReflectionClass(BoatBaseBean::class); |
||||
1881 | $this->assertSame('string', $reflectionClass->getMethod('getLength')->getReturnType()->getName()); |
||||
1882 | } |
||||
1883 | |||||
1884 | /** |
||||
1885 | * @depends testDaoGeneration |
||||
1886 | */ |
||||
1887 | public function testInsertMultiPrimaryKeysBean(): void |
||||
1888 | { |
||||
1889 | $countryDao = new CountryDao($this->tdbmService); |
||||
1890 | |||||
1891 | $country = $countryDao->getById(1); |
||||
1892 | |||||
1893 | $stateDao = new StateDao($this->tdbmService); |
||||
1894 | $state = new StateBean($country, 'IDF', 'Ile de France'); |
||||
1895 | $stateDao->save($state); |
||||
1896 | |||||
1897 | $this->assertSame($state, $stateDao->findAll()[0]); |
||||
1898 | } |
||||
1899 | |||||
1900 | /** |
||||
1901 | * @depends testInsertMultiPrimaryKeysBean |
||||
1902 | */ |
||||
1903 | public function testDeleteMultiPrimaryKeysBean(): void |
||||
1904 | { |
||||
1905 | $stateDao = new StateDao($this->tdbmService); |
||||
1906 | |||||
1907 | $state = $stateDao->findAll()[0]; |
||||
1908 | $stateDao->delete($state); |
||||
1909 | $this->assertCount(0, $stateDao->findAll()); |
||||
1910 | } |
||||
1911 | |||||
1912 | /** |
||||
1913 | * @depends testDaoGeneration |
||||
1914 | */ |
||||
1915 | public function testCompositePrimaryKeyGetter(): void |
||||
1916 | { |
||||
1917 | $stateDao = new StateDao($this->tdbmService); |
||||
1918 | $country = new CountryBean('USA'); |
||||
1919 | $stateBean = new StateBean($country, 'CA', 'California'); |
||||
1920 | $stateDao->save($stateBean); |
||||
1921 | $this->assertSame($stateBean, $stateDao->getById($country->getId(), 'CA')); |
||||
1922 | } |
||||
1923 | |||||
1924 | /** |
||||
1925 | * @depends testDaoGeneration |
||||
1926 | */ |
||||
1927 | public function testSortOnInheritedTable(): void |
||||
1928 | { |
||||
1929 | $animalDao = new AnimalDao($this->tdbmService); |
||||
1930 | |||||
1931 | // Let's insert an animal that is nothing. |
||||
1932 | $animal = new AnimalBean('Mickey'); |
||||
1933 | $animalDao->save($animal); |
||||
1934 | |||||
1935 | $animals = $animalDao->findAll()->withOrder('dog.race ASC'); |
||||
1936 | |||||
1937 | $animalsArr = $animals->toArray(); |
||||
1938 | $this->assertCount(3, $animalsArr); |
||||
1939 | } |
||||
1940 | |||||
1941 | /** |
||||
1942 | * @depends testDaoGeneration |
||||
1943 | */ |
||||
1944 | public function testJsonKey(): void |
||||
1945 | { |
||||
1946 | $node = new NodeBean('foo.html'); |
||||
1947 | $json = $node->jsonSerialize(); |
||||
1948 | self::assertTrue(isset($json['basename'])); |
||||
1949 | self::assertEquals('foo.html', $json['basename']); |
||||
1950 | } |
||||
1951 | |||||
1952 | /** |
||||
1953 | * @depends testDaoGeneration |
||||
1954 | */ |
||||
1955 | public function testJsonIgnore(): void |
||||
1956 | { |
||||
1957 | $nodeDao = new NodeDao($this->tdbmService); |
||||
1958 | $index = $nodeDao->getById(6); |
||||
1959 | $json = $index->jsonSerialize(); |
||||
1960 | // Ignored scalar 'id' |
||||
1961 | self::assertTrue(!isset($json['id'])); |
||||
1962 | // Ignored object 'root' |
||||
1963 | self::assertTrue(!isset($json['root'])); |
||||
1964 | self::assertTrue(isset($json['guests'])); |
||||
1965 | self::assertTrue(!empty($json['guests'])); |
||||
1966 | $account = $index->getAccounts()[0]; |
||||
1967 | $json = $account->jsonSerialize(); |
||||
1968 | // Ignored array 'nodes' (from nodes_users table) |
||||
1969 | self::assertTrue(!isset($json['nodes'])); |
||||
1970 | } |
||||
1971 | |||||
1972 | /** |
||||
1973 | * @depends testDaoGeneration |
||||
1974 | */ |
||||
1975 | public function testJsonInclude(): void |
||||
1976 | { |
||||
1977 | $nodeDao = new NodeDao($this->tdbmService); |
||||
1978 | $index = $nodeDao->getById(6); |
||||
1979 | $json = $index->jsonSerialize(); |
||||
1980 | // Whole chain of parents should be serialized |
||||
1981 | self::assertTrue(isset($json['parent'])); |
||||
1982 | self::assertTrue(isset($json['parent']['parent'])); |
||||
1983 | self::assertTrue(isset($json['parent']['parent']['parent'])); |
||||
1984 | self::assertEquals('/', $json['parent']['parent']['parent']['basename']); |
||||
1985 | } |
||||
1986 | |||||
1987 | /** |
||||
1988 | * @depends testDaoGeneration |
||||
1989 | */ |
||||
1990 | public function testJsonRecursive(): void |
||||
1991 | { |
||||
1992 | $nodeDao = new NodeDao($this->tdbmService); |
||||
1993 | $index = $nodeDao->getById(8); |
||||
1994 | $json = $index->jsonSerialize(); |
||||
1995 | // Original chain of aliases is recursively serialized, ... |
||||
1996 | self::assertTrue(isset($json['alias'])); |
||||
1997 | self::assertTrue(isset($json['alias']['alias'])); |
||||
1998 | self::assertEquals('index.html', $json['alias']['alias']['basename']); |
||||
1999 | // ... each alias even serializes its parents, ... |
||||
2000 | self::assertTrue(isset($json['alias']['alias']['parent']['parent'])); |
||||
2001 | // ... however, parents aliases chains have just their foreign key (id), as parents are serialized with $stopRecursion=true |
||||
2002 | self::assertEquals(3, $json['alias']['alias']['parent']['parent']['alias']['id']); |
||||
2003 | self::assertCount(1, $json['alias']['alias']['parent']['parent']['alias']); |
||||
2004 | } |
||||
2005 | |||||
2006 | /** |
||||
2007 | * @depends testDaoGeneration |
||||
2008 | */ |
||||
2009 | public function testJsonFormat(): void |
||||
2010 | { |
||||
2011 | $nodeDao = new NodeDao($this->tdbmService); |
||||
2012 | $index = $nodeDao->getById(6); |
||||
2013 | $json = $index->jsonSerialize(); |
||||
2014 | self::assertTrue(isset($json['size'])); |
||||
2015 | self::assertEquals('512 o', $json['size']); |
||||
2016 | self::assertEquals('42.50g', $json['weight']); |
||||
2017 | self::assertEquals($index->getCreatedAt()->format('Y-m-d'), $json['createdAt']); |
||||
2018 | self::assertEquals($index->getOwner()->getName(), $json['owner']); |
||||
2019 | self::assertEquals($index->getAccounts()[1]->getName(), $json['guests'][1]); |
||||
2020 | self::assertTrue(isset($json['entries'])); |
||||
2021 | self::assertEquals('Hello, World', $json['entries'][1]); |
||||
2022 | $www = $index->getParent(); |
||||
2023 | $json = $www->jsonSerialize(); |
||||
2024 | self::assertEquals('0 o', $json['size']); |
||||
2025 | self::assertNull($json['weight']); |
||||
2026 | self::assertNull($json['owner']); |
||||
2027 | } |
||||
2028 | |||||
2029 | /** |
||||
2030 | * @depends testDaoGeneration |
||||
2031 | */ |
||||
2032 | public function testJsonCollection(): void |
||||
2033 | { |
||||
2034 | // This test tries to perform a SELECT DISTINCT on a JSON column (which is represented as a CLOB column in Oracle) |
||||
2035 | // DISTINCT statements cannot be applied on CLOB columns. As a result, JSON columns are not supported in Oracle + TDBM 5 for now. |
||||
2036 | $this->skipOracle(); |
||||
2037 | |||||
2038 | $artists = new ArtistDao($this->tdbmService); |
||||
2039 | $pinkFloyd = $artists->getById(1); |
||||
2040 | $animals = $pinkFloyd->getAlbums()[0]; |
||||
2041 | $json = $pinkFloyd->jsonSerialize(); |
||||
2042 | // Collection name properly handled ('discography' instead of default 'albums') |
||||
2043 | self::assertTrue(isset($json['discography'])); |
||||
2044 | self::assertEquals($animals->getTitle(), $json['discography'][0]['title']); |
||||
2045 | // Make sure top object have just its primary key |
||||
2046 | self::assertEquals(1, $json['discography'][0]['artist']['id']); |
||||
2047 | self::assertCount(1, $json['discography'][0]['artist']); |
||||
2048 | $json = $animals->jsonSerialize(); |
||||
2049 | // Nevertheless, artist should be serialized in album as top object... |
||||
2050 | self::assertTrue(isset($json['artist'])); |
||||
2051 | // ... as should be tracks... |
||||
2052 | self::assertTrue(isset($json['tracks'][0])); |
||||
2053 | self::assertEquals('Pigs on the Wing 1', $json['tracks'][0]['title']); |
||||
2054 | // ... and, ultimately, list of featuring artists, since feat is included |
||||
2055 | self::assertTrue(isset($json['tracks'][0]['feat'][0])); |
||||
2056 | self::assertEquals('Roger Waters', $json['tracks'][0]['feat'][0]['name']); |
||||
2057 | } |
||||
2058 | |||||
2059 | public function testFloydHasNoParent(): void |
||||
2060 | { |
||||
2061 | // This test tries to perform a SELECT DISTINCT on a JSON column (which is represented as a CLOB column in Oracle) |
||||
2062 | // DISTINCT statements cannot be applied on CLOB columns. As a result, JSON columns are not supported in Oracle + TDBM 5 for now. |
||||
2063 | $this->skipOracle(); |
||||
2064 | |||||
2065 | $artists = new ArtistDao($this->tdbmService); |
||||
2066 | $pinkFloyd = $artists->getById(1); |
||||
2067 | $parents = $pinkFloyd->getParents(); |
||||
2068 | |||||
2069 | $this->assertEquals([], $parents); |
||||
2070 | } |
||||
2071 | |||||
2072 | public function testFloydHasOneChild(): void |
||||
2073 | { |
||||
2074 | // This test tries to perform a SELECT DISTINCT on a JSON column (which is represented as a CLOB column in Oracle) |
||||
2075 | // DISTINCT statements cannot be applied on CLOB columns. As a result, JSON columns are not supported in Oracle + TDBM 5 for now. |
||||
2076 | $this->skipOracle(); |
||||
2077 | |||||
2078 | $artists = new ArtistDao($this->tdbmService); |
||||
2079 | $pinkFloyd = $artists->getById(1); |
||||
2080 | $children = $pinkFloyd->getChildrenByArtistsRelations(); |
||||
2081 | |||||
2082 | $this->assertEquals(1, count($children)); |
||||
2083 | $this->assertEquals(2, $children[0]->getId()); |
||||
2084 | } |
||||
2085 | |||||
2086 | /** |
||||
2087 | * @depends testDaoGeneration |
||||
2088 | */ |
||||
2089 | public function testAddInterfaceAnnotation(): void |
||||
2090 | { |
||||
2091 | $refClass = new ReflectionClass(UserBaseBean::class); |
||||
2092 | $this->assertTrue($refClass->implementsInterface(TestUserInterface::class)); |
||||
2093 | } |
||||
2094 | |||||
2095 | /** |
||||
2096 | * @depends testDaoGeneration |
||||
2097 | */ |
||||
2098 | public function testAddInterfaceOnDaoAnnotation(): void |
||||
2099 | { |
||||
2100 | $refClass = new ReflectionClass(UserBaseDao::class); |
||||
2101 | $this->assertTrue($refClass->implementsInterface(TestUserDaoInterface::class)); |
||||
2102 | } |
||||
2103 | |||||
2104 | /** |
||||
2105 | * @depends testDaoGeneration |
||||
2106 | */ |
||||
2107 | public function testTrait(): void |
||||
2108 | { |
||||
2109 | $userDao = new UserDao($this->tdbmService); |
||||
2110 | $userBean = $userDao->getById(1); |
||||
2111 | |||||
2112 | $this->assertSame('TestOtherUserTrait', $userBean->method1()); |
||||
2113 | $this->assertSame('TestUserTrait', $userBean->method1renamed()); |
||||
2114 | |||||
2115 | $refClass = new ReflectionClass(UserBaseDao::class); |
||||
2116 | $this->assertTrue($refClass->hasMethod('findNothing')); |
||||
2117 | } |
||||
2118 | |||||
2119 | /** |
||||
2120 | * @depends testDaoGeneration |
||||
2121 | */ |
||||
2122 | public function testNonInstantiableAbstractDaosAndBeans(): void |
||||
2123 | { |
||||
2124 | $refClass = new ReflectionClass(UserBaseDao::class); |
||||
2125 | $this->assertFalse($refClass->isInstantiable()); |
||||
2126 | |||||
2127 | $refClass = new ReflectionClass(UserBaseBean::class); |
||||
2128 | $this->assertFalse($refClass->isInstantiable()); |
||||
2129 | } |
||||
2130 | |||||
2131 | /** |
||||
2132 | * @depends testDaoGeneration |
||||
2133 | */ |
||||
2134 | public function testCanNullifyBlob(): void |
||||
2135 | { |
||||
2136 | $article = new ArticleBean('content'); |
||||
2137 | $fp = fopen(__FILE__, 'r'); |
||||
2138 | $article->setAttachment($fp); |
||||
2139 | $article->setAttachment(null); |
||||
2140 | $this->assertNull($article->getAttachment(null)); |
||||
2141 | fclose($fp); |
||||
2142 | } |
||||
2143 | |||||
2144 | /** |
||||
2145 | * @depends testDaoGeneration |
||||
2146 | */ |
||||
2147 | public function testOptionnalParametersCanBeNullInFindOneBy() |
||||
2148 | { |
||||
2149 | $albumDao = new AlbumDao($this->tdbmService); |
||||
2150 | $artist = new ArtistBean('Marcel'); |
||||
2151 | |||||
2152 | $albumDao->findOneByArtistAndNode($artist, null); |
||||
2153 | $this->assertEquals(1, 1); |
||||
2154 | } |
||||
2155 | |||||
2156 | /** |
||||
2157 | * @depends testDaoGeneration |
||||
2158 | */ |
||||
2159 | public function testRequiredParametersCannotBeNullInFindOneBy() |
||||
2160 | { |
||||
2161 | $albumDao = new AlbumDao($this->tdbmService); |
||||
2162 | $artist = new ArtistBean('Marcel'); |
||||
2163 | $account = new AccountBean('Jamie'); |
||||
2164 | |||||
2165 | $albumDao->findOneByArtistAndAccount($artist, $account); |
||||
2166 | |||||
2167 | $this->expectException('TypeError'); |
||||
2168 | $albumDao->findOneByArtistAndAccount($artist, null); |
||||
2169 | } |
||||
2170 | |||||
2171 | /** |
||||
2172 | * @depends testDaoGeneration |
||||
2173 | */ |
||||
2174 | public function testLazyLoad(): void |
||||
2175 | { |
||||
2176 | $roleDao = new RoleDao($this->tdbmService); |
||||
2177 | $roleBean = $roleDao->getById(1, true); |
||||
2178 | |||||
2179 | $this->assertSame(TDBMObjectStateEnum::STATE_NOT_LOADED, $roleBean->_getDbRows()['roles']->_getStatus()); |
||||
2180 | $roleBean->getId(); |
||||
2181 | $this->assertSame(TDBMObjectStateEnum::STATE_NOT_LOADED, $roleBean->_getDbRows()['roles']->_getStatus()); |
||||
2182 | } |
||||
2183 | |||||
2184 | /** |
||||
2185 | * @depends testDaoGeneration |
||||
2186 | */ |
||||
2187 | public function testOneToOneInverseRelationGetter(): void |
||||
2188 | { |
||||
2189 | $this->skipOracle(); |
||||
2190 | |||||
2191 | $objectBaseDao = new BaseObjectDao($this->tdbmService); |
||||
2192 | $objectInheritedDao = new InheritedObjectDao($this->tdbmService); |
||||
2193 | $objectBase = new BaseObjectBean('label'); |
||||
2194 | $objectBaseDao->save($objectBase); |
||||
2195 | $this->assertNull($objectBase->getInheritedObject()); |
||||
2196 | $objectInherited = new InheritedObjectBean($objectBase); |
||||
2197 | $objectInheritedDao->save($objectInherited); |
||||
2198 | $this->assertSame($objectInherited, $objectBase->getInheritedObject()); |
||||
2199 | $this->assertEquals(1, $objectBase->jsonSerialize()['inheritedObject']['id']); |
||||
2200 | } |
||||
2201 | |||||
2202 | public function testLazyStopRecursion(): void |
||||
2203 | { |
||||
2204 | $albumDao = new AlbumDao($this->tdbmService); |
||||
2205 | $albumBean = $albumDao->getById(1); |
||||
2206 | $json = $albumBean->jsonSerialize(true); |
||||
2207 | $this->assertArrayHasKey('id', $json['artist']); |
||||
2208 | $this->assertArrayNotHasKey('name', $json['artist']); |
||||
2209 | } |
||||
2210 | |||||
2211 | public function testLazyStopRecursionOnCompositeForeignKey(): void |
||||
2212 | { |
||||
2213 | $compositeFkSourceDao = new CompositeFkSourceDao($this->tdbmService); |
||||
2214 | $compositeFkSourceBean = $compositeFkSourceDao->getById(1); |
||||
2215 | $json = $compositeFkSourceBean->jsonSerialize(true); |
||||
2216 | $this->assertEquals(1, $json['compositeFkTarget']['1']['id']); |
||||
2217 | $this->assertEquals(1, $json['compositeFkTarget']['id2']); |
||||
2218 | } |
||||
2219 | |||||
2220 | public function testMethodNameConflictsBetweenRegularAndAutoPivotProperties(): void |
||||
2221 | { |
||||
2222 | $artist = new ArtistBean('Super'); |
||||
2223 | $artist->getChildren(); // regular property |
||||
2224 | $artist->getChildrenByArtistId(); // one-to-may relationship |
||||
2225 | $artist->getChildrenByArtistsRelations(); // auto-pivot relationship |
||||
2226 | $this->assertEquals(1, 1); |
||||
2227 | } |
||||
2228 | |||||
2229 | /** |
||||
2230 | * @depends testDaoGeneration |
||||
2231 | */ |
||||
2232 | public function testSQLCountWithArray(): void |
||||
2233 | { |
||||
2234 | $userDao = new TestUserDao($this->tdbmService); |
||||
2235 | $countryDao = new CountryDao($this->tdbmService); |
||||
2236 | |||||
2237 | $country = $countryDao->getById(2); |
||||
2238 | |||||
2239 | // Let's test filter bags by bean and filter bag with many values. |
||||
2240 | $users = $userDao->getUsersByComplexFilterBag($country, ['John Doe', 'John Smith'])->take(0, 1); |
||||
2241 | $this->assertEquals(1, $users->count()); |
||||
2242 | } |
||||
2243 | |||||
2244 | /** |
||||
2245 | * @depends testDaoGeneration |
||||
2246 | */ |
||||
2247 | public function testSubQueryWithFind(): void |
||||
2248 | { |
||||
2249 | $userDao = new TestUserDao($this->tdbmService); |
||||
2250 | $articleDao = new TestArticleSubQueryDao($this->tdbmService, $userDao); |
||||
2251 | |||||
2252 | $bill = $userDao->getById(4); |
||||
2253 | $article = new ArticleBean('Foo'); |
||||
2254 | $article->setAuthor($bill); |
||||
2255 | $articleDao->save($article); |
||||
2256 | |||||
2257 | $results = $articleDao->getArticlesByUserLoginStartingWith('bill'); |
||||
2258 | |||||
2259 | $this->assertCount(1, $results); |
||||
2260 | $this->assertSame('Foo', $results[0]->getContent()); |
||||
2261 | } |
||||
2262 | |||||
2263 | public function testSubQueryExceptionOnPrimaryKeysWithMultipleColumns(): void |
||||
2264 | { |
||||
2265 | $stateDao = new StateDao($this->tdbmService); |
||||
2266 | $states = $stateDao->findAll(); |
||||
2267 | $this->expectException(TDBMException::class); |
||||
2268 | $this->expectExceptionMessage('You cannot use in a sub-query a table that has a primary key on more that 1 column.'); |
||||
2269 | $states->_getSubQuery(); |
||||
2270 | } |
||||
2271 | |||||
2272 | public function testFindByDateTime(): void |
||||
2273 | { |
||||
2274 | $personDao = new PersonDao($this->tdbmService); |
||||
2275 | $personDao->findByModifiedAt(new \DateTimeImmutable())->count(); |
||||
2276 | $this->assertTrue(true); |
||||
2277 | } |
||||
2278 | |||||
2279 | /** |
||||
2280 | * Bug: find from sql use a `COUNT(DISTINCT *)` which fails because of null values. |
||||
2281 | */ |
||||
2282 | public function testFindFromRawSqlCount(): void |
||||
2283 | { |
||||
2284 | $dao = new TestAlbumDao($this->tdbmService); |
||||
2285 | $albums = $dao->findAllFromRawSql(); |
||||
2286 | |||||
2287 | $firstAlbum = $albums->first(); |
||||
2288 | assert($firstAlbum instanceof AlbumBean); |
||||
2289 | $this->assertNull($firstAlbum->getNode()); // This null ensure reproducibility of the bug |
||||
2290 | $expectedCount = $dao->findAllFromRawSqlWithCount()->count(); |
||||
2291 | $this->assertEquals($expectedCount, $albums->count()); |
||||
2292 | } |
||||
2293 | |||||
2294 | public function testFindFromRawSQLOnInheritance(): void |
||||
2295 | { |
||||
2296 | $dao = new TestPersonDao($this->tdbmService); |
||||
2297 | $objects = $dao->testFindFromRawSQLOnInherited(); |
||||
2298 | |||||
2299 | $this->assertNotNull($objects->first()); |
||||
2300 | $this->assertNotEquals(0, $objects->count()); |
||||
2301 | } |
||||
2302 | |||||
2303 | public function testGeneratedColumnsAreNotPartOfTheConstructor(): void |
||||
2304 | { |
||||
2305 | if (!$this->tdbmService->getConnection()->getDatabasePlatform() instanceof MySqlPlatform || self::isMariaDb($this->tdbmService->getConnection())) { |
||||
2306 | $this->markTestSkipped('ReadOnly column is only tested with MySQL'); |
||||
2307 | } |
||||
2308 | |||||
2309 | $dao = new PlayerDao($this->tdbmService); |
||||
2310 | |||||
2311 | $player = new PlayerBean([ |
||||
2312 | 'id' => 1, |
||||
2313 | 'name' => 'Sally', |
||||
2314 | 'games_played' => |
||||
2315 | [ |
||||
2316 | 'Battlefield' => |
||||
2317 | [ |
||||
2318 | 'weapon' => 'sniper rifle', |
||||
2319 | 'rank' => 'Sergeant V', |
||||
2320 | 'level' => 20, |
||||
2321 | ], |
||||
2322 | 'Crazy Tennis' => |
||||
2323 | [ |
||||
2324 | 'won' => 4, |
||||
2325 | 'lost' => 1, |
||||
2326 | ], |
||||
2327 | 'Puzzler' => |
||||
2328 | [ |
||||
2329 | 'time' => 7, |
||||
2330 | ], |
||||
2331 | ], |
||||
2332 | ]); |
||||
2333 | |||||
2334 | $dao->save($player); |
||||
2335 | |||||
2336 | $this->assertTrue(true); |
||||
2337 | } |
||||
2338 | |||||
2339 | public function testCanReadVirtualColumn(): void |
||||
2340 | { |
||||
2341 | if (!$this->tdbmService->getConnection()->getDatabasePlatform() instanceof MySqlPlatform || self::isMariaDb($this->tdbmService->getConnection())) { |
||||
2342 | $this->markTestSkipped('ReadOnly column is only tested with MySQL'); |
||||
2343 | } |
||||
2344 | |||||
2345 | $dao = new PlayerDao($this->tdbmService); |
||||
2346 | |||||
2347 | $player = $dao->getById(1); |
||||
2348 | $this->assertSame('Sally', $player->getNamesVirtual()); |
||||
2349 | } |
||||
2350 | |||||
2351 | private function skipOracle() |
||||
2352 | { |
||||
2353 | if (self::getConnection()->getDatabasePlatform() instanceof OraclePlatform) { |
||||
2354 | $this->markTestSkipped('Not supported in Oracle'); |
||||
2355 | } |
||||
2356 | } |
||||
2357 | } |
||||
2358 |