Test Failed
Pull Request — master (#43)
by David
03:21
created

testForeignKeyPointingToNonPrimaryKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 7
rs 9.4285
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\TestCountryDao;
29
use TheCodingMachine\TDBM\Dao\TestRoleDao;
30
use TheCodingMachine\TDBM\Dao\TestUserDao;
31
use TheCodingMachine\TDBM\Test\Dao\AllNullableDao;
32
use TheCodingMachine\TDBM\Test\Dao\AnimalDao;
33
use TheCodingMachine\TDBM\Test\Dao\Bean\AllNullableBean;
34
use TheCodingMachine\TDBM\Test\Dao\Bean\Article2Bean;
35
use TheCodingMachine\TDBM\Test\Dao\Bean\ArticleBean;
36
use TheCodingMachine\TDBM\Test\Dao\Bean\BoatBean;
37
use TheCodingMachine\TDBM\Test\Dao\Bean\CatBean;
38
use TheCodingMachine\TDBM\Test\Dao\Bean\CategoryBean;
39
use TheCodingMachine\TDBM\Test\Dao\Bean\CountryBean;
40
use TheCodingMachine\TDBM\Test\Dao\Bean\DogBean;
41
use TheCodingMachine\TDBM\Test\Dao\Bean\Generated\UserBaseBean;
42
use TheCodingMachine\TDBM\Test\Dao\Bean\PersonBean;
43
use TheCodingMachine\TDBM\Test\Dao\Bean\RoleBean;
44
use TheCodingMachine\TDBM\Test\Dao\Bean\UserBean;
45
use TheCodingMachine\TDBM\Test\Dao\BoatDao;
46
use TheCodingMachine\TDBM\Test\Dao\CatDao;
47
use TheCodingMachine\TDBM\Test\Dao\CategoryDao;
48
use TheCodingMachine\TDBM\Test\Dao\ContactDao;
49
use TheCodingMachine\TDBM\Test\Dao\CountryDao;
50
use TheCodingMachine\TDBM\Test\Dao\DogDao;
51
use TheCodingMachine\TDBM\Test\Dao\Generated\UserBaseDao;
52
use TheCodingMachine\TDBM\Test\Dao\RefNoPrimKeyDao;
53
use TheCodingMachine\TDBM\Test\Dao\RoleDao;
54
use TheCodingMachine\TDBM\Test\Dao\UserDao;
55
use TheCodingMachine\TDBM\Utils\PathFinder\NoPathFoundException;
56
use TheCodingMachine\TDBM\Utils\TDBMDaoGenerator;
57
use Symfony\Component\Process\Process;
58
59
class TDBMDaoGeneratorTest extends TDBMAbstractServiceTest
60
{
61
    /** @var TDBMDaoGenerator $tdbmDaoGenerator */
62
    protected $tdbmDaoGenerator;
63
64
    private $rootPath;
65
66
    protected function setUp()
67
    {
68
        parent::setUp();
69
        $schemaManager = $this->tdbmService->getConnection()->getSchemaManager();
70
        $schemaAnalyzer = new SchemaAnalyzer($schemaManager);
71
        $tdbmSchemaAnalyzer = new TDBMSchemaAnalyzer($this->tdbmService->getConnection(), new ArrayCache(), $schemaAnalyzer);
72
        $this->tdbmDaoGenerator = new TDBMDaoGenerator($this->getConfiguration(), $tdbmSchemaAnalyzer);
73
        $this->rootPath = __DIR__.'/../';
74
        //$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...
75
    }
76
77
    public function testDaoGeneration()
78
    {
79
        // Remove all previously generated files.
80
        $this->recursiveDelete($this->rootPath.'src/Test/Dao/');
81
82
        $this->tdbmDaoGenerator->generateAllDaosAndBeans();
83
84
        // Let's require all files to check they are valid PHP!
85
        // Test the daoFactory
86
        require_once $this->rootPath.'src/Test/Dao/Generated/DaoFactory.php';
87
        // Test the others
88
89
        $beanDescriptors = $this->getDummyGeneratorListener()->getBeanDescriptors();
90
91
        foreach ($beanDescriptors as $beanDescriptor) {
92
            $daoName = $beanDescriptor->getDaoClassName();
93
            $daoBaseName = $beanDescriptor->getBaseDaoClassName();
94
            $beanName = $beanDescriptor->getBeanClassName();
95
            $baseBeanName = $beanDescriptor->getBaseBeanClassName();
96
            require_once $this->rootPath.'src/Test/Dao/Bean/Generated/'.$baseBeanName.'.php';
97
            require_once $this->rootPath.'src/Test/Dao/Bean/'.$beanName.'.php';
98
            require_once $this->rootPath.'src/Test/Dao/Generated/'.$daoBaseName.'.php';
99
            require_once $this->rootPath.'src/Test/Dao/'.$daoName.'.php';
100
        }
101
102
        // Check that pivot tables do not generate DAOs or beans.
103
        $this->assertFalse(class_exists('TheCodingMachine\\TDBM\\Test\\Dao\\RolesRightDao'));
104
    }
105
106
    public function testGenerationException()
107
    {
108
        $configuration = new Configuration('UnknownVendor\\Dao', 'UnknownVendor\\Bean', self::getConnection(), $this->getNamingStrategy());
109
110
        $schemaManager = $this->tdbmService->getConnection()->getSchemaManager();
111
        $schemaAnalyzer = new SchemaAnalyzer($schemaManager);
112
        $tdbmSchemaAnalyzer = new TDBMSchemaAnalyzer($this->tdbmService->getConnection(), new ArrayCache(), $schemaAnalyzer);
113
        $tdbmDaoGenerator = new TDBMDaoGenerator($configuration, $tdbmSchemaAnalyzer);
114
        $this->rootPath = __DIR__.'/../../../../';
115
        //$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...
116
117
        $this->expectException(NoPathFoundException::class);
118
        $tdbmDaoGenerator->generateAllDaosAndBeans();
119
    }
120
121
    /**
122
     * Delete a file or recursively delete a directory.
123
     *
124
     * @param string $str Path to file or directory
125
     * @return bool
126
     */
127
    private function recursiveDelete(string $str) : bool
128
    {
129
        if (is_file($str)) {
130
            return @unlink($str);
131
        } elseif (is_dir($str)) {
132
            $scan = glob(rtrim($str, '/') . '/*');
133
            foreach ($scan as $index => $path) {
134
                $this->recursiveDelete($path);
135
            }
136
137
            return @rmdir($str);
138
        }
139
        return false;
140
    }
141
142
    /**
143
     * @depends testDaoGeneration
144
     */
145
    public function testGetBeanClassName()
146
    {
147
        $this->assertEquals(UserBean::class, $this->tdbmService->getBeanClassName('users'));
148
    }
149
150
    /**
151
     * @depends testDaoGeneration
152
     */
153
    public function testGetBeanClassNameException()
154
    {
155
        $this->expectException(TDBMInvalidArgumentException::class);
156
        $this->tdbmService->getBeanClassName('not_exists');
157
    }
158
159
    /**
160
     * @depends testDaoGeneration
161
     */
162
    public function testGeneratedGetById()
163
    {
164
        $contactDao = new ContactDao($this->tdbmService);
165
        $contactBean = $contactDao->getById(1);
166
        $this->assertEquals(1, $contactBean->getId());
167
        $this->assertInstanceOf('\\DateTimeInterface', $contactBean->getCreatedAt());
168
169
        // FIXME: Question: que faire du paramètre stockage "UTC"????
170
    }
171
172
    /**
173
     * @depends testDaoGeneration
174
     */
175
    public function testGeneratedGetByIdLazyLoaded()
176
    {
177
        $roleDao = new RoleDao($this->tdbmService);
178
        $roleBean = $roleDao->getById(1, true);
179
        $this->assertEquals(1, $roleBean->getId());
180
        $this->assertInstanceOf('\\DateTimeInterface', $roleBean->getCreatedAt());
181
182
        $roleBean2 = $roleDao->getById(1, true);
183
        $this->assertTrue($roleBean === $roleBean2);
184
    }
185
186
    /**
187
     * @depends testDaoGeneration
188
     */
189
    public function testDefaultValueOnNewBean()
190
    {
191
        $roleBean = new RoleBean('my_role');
192
        $this->assertEquals(1, $roleBean->getStatus());
193
    }
194
195
    /**
196
     * @depends testDaoGeneration
197
     */
198 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...
199
    {
200
        $userDao = new UserDao($this->tdbmService);
201
        $userBean = $userDao->getById(1);
202
        $country = $userBean->getCountry();
203
204
        $this->assertEquals('UK', $country->getLabel());
205
206
        $userBean2 = $userDao->getById(1);
207
        $this->assertTrue($userBean === $userBean2);
208
209
        $contactDao = new ContactDao($this->tdbmService);
210
        $contactBean = $contactDao->getById(1);
211
212
        $this->assertTrue($userBean === $contactBean);
213
    }
214
215
    /**
216
     * @depends testDaoGeneration
217
     */
218
    public function testNewBeans()
219
    {
220
        $countryDao = new CountryDao($this->tdbmService);
221
        $userDao = new UserDao($this->tdbmService);
222
        $userBean = new UserBean('John Doe', '[email protected]', $countryDao->getById(2), 'john.doe');
223
        $userBean->setOrder(1); // Let's set a "protected keyword" column.
224
225
        $userDao->save($userBean);
226
227
        $this->assertNull($userBean->getManager());
228
    }
229
230
    /**
231
     * @depends testDaoGeneration
232
     */
233
    public function testDateTimeImmutableGetter()
234
    {
235
        $userDao = new UserDao($this->tdbmService);
236
        $user = $userDao->getById(1);
237
238
        $this->assertInstanceOf('\DateTimeImmutable', $user->getCreatedAt());
239
    }
240
241
    /**
242
     * @depends testDaoGeneration
243
     */
244 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...
245
    {
246
        $userDao = new UserDao($this->tdbmService);
247
        $countryBean = new CountryBean('Mexico');
248
        $userBean = new UserBean('Speedy Gonzalez', '[email protected]', $countryBean, 'speedy.gonzalez');
249
        $this->assertEquals($countryBean, $userBean->getCountry());
250
251
        $userDao->save($userBean);
252
    }
253
254
    /**
255
     * @depends testAssigningNewBeans
256
     */
257
    public function testUpdatingProtectedColumn()
258
    {
259
        $userDao = new UserDao($this->tdbmService);
260
        $userBean = $userDao->findOneByLogin('speedy.gonzalez');
261
        $userBean->setOrder(2);
262
        $userDao->save($userBean);
263
    }
264
265
    /**
266
     * @depends testDaoGeneration
267
     */
268 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...
269
    {
270
        $userDao = new UserDao($this->tdbmService);
271
        $user = $userDao->getById(1);
272
        $countryDao = new CountryDao($this->tdbmService);
273
        $country = $countryDao->getById(2);
274
275
        $user->setCountry($country);
276
        $this->assertEquals(TDBMObjectStateEnum::STATE_DIRTY, $user->_getStatus());
277
    }
278
279
    /**
280
     * @depends testDaoGeneration
281
     */
282
    public function testDirectReversedRelationship()
283
    {
284
        $countryDao = new CountryDao($this->tdbmService);
285
        $country = $countryDao->getById(1);
286
        $users = $country->getUsers();
287
288
        $arr = $users->toArray();
289
290
        $this->assertCount(1, $arr);
291
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $arr[0]);
292
        $this->assertEquals('jean.dupont', $arr[0]->getLogin());
293
294
        $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...
295
        $users = $country->getUsers();
296
297
        $arr = $users->toArray();
298
299
        $this->assertCount(2, $arr);
300
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $arr[1]);
301
        $this->assertEquals('speedy.gonzalez', $arr[1]->getLogin());
302
    }
303
304
    /**
305
     * @depends testDaoGeneration
306
     */
307
    public function testDeleteInDirectReversedRelationship()
308
    {
309
        $countryDao = new CountryDao($this->tdbmService);
310
        $country = $countryDao->getById(1);
311
312
        $userDao = new UserDao($this->tdbmService);
313
        $newUser = new UserBean('John Snow', '[email protected]', $country, 'john.snow');
314
        $userDao->save($newUser);
315
316
        $users = $country->getUsers();
317
318
        $arr = $users->toArray();
319
320
        $this->assertCount(2, $arr);
321
322
        $userDao->delete($arr[1]);
323
324
        $users = $country->getUsers();
325
        $arr = $users->toArray();
326
        $this->assertCount(1, $arr);
327
    }
328
329
    /**
330
     * @depends testDaoGeneration
331
     */
332
    public function testJointureGetters()
333
    {
334
        $roleDao = new RoleDao($this->tdbmService);
335
        $role = $roleDao->getById(1);
336
        $users = $role->getUsers();
337
338
        $this->assertCount(2, $users);
339
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\UserBean', $users[0]);
340
341
        $rights = $role->getRights();
342
343
        $this->assertCount(2, $rights);
344
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\RightBean', $rights[0]);
345
    }
346
347
    /**
348
     * @depends testDaoGeneration
349
     */
350
    public function testNewBeanConstructor()
351
    {
352
        $role = new RoleBean('Newrole');
353
        $this->assertEquals(TDBMObjectStateEnum::STATE_DETACHED, $role->_getStatus());
354
    }
355
356
    /**
357
     * @depends testDaoGeneration
358
     */
359
    public function testJointureAdderOnNewBean()
360
    {
361
        $countryDao = new CountryDao($this->tdbmService);
362
        $country = $countryDao->getById(1);
363
        $user = new UserBean('Speedy Gonzalez', '[email protected]', $country, 'speedy.gonzalez');
364
        $role = new RoleBean('Mouse');
365
        $user->addRole($role);
366
        $roles = $user->getRoles();
367
        $this->assertCount(1, $roles);
368
        $role = $roles[0];
369
        $this->assertInstanceOf('TheCodingMachine\\TDBM\\Test\\Dao\\Bean\\RoleBean', $role);
370
        $users = $role->getUsers();
371
        $this->assertCount(1, $users);
372
        $this->assertEquals($user, $users[0]);
373
374
        $role->removeUser($user);
375
        $this->assertCount(0, $role->getUsers());
376
        $this->assertCount(0, $user->getRoles());
377
    }
378
379
    /**
380
     * @depends testDaoGeneration
381
     */
382 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...
383
    {
384
        $roleDao = new RoleDao($this->tdbmService);
385
        $userDao = new UserDao($this->tdbmService);
386
        $role = $roleDao->getById(1);
387
        $user = $userDao->getById(1);
388
389
        // We call removeUser BEFORE calling getUsers
390
        // This should work as expected.
391
        $role->removeUser($user);
392
        $users = $role->getUsers();
393
394
        $this->assertCount(1, $users);
395
    }
396
397
    /**
398
     * @depends testDaoGeneration
399
     */
400
    public function testJointureMultiAdd()
401
    {
402
        $countryDao = new CountryDao($this->tdbmService);
403
        $country = $countryDao->getById(1);
404
        $user = new UserBean('Speedy Gonzalez', '[email protected]', $country, 'speedy.gonzalez');
405
        $role = new RoleBean('Mouse');
406
        $user->addRole($role);
407
        $role->addUser($user);
408
        $user->addRole($role);
409
410
        $this->assertCount(1, $user->getRoles());
411
    }
412
413
    /**
414
     * Step 1: we remove the role 1 from user 1 but save role 1.
415
     * Expected result: no save done.
416
     *
417
     * @depends testDaoGeneration
418
     */
419
    public function testJointureSave1()
420
    {
421
        $roleDao = new RoleDao($this->tdbmService);
422
        $role = $roleDao->getById(1);
423
        $userDao = new UserDao($this->tdbmService);
424
        $user = $userDao->getById(1);
425
426
        $this->assertTrue($user->hasRole($role));
427
        $this->assertTrue($role->hasUser($user));
428
        $user->removeRole($role);
429
        $this->assertFalse($user->hasRole($role));
430
        $this->assertFalse($role->hasUser($user));
431
        $roleDao->save($role);
432
433
        $this->assertEquals(TDBMObjectStateEnum::STATE_DIRTY, $user->_getStatus());
434
        $this->assertEquals(TDBMObjectStateEnum::STATE_LOADED, $role->_getStatus());
435
    }
436
437
    /**
438
     * Step 2: we check that nothing was saved
439
     * Expected result: no save done.
440
     *
441
     * @depends testJointureSave1
442
     */
443
    public function testJointureSave2()
444
    {
445
        $roleDao = new RoleDao($this->tdbmService);
446
        $role = $roleDao->getById(1);
447
        $this->assertCount(2, $role->getUsers());
448
    }
449
450
    /**
451
     * Step 3: we remove the role 1 from user 1 and save user 1.
452
     * Expected result: save done.
453
     *
454
     * @depends testJointureSave2
455
     */
456
    public function testJointureSave3()
457
    {
458
        $roleDao = new RoleDao($this->tdbmService);
459
        $role = $roleDao->getById(1);
460
        $userDao = new UserDao($this->tdbmService);
461
        $user = $userDao->getById(1);
462
463
        $this->assertCount(1, $user->getRoles());
464
        $user->removeRole($role);
465
        $this->assertCount(0, $user->getRoles());
466
        $userDao->save($user);
467
        $this->assertCount(0, $user->getRoles());
468
    }
469
470
    /**
471
     * Step 4: we check that save was done
472
     * Expected result: save done.
473
     *
474
     * @depends testJointureSave3
475
     */
476 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...
477
    {
478
        $roleDao = new RoleDao($this->tdbmService);
479
        $role = $roleDao->getById(1);
480
        $this->assertCount(1, $role->getUsers());
481
        $userDao = new UserDao($this->tdbmService);
482
        $user = $userDao->getById(1);
483
        $this->assertCount(0, $user->getRoles());
484
    }
485
486
    /**
487
     * Step 5: we add the role 1 from user 1 and save user 1.
488
     * Expected result: save done.
489
     *
490
     * @depends testJointureSave4
491
     */
492 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...
493
    {
494
        $roleDao = new RoleDao($this->tdbmService);
495
        $role = $roleDao->getById(1);
496
        $userDao = new UserDao($this->tdbmService);
497
        $user = $userDao->getById(1);
498
499
        $user->addRole($role);
500
        $this->assertCount(1, $user->getRoles());
501
        $userDao->save($user);
502
    }
503
504
    /**
505
     * Step 6: we check that save was done
506
     * Expected result: save done.
507
     *
508
     * @depends testJointureSave5
509
     */
510 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...
511
    {
512
        $roleDao = new RoleDao($this->tdbmService);
513
        $role = $roleDao->getById(1);
514
        $this->assertCount(2, $role->getUsers());
515
        $userDao = new UserDao($this->tdbmService);
516
        $user = $userDao->getById(1);
517
        $this->assertCount(1, $user->getRoles());
518
    }
519
520
    /**
521
     * Step 7: we add a new role to user 1 and save user 1.
522
     * Expected result: save done, including the new role.
523
     *
524
     * @depends testJointureSave6
525
     */
526
    public function testJointureSave7()
527
    {
528
        $role = new RoleBean('my new role');
529
        $userDao = new UserDao($this->tdbmService);
530
        $user = $userDao->getById(1);
531
532
        $user->addRole($role);
533
        $userDao->save($user);
534
535
        $this->assertEquals(TDBMObjectStateEnum::STATE_LOADED, $role->_getStatus());
536
    }
537
538
    /**
539
     * Step 8: we check that save was done
540
     * Expected result: save done.
541
     *
542
     * @depends testJointureSave7
543
     */
544 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...
545
    {
546
        $roleDao = new RoleDao($this->tdbmService);
547
        $userDao = new UserDao($this->tdbmService);
548
        $user = $userDao->getById(1);
549
550
        $roles = $user->getRoles();
551
        foreach ($roles as $role) {
552
            if ($role->getName() === 'my new role') {
553
                $selectedRole = $role;
554
                break;
555
            }
556
        }
557
        $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...
558
559
        $this->assertCount(2, $user->getRoles());
560
561
        // Expected: relationship removed!
562
        $roleDao->delete($selectedRole);
563
564
        $this->assertCount(1, $user->getRoles());
565
    }
566
567
    /**
568
     * Step 9: Let's test the setXXX method.
569
     *
570
     * @depends testJointureSave8
571
     */
572
    public function testJointureSave9()
573
    {
574
        $roleDao = new RoleDao($this->tdbmService);
575
        $userDao = new UserDao($this->tdbmService);
576
        $user = $userDao->getById(1);
577
578
        // At this point, user 1 is linked to role 1.
579
        // Let's bind it to role 2.
580
        $user->setRoles([$roleDao->getById(2)]);
581
        $userDao->save($user);
582
    }
583
584
    /**
585
     * Step 10: Let's check results of 9.
586
     *
587
     * @depends testJointureSave9
588
     */
589
    public function testJointureSave10()
590
    {
591
        $userDao = new UserDao($this->tdbmService);
592
        $user = $userDao->getById(1);
593
594
        $roles = $user->getRoles();
595
596
        $this->assertCount(1, $roles);
597
        $this->assertEquals(2, $roles[0]->getId());
598
    }
599
600
    /**
601
     * @depends testDaoGeneration
602
     */
603 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...
604
    {
605
        $userDao = new TestUserDao($this->tdbmService);
606
        $users = $userDao->getUsersByAlphabeticalOrder();
607
608
        $this->assertCount(6, $users);
609
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
610
        $this->assertEquals('jean.dupont', $users[1]->getLogin());
611
612
        $users = $userDao->getUsersByCountryOrder();
613
        $this->assertCount(6, $users);
614
        $countryName1 = $users[0]->getCountry()->getLabel();
615
        for ($i = 1; $i < 6; $i++) {
616
            $countryName2 = $users[$i]->getCountry()->getLabel();
617
            $this->assertLessThanOrEqual(0, strcmp($countryName1, $countryName2));
618
            $countryName1 = $countryName2;
619
        }
620
    }
621
622
    /**
623
     * @depends testDaoGeneration
624
     */
625 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...
626
    {
627
        $userDao = new TestUserDao($this->tdbmService);
628
        $users = $userDao->getUsersFromSqlByAlphabeticalOrder();
629
630
        $this->assertCount(6, $users);
631
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
632
        $this->assertEquals('jean.dupont', $users[1]->getLogin());
633
634
        $users = $userDao->getUsersFromSqlByCountryOrder();
635
        $this->assertCount(6, $users);
636
        $countryName1 = $users[0]->getCountry()->getLabel();
637
        for ($i = 1; $i < 6; $i++) {
638
            $countryName2 = $users[$i]->getCountry()->getLabel();
639
            $this->assertLessThanOrEqual(0, strcmp($countryName1, $countryName2));
640
            $countryName1 = $countryName2;
641
        }
642
    }
643
644
    /**
645
     * @depends testDaoGeneration
646
     */
647
    public function testFindFromSqlOrderByJoinRole()
648
    {
649
        $roleDao = new TestRoleDao($this->tdbmService);
650
        $roles = $roleDao->getRolesByRightCanSing('roles.name DESC');
651
652
        $this->assertCount(2, $roles);
653
        $this->assertEquals('Singers', $roles[0]->getName());
654
        $this->assertEquals('Admins', $roles[1]->getName());
655
    }
656
657
    /**
658
     * @depends testDaoGeneration
659
     */
660
    public function testFindFromRawSqlOrderByUserCount()
661
    {
662
        $countryDao = new TestCountryDao($this->tdbmService);
663
        $countries = $countryDao->getCountriesByUserCount();
664
665
        $this->assertCount(4, $countries);
666
        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...
667
            $this->assertLessThanOrEqual($countries[$i - 1]->getUsers()->count(), $countries[$i]->getUsers()->count());
668
        }
669
    }
670
671
    /**
672
     * @depends testDaoGeneration
673
     */
674 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...
675
    {
676
        $userDao = new TestUserDao($this->tdbmService);
677
        $users = $userDao->getUsersByLoginStartingWith('bill');
678
679
        $this->assertCount(1, $users);
680
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
681
    }
682
683
    /**
684
     * @expectedException \TheCodingMachine\TDBM\TDBMException
685
     * @depends testDaoGeneration
686
     */
687
    public function testFindMode()
688
    {
689
        $userDao = new TestUserDao($this->tdbmService);
690
        $users = $userDao->getUsersByLoginStartingWith('bill', TDBMService::MODE_CURSOR);
691
692
        $users[0];
693
    }
694
695
    /**
696
     * @depends testDaoGeneration
697
     */
698
    public function testFindAll()
699
    {
700
        $userDao = new TestUserDao($this->tdbmService);
701
        $users = $userDao->findAll();
702
703
        $this->assertCount(6, $users);
704
    }
705
706
    /**
707
     * @depends testDaoGeneration
708
     */
709
    public function testFindOne()
710
    {
711
        $userDao = new TestUserDao($this->tdbmService);
712
        $user = $userDao->getUserByLogin('bill.shakespeare');
713
714
        $this->assertEquals('bill.shakespeare', $user->getLogin());
715
    }
716
717
    /**
718
     * @depends testDaoGeneration
719
     */
720
    public function testJsonEncodeBean()
721
    {
722
        $userDao = new TestUserDao($this->tdbmService);
723
        $user = $userDao->getUserByLogin('bill.shakespeare');
724
725
        $jsonEncoded = json_encode($user);
726
        $userDecoded = json_decode($jsonEncoded, true);
727
728
        $this->assertEquals('bill.shakespeare', $userDecoded['login']);
729
730
        // test serialization of dates.
731
        $this->assertTrue(is_string($userDecoded['createdAt']));
732
        $this->assertEquals('2015-10-24', (new \DateTimeImmutable($userDecoded['createdAt']))->format('Y-m-d'));
733
        $this->assertNull($userDecoded['modifiedAt']);
734
735
        // testing many to 1 relationships
736
        $this->assertEquals('UK', $userDecoded['country']['label']);
737
738
        // testing many to many relationships
739
        $this->assertCount(1, $userDecoded['roles']);
740
        $this->assertArrayNotHasKey('users', $userDecoded['roles'][0]);
741
        $this->assertArrayNotHasKey('rights', $userDecoded['roles'][0]);
742
    }
743
744
    /**
745
     * @depends testDaoGeneration
746
     */
747
    public function testNullableForeignKey()
748
    {
749
        $userDao = new TestUserDao($this->tdbmService);
750
        $user = $userDao->getUserByLogin('john.smith');
751
752
        $this->assertNull(null, $user->getManager());
753
754
        $jsonEncoded = json_encode($user);
755
        $userDecoded = json_decode($jsonEncoded, true);
756
757
        $this->assertNull(null, $userDecoded['manager']);
758
    }
759
760
    /**
761
     * Test that setting (and saving) objects' references (foreign keys relations) to null is working.
762
     *
763
     * @depends testDaoGeneration
764
     */
765
    public function testSetToNullForeignKey()
766
    {
767
        $userDao = new TestUserDao($this->tdbmService);
768
        $user = $userDao->getUserByLogin('john.smith');
769
        $manager = $userDao->getUserByLogin('jean.dupont');
770
771
        $user->setManager($manager);
772
        $userDao->save($user);
773
774
        $user->setManager(null);
775
        $userDao->save($user);
776
    }
777
778
    /**
779
     * @depends testDaoGeneration
780
     * @expectedException \Mouf\Database\SchemaAnalyzer\SchemaAnalyzerTableNotFoundException
781
     * @expectedExceptionMessage Could not find table 'contacts'. Did you mean 'contact'?
782
     */
783
    public function testQueryOnWrongTableName()
784
    {
785
        $userDao = new TestUserDao($this->tdbmService);
786
        $users = $userDao->getUsersWrongTableName();
787
        $users->count();
788
    }
789
790
    /**
791
     * @depends testDaoGeneration
792
     */
793
    /*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...
794
    {
795
        $userDao = new TestUserDao($this->tdbmService);
796
        $users = $userDao->getUsersByManagerId(null);
797
        $this->assertCount(3, $users);
798
    }*/
799
800
    /**
801
     * @depends testDaoGeneration
802
     */
803
    public function testInnerJsonEncode()
804
    {
805
        $userDao = new TestUserDao($this->tdbmService);
806
        $user = $userDao->getUserByLogin('bill.shakespeare');
807
808
        $jsonEncoded = json_encode(['user' => $user]);
809
        $msgDecoded = json_decode($jsonEncoded, true);
810
811
        $this->assertEquals('bill.shakespeare', $msgDecoded['user']['login']);
812
    }
813
814
    /**
815
     * @depends testDaoGeneration
816
     */
817 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...
818
    {
819
        $userDao = new TestUserDao($this->tdbmService);
820
        $users = $userDao->getUsersByLoginStartingWith('bill');
821
822
        $jsonEncoded = json_encode($users);
823
        $msgDecoded = json_decode($jsonEncoded, true);
824
825
        $this->assertCount(1, $msgDecoded);
826
    }
827
828
    /**
829
     * @depends testDaoGeneration
830
     */
831 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...
832
    {
833
        $userDao = new TestUserDao($this->tdbmService);
834
        $users = $userDao->getUsersByLoginStartingWith('bill', TDBMService::MODE_CURSOR);
835
836
        $jsonEncoded = json_encode($users);
837
        $msgDecoded = json_decode($jsonEncoded, true);
838
839
        $this->assertCount(1, $msgDecoded);
840
    }
841
842
    /**
843
     * @depends testDaoGeneration
844
     */
845 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...
846
    {
847
        $userDao = new TestUserDao($this->tdbmService);
848
        $users = $userDao->getUsersByLoginStartingWith('bill');
849
850
        $jsonEncoded = json_encode($users->take(0, 1));
851
        $msgDecoded = json_decode($jsonEncoded, true);
852
853
        $this->assertCount(1, $msgDecoded);
854
    }
855
856
    /**
857
     * @depends testDaoGeneration
858
     */
859 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...
860
    {
861
        $userDao = new TestUserDao($this->tdbmService);
862
        $users = $userDao->getUsersByLoginStartingWith('bill');
863
864
        $bill = $users->first();
865
        $this->assertEquals('bill.shakespeare', $bill->getLogin());
866
    }
867
868
    /**
869
     * @depends testDaoGeneration
870
     */
871
    public function testFirstNull()
872
    {
873
        $userDao = new TestUserDao($this->tdbmService);
874
        $users = $userDao->getUsersByLoginStartingWith('mike');
875
876
        $user = $users->first();
877
        $this->assertNull($user);
878
    }
879
880
    /**
881
     * @depends testDaoGeneration
882
     */
883
    public function testCloneBeanAttachedBean()
884
    {
885
        $userDao = new TestUserDao($this->tdbmService);
886
        $user = $userDao->getUserByLogin('bill.shakespeare');
887
        $this->assertEquals(4, $user->getId());
888
        $user2 = clone $user;
889
        $this->assertNull($user2->getId());
890
        $this->assertEquals('bill.shakespeare', $user2->getLogin());
891
        $this->assertEquals('Bill Shakespeare', $user2->getName());
892
        $this->assertEquals('UK', $user2->getCountry()->getLabel());
893
894
        // MANY 2 MANY must be duplicated
895
        $this->assertEquals('Writers', $user2->getRoles()[0]->getName());
896
897
        // Let's test saving this clone
898
        $user2->setLogin('william.shakespeare');
899
        $userDao->save($user2);
900
901
        $user3 = $userDao->getUserByLogin('william.shakespeare');
902
        $this->assertTrue($user3 === $user2);
903
        $userDao->delete($user3);
904
905
        // Finally, let's test the origin user still exists!
906
        $user4 = $userDao->getUserByLogin('bill.shakespeare');
907
        $this->assertEquals('bill.shakespeare', $user4->getLogin());
908
    }
909
910
    /**
911
     * @depends testDaoGeneration
912
     */
913
    public function testCloneNewBean()
914
    {
915
        $countryDao = new CountryDao($this->tdbmService);
916
        $roleDao = new RoleDao($this->tdbmService);
917
        $role = $roleDao->getById(1);
918
919
        $userBean = new UserBean('John Doe', '[email protected]', $countryDao->getById(2), 'john.doe');
920
        $userBean->addRole($role);
921
922
        $user2 = clone $userBean;
923
924
        $this->assertNull($user2->getId());
925
        $this->assertEquals('john.doe', $user2->getLogin());
926
        $this->assertEquals('John Doe', $user2->getName());
927
        $this->assertEquals('UK', $user2->getCountry()->getLabel());
928
929
        // MANY 2 MANY must be duplicated
930
        $this->assertEquals($role->getName(), $user2->getRoles()[0]->getName());
931
    }
932
933
    /**
934
     * @depends testDaoGeneration
935
     */
936
    public function testCascadeDelete()
937
    {
938
        $userDao = new TestUserDao($this->tdbmService);
939
        $countryDao = new CountryDao($this->tdbmService);
940
941
        $spain = new CountryBean('Spain');
942
        $sanchez = new UserBean('Manuel Sanchez', '[email protected]', $spain, 'manuel.sanchez');
943
944
        $countryDao->save($spain);
945
        $userDao->save($sanchez);
946
947
        $speedy2 = $userDao->getUserByLogin('manuel.sanchez');
948
        $this->assertTrue($sanchez === $speedy2);
949
950
        $exceptionTriggered = false;
951
        try {
952
            $countryDao->delete($spain);
953
        } catch (ForeignKeyConstraintViolationException $e) {
954
            $exceptionTriggered = true;
955
        }
956
        $this->assertTrue($exceptionTriggered);
957
958
        $countryDao->delete($spain, true);
959
960
        // Let's check that speed gonzalez was removed.
961
        $speedy3 = $userDao->getUserByLogin('manuel.sanchez');
962
        $this->assertNull($speedy3);
963
    }
964
965
    /**
966
     * @depends testDaoGeneration
967
     */
968
    public function testDiscardChanges()
969
    {
970
        $contactDao = new ContactDao($this->tdbmService);
971
        $contactBean = $contactDao->getById(1);
972
973
        $oldName = $contactBean->getName();
974
975
        $contactBean->setName('MyNewName');
976
977
        $contactBean->discardChanges();
978
979
        $this->assertEquals($oldName, $contactBean->getName());
980
    }
981
982
    /**
983
     * @expectedException \TheCodingMachine\TDBM\TDBMException
984
     * @depends testDaoGeneration
985
     */
986
    public function testDiscardChangesOnNewBeanFails()
987
    {
988
        $person = new PersonBean('John Foo', new \DateTimeImmutable());
989
        $person->discardChanges();
990
    }
991
992
    /**
993
     * @expectedException \TheCodingMachine\TDBM\TDBMException
994
     * @depends testDaoGeneration
995
     */
996
    public function testDiscardChangesOnDeletedBeanFails()
997
    {
998
        $userDao = new TestUserDao($this->tdbmService);
999
        $countryDao = new CountryDao($this->tdbmService);
1000
1001
        $sanchez = new UserBean('Manuel Sanchez', '[email protected]', $countryDao->getById(1), 'manuel.sanchez');
1002
1003
        $userDao->save($sanchez);
1004
1005
        $userDao->delete($sanchez);
1006
1007
        // Cannot discard changes on a bean that is already deleted.
1008
        $sanchez->discardChanges();
1009
    }
1010
1011
    /**
1012
     * @depends testDaoGeneration
1013
     */
1014 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...
1015
    {
1016
        $userDao = new UserDao($this->tdbmService);
1017
        $user = $userDao->findOneByLogin('bill.shakespeare');
1018
1019
        $this->assertEquals('bill.shakespeare', $user->getLogin());
1020
        $this->assertEquals('Bill Shakespeare', $user->getName());
1021
    }
1022
1023
    /**
1024
     * @depends testDaoGeneration
1025
     */
1026 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...
1027
    {
1028
        $countryDao = new CountryDao($this->tdbmService);
1029
        $userDao = new UserDao($this->tdbmService);
1030
        $users = $userDao->findByStatusAndCountry('on', $countryDao->getById(1));
1031
1032
        $this->assertEquals('jean.dupont', $users[0]->getLogin());
1033
    }
1034
1035
    /**
1036
     * @depends testDaoGeneration
1037
     */
1038
    public function testCreationInNullableDate()
1039
    {
1040
        $roleDao = new RoleDao($this->tdbmService);
1041
1042
        $role = new RoleBean('newbee');
1043
        $roleDao->save($role);
1044
1045
        $this->assertNull($role->getCreatedAt());
1046
    }
1047
1048
    /**
1049
     * @depends testDaoGeneration
1050
     */
1051
    public function testUpdateInNullableDate()
1052
    {
1053
        $roleDao = new RoleDao($this->tdbmService);
1054
1055
        $role = new RoleBean('newbee');
1056
        $roleDao->save($role);
1057
1058
        $role->setCreatedAt(null);
1059
        $roleDao->save($role);
1060
        $this->assertNull($role->getCreatedAt());
1061
    }
1062
1063
    /**
1064
     * @depends testDaoGeneration
1065
     */
1066
    public function testFindFromSql()
1067
    {
1068
        $roleDao = new TestRoleDao($this->tdbmService);
1069
1070
        $roles = $roleDao->getRolesByRightCanSing();
1071
        $this->assertCount(2, $roles);
1072
        $this->assertInstanceOf(RoleBean::class, $roles[0]);
1073
    }
1074
1075
    /**
1076
     * @depends testDaoGeneration
1077
     */
1078
    public function testFindOneFromSql()
1079
    {
1080
        $roleDao = new TestRoleDao($this->tdbmService);
1081
1082
        $role = $roleDao->getRoleByRightCanSingAndNameSinger();
1083
        $this->assertInstanceOf(RoleBean::class, $role);
1084
    }
1085
1086
    /**
1087
     * @depends testDaoGeneration
1088
     */
1089
    public function testCreateEmptyExtendedBean()
1090
    {
1091
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/92
1092
1093
        $dogDao = new DogDao($this->tdbmService);
1094
1095
        // We are not filling no field that is part of dog table.
1096
        $dog = new DogBean('Youki');
1097
        $dog->setOrder(1);
1098
1099
        $dogDao->save($dog);
1100
    }
1101
1102
    /**
1103
     * @depends testCreateEmptyExtendedBean
1104
     */
1105
    public function testFetchEmptyExtendedBean()
1106
    {
1107
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/92
1108
1109
        $animalDao = new AnimalDao($this->tdbmService);
1110
1111
        // We are not filling no field that is part of dog table.
1112
        $animalBean = $animalDao->getById(1);
1113
1114
        $this->assertInstanceOf(DogBean::class, $animalBean);
1115
    }
1116
1117
    /**
1118
     * @depends testDaoGeneration
1119
     */
1120
    public function testTwoBranchesHierarchy()
1121
    {
1122
        // This test cases checks issue https://github.com/thecodingmachine/mouf/issues/131
1123
1124
        $catDao = new CatDao($this->tdbmService);
1125
1126
        // We are not filling no field that is part of dog table.
1127
        $cat = new CatBean('Mew');
1128
        $cat->setOrder(2);
1129
1130
        $catDao->save($cat);
1131
    }
1132
1133
    /**
1134
     * @depends testTwoBranchesHierarchy
1135
     */
1136
    public function testFetchTwoBranchesHierarchy()
1137
    {
1138
        // This test cases checks issue https://github.com/thecodingmachine/mouf/issues/131
1139
1140
        $animalDao = new AnimalDao($this->tdbmService);
1141
1142
        $animalBean = $animalDao->getById(2);
1143
1144
        $this->assertInstanceOf(CatBean::class, $animalBean);
1145
        /* @var $animalBean CatBean */
1146
        $animalBean->setCutenessLevel(999);
1147
1148
        $animalDao->save($animalBean);
1149
    }
1150
1151
    /**
1152
     * @depends testDaoGeneration
1153
     */
1154
    public function testExceptionOnGetById()
1155
    {
1156
        $countryDao = new CountryDao($this->tdbmService);
1157
        $this->expectException(\TypeError::class);
1158
        $countryDao->getById(null);
1159
    }
1160
1161
    /**
1162
     * @depends testDaoGeneration
1163
     */
1164
    public function testDisconnectedManyToOne()
1165
    {
1166
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/99
1167
1168
        $country = new CountryBean('Spain');
1169
1170
        $user = new UserBean('John Doe', '[email protected]', $country, 'john.doe');
1171
1172
        $this->assertCount(1, $country->getUsers());
1173
        $this->assertSame($user, $country->getUsers()[0]);
1174
    }
1175
1176
    /**
1177
     * @depends testDaoGeneration
1178
     */
1179 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...
1180
    {
1181
        // This test cases checks issue https://github.com/thecodingmachine/database.tdbm/issues/106
1182
1183
        $userDao = new TestUserDao($this->tdbmService);
1184
        $users = $userDao->getUsersByCountryName();
1185
1186
        $this->assertEquals('UK', $users[0]->getCountry()->getLabel());
1187
    }
1188
1189
    /**
1190
     * @depends testDaoGeneration
1191
     */
1192
    public function testResultIteratorSort()
1193
    {
1194
        $userDao = new UserDao($this->tdbmService);
1195
        $users = $userDao->findAll()->withOrder('country.label DESC');
1196
1197
        $this->assertEquals('UK', $users[0]->getCountry()->getLabel());
1198
1199
        $users = $users->withOrder('country.label ASC');
1200
        $this->assertEquals('France', $users[0]->getCountry()->getLabel());
1201
    }
1202
1203
    /**
1204
     * @depends testDaoGeneration
1205
     */
1206
    public function testResultIteratorWithParameters()
1207
    {
1208
        $userDao = new TestUserDao($this->tdbmService);
1209
        $users = $userDao->getUsersByLoginStartingWith()->withParameters(['login' => 'bill%']);
1210
        $this->assertEquals('bill.shakespeare', $users[0]->getLogin());
1211
1212
        $users = $users->withParameters(['login' => 'jean%']);
1213
        $this->assertEquals('jean.dupont', $users[0]->getLogin());
1214
    }
1215
1216
    /**
1217
     * @depends testDaoGeneration
1218
     */
1219 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...
1220
    {
1221
        $userDao = new TestUserDao($this->tdbmService);
1222
        $users = $userDao->getUsersByReversedCountryName();
1223
1224
        $this->assertEquals('Jamaica', $users[0]->getCountry()->getLabel());
1225
    }
1226
1227
    /**
1228
     * @depends testDaoGeneration
1229
     */
1230
    public function testOrderByException()
1231
    {
1232
        $userDao = new TestUserDao($this->tdbmService);
1233
        $users = $userDao->getUsersByInvalidOrderBy();
1234
        $this->expectException(TDBMInvalidArgumentException::class);
1235
        $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...
1236
    }
1237
1238
    /**
1239
     * @depends testDaoGeneration
1240
     */
1241
    public function testOrderByProtectedColumn()
1242
    {
1243
        $animalDao = new AnimalDao($this->tdbmService);
1244
        $animals = $animalDao->findAll();
1245
        $animals = $animals->withOrder('`order` ASC');
1246
1247
        $this->assertInstanceOf(DogBean::class, $animals[0]);
1248
        $this->assertInstanceOf(CatBean::class, $animals[1]);
1249
1250
        $animals = $animals->withOrder('`order` DESC');
1251
1252
        $this->assertInstanceOf(CatBean::class, $animals[0]);
1253
        $this->assertInstanceOf(DogBean::class, $animals[1]);
1254
    }
1255
1256
    /**
1257
     * @depends testDaoGeneration
1258
     */
1259
    public function testGetOnAllNullableValues()
1260
    {
1261
        // Tests that a get performed on a column that has only nullable fields succeeds.
1262
        $allNullable = new AllNullableBean();
1263
        $this->assertNull($allNullable->getId());
1264
        $this->assertNull($allNullable->getLabel());
1265
        $this->assertNull($allNullable->getCountry());
1266
    }
1267
1268
    /**
1269
     * @depends testDaoGeneration
1270
     */
1271
    public function testExceptionOnMultipleInheritance()
1272
    {
1273
        $connection = self::getConnection();
1274
        self::insert($connection, 'animal', [
1275
            'id' => 99, 'name' => 'Snoofield',
1276
        ]);
1277
        self::insert($connection, 'dog', [
1278
            'id' => 99, 'race' => 'dog',
1279
        ]);
1280
        self::insert($connection, 'cat', [
1281
            'id' => 99, 'cuteness_level' => 0,
1282
        ]);
1283
1284
        $catched = false;
1285
        try {
1286
            $animalDao = new AnimalDao($this->tdbmService);
1287
            $animalDao->getById(99);
1288
        } catch (TDBMInheritanceException $e) {
1289
            $catched = true;
1290
        }
1291
        $this->assertTrue($catched, 'Exception TDBMInheritanceException was not caught');
1292
1293
        self::delete($connection, 'cat', ['id' => 99]);
1294
        self::delete($connection, 'dog', ['id' => 99]);
1295
        self::delete($connection, 'animal', ['id' => 99]);
1296
    }
1297
1298
    /**
1299
     * @depends testDaoGeneration
1300
     */
1301
    public function testReferenceNotSaved()
1302
    {
1303
        $boatDao = new BoatDao($this->tdbmService);
1304
1305
        $country = new CountryBean('Atlantis');
1306
        $boat = new BoatBean($country, 'Titanic');
1307
1308
        $boatDao->save($boat);
1309
    }
1310
1311
    /**
1312
     * @depends testDaoGeneration
1313
     */
1314
    public function testReferenceDeleted()
1315
    {
1316
        $countryDao = new CountryDao($this->tdbmService);
1317
        $boatDao = new BoatDao($this->tdbmService);
1318
1319
        $country = new CountryBean('Atlantis');
1320
        $countryDao->save($country);
1321
1322
        $boat = new BoatBean($country, 'Titanic');
1323
        $countryDao->delete($country);
1324
1325
        $this->expectException(TDBMMissingReferenceException::class);
1326
        $boatDao->save($boat);
1327
    }
1328
1329
    /**
1330
     * @depends testDaoGeneration
1331
     */
1332 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...
1333
    {
1334
        $userDao = new UserDao($this->tdbmService);
1335
1336
        $country = new CountryBean('Norrisland');
1337
        $user = new UserBean('Chuck Norris', '[email protected]', $country, 'chuck.norris');
1338
1339
        $user->setManager($user);
1340
1341
        $this->expectException(TDBMCyclicReferenceException::class);
1342
        $userDao->save($user);
1343
    }
1344
1345
    /**
1346
     * @depends testDaoGeneration
1347
     */
1348
    public function testCyclicReference()
1349
    {
1350
        $categoryDao = new CategoryDao($this->tdbmService);
1351
1352
        $category = new CategoryBean('Root');
1353
1354
        $category->setParent($category);
1355
1356
        $this->expectException(TDBMCyclicReferenceException::class);
1357
        $categoryDao->save($category);
1358
    }
1359
1360
    /**
1361
     * @depends testDaoGeneration
1362
     */
1363
    public function testCorrectTypeForPrimaryKeyAfterSave()
1364
    {
1365
        // PosqtgreSQL does not particularly like empty inserts (i.e.: "INSERT INTO all_nullable () VALUES ()" )
1366
        $this->onlyMySql();
1367
1368
        $allNullableDao = new AllNullableDao($this->tdbmService);
1369
        $allNullable = new AllNullableBean();
1370
        $allNullableDao->save($allNullable);
1371
        $id = $allNullable->getId();
1372
1373
        $this->assertTrue(is_int($id));
1374
    }
1375
1376
    /**
1377
     * @depends testDaoGeneration
1378
     */
1379
    public function testPSR2Compliance()
1380
    {
1381
        $process = new Process('vendor/bin/php-cs-fixer fix src/Test/  --dry-run --diff --rules=@PSR2');
1382
        $process->run();
1383
1384
        // executes after the command finishes
1385
        if (!$process->isSuccessful()) {
1386
            echo $process->getOutput();
1387
            $this->fail('Generated code is not PRS2 compliant');
1388
        }
1389
    }
1390
1391
    /**
1392
     * @depends testDaoGeneration
1393
     */
1394
    public function testFindOneByGeneration()
1395
    {
1396
        $reflectionMethod = new \ReflectionMethod(UserBaseDao::class, 'findOneByLogin');
1397
        $parameters = $reflectionMethod->getParameters();
1398
1399
        $this->assertCount(2, $parameters);
1400
        $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...
1401
        $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...
1402
    }
1403
1404
    /**
1405
     * @depends testDaoGeneration
1406
     */
1407 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...
1408
    {
1409
        $article = new ArticleBean('content');
1410
        $this->assertSame('content', $article->getContent());
1411
        $this->assertNotEmpty($article->getId());
1412
        $uuid = Uuid::fromString($article->getId());
1413
        $this->assertSame(1, $uuid->getVersion());
1414
    }
1415
1416
    /**
1417
     * @depends testDaoGeneration
1418
     */
1419 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...
1420
    {
1421
        $article = new Article2Bean('content');
1422
        $this->assertSame('content', $article->getContent());
1423
        $this->assertNotEmpty($article->getId());
1424
        $uuid = Uuid::fromString($article->getId());
1425
        $this->assertSame(4, $uuid->getVersion());
1426
    }
1427
1428
    /**
1429
     * @depends testDaoGeneration
1430
     */
1431
    public function testTypeHintedConstructors()
1432
    {
1433
        $userBaseBeanReflectionConstructor = new \ReflectionMethod(UserBaseBean::class, '__construct');
1434
        $nameParam = $userBaseBeanReflectionConstructor->getParameters()[0];
1435
1436
        $this->assertSame('string', (string) $nameParam->getType());
1437
    }
1438
1439
    /**
1440
     * @depends testDaoGeneration
1441
     */
1442
    public function testSaveTransaction()
1443
    {
1444
        $countryDao = new CountryDao($this->tdbmService);
1445
1446
        $boatDao = new BoatDao($this->tdbmService);
1447
        $boatBean = $boatDao->getById(1);
1448
        $boatBean->setName('Bismark');
1449
1450
        $boatBean->getCountry();
1451
1452
        // Let's insert a row without telling TDBM to trigger an error!
1453
        self::insert($this->getConnection(), 'sailed_countries', [
1454
            'boat_id' => 1,
1455
            'country_id' => 2
1456
        ]);
1457
1458
        $boatBean->addCountry($countryDao->getById(2));
1459
1460
        $this->expectException(UniqueConstraintViolationException::class);
1461
1462
        $boatDao->save($boatBean);
1463
    }
1464
1465
    /**
1466
     * @depends testSaveTransaction
1467
     */
1468
    public function testSaveTransaction2()
1469
    {
1470
        $boatDao = new BoatDao($this->tdbmService);
1471
        $boatBean = $boatDao->getById(1);
1472
1473
        // The name should not have been saved because the transaction of the previous test should have rollbacked.
1474
        $this->assertNotSame('Bismark', $boatBean->getName());
1475
    }
1476
1477
    public function testForeignKeyPointingToNonPrimaryKey()
1478
    {
1479
        $dao = new RefNoPrimKeyDao($this->tdbmService);
1480
        $bean = $dao->getById(1);
1481
1482
        $this->assertSame('foo', $bean->getFrom()->getTo());
1483
    }
1484
}
1485