Passed
Pull Request — master (#52)
by David
08:24
created

testCreateEmptyExtendedBean()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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