Passed
Pull Request — master (#68)
by David
06:38
created

TDBMDaoGeneratorTest::testRecursiveSave()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 0
dl 0
loc 19
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
 Copyright (C) 2006-2014 David Négrier - THE CODING MACHINE
5
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
*/
20
21
namespace TheCodingMachine\TDBM;
22
23
use Doctrine\Common\Cache\ArrayCache;
24
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
25
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
26
use Mouf\Database\SchemaAnalyzer\SchemaAnalyzer;
27
use Ramsey\Uuid\Uuid;
28
use TheCodingMachine\TDBM\Dao\TestArticleDao;
29
use TheCodingMachine\TDBM\Dao\TestCountryDao;
30
use TheCodingMachine\TDBM\Dao\TestRoleDao;
31
use TheCodingMachine\TDBM\Dao\TestUserDao;
32
use TheCodingMachine\TDBM\Test\Dao\AllNullableDao;
33
use TheCodingMachine\TDBM\Test\Dao\AnimalDao;
34
use TheCodingMachine\TDBM\Test\Dao\Bean\AllNullableBean;
35
use TheCodingMachine\TDBM\Test\Dao\Bean\Article2Bean;
36
use TheCodingMachine\TDBM\Test\Dao\Bean\ArticleBean;
37
use TheCodingMachine\TDBM\Test\Dao\Bean\BoatBean;
38
use TheCodingMachine\TDBM\Test\Dao\Bean\CatBean;
39
use TheCodingMachine\TDBM\Test\Dao\Bean\CategoryBean;
40
use TheCodingMachine\TDBM\Test\Dao\Bean\CountryBean;
41
use TheCodingMachine\TDBM\Test\Dao\Bean\DogBean;
42
use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\UserBaseBean;
43
use TheCodingMachine\TDBM\Test\Dao\Bean\PersonBean;
44
use TheCodingMachine\TDBM\Test\Dao\Bean\RefNoPrimKeyBean;
45
use TheCodingMachine\TDBM\Test\Dao\Bean\RoleBean;
46
use TheCodingMachine\TDBM\Test\Dao\Bean\UserBean;
47
use TheCodingMachine\TDBM\Test\Dao\BoatDao;
48
use TheCodingMachine\TDBM\Test\Dao\CatDao;
49
use TheCodingMachine\TDBM\Test\Dao\CategoryDao;
50
use TheCodingMachine\TDBM\Test\Dao\ContactDao;
51
use TheCodingMachine\TDBM\Test\Dao\CountryDao;
52
use TheCodingMachine\TDBM\Test\Dao\DogDao;
53
use TheCodingMachine\TDBM\Test\Dao\Generated\UserBaseDao;
54
use TheCodingMachine\TDBM\Test\Dao\RefNoPrimKeyDao;
55
use TheCodingMachine\TDBM\Test\Dao\RoleDao;
56
use TheCodingMachine\TDBM\Test\Dao\UserDao;
57
use TheCodingMachine\TDBM\Utils\PathFinder\NoPathFoundException;
58
use TheCodingMachine\TDBM\Utils\TDBMDaoGenerator;
59
use Symfony\Component\Process\Process;
60
61
class TDBMDaoGeneratorTest extends TDBMAbstractServiceTest
62
{
63
    /** @var TDBMDaoGenerator $tdbmDaoGenerator */
64
    protected $tdbmDaoGenerator;
65
66
    private $rootPath;
67
68
    protected function setUp()
69
    {
70
        parent::setUp();
71
        $schemaManager = $this->tdbmService->getConnection()->getSchemaManager();
72
        $schemaAnalyzer = new SchemaAnalyzer($schemaManager);
73
        $tdbmSchemaAnalyzer = new TDBMSchemaAnalyzer($this->tdbmService->getConnection(), new ArrayCache(), $schemaAnalyzer);
74
        $this->tdbmDaoGenerator = new TDBMDaoGenerator($this->getConfiguration(), $tdbmSchemaAnalyzer);
75
        $this->rootPath = __DIR__.'/../';
76
        //$this->tdbmDaoGenerator->setComposerFile($this->rootPath.'composer.json');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
77
    }
78
79
    public function testDaoGeneration()
80
    {
81
        // Remove all previously generated files.
82
        $this->recursiveDelete($this->rootPath.'src/Test/Dao/');
83
84
        $this->tdbmDaoGenerator->generateAllDaosAndBeans();
85
86
        // Let's require all files to check they are valid PHP!
87
        // Test the daoFactory
88
        require_once $this->rootPath.'src/Test/Dao/Generated/DaoFactory.php';
89
        // Test the others
90
91
        $beanDescriptors = $this->getDummyGeneratorListener()->getBeanDescriptors();
92
93
        foreach ($beanDescriptors as $beanDescriptor) {
94
            $daoName = $beanDescriptor->getDaoClassName();
95
            $daoBaseName = $beanDescriptor->getBaseDaoClassName();
96
            $beanName = $beanDescriptor->getBeanClassName();
97
            $baseBeanName = $beanDescriptor->getBaseBeanClassName();
98
            require_once $this->rootPath.'src/Test/Dao/Bean/Generated/'.$baseBeanName.'.php';
99
            require_once $this->rootPath.'src/Test/Dao/Bean/'.$beanName.'.php';
100
            require_once $this->rootPath.'src/Test/Dao/Generated/'.$daoBaseName.'.php';
101
            require_once $this->rootPath.'src/Test/Dao/'.$daoName.'.php';
102
        }
103
104
        // Check that pivot tables do not generate DAOs or beans.
105
        $this->assertFalse(class_exists('TheCodingMachine\\TDBM\\Test\\Dao\\RolesRightDao'));
106
    }
107
108
    public function testGenerationException()
109
    {
110
        $configuration = new Configuration('UnknownVendor\\Dao', 'UnknownVendor\\Bean', self::getConnection(), $this->getNamingStrategy());
111
112
        $schemaManager = $this->tdbmService->getConnection()->getSchemaManager();
113
        $schemaAnalyzer = new SchemaAnalyzer($schemaManager);
114
        $tdbmSchemaAnalyzer = new TDBMSchemaAnalyzer($this->tdbmService->getConnection(), new ArrayCache(), $schemaAnalyzer);
115
        $tdbmDaoGenerator = new TDBMDaoGenerator($configuration, $tdbmSchemaAnalyzer);
116
        $this->rootPath = __DIR__.'/../../../../';
117
        //$tdbmDaoGenerator->setComposerFile($this->rootPath.'composer.json');
0 ignored issues
show
Unused Code Comprehensibility introduced by
73% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
118
119
        $this->expectException(NoPathFoundException::class);
120
        $tdbmDaoGenerator->generateAllDaosAndBeans();
121
    }
122
123
    /**
124
     * Delete a file or recursively delete a directory.
125
     *
126
     * @param string $str Path to file or directory
127
     * @return bool
128
     */
129
    private function recursiveDelete(string $str) : bool
130
    {
131
        if (is_file($str)) {
132
            return @unlink($str);
133
        } elseif (is_dir($str)) {
134
            $scan = glob(rtrim($str, '/') . '/*');
135
            foreach ($scan as $index => $path) {
136
                $this->recursiveDelete($path);
137
            }
138
139
            return @rmdir($str);
140
        }
141
        return false;
142
    }
143
144
    /**
145
     * @depends testDaoGeneration
146
     */
147
    public function testGetBeanClassName()
148
    {
149
        $this->assertEquals(UserBean::class, $this->tdbmService->getBeanClassName('users'));
150
    }
151
152
    /**
153
     * @depends testDaoGeneration
154
     */
155
    public function testGetBeanClassNameException()
156
    {
157
        $this->expectException(TDBMInvalidArgumentException::class);
158
        $this->tdbmService->getBeanClassName('not_exists');
159
    }
160
161
    /**
162
     * @depends testDaoGeneration
163
     */
164
    public function testGeneratedGetById()
165
    {
166
        $contactDao = new ContactDao($this->tdbmService);
167
        $contactBean = $contactDao->getById(1);
168
        $this->assertEquals(1, $contactBean->getId());
169
        $this->assertInstanceOf('\\DateTimeInterface', $contactBean->getCreatedAt());
170
171
        // FIXME: Question: que faire du paramètre stockage "UTC"????
172
    }
173
174
    /**
175
     * @depends testDaoGeneration
176
     */
177
    public function testGeneratedGetByIdLazyLoaded()
178
    {
179
        $roleDao = new RoleDao($this->tdbmService);
180
        $roleBean = $roleDao->getById(1, true);
181
        $this->assertEquals(1, $roleBean->getId());
182
        $this->assertInstanceOf('\\DateTimeInterface', $roleBean->getCreatedAt());
183
184
        $roleBean2 = $roleDao->getById(1, true);
185
        $this->assertTrue($roleBean === $roleBean2);
186
    }
187
188
    /**
189
     * @depends testDaoGeneration
190
     */
191
    public function testDefaultValueOnNewBean()
192
    {
193
        $roleBean = new RoleBean('my_role');
194
        $this->assertEquals(1, $roleBean->getStatus());
195
    }
196
197
    /**
198
     * @depends testDaoGeneration
199
     */
200 View Code Duplication
    public function testForeignKeyInBean()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
201
    {
202
        $userDao = new UserDao($this->tdbmService);
203
        $userBean = $userDao->getById(1);
204
        $country = $userBean->getCountry();
205
206
        $this->assertEquals('UK', $country->getLabel());
207
208
        $userBean2 = $userDao->getById(1);
209
        $this->assertTrue($userBean === $userBean2);
210
211
        $contactDao = new ContactDao($this->tdbmService);
212
        $contactBean = $contactDao->getById(1);
213
214
        $this->assertTrue($userBean === $contactBean);
215
    }
216
217
    /**
218
     * @depends testDaoGeneration
219
     */
220
    public function testNewBeans()
221
    {
222
        $countryDao = new CountryDao($this->tdbmService);
223
        $userDao = new UserDao($this->tdbmService);
224
        $userBean = new UserBean('John Doe', '[email protected]', $countryDao->getById(2), 'john.doe');
225
        $userBean->setOrder(1); // Let's set a "protected keyword" column.
226
227
        $userDao->save($userBean);
228
229
        $this->assertNull($userBean->getManager());
230
    }
231
232
    /**
233
     * @depends testDaoGeneration
234
     */
235
    public function testDateTimeImmutableGetter()
236
    {
237
        $userDao = new UserDao($this->tdbmService);
238
        $user = $userDao->getById(1);
239
240
        $this->assertInstanceOf('\DateTimeImmutable', $user->getCreatedAt());
241
    }
242
243
    /**
244
     * @depends testDaoGeneration
245
     */
246 View Code Duplication
    public function testAssigningNewBeans()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
247
    {
248
        $userDao = new UserDao($this->tdbmService);
249
        $countryBean = new CountryBean('Mexico');
250
        $userBean = new UserBean('Speedy Gonzalez', '[email protected]', $countryBean, 'speedy.gonzalez');
251
        $this->assertEquals($countryBean, $userBean->getCountry());
252
253
        $userDao->save($userBean);
254
    }
255
256
    /**
257
     * @depends testAssigningNewBeans
258
     */
259
    public function testUpdatingProtectedColumn()
260
    {
261
        $userDao = new UserDao($this->tdbmService);
262
        $userBean = $userDao->findOneByLogin('speedy.gonzalez');
263
        $userBean->setOrder(2);
264
        $userDao->save($userBean);
265
    }
266
267
    /**
268
     * @depends testDaoGeneration
269
     */
270 View Code Duplication
    public function testAssigningExistingRelationship()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
271
    {
272
        $userDao = new UserDao($this->tdbmService);
273
        $user = $userDao->getById(1);
274
        $countryDao = new CountryDao($this->tdbmService);
275
        $country = $countryDao->getById(2);
276
277
        $user->setCountry($country);
278
        $this->assertEquals(TDBMObjectStateEnum::STATE_DIRTY, $user->_getStatus());
279
    }
280
281
    /**
282
     * @depends testDaoGeneration
283
     */
284
    public function testDirectReversedRelationship()
285
    {
286
        $countryDao = new CountryDao($this->tdbmService);
287
        $country = $countryDao->getById(1);
288
        $users = $country->getUsers();
289
290
        $arr = $users->toArray();
291
292
        $this->assertCount(1, $arr);
293
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $arr[0]);
294
        $this->assertEquals('jean.dupont', $arr[0]->getLogin());
295
296
        $newUser = new UserBean('Speedy Gonzalez', '[email protected]', $country, 'speedy.gonzalez');
0 ignored issues
show
Unused Code introduced by
$newUser is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
297
        $users = $country->getUsers();
298
299
        $arr = $users->toArray();
300
301
        $this->assertCount(2, $arr);
302
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $arr[1]);
303
        $this->assertEquals('speedy.gonzalez', $arr[1]->getLogin());
304
    }
305
306
    /**
307
     * @depends testDaoGeneration
308
     */
309
    public function testDeleteInDirectReversedRelationship()
310
    {
311
        $countryDao = new CountryDao($this->tdbmService);
312
        $country = $countryDao->getById(1);
313
314
        $userDao = new UserDao($this->tdbmService);
315
        $newUser = new UserBean('John Snow', '[email protected]', $country, 'john.snow');
316
        $userDao->save($newUser);
317
318
        $users = $country->getUsers();
319
320
        $arr = $users->toArray();
321
322
        $this->assertCount(2, $arr);
323
324
        $userDao->delete($arr[1]);
325
326
        $users = $country->getUsers();
327
        $arr = $users->toArray();
328
        $this->assertCount(1, $arr);
329
    }
330
331
    /**
332
     * @depends testDaoGeneration
333
     */
334
    public function testJointureGetters()
335
    {
336
        $roleDao = new RoleDao($this->tdbmService);
337
        $role = $roleDao->getById(1);
338
        $users = $role->getUsers();
339
340
        $this->assertCount(2, $users);
341
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $users[0]);
342
343
        $rights = $role->getRights();
344
345
        $this->assertCount(2, $rights);
346
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\RightBean', $rights[0]);
347
    }
348
349
    /**
350
     * @depends testDaoGeneration
351
     */
352
    public function testNestedIterationOnAlterableResultIterator()
353
    {
354
        $countryDao = new CountryDao($this->tdbmService);
355
        $country = $countryDao->getById(2);
356
357
        $count = 0;
358
        // Let's perform 2 nested calls to check that iterators do not melt.
359
        foreach ($country->getUsers() as $user) {
360
            foreach ($country->getUsers() as $user2) {
361
                $count++;
362
            }
363
        }
364
        // There are 3 users linked to country 2.
365
        $this->assertSame(9, $count);
366
    }
367
368
    /**
369
     * @depends testDaoGeneration
370
     */
371
    public function testNewBeanConstructor()
372
    {
373
        $role = new RoleBean('Newrole');
374
        $this->assertEquals(TDBMObjectStateEnum::STATE_DETACHED, $role->_getStatus());
375
    }
376
377
    /**
378
     * @depends testDaoGeneration
379
     */
380
    public function testJointureAdderOnNewBean()
381
    {
382
        $countryDao = new CountryDao($this->tdbmService);
383
        $country = $countryDao->getById(1);
384
        $user = new UserBean('Speedy Gonzalez', '[email protected]', $country, 'speedy.gonzalez');
385
        $role = new RoleBean('Mouse');
386
        $user->addRole($role);
387
        $roles = $user->getRoles();
388
        $this->assertCount(1, $roles);
389
        $role = $roles[0];
390
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\RoleBean', $role);
391
        $users = $role->getUsers();
392
        $this->assertCount(1, $users);
393
        $this->assertEquals($user, $users[0]);
394
395
        $role->removeUser($user);
396
        $this->assertCount(0, $role->getUsers());
397
        $this->assertCount(0, $user->getRoles());
398
    }
399
400
    /**
401
     * @depends testDaoGeneration
402
     */
403 View Code Duplication
    public function testJointureDeleteBeforeGetters()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
404
    {
405
        $roleDao = new RoleDao($this->tdbmService);
406
        $userDao = new UserDao($this->tdbmService);
407
        $role = $roleDao->getById(1);
408
        $user = $userDao->getById(1);
409
410
        // We call removeUser BEFORE calling getUsers
411
        // This should work as expected.
412
        $role->removeUser($user);
413
        $users = $role->getUsers();
414
415
        $this->assertCount(1, $users);
416
    }
417
418
    /**
419
     * @depends testDaoGeneration
420
     */
421
    public function testJointureMultiAdd()
422
    {
423
        $countryDao = new CountryDao($this->tdbmService);
424
        $country = $countryDao->getById(1);
425
        $user = new UserBean('Speedy Gonzalez', '[email protected]', $country, 'speedy.gonzalez');
426
        $role = new RoleBean('Mouse');
427
        $user->addRole($role);
428
        $role->addUser($user);
429
        $user->addRole($role);
430
431
        $this->assertCount(1, $user->getRoles());
432
    }
433
434
    /**
435
     * Step 1: we remove the role 1 from user 1 but save role 1.
436
     * Expected result: no save done.
437
     *
438
     * @depends testDaoGeneration
439
     */
440
    public function testJointureSave1()
441
    {
442
        $roleDao = new RoleDao($this->tdbmService);
443
        $role = $roleDao->getById(1);
444
        $userDao = new UserDao($this->tdbmService);
445
        $user = $userDao->getById(1);
446
447
        $this->assertTrue($user->hasRole($role));
448
        $this->assertTrue($role->hasUser($user));
449
        $user->removeRole($role);
450
        $this->assertFalse($user->hasRole($role));
451
        $this->assertFalse($role->hasUser($user));
452
        $roleDao->save($role);
453
454
        $this->assertEquals(TDBMObjectStateEnum::STATE_DIRTY, $user->_getStatus());
455
        $this->assertEquals(TDBMObjectStateEnum::STATE_LOADED, $role->_getStatus());
456
    }
457
458
    /**
459
     * Step 2: we check that nothing was saved
460
     * Expected result: no save done.
461
     *
462
     * @depends testJointureSave1
463
     */
464
    public function testJointureSave2()
465
    {
466
        $roleDao = new RoleDao($this->tdbmService);
467
        $role = $roleDao->getById(1);
468
        $this->assertCount(2, $role->getUsers());
469
    }
470
471
    /**
472
     * Step 3: we remove the role 1 from user 1 and save user 1.
473
     * Expected result: save done.
474
     *
475
     * @depends testJointureSave2
476
     */
477
    public function testJointureSave3()
478
    {
479
        $roleDao = new RoleDao($this->tdbmService);
480
        $role = $roleDao->getById(1);
481
        $userDao = new UserDao($this->tdbmService);
482
        $user = $userDao->getById(1);
483
484
        $this->assertCount(1, $user->getRoles());
485
        $user->removeRole($role);
486
        $this->assertCount(0, $user->getRoles());
487
        $userDao->save($user);
488
        $this->assertCount(0, $user->getRoles());
489
    }
490
491
    /**
492
     * Step 4: we check that save was done
493
     * Expected result: save done.
494
     *
495
     * @depends testJointureSave3
496
     */
497 View Code Duplication
    public function testJointureSave4()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
498
    {
499
        $roleDao = new RoleDao($this->tdbmService);
500
        $role = $roleDao->getById(1);
501
        $this->assertCount(1, $role->getUsers());
502
        $userDao = new UserDao($this->tdbmService);
503
        $user = $userDao->getById(1);
504
        $this->assertCount(0, $user->getRoles());
505
    }
506
507
    /**
508
     * Step 5: we add the role 1 from user 1 and save user 1.
509
     * Expected result: save done.
510
     *
511
     * @depends testJointureSave4
512
     */
513 View Code Duplication
    public function testJointureSave5()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
514
    {
515
        $roleDao = new RoleDao($this->tdbmService);
516
        $role = $roleDao->getById(1);
517
        $userDao = new UserDao($this->tdbmService);
518
        $user = $userDao->getById(1);
519
520
        $user->addRole($role);
521
        $this->assertCount(1, $user->getRoles());
522
        $userDao->save($user);
523
    }
524
525
    /**
526
     * Step 6: we check that save was done
527
     * Expected result: save done.
528
     *
529
     * @depends testJointureSave5
530
     */
531 View Code Duplication
    public function testJointureSave6()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
532
    {
533
        $roleDao = new RoleDao($this->tdbmService);
534
        $role = $roleDao->getById(1);
535
        $this->assertCount(2, $role->getUsers());
536
        $userDao = new UserDao($this->tdbmService);
537
        $user = $userDao->getById(1);
538
        $this->assertCount(1, $user->getRoles());
539
    }
540
541
    /**
542
     * Step 7: we add a new role to user 1 and save user 1.
543
     * Expected result: save done, including the new role.
544
     *
545
     * @depends testJointureSave6
546
     */
547
    public function testJointureSave7()
548
    {
549
        $role = new RoleBean('my new role');
550
        $userDao = new UserDao($this->tdbmService);
551
        $user = $userDao->getById(1);
552
553
        $user->addRole($role);
554
        $userDao->save($user);
555
556
        $this->assertEquals(TDBMObjectStateEnum::STATE_LOADED, $role->_getStatus());
557
    }
558
559
    /**
560
     * Step 8: we check that save was done
561
     * Expected result: save done.
562
     *
563
     * @depends testJointureSave7
564
     */
565 View Code Duplication
    public function testJointureSave8()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
566
    {
567
        $roleDao = new RoleDao($this->tdbmService);
568
        $userDao = new UserDao($this->tdbmService);
569
        $user = $userDao->getById(1);
570
571
        $roles = $user->getRoles();
572
        foreach ($roles as $role) {
573
            if ($role->getName() === 'my new role') {
574
                $selectedRole = $role;
575
                break;
576
            }
577
        }
578
        $this->assertNotNull($selectedRole);
0 ignored issues
show
Bug introduced by
The variable $selectedRole does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
579
580
        $this->assertCount(2, $user->getRoles());
581
582
        // Expected: relationship removed!
583
        $roleDao->delete($selectedRole);
584
585
        $this->assertCount(1, $user->getRoles());
586
    }
587
588
    /**
589
     * Step 9: Let's test the setXXX method.
590
     *
591
     * @depends testJointureSave8
592
     */
593
    public function testJointureSave9()
594
    {
595
        $roleDao = new RoleDao($this->tdbmService);
596
        $userDao = new UserDao($this->tdbmService);
597
        $user = $userDao->getById(1);
598
599
        // At this point, user 1 is linked to role 1.
600
        // Let's bind it to role 2.
601
        $user->setRoles([$roleDao->getById(2)]);
602
        $userDao->save($user);
603
    }
604
605
    /**
606
     * Step 10: Let's check results of 9.
607
     *
608
     * @depends testJointureSave9
609
     */
610
    public function testJointureSave10()
611
    {
612
        $userDao = new UserDao($this->tdbmService);
613
        $user = $userDao->getById(1);
614
615
        $roles = $user->getRoles();
616
617
        $this->assertCount(1, $roles);
618
        $this->assertEquals(2, $roles[0]->getId());
619
    }
620
621
    /**
622
     * @depends testDaoGeneration
623
     */
624 View Code Duplication
    public function testFindOrderBy()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
625
    {
626
        $userDao = new TestUserDao($this->tdbmService);
627
        $users = $userDao->getUsersByAlphabeticalOrder();
628
629
        $this->assertCount(6, $users);
630
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
631
        $this->assertEquals('jean.dupont', $users[1]->getLogin());
632
633
        $users = $userDao->getUsersByCountryOrder();
634
        $this->assertCount(6, $users);
635
        $countryName1 = $users[0]->getCountry()->getLabel();
636
        for ($i = 1; $i < 6; $i++) {
637
            $countryName2 = $users[$i]->getCountry()->getLabel();
638
            $this->assertLessThanOrEqual(0, strcmp($countryName1, $countryName2));
639
            $countryName1 = $countryName2;
640
        }
641
    }
642
643
    /**
644
     * @depends testDaoGeneration
645
     */
646 View Code Duplication
    public function testFindFromSqlOrderBy()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
647
    {
648
        $userDao = new TestUserDao($this->tdbmService);
649
        $users = $userDao->getUsersFromSqlByAlphabeticalOrder();
650
651
        $this->assertCount(6, $users);
652
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
653
        $this->assertEquals('jean.dupont', $users[1]->getLogin());
654
655
        $users = $userDao->getUsersFromSqlByCountryOrder();
656
        $this->assertCount(6, $users);
657
        $countryName1 = $users[0]->getCountry()->getLabel();
658
        for ($i = 1; $i < 6; $i++) {
659
            $countryName2 = $users[$i]->getCountry()->getLabel();
660
            $this->assertLessThanOrEqual(0, strcmp($countryName1, $countryName2));
661
            $countryName1 = $countryName2;
662
        }
663
    }
664
665
    /**
666
     * @depends testDaoGeneration
667
     */
668
    public function testFindFromSqlOrderByOnInheritedBean()
669
    {
670
        $articleDao = new TestArticleDao($this->tdbmService);
671
        $articles = $articleDao->getArticlesByUserLogin();
672
673
        foreach ($articles as $article) {
674
            var_dump($article);
0 ignored issues
show
Security Debugging Code introduced by
var_dump($article); looks like debug code. Are you sure you do not want to remove it? This might expose sensitive data.
Loading history...
675
        }
676
        $this->assertCount(0, $articles);
677
    }
678
679
680
    /**
681
     * @depends testDaoGeneration
682
     */
683
    public function testFindFromSqlOrderByJoinRole()
684
    {
685
        $roleDao = new TestRoleDao($this->tdbmService);
686
        $roles = $roleDao->getRolesByRightCanSing('roles.name DESC');
687
688
        $this->assertCount(2, $roles);
689
        $this->assertEquals('Singers', $roles[0]->getName());
690
        $this->assertEquals('Admins', $roles[1]->getName());
691
    }
692
693
    /**
694
     * @depends testDaoGeneration
695
     */
696
    public function testFindFromRawSqlOrderByUserCount()
697
    {
698
        $countryDao = new TestCountryDao($this->tdbmService);
699
        $countries = $countryDao->getCountriesByUserCount();
700
701
        $this->assertCount(4, $countries);
702
        for ($i = 1; $i < count($countries); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
703
            $this->assertLessThanOrEqual($countries[$i - 1]->getUsers()->count(), $countries[$i]->getUsers()->count());
704
        }
705
    }
706
707
    /**
708
     * @depends testDaoGeneration
709
     */
710 View Code Duplication
    public function testFindFromRawSqlWithUnion()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
711
    {
712
        $countryDao = new TestCountryDao($this->tdbmService);
713
        $countries = $countryDao->getCountriesUsingUnion();
714
715
        $this->assertCount(2, $countries);
716
        $this->assertEquals(1, $countries[0]->getId());
717
    }
718
719
    /**
720
     * @depends testDaoGeneration
721
     */
722 View Code Duplication
    public function testFindFromRawSqlWithSimpleQuery()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
723
    {
724
        $countryDao = new TestCountryDao($this->tdbmService);
725
        $countries = $countryDao->getCountriesUsingSimpleQuery();
726
727
        $this->assertCount(1, $countries);
728
        $this->assertEquals(1, $countries[0]->getId());
729
    }
730
731
    /**
732
     * @depends testDaoGeneration
733
     */
734 View Code Duplication
    public function testFindFromRawSqlWithDistinctQuery()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
735
    {
736
        $countryDao = new TestCountryDao($this->tdbmService);
737
        $countries = $countryDao->getCountriesUsingDistinctQuery();
738
739
        $this->assertCount(1, $countries);
740
        $this->assertEquals(2, $countries[0]->getId());
741
    }
742
743
    /**
744
     * @depends testDaoGeneration
745
     */
746 View Code Duplication
    public function testFindFilters()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
747
    {
748
        $userDao = new TestUserDao($this->tdbmService);
749
        $users = $userDao->getUsersByLoginStartingWith('bill');
750
751
        $this->assertCount(1, $users);
752
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
753
    }
754
755
    /**
756
     * @expectedException \TheCodingMachine\TDBM\TDBMException
757
     * @depends testDaoGeneration
758
     */
759
    public function testFindMode()
760
    {
761
        $userDao = new TestUserDao($this->tdbmService);
762
        $users = $userDao->getUsersByLoginStartingWith('bill', TDBMService::MODE_CURSOR);
763
764
        $users[0];
765
    }
766
767
    /**
768
     * @depends testDaoGeneration
769
     */
770
    public function testFindAll()
771
    {
772
        $userDao = new TestUserDao($this->tdbmService);
773
        $users = $userDao->findAll();
774
775
        $this->assertCount(6, $users);
776
    }
777
778
    /**
779
     * @depends testDaoGeneration
780
     */
781
    public function testFindOne()
782
    {
783
        $userDao = new TestUserDao($this->tdbmService);
784
        $user = $userDao->getUserByLogin('bill.shakespeare');
785
786
        $this->assertEquals('bill.shakespeare', $user->getLogin());
787
    }
788
789
    /**
790
     * @depends testDaoGeneration
791
     */
792
    public function testJsonEncodeBean()
793
    {
794
        $userDao = new TestUserDao($this->tdbmService);
795
        $user = $userDao->getUserByLogin('bill.shakespeare');
796
797
        $jsonEncoded = json_encode($user);
798
        $userDecoded = json_decode($jsonEncoded, true);
799
800
        $this->assertEquals('bill.shakespeare', $userDecoded['login']);
801
802
        // test serialization of dates.
803
        $this->assertTrue(is_string($userDecoded['createdAt']));
804
        $this->assertEquals('2015-10-24', (new \DateTimeImmutable($userDecoded['createdAt']))->format('Y-m-d'));
805
        $this->assertNull($userDecoded['modifiedAt']);
806
807
        // testing many to 1 relationships
808
        $this->assertEquals('UK', $userDecoded['country']['label']);
809
810
        // testing many to many relationships
811
        $this->assertCount(1, $userDecoded['roles']);
812
        $this->assertArrayNotHasKey('users', $userDecoded['roles'][0]);
813
        $this->assertArrayNotHasKey('rights', $userDecoded['roles'][0]);
814
    }
815
816
    /**
817
     * @depends testDaoGeneration
818
     */
819
    public function testNullableForeignKey()
820
    {
821
        $userDao = new TestUserDao($this->tdbmService);
822
        $user = $userDao->getUserByLogin('john.smith');
823
824
        $this->assertNull(null, $user->getManager());
825
826
        $jsonEncoded = json_encode($user);
827
        $userDecoded = json_decode($jsonEncoded, true);
828
829
        $this->assertNull(null, $userDecoded['manager']);
830
    }
831
832
    /**
833
     * Test that setting (and saving) objects' references (foreign keys relations) to null is working.
834
     *
835
     * @depends testDaoGeneration
836
     */
837
    public function testSetToNullForeignKey()
838
    {
839
        $userDao = new TestUserDao($this->tdbmService);
840
        $user = $userDao->getUserByLogin('john.smith');
841
        $manager = $userDao->getUserByLogin('jean.dupont');
842
843
        $user->setManager($manager);
844
        $userDao->save($user);
845
846
        $user->setManager(null);
847
        $userDao->save($user);
848
    }
849
850
    /**
851
     * @depends testDaoGeneration
852
     * @expectedException \Mouf\Database\SchemaAnalyzer\SchemaAnalyzerTableNotFoundException
853
     * @expectedExceptionMessage Could not find table 'contacts'. Did you mean 'contact'?
854
     */
855
    public function testQueryOnWrongTableName()
856
    {
857
        $userDao = new TestUserDao($this->tdbmService);
858
        $users = $userDao->getUsersWrongTableName();
859
        $users->count();
860
    }
861
862
    /**
863
     * @depends testDaoGeneration
864
     */
865
    /*public function testQueryNullForeignKey()
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
866
    {
867
        $userDao = new TestUserDao($this->tdbmService);
868
        $users = $userDao->getUsersByManagerId(null);
869
        $this->assertCount(3, $users);
870
    }*/
871
872
    /**
873
     * @depends testDaoGeneration
874
     */
875
    public function testInnerJsonEncode()
876
    {
877
        $userDao = new TestUserDao($this->tdbmService);
878
        $user = $userDao->getUserByLogin('bill.shakespeare');
879
880
        $jsonEncoded = json_encode(['user' => $user]);
881
        $msgDecoded = json_decode($jsonEncoded, true);
882
883
        $this->assertEquals('bill.shakespeare', $msgDecoded['user']['login']);
884
    }
885
886
    /**
887
     * @depends testDaoGeneration
888
     */
889 View Code Duplication
    public function testArrayJsonEncode()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
890
    {
891
        $userDao = new TestUserDao($this->tdbmService);
892
        $users = $userDao->getUsersByLoginStartingWith('bill');
893
894
        $jsonEncoded = json_encode($users);
895
        $msgDecoded = json_decode($jsonEncoded, true);
896
897
        $this->assertCount(1, $msgDecoded);
898
    }
899
900
    /**
901
     * @depends testDaoGeneration
902
     */
903 View Code Duplication
    public function testCursorJsonEncode()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
904
    {
905
        $userDao = new TestUserDao($this->tdbmService);
906
        $users = $userDao->getUsersByLoginStartingWith('bill', TDBMService::MODE_CURSOR);
907
908
        $jsonEncoded = json_encode($users);
909
        $msgDecoded = json_decode($jsonEncoded, true);
910
911
        $this->assertCount(1, $msgDecoded);
912
    }
913
914
    /**
915
     * @depends testDaoGeneration
916
     */
917 View Code Duplication
    public function testPageJsonEncode()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
918
    {
919
        $userDao = new TestUserDao($this->tdbmService);
920
        $users = $userDao->getUsersByLoginStartingWith('bill');
921
922
        $jsonEncoded = json_encode($users->take(0, 1));
923
        $msgDecoded = json_decode($jsonEncoded, true);
924
925
        $this->assertCount(1, $msgDecoded);
926
    }
927
928
    /**
929
     * @depends testDaoGeneration
930
     */
931 View Code Duplication
    public function testFirst()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
932
    {
933
        $userDao = new TestUserDao($this->tdbmService);
934
        $users = $userDao->getUsersByLoginStartingWith('bill');
935
936
        $bill = $users->first();
937
        $this->assertEquals('bill.shakespeare', $bill->getLogin());
938
    }
939
940
    /**
941
     * @depends testDaoGeneration
942
     */
943
    public function testFirstNull()
944
    {
945
        $userDao = new TestUserDao($this->tdbmService);
946
        $users = $userDao->getUsersByLoginStartingWith('mike');
947
948
        $user = $users->first();
949
        $this->assertNull($user);
950
    }
951
952
    /**
953
     * @depends testDaoGeneration
954
     */
955
    public function testCloneBeanAttachedBean()
956
    {
957
        $userDao = new TestUserDao($this->tdbmService);
958
        $user = $userDao->getUserByLogin('bill.shakespeare');
959
        $this->assertEquals(4, $user->getId());
960
        $user2 = clone $user;
961
        $this->assertNull($user2->getId());
962
        $this->assertEquals('bill.shakespeare', $user2->getLogin());
963
        $this->assertEquals('Bill Shakespeare', $user2->getName());
964
        $this->assertEquals('UK', $user2->getCountry()->getLabel());
965
966
        // MANY 2 MANY must be duplicated
967
        $this->assertEquals('Writers', $user2->getRoles()[0]->getName());
968
969
        // Let's test saving this clone
970
        $user2->setLogin('william.shakespeare');
971
        $userDao->save($user2);
972
973
        $user3 = $userDao->getUserByLogin('william.shakespeare');
974
        $this->assertTrue($user3 === $user2);
975
        $userDao->delete($user3);
976
977
        // Finally, let's test the origin user still exists!
978
        $user4 = $userDao->getUserByLogin('bill.shakespeare');
979
        $this->assertEquals('bill.shakespeare', $user4->getLogin());
980
    }
981
982
    /**
983
     * @depends testDaoGeneration
984
     */
985
    public function testCloneNewBean()
986
    {
987
        $countryDao = new CountryDao($this->tdbmService);
988
        $roleDao = new RoleDao($this->tdbmService);
989
        $role = $roleDao->getById(1);
990
991
        $userBean = new UserBean('John Doe', '[email protected]', $countryDao->getById(2), 'john.doe');
992
        $userBean->addRole($role);
993
994
        $user2 = clone $userBean;
995
996
        $this->assertNull($user2->getId());
997
        $this->assertEquals('john.doe', $user2->getLogin());
998
        $this->assertEquals('John Doe', $user2->getName());
999
        $this->assertEquals('UK', $user2->getCountry()->getLabel());
1000
1001
        // MANY 2 MANY must be duplicated
1002
        $this->assertEquals($role->getName(), $user2->getRoles()[0]->getName());
1003
    }
1004
1005
    /**
1006
     * @depends testDaoGeneration
1007
     */
1008
    public function testCascadeDelete()
1009
    {
1010
        $userDao = new TestUserDao($this->tdbmService);
1011
        $countryDao = new CountryDao($this->tdbmService);
1012
1013
        $spain = new CountryBean('Spain');
1014
        $sanchez = new UserBean('Manuel Sanchez', '[email protected]', $spain, 'manuel.sanchez');
1015
1016
        $countryDao->save($spain);
1017
        $userDao->save($sanchez);
1018
1019
        $speedy2 = $userDao->getUserByLogin('manuel.sanchez');
1020
        $this->assertTrue($sanchez === $speedy2);
1021
1022
        $exceptionTriggered = false;
1023
        try {
1024
            $countryDao->delete($spain);
1025
        } catch (ForeignKeyConstraintViolationException $e) {
1026
            $exceptionTriggered = true;
1027
        }
1028
        $this->assertTrue($exceptionTriggered);
1029
1030
        $countryDao->delete($spain, true);
1031
1032
        // Let's check that speed gonzalez was removed.
1033
        $speedy3 = $userDao->getUserByLogin('manuel.sanchez');
1034
        $this->assertNull($speedy3);
1035
    }
1036
1037
    /**
1038
     * @depends testDaoGeneration
1039
     */
1040
    public function testDiscardChanges()
1041
    {
1042
        $contactDao = new ContactDao($this->tdbmService);
1043
        $contactBean = $contactDao->getById(1);
1044
1045
        $oldName = $contactBean->getName();
1046
1047
        $contactBean->setName('MyNewName');
1048
1049
        $contactBean->discardChanges();
1050
1051
        $this->assertEquals($oldName, $contactBean->getName());
1052
    }
1053
1054
    /**
1055
     * @expectedException \TheCodingMachine\TDBM\TDBMException
1056
     * @depends testDaoGeneration
1057
     */
1058
    public function testDiscardChangesOnNewBeanFails()
1059
    {
1060
        $person = new PersonBean('John Foo', new \DateTimeImmutable());
1061
        $person->discardChanges();
1062
    }
1063
1064
    /**
1065
     * @expectedException \TheCodingMachine\TDBM\TDBMException
1066
     * @depends testDaoGeneration
1067
     */
1068
    public function testDiscardChangesOnDeletedBeanFails()
1069
    {
1070
        $userDao = new TestUserDao($this->tdbmService);
1071
        $countryDao = new CountryDao($this->tdbmService);
1072
1073
        $sanchez = new UserBean('Manuel Sanchez', '[email protected]', $countryDao->getById(1), 'manuel.sanchez');
1074
1075
        $userDao->save($sanchez);
1076
1077
        $userDao->delete($sanchez);
1078
1079
        // Cannot discard changes on a bean that is already deleted.
1080
        $sanchez->discardChanges();
1081
    }
1082
1083
    /**
1084
     * @depends testDaoGeneration
1085
     */
1086 View Code Duplication
    public function testUniqueIndexBasedSearch()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1087
    {
1088
        $userDao = new UserDao($this->tdbmService);
1089
        $user = $userDao->findOneByLogin('bill.shakespeare');
1090
1091
        $this->assertEquals('bill.shakespeare', $user->getLogin());
1092
        $this->assertEquals('Bill Shakespeare', $user->getName());
1093
    }
1094
1095
    /**
1096
     * @depends testDaoGeneration
1097
     */
1098
    public function testFindOneByRetunsNull()
1099
    {
1100
        // Let's assert that the findOneBy... methods can return null.
1101
        $userDao = new UserDao($this->tdbmService);
1102
        $userBean = $userDao->findOneByLogin('not_exist');
1103
1104
        $this->assertNull($userBean);
1105
    }
1106
1107
    /**
1108
     * @depends testDaoGeneration
1109
     */
1110 View Code Duplication
    public function testMultiColumnsIndexBasedSearch()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1111
    {
1112
        $countryDao = new CountryDao($this->tdbmService);
1113
        $userDao = new UserDao($this->tdbmService);
1114
        $users = $userDao->findByStatusAndCountry('on', $countryDao->getById(1));
1115
1116
        $this->assertEquals('jean.dupont', $users[0]->getLogin());
1117
    }
1118
1119
    /**
1120
     * @depends testDaoGeneration
1121
     */
1122
    public function testCreationInNullableDate()
1123
    {
1124
        $roleDao = new RoleDao($this->tdbmService);
1125
1126
        $role = new RoleBean('newbee');
1127
        $roleDao->save($role);
1128
1129
        $this->assertNull($role->getCreatedAt());
1130
    }
1131
1132
    /**
1133
     * @depends testDaoGeneration
1134
     */
1135
    public function testUpdateInNullableDate()
1136
    {
1137
        $roleDao = new RoleDao($this->tdbmService);
1138
1139
        $role = new RoleBean('newbee');
1140
        $roleDao->save($role);
1141
1142
        $role->setCreatedAt(null);
1143
        $roleDao->save($role);
1144
        $this->assertNull($role->getCreatedAt());
1145
    }
1146
1147
    /**
1148
     * @depends testDaoGeneration
1149
     */
1150
    public function testFindFromSql()
1151
    {
1152
        $roleDao = new TestRoleDao($this->tdbmService);
1153
1154
        $roles = $roleDao->getRolesByRightCanSing();
1155
        $this->assertCount(2, $roles);
1156
        $this->assertInstanceOf(RoleBean::class, $roles[0]);
1157
    }
1158
1159
    /**
1160
     * @depends testDaoGeneration
1161
     */
1162
    public function testFindOneFromSql()
1163
    {
1164
        $roleDao = new TestRoleDao($this->tdbmService);
1165
1166
        $role = $roleDao->getRoleByRightCanSingAndNameSinger();
1167
        $this->assertInstanceOf(RoleBean::class, $role);
1168
    }
1169
1170
    /**
1171
     * @depends testDaoGeneration
1172
     */
1173
    public function testCreateEmptyExtendedBean()
1174
    {
1175
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/92
1176
1177
        $dogDao = new DogDao($this->tdbmService);
1178
1179
        // We are not filling no field that is part of dog table.
1180
        $dog = new DogBean('Youki');
1181
        $dog->setOrder(1);
1182
1183
        $dogDao->save($dog);
1184
    }
1185
1186
    /**
1187
     * @depends testCreateEmptyExtendedBean
1188
     */
1189
    public function testFetchEmptyExtendedBean()
1190
    {
1191
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/92
1192
1193
        $animalDao = new AnimalDao($this->tdbmService);
1194
1195
        // We are not filling no field that is part of dog table.
1196
        $animalBean = $animalDao->getById(1);
1197
1198
        $this->assertInstanceOf(DogBean::class, $animalBean);
1199
    }
1200
1201
    /**
1202
     * @depends testDaoGeneration
1203
     */
1204
    public function testTwoBranchesHierarchy()
1205
    {
1206
        // This test cases checks issue https://github.com/thecodingmachine/mouf/issues/131
1207
1208
        $catDao = new CatDao($this->tdbmService);
1209
1210
        // We are not filling no field that is part of dog table.
1211
        $cat = new CatBean('Mew');
1212
        $cat->setOrder(2);
1213
1214
        $catDao->save($cat);
1215
    }
1216
1217
    /**
1218
     * @depends testTwoBranchesHierarchy
1219
     */
1220
    public function testFetchTwoBranchesHierarchy()
1221
    {
1222
        // This test cases checks issue https://github.com/thecodingmachine/mouf/issues/131
1223
1224
        $animalDao = new AnimalDao($this->tdbmService);
1225
1226
        $animalBean = $animalDao->getById(2);
1227
1228
        $this->assertInstanceOf(CatBean::class, $animalBean);
1229
        /* @var $animalBean CatBean */
1230
        $animalBean->setCutenessLevel(999);
1231
1232
        $animalDao->save($animalBean);
1233
    }
1234
1235
    /**
1236
     * @depends testDaoGeneration
1237
     */
1238
    public function testExceptionOnGetById()
1239
    {
1240
        $countryDao = new CountryDao($this->tdbmService);
1241
        $this->expectException(\TypeError::class);
1242
        $countryDao->getById(null);
1243
    }
1244
1245
    /**
1246
     * @depends testDaoGeneration
1247
     */
1248
    public function testDisconnectedManyToOne()
1249
    {
1250
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/99
1251
1252
        $country = new CountryBean('Spain');
1253
1254
        $user = new UserBean('John Doe', '[email protected]', $country, 'john.doe');
1255
1256
        $this->assertCount(1, $country->getUsers());
1257
        $this->assertSame($user, $country->getUsers()[0]);
1258
    }
1259
1260
    /**
1261
     * @depends testDaoGeneration
1262
     */
1263 View Code Duplication
    public function testOrderByExternalCol()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1264
    {
1265
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/106
1266
1267
        $userDao = new TestUserDao($this->tdbmService);
1268
        $users = $userDao->getUsersByCountryName();
1269
1270
        $this->assertEquals('UK', $users[0]->getCountry()->getLabel());
1271
    }
1272
1273
    /**
1274
     * @depends testDaoGeneration
1275
     */
1276
    public function testResultIteratorSort()
1277
    {
1278
        $userDao = new UserDao($this->tdbmService);
1279
        $users = $userDao->findAll()->withOrder('country.label DESC');
1280
1281
        $this->assertEquals('UK', $users[0]->getCountry()->getLabel());
1282
1283
        $users = $users->withOrder('country.label ASC');
1284
        $this->assertEquals('France', $users[0]->getCountry()->getLabel());
1285
    }
1286
1287
    /**
1288
     * @depends testDaoGeneration
1289
     */
1290
    public function testResultIteratorWithParameters()
1291
    {
1292
        $userDao = new TestUserDao($this->tdbmService);
1293
        $users = $userDao->getUsersByLoginStartingWith()->withParameters(['login' => 'bill%']);
1294
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
1295
1296
        $users = $users->withParameters(['login' => 'jean%']);
1297
        $this->assertEquals('jean.dupont', $users[0]->getLogin());
1298
    }
1299
1300
    /**
1301
     * @depends testDaoGeneration
1302
     */
1303 View Code Duplication
    public function testOrderByExpression()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1304
    {
1305
        $userDao = new TestUserDao($this->tdbmService);
1306
        $users = $userDao->getUsersByReversedCountryName();
1307
1308
        $this->assertEquals('Jamaica', $users[0]->getCountry()->getLabel());
1309
    }
1310
1311
    /**
1312
     * @depends testDaoGeneration
1313
     */
1314
    public function testOrderByException()
1315
    {
1316
        $userDao = new TestUserDao($this->tdbmService);
1317
        $users = $userDao->getUsersByInvalidOrderBy();
1318
        $this->expectException(TDBMInvalidArgumentException::class);
1319
        $user = $users[0];
0 ignored issues
show
Unused Code introduced by
$user is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1320
    }
1321
1322
    /**
1323
     * @depends testDaoGeneration
1324
     */
1325
    public function testOrderByProtectedColumn()
1326
    {
1327
        $animalDao = new AnimalDao($this->tdbmService);
1328
        $animals = $animalDao->findAll();
1329
        $animals = $animals->withOrder('`order` ASC');
1330
1331
        $this->assertInstanceOf(DogBean::class, $animals[0]);
1332
        $this->assertInstanceOf(CatBean::class, $animals[1]);
1333
1334
        $animals = $animals->withOrder('`order` DESC');
1335
1336
        $this->assertInstanceOf(CatBean::class, $animals[0]);
1337
        $this->assertInstanceOf(DogBean::class, $animals[1]);
1338
    }
1339
1340
    /**
1341
     * @depends testDaoGeneration
1342
     */
1343
    public function testGetOnAllNullableValues()
1344
    {
1345
        // Tests that a get performed on a column that has only nullable fields succeeds.
1346
        $allNullable = new AllNullableBean();
1347
        $this->assertNull($allNullable->getId());
1348
        $this->assertNull($allNullable->getLabel());
1349
        $this->assertNull($allNullable->getCountry());
1350
    }
1351
1352
    /**
1353
     * @depends testDaoGeneration
1354
     */
1355
    public function testExceptionOnMultipleInheritance()
1356
    {
1357
        $connection = self::getConnection();
1358
        self::insert($connection, 'animal', [
1359
            'id' => 99, 'name' => 'Snoofield',
1360
        ]);
1361
        self::insert($connection, 'dog', [
1362
            'id' => 99, 'race' => 'dog',
1363
        ]);
1364
        self::insert($connection, 'cat', [
1365
            'id' => 99, 'cuteness_level' => 0,
1366
        ]);
1367
1368
        $catched = false;
1369
        try {
1370
            $animalDao = new AnimalDao($this->tdbmService);
1371
            $animalDao->getById(99);
1372
        } catch (TDBMInheritanceException $e) {
1373
            $catched = true;
1374
        }
1375
        $this->assertTrue($catched, 'Exception TDBMInheritanceException was not caught');
1376
1377
        self::delete($connection, 'cat', ['id' => 99]);
1378
        self::delete($connection, 'dog', ['id' => 99]);
1379
        self::delete($connection, 'animal', ['id' => 99]);
1380
    }
1381
1382
    /**
1383
     * @depends testDaoGeneration
1384
     */
1385
    public function testReferenceNotSaved()
1386
    {
1387
        $boatDao = new BoatDao($this->tdbmService);
1388
1389
        $country = new CountryBean('Atlantis');
1390
        $boat = new BoatBean($country, 'Titanic');
1391
1392
        $boatDao->save($boat);
1393
    }
1394
1395
    /**
1396
     * @depends testDaoGeneration
1397
     */
1398
    public function testReferenceDeleted()
1399
    {
1400
        $countryDao = new CountryDao($this->tdbmService);
1401
        $boatDao = new BoatDao($this->tdbmService);
1402
1403
        $country = new CountryBean('Atlantis');
1404
        $countryDao->save($country);
1405
1406
        $boat = new BoatBean($country, 'Titanic');
1407
        $countryDao->delete($country);
1408
1409
        $this->expectException(TDBMMissingReferenceException::class);
1410
        $boatDao->save($boat);
1411
    }
1412
1413
    /**
1414
     * @depends testDaoGeneration
1415
     */
1416 View Code Duplication
    public function testCyclicReferenceWithInheritance()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1417
    {
1418
        $userDao = new UserDao($this->tdbmService);
1419
1420
        $country = new CountryBean('Norrisland');
1421
        $user = new UserBean('Chuck Norris', '[email protected]', $country, 'chuck.norris');
1422
1423
        $user->setManager($user);
1424
1425
        $this->expectException(TDBMCyclicReferenceException::class);
1426
        $userDao->save($user);
1427
    }
1428
1429
    /**
1430
     * @depends testDaoGeneration
1431
     */
1432
    public function testCyclicReference()
1433
    {
1434
        $categoryDao = new CategoryDao($this->tdbmService);
1435
1436
        $category = new CategoryBean('Root');
1437
1438
        $category->setParent($category);
1439
1440
        $this->expectException(TDBMCyclicReferenceException::class);
1441
        $categoryDao->save($category);
1442
    }
1443
1444
    /**
1445
     * @depends testDaoGeneration
1446
     */
1447
    public function testCorrectTypeForPrimaryKeyAfterSave()
1448
    {
1449
        // PosqtgreSQL does not particularly like empty inserts (i.e.: "INSERT INTO all_nullable () VALUES ()" )
1450
        $this->onlyMySql();
1451
1452
        $allNullableDao = new AllNullableDao($this->tdbmService);
1453
        $allNullable = new AllNullableBean();
1454
        $allNullableDao->save($allNullable);
1455
        $id = $allNullable->getId();
1456
1457
        $this->assertTrue(is_int($id));
1458
    }
1459
1460
    /**
1461
     * @depends testDaoGeneration
1462
     */
1463
    public function testPSR2Compliance()
1464
    {
1465
        $process = new Process('vendor/bin/php-cs-fixer fix src/Test/  --dry-run --diff --rules=@PSR2');
1466
        $process->run();
1467
1468
        // executes after the command finishes
1469
        if (!$process->isSuccessful()) {
1470
            echo $process->getOutput();
1471
            $this->fail('Generated code is not PRS2 compliant');
1472
        }
1473
    }
1474
1475
    /**
1476
     * @depends testDaoGeneration
1477
     */
1478
    public function testFindOneByGeneration()
1479
    {
1480
        $reflectionMethod = new \ReflectionMethod(UserBaseDao::class, 'findOneByLogin');
1481
        $parameters = $reflectionMethod->getParameters();
1482
1483
        $this->assertCount(2, $parameters);
1484
        $this->assertSame('login', $parameters[0]->getName());
0 ignored issues
show
Bug introduced by
Consider using $parameters[0]->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
1485
        $this->assertSame('additionalTablesFetch', $parameters[1]->getName());
0 ignored issues
show
Bug introduced by
Consider using $parameters[1]->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
1486
    }
1487
1488
    /**
1489
     * @depends testDaoGeneration
1490
     */
1491 View Code Duplication
    public function testUuid()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1492
    {
1493
        $article = new ArticleBean('content');
1494
        $this->assertSame('content', $article->getContent());
1495
        $this->assertNotEmpty($article->getId());
1496
        $uuid = Uuid::fromString($article->getId());
1497
        $this->assertSame(1, $uuid->getVersion());
1498
    }
1499
1500
    /**
1501
     * @depends testDaoGeneration
1502
     */
1503 View Code Duplication
    public function testUuidv4()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1504
    {
1505
        $article = new Article2Bean('content');
1506
        $this->assertSame('content', $article->getContent());
1507
        $this->assertNotEmpty($article->getId());
1508
        $uuid = Uuid::fromString($article->getId());
1509
        $this->assertSame(4, $uuid->getVersion());
1510
    }
1511
1512
    /**
1513
     * @depends testDaoGeneration
1514
     */
1515
    public function testTypeHintedConstructors()
1516
    {
1517
        $userBaseBeanReflectionConstructor = new \ReflectionMethod(UserBaseBean::class, '__construct');
1518
        $nameParam = $userBaseBeanReflectionConstructor->getParameters()[0];
1519
1520
        $this->assertSame('string', (string) $nameParam->getType());
1521
    }
1522
1523
    /**
1524
     * @depends testDaoGeneration
1525
     */
1526
    public function testSaveTransaction()
1527
    {
1528
        $countryDao = new CountryDao($this->tdbmService);
1529
1530
        $boatDao = new BoatDao($this->tdbmService);
1531
        $boatBean = $boatDao->getById(1);
1532
        $boatBean->setName('Bismark');
1533
1534
        $boatBean->getCountry();
1535
1536
        // Let's insert a row without telling TDBM to trigger an error!
1537
        self::insert($this->getConnection(), 'sailed_countries', [
1538
            'boat_id' => 1,
1539
            'country_id' => 2
1540
        ]);
1541
1542
        $boatBean->addCountry($countryDao->getById(2));
1543
1544
        $this->expectException(UniqueConstraintViolationException::class);
1545
1546
        $boatDao->save($boatBean);
1547
    }
1548
1549
    /**
1550
     * @depends testSaveTransaction
1551
     */
1552
    public function testSaveTransaction2()
1553
    {
1554
        $boatDao = new BoatDao($this->tdbmService);
1555
        $boatBean = $boatDao->getById(1);
1556
1557
        // The name should not have been saved because the transaction of the previous test should have rollbacked.
1558
        $this->assertNotSame('Bismark', $boatBean->getName());
1559
    }
1560
1561
    /**
1562
     * @depends testDaoGeneration
1563
     */
1564
    public function testForeignKeyPointingToNonPrimaryKey()
1565
    {
1566
        $dao = new RefNoPrimKeyDao($this->tdbmService);
1567
        $bean = $dao->getById(1);
1568
1569
        $this->assertSame('foo', $bean->getFrom()->getTo());
1570
1571
        $newBean = new RefNoPrimKeyBean($bean, 'baz');
1572
        $dao->save($newBean);
1573
        $this->assertSame('foo', $newBean->getFrom()->getTo());
1574
    }
1575
1576
    /**
1577
     * @depends testDaoGeneration
1578
     */
1579
    public function testCloningUuidBean()
1580
    {
1581
        $article = new ArticleBean('content');
1582
        $this->assertNotEmpty($article->getId());
1583
        $article2 = clone $article;
1584
        $this->assertNotEmpty($article2->getId());
1585
        $this->assertNotSame($article->getId(), $article2->getId());
1586
    }
1587
1588
    /**
1589
     * @depends testDaoGeneration
1590
     */
1591
    public function testRecursiveSave()
1592
    {
1593
        $categoryDao = new CategoryDao($this->tdbmService);
1594
1595
        $root1 = new CategoryBean('Root1');
1596
        $categoryDao->save($root1);
1597
        // Root 2 is not saved yet.
1598
        $root2 = new CategoryBean('Root2');
1599
        $intermediate = new CategoryBean('Intermediate');
1600
        $categoryDao->save($intermediate);
1601
1602
        // Let's switch the parent to a bean in detached state.
1603
        $intermediate->setParent($root2);
1604
1605
        // Now, let's save a new category that references the leaf category.
1606
        $leaf = new CategoryBean('Leaf');
1607
        $leaf->setParent($intermediate);
1608
        $categoryDao->save($leaf);
1609
    }
1610
}
1611