Failed Conditions
Pull Request — master (#6485)
by Alessandro
12:30
created

BasicFunctionalTest   F

Complexity

Total Complexity 47

Size/Duplication

Total Lines 1277
Duplicated Lines 7.75 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 0
Metric Value
wmc 47
lcom 1
cbo 14
dl 99
loc 1277
rs 2.891
c 0
b 0
f 0

43 Methods

Rating   Name   Duplication   Size   Complexity  
B testBasicOneToOne() 0 35 1
B testRemove() 0 30 1
B testBasicQuery() 0 36 1
A testBasicOneToManyInnerJoin() 0 15 1
A setUp() 0 5 1
A testBasicUnitsOfWorkWithOneToManyAssociation() 0 51 1
B testOneToManyAssociationModification() 0 27 1
A testBasicOneToManyLeftJoin() 0 21 1
A testBasicRefresh() 0 16 1
B testRefreshResetsCollection() 0 28 1
B testDqlRefreshResetsCollection() 0 32 1
B testCreateEntityOfProxy() 0 32 1
B testSetSetAssociationWithGetReference() 0 38 1
B testTextColumnSaveAndRetrieve() 0 36 1
B testFlushDoesNotIssueUnnecessaryUpdates() 0 43 1
A testRemoveEntityByReference() 0 22 1
B testQueryEntityByReference() 0 33 1
B testOneToOneNullUpdate() 0 25 1
A testNewAssociatedEntityDuringFlushThrowsException() 0 20 1
B testNewAssociatedEntityDuringFlushThrowsException2() 0 28 1
A testNewAssociatedEntityDuringFlushThrowsException3() 0 17 1
A testOneToOneOrphanRemoval() 0 48 1
A testGetPartialReferenceToUpdateObjectWithoutLoadingIt() 0 22 1
A testMergePersistsNewEntities() 0 22 1
B testMergeNonPersistedProperties() 0 26 1
B testOneToOneMergeSetNull() 0 25 1
B testManyToOneFetchModeQuery() 0 27 1
B testClearWithEntityName() 0 45 1
B testFlushManyExplicitEntities() 0 30 1
A testFlushSingleAndNewEntity() 0 23 1
A testFlushAndCascadePersist() 0 23 1
B testProxyIsIgnored() 0 24 1
B testFlushSingleSaveOnlySingle() 0 25 1
A testWrongAssociationInstance() 0 18 1
B testOneToManyOrphanRemoval() 5 31 2
B testAddToCollectionDoesNotInitialize() 5 39 2
B testInitializeCollectionWithNewObjectsRetainsNewObjects() 5 40 2
B testOneToManyCascadeRemove() 5 33 2
A testMergeThrowsExceptionIfEntityWithGeneratedIdentifierDoesNotExist() 11 11 1
A testFlushSingleManagedEntity() 17 17 1
A testFlushSingleUnmanagedEntity() 12 12 1
A testFlushSingleAndNoCascade() 21 21 1
A testFlushSingleNewEntityThenRemove() 18 18 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like BasicFunctionalTest often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use BasicFunctionalTest, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Doctrine\Tests\ORM\Functional;
4
5
use Doctrine\DBAL\Logging\DebugStack;
6
use Doctrine\ORM\EntityNotFoundException;
7
use Doctrine\ORM\Mapping\ClassMetadata;
8
use Doctrine\ORM\ORMInvalidArgumentException;
9
use Doctrine\ORM\PersistentCollection;
10
use Doctrine\ORM\Proxy\Proxy;
11
use Doctrine\ORM\Query;
12
use Doctrine\ORM\UnitOfWork;
13
use Doctrine\Tests\Models\CMS\CmsAddress;
14
use Doctrine\Tests\Models\CMS\CmsArticle;
15
use Doctrine\Tests\Models\CMS\CmsComment;
16
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
17
use Doctrine\Tests\Models\CMS\CmsUser;
18
use Doctrine\Tests\OrmFunctionalTestCase;
19
20
class BasicFunctionalTest extends OrmFunctionalTestCase
21
{
22
    protected function setUp()
23
    {
24
        $this->useModelSet('cms');
25
        parent::setUp();
26
    }
27
28
    public function testBasicUnitsOfWorkWithOneToManyAssociation()
29
    {
30
        // Create
31
        $user = new CmsUser;
32
        $user->name = 'Roman';
33
        $user->username = 'romanb';
34
        $user->status = 'developer';
35
        $this->_em->persist($user);
36
37
        $this->_em->flush();
38
39
        $this->assertTrue(is_numeric($user->id));
40
        $this->assertTrue($this->_em->contains($user));
41
42
        // Read
43
        $user2 = $this->_em->find(CmsUser::class, $user->id);
44
        $this->assertTrue($user === $user2);
45
46
        // Add a phonenumber
47
        $ph = new CmsPhonenumber;
48
        $ph->phonenumber = "12345";
49
        $user->addPhonenumber($ph);
50
        $this->_em->flush();
51
        $this->assertTrue($this->_em->contains($ph));
52
        $this->assertTrue($this->_em->contains($user));
53
54
        // Update name
55
        $user->name = 'guilherme';
56
        $this->_em->flush();
57
        $this->assertEquals('guilherme', $user->name);
58
59
        // Add another phonenumber
60
        $ph2 = new CmsPhonenumber;
61
        $ph2->phonenumber = "6789";
62
        $user->addPhonenumber($ph2);
63
        $this->_em->flush();
64
        $this->assertTrue($this->_em->contains($ph2));
65
66
        // Delete
67
        $this->_em->remove($user);
68
        $this->assertTrue($this->_em->getUnitOfWork()->isScheduledForDelete($user));
69
        $this->assertTrue($this->_em->getUnitOfWork()->isScheduledForDelete($ph));
70
        $this->assertTrue($this->_em->getUnitOfWork()->isScheduledForDelete($ph2));
71
        $this->_em->flush();
72
        $this->assertFalse($this->_em->getUnitOfWork()->isScheduledForDelete($user));
73
        $this->assertFalse($this->_em->getUnitOfWork()->isScheduledForDelete($ph));
74
        $this->assertFalse($this->_em->getUnitOfWork()->isScheduledForDelete($ph2));
75
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user));
76
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($ph));
77
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($ph2));
78
    }
79
80
    public function testOneToManyAssociationModification()
81
    {
82
        $user = new CmsUser;
83
        $user->name = 'Roman';
84
        $user->username = 'romanb';
85
        $user->status = 'developer';
86
87
        $ph1 = new CmsPhonenumber;
88
        $ph1->phonenumber = "0301234";
89
        $ph2 = new CmsPhonenumber;
90
        $ph2->phonenumber = "987654321";
91
92
        $user->addPhonenumber($ph1);
93
        $user->addPhonenumber($ph2);
94
95
        $this->_em->persist($user);
96
        $this->_em->flush();
97
98
        // Remove the first element from the collection
99
        unset($user->phonenumbers[0]);
100
        $ph1->user = null; // owning side!
101
102
        $this->_em->flush();
103
104
        $this->assertEquals(1, count($user->phonenumbers));
105
        $this->assertNull($ph1->user);
106
    }
107
108
    public function testBasicOneToOne()
109
    {
110
        //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% 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...
111
        $user = new CmsUser;
112
        $user->name = 'Roman';
113
        $user->username = 'romanb';
114
        $user->status = 'developer';
115
116
        $address = new CmsAddress;
117
        $address->country = 'Germany';
118
        $address->city = 'Berlin';
119
        $address->zip = '12345';
120
121
        $user->address = $address; // inverse side
122
        $address->user = $user; // owning side!
123
124
        $this->_em->persist($user);
125
        $this->_em->flush();
126
127
        // Check that the foreign key has been set
128
        $userId = $this->_em->getConnection()->executeQuery(
129
            "SELECT user_id FROM cms_addresses WHERE id=?", [$address->id]
130
        )->fetchColumn();
131
        $this->assertTrue(is_numeric($userId));
132
133
        $this->_em->clear();
134
135
        $user2 = $this->_em->createQuery('select u from \Doctrine\Tests\Models\CMS\CmsUser u where u.id=?1')
136
                ->setParameter(1, $userId)
137
                ->getSingleResult();
138
139
        // Address has been eager-loaded because it cant be lazy
140
        $this->assertInstanceOf(CmsAddress::class, $user2->address);
141
        $this->assertNotInstanceOf(Proxy::class, $user2->address);
142
    }
143
144
    /**
145
     * @group DDC-1230
146
     */
147
    public function testRemove()
148
    {
149
        $user = new CmsUser;
150
        $user->name = 'Guilherme';
151
        $user->username = 'gblanco';
152
        $user->status = 'developer';
153
154
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW");
155
156
        $this->_em->persist($user);
157
158
        $this->assertEquals(UnitOfWork::STATE_MANAGED, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_MANAGED");
159
160
        $this->_em->remove($user);
161
162
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW");
163
164
        $this->_em->persist($user);
165
        $this->_em->flush();
166
        $id = $user->getId();
167
168
        $this->_em->remove($user);
169
170
        $this->assertEquals(UnitOfWork::STATE_REMOVED, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_REMOVED");
171
        $this->_em->flush();
172
173
        $this->assertEquals(UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW");
174
175
        $this->assertNull($this->_em->find(CmsUser::class, $id));
176
    }
177
178
    public function testOneToManyOrphanRemoval()
179
    {
180
        $user = new CmsUser;
181
        $user->name = 'Guilherme';
182
        $user->username = 'gblanco';
183
        $user->status = 'developer';
184
185 View Code Duplication
        for ($i=0; $i<3; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
186
            $phone = new CmsPhonenumber;
187
            $phone->phonenumber = 100 + $i;
188
            $user->addPhonenumber($phone);
189
        }
190
191
        $this->_em->persist($user);
192
193
        $this->_em->flush();
194
195
        $user->getPhonenumbers()->remove(0);
196
        $this->assertEquals(2, count($user->getPhonenumbers()));
197
198
        $this->_em->flush();
199
200
        // Check that there are just 2 phonenumbers left
201
        $count = $this->_em->getConnection()->fetchColumn("SELECT COUNT(*) FROM cms_phonenumbers");
202
        $this->assertEquals(2, $count); // only 2 remaining
203
204
        // check that clear() removes the others via orphan removal
205
        $user->getPhonenumbers()->clear();
206
        $this->_em->flush();
207
        $this->assertEquals(0, $this->_em->getConnection()->fetchColumn("select count(*) from cms_phonenumbers"));
208
    }
209
210
    public function testBasicQuery()
211
    {
212
        $user = new CmsUser;
213
        $user->name = 'Guilherme';
214
        $user->username = 'gblanco';
215
        $user->status = 'developer';
216
        $this->_em->persist($user);
217
        $this->_em->flush();
218
219
        $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u");
220
221
        $users = $query->getResult();
222
223
        $this->assertEquals(1, count($users));
224
        $this->assertEquals('Guilherme', $users[0]->name);
225
        $this->assertEquals('gblanco', $users[0]->username);
226
        $this->assertEquals('developer', $users[0]->status);
227
        //$this->assertNull($users[0]->phonenumbers);
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
228
        //$this->assertNull($users[0]->articles);
0 ignored issues
show
Unused Code Comprehensibility introduced by
84% 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...
229
230
        $usersArray = $query->getArrayResult();
231
232
        $this->assertTrue(is_array($usersArray));
233
        $this->assertEquals(1, count($usersArray));
234
        $this->assertEquals('Guilherme', $usersArray[0]['name']);
235
        $this->assertEquals('gblanco', $usersArray[0]['username']);
236
        $this->assertEquals('developer', $usersArray[0]['status']);
237
238
        $usersScalar = $query->getScalarResult();
239
240
        $this->assertTrue(is_array($usersScalar));
241
        $this->assertEquals(1, count($usersScalar));
242
        $this->assertEquals('Guilherme', $usersScalar[0]['u_name']);
243
        $this->assertEquals('gblanco', $usersScalar[0]['u_username']);
244
        $this->assertEquals('developer', $usersScalar[0]['u_status']);
245
    }
246
247
    public function testBasicOneToManyInnerJoin()
248
    {
249
        $user = new CmsUser;
250
        $user->name = 'Guilherme';
251
        $user->username = 'gblanco';
252
        $user->status = 'developer';
253
        $this->_em->persist($user);
254
        $this->_em->flush();
255
256
        $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u join u.phonenumbers p");
257
258
        $users = $query->getResult();
259
260
        $this->assertEquals(0, count($users));
261
    }
262
263
    public function testBasicOneToManyLeftJoin()
264
    {
265
        $user = new CmsUser;
266
        $user->name = 'Guilherme';
267
        $user->username = 'gblanco';
268
        $user->status = 'developer';
269
        $this->_em->persist($user);
270
        $this->_em->flush();
271
272
        $query = $this->_em->createQuery("select u,p from Doctrine\Tests\Models\CMS\CmsUser u left join u.phonenumbers p");
273
274
        $users = $query->getResult();
275
276
        $this->assertEquals(1, count($users));
277
        $this->assertEquals('Guilherme', $users[0]->name);
278
        $this->assertEquals('gblanco', $users[0]->username);
279
        $this->assertEquals('developer', $users[0]->status);
280
        $this->assertInstanceOf(PersistentCollection::class, $users[0]->phonenumbers);
281
        $this->assertTrue($users[0]->phonenumbers->isInitialized());
282
        $this->assertEquals(0, $users[0]->phonenumbers->count());
283
    }
284
285
    public function testBasicRefresh()
286
    {
287
        $user = new CmsUser;
288
        $user->name = 'Guilherme';
289
        $user->username = 'gblanco';
290
        $user->status = 'developer';
291
292
        $this->_em->persist($user);
293
        $this->_em->flush();
294
295
        $user->status = 'mascot';
296
297
        $this->assertEquals('mascot', $user->status);
298
        $this->_em->refresh($user);
299
        $this->assertEquals('developer', $user->status);
300
    }
301
302
    /**
303
     * @group DDC-833
304
     */
305
    public function testRefreshResetsCollection()
306
    {
307
        $user = new CmsUser;
308
        $user->name = 'Guilherme';
309
        $user->username = 'gblanco';
310
        $user->status = 'developer';
311
312
        // Add a phonenumber
313
        $ph1 = new CmsPhonenumber;
314
        $ph1->phonenumber = "12345";
315
        $user->addPhonenumber($ph1);
316
317
        // Add a phonenumber
318
        $ph2 = new CmsPhonenumber;
319
        $ph2->phonenumber = "54321";
320
321
        $this->_em->persist($user);
322
        $this->_em->persist($ph1);
323
        $this->_em->persist($ph2);
324
        $this->_em->flush();
325
326
        $user->addPhonenumber($ph2);
327
328
        $this->assertEquals(2, count($user->phonenumbers));
329
        $this->_em->refresh($user);
330
331
        $this->assertEquals(1, count($user->phonenumbers));
332
    }
333
334
    /**
335
     * @group DDC-833
336
     */
337
    public function testDqlRefreshResetsCollection()
338
    {
339
        $user = new CmsUser;
340
        $user->name = 'Guilherme';
341
        $user->username = 'gblanco';
342
        $user->status = 'developer';
343
344
        // Add a phonenumber
345
        $ph1 = new CmsPhonenumber;
346
        $ph1->phonenumber = "12345";
347
        $user->addPhonenumber($ph1);
348
349
        // Add a phonenumber
350
        $ph2 = new CmsPhonenumber;
351
        $ph2->phonenumber = "54321";
352
353
        $this->_em->persist($user);
354
        $this->_em->persist($ph1);
355
        $this->_em->persist($ph2);
356
        $this->_em->flush();
357
358
        $user->addPhonenumber($ph2);
359
360
        $this->assertEquals(2, count($user->phonenumbers));
361
        $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1";
362
        $user = $this->_em->createQuery($dql)
363
                          ->setParameter(1, $user->id)
364
                          ->setHint(Query::HINT_REFRESH, true)
365
                          ->getSingleResult();
366
367
        $this->assertEquals(1, count($user->phonenumbers));
368
    }
369
370
    /**
371
     * @group DDC-833
372
     */
373
    public function testCreateEntityOfProxy()
374
    {
375
        $user = new CmsUser;
376
        $user->name = 'Guilherme';
377
        $user->username = 'gblanco';
378
        $user->status = 'developer';
379
380
        // Add a phonenumber
381
        $ph1 = new CmsPhonenumber;
382
        $ph1->phonenumber = "12345";
383
        $user->addPhonenumber($ph1);
384
385
        // Add a phonenumber
386
        $ph2 = new CmsPhonenumber;
387
        $ph2->phonenumber = "54321";
388
389
        $this->_em->persist($user);
390
        $this->_em->persist($ph1);
391
        $this->_em->persist($ph2);
392
        $this->_em->flush();
393
        $this->_em->clear();
394
395
        $userId = $user->id;
396
        $user = $this->_em->getReference(CmsUser::class, $user->id);
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...
397
398
        $dql = "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1";
399
        $user = $this->_em->createQuery($dql)
400
                          ->setParameter(1, $userId)
401
                          ->getSingleResult();
402
403
        $this->assertEquals(1, count($user->phonenumbers));
404
    }
405
406
    public function testAddToCollectionDoesNotInitialize()
407
    {
408
        $user = new CmsUser;
409
        $user->name = 'Guilherme';
410
        $user->username = 'gblanco';
411
        $user->status = 'developer';
412
413 View Code Duplication
        for ($i=0; $i<3; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
414
            $phone = new CmsPhonenumber;
415
            $phone->phonenumber = 100 + $i;
416
            $user->addPhonenumber($phone);
417
        }
418
419
        $this->_em->persist($user);
420
        $this->_em->flush();
421
        $this->_em->clear();
422
423
        $this->assertEquals(3, $user->getPhonenumbers()->count());
424
425
        $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username='gblanco'");
426
427
        $gblanco = $query->getSingleResult();
428
429
        $this->assertFalse($gblanco->getPhonenumbers()->isInitialized());
430
431
        $newPhone = new CmsPhonenumber;
432
        $newPhone->phonenumber = 555;
433
        $gblanco->addPhonenumber($newPhone);
434
435
        $this->assertFalse($gblanco->getPhonenumbers()->isInitialized());
436
        $this->_em->persist($gblanco);
437
438
        $this->_em->flush();
439
        $this->_em->clear();
440
441
        $query = $this->_em->createQuery("select u, p from Doctrine\Tests\Models\CMS\CmsUser u join u.phonenumbers p where u.username='gblanco'");
442
        $gblanco2 = $query->getSingleResult();
443
        $this->assertEquals(4, $gblanco2->getPhonenumbers()->count());
444
    }
445
446
    public function testInitializeCollectionWithNewObjectsRetainsNewObjects()
447
    {
448
        $user = new CmsUser;
449
        $user->name = 'Guilherme';
450
        $user->username = 'gblanco';
451
        $user->status = 'developer';
452
453 View Code Duplication
        for ($i=0; $i<3; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
454
            $phone = new CmsPhonenumber;
455
            $phone->phonenumber = 100 + $i;
456
            $user->addPhonenumber($phone);
457
        }
458
459
        $this->_em->persist($user);
460
        $this->_em->flush();
461
        $this->_em->clear();
462
463
        $this->assertEquals(3, $user->getPhonenumbers()->count());
464
465
        $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username='gblanco'");
466
467
        $gblanco = $query->getSingleResult();
468
469
        $this->assertFalse($gblanco->getPhonenumbers()->isInitialized());
470
471
        $newPhone = new CmsPhonenumber;
472
        $newPhone->phonenumber = 555;
473
        $gblanco->addPhonenumber($newPhone);
474
475
        $this->assertFalse($gblanco->getPhonenumbers()->isInitialized());
476
        $this->assertEquals(4, $gblanco->getPhonenumbers()->count());
477
        $this->assertTrue($gblanco->getPhonenumbers()->isInitialized());
478
479
        $this->_em->flush();
480
        $this->_em->clear();
481
482
        $query = $this->_em->createQuery("select u, p from Doctrine\Tests\Models\CMS\CmsUser u join u.phonenumbers p where u.username='gblanco'");
483
        $gblanco2 = $query->getSingleResult();
484
        $this->assertEquals(4, $gblanco2->getPhonenumbers()->count());
485
    }
486
487
    public function testSetSetAssociationWithGetReference()
488
    {
489
        $user = new CmsUser;
490
        $user->name = 'Guilherme';
491
        $user->username = 'gblanco';
492
        $user->status = 'developer';
493
        $this->_em->persist($user);
494
495
        $address = new CmsAddress;
496
        $address->country = 'Germany';
497
        $address->city = 'Berlin';
498
        $address->zip = '12345';
499
        $this->_em->persist($address);
500
501
        $this->_em->flush();
502
        $this->_em->detach($address);
503
504
        $this->assertFalse($this->_em->contains($address));
505
        $this->assertTrue($this->_em->contains($user));
506
507
        // Assume we only got the identifier of the address and now want to attach
508
        // that address to the user without actually loading it, using getReference().
509
        $addressRef = $this->_em->getReference(CmsAddress::class, $address->getId());
510
511
        $user->setAddress($addressRef); // Ugh! Initializes address 'cause of $address->setUser($user)!
0 ignored issues
show
Documentation introduced by
$addressRef is of type object|null, but the function expects a object<Doctrine\Tests\Models\CMS\CmsAddress>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
512
513
        $this->_em->flush();
514
        $this->_em->clear();
515
516
        // Check with a fresh load that the association is indeed there
517
        $query = $this->_em->createQuery("select u, a from Doctrine\Tests\Models\CMS\CmsUser u join u.address a where u.username='gblanco'");
518
        $gblanco = $query->getSingleResult();
519
520
        $this->assertInstanceOf(CmsUser::class, $gblanco);
521
        $this->assertInstanceOf(CmsAddress::class, $gblanco->getAddress());
522
        $this->assertEquals('Berlin', $gblanco->getAddress()->getCity());
523
524
    }
525
526
    public function testOneToManyCascadeRemove()
527
    {
528
        $user = new CmsUser;
529
        $user->name = 'Guilherme';
530
        $user->username = 'gblanco';
531
        $user->status = 'developer';
532
533 View Code Duplication
        for ($i=0; $i<3; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
534
            $phone = new CmsPhonenumber;
535
            $phone->phonenumber = 100 + $i;
536
            $user->addPhonenumber($phone);
537
        }
538
539
        $this->_em->persist($user);
540
        $this->_em->flush();
541
        $this->_em->clear();
542
543
        $query = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u where u.username='gblanco'");
544
        $gblanco = $query->getSingleResult();
545
546
        $this->_em->remove($gblanco);
547
        $this->_em->flush();
548
549
        $this->_em->clear();
550
551
        $this->assertEquals(0, $this->_em->createQuery(
552
                "select count(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p")
553
                ->getSingleScalarResult());
554
555
        $this->assertEquals(0, $this->_em->createQuery(
556
                "select count(u.id) from Doctrine\Tests\Models\CMS\CmsUser u")
557
                ->getSingleScalarResult());
558
    }
559
560
    public function testTextColumnSaveAndRetrieve()
561
    {
562
        $user = new CmsUser;
563
        $user->name = 'Guilherme';
564
        $user->username = 'gblanco';
565
        $user->status = 'developer';
566
567
        $this->_em->persist($user);
568
569
        $article = new CmsArticle();
570
        $article->text = "Lorem ipsum dolor sunt.";
571
        $article->topic = "A Test Article!";
572
        $article->setAuthor($user);
573
574
        $this->_em->persist($article);
575
        $this->_em->flush();
576
        $articleId = $article->id;
577
578
        $this->_em->clear();
579
580
        // test find() with leading backslash at the same time
581
        $articleNew = $this->_em->find('\Doctrine\Tests\Models\CMS\CmsArticle', $articleId);
582
        $this->assertTrue($this->_em->contains($articleNew));
0 ignored issues
show
Bug introduced by
It seems like $articleNew defined by $this->_em->find('\\Doct...msArticle', $articleId) on line 581 can also be of type null; however, Doctrine\ORM\EntityManager::contains() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
583
        $this->assertEquals("Lorem ipsum dolor sunt.", $articleNew->text);
584
585
        $this->assertNotSame($article, $articleNew);
586
587
        $articleNew->text = "Lorem ipsum dolor sunt. And stuff!";
588
589
        $this->_em->flush();
590
        $this->_em->clear();
591
592
        $articleNew = $this->_em->find(CmsArticle::class, $articleId);
593
        $this->assertEquals("Lorem ipsum dolor sunt. And stuff!", $articleNew->text);
594
        $this->assertTrue($this->_em->contains($articleNew));
595
    }
596
597
    public function testFlushDoesNotIssueUnnecessaryUpdates()
598
    {
599
        $user = new CmsUser;
600
        $user->name = 'Guilherme';
601
        $user->username = 'gblanco';
602
        $user->status = 'developer';
603
604
        $address = new CmsAddress;
605
        $address->country = 'Germany';
606
        $address->city = 'Berlin';
607
        $address->zip = '12345';
608
609
        $address->user = $user;
610
        $user->address = $address;
611
612
        $article = new CmsArticle();
613
        $article->text = "Lorem ipsum dolor sunt.";
614
        $article->topic = "A Test Article!";
615
        $article->setAuthor($user);
616
617
        $this->_em->persist($article);
618
        $this->_em->persist($user);
619
620
        //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% 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...
621
622
        $this->_em->flush();
623
        $this->_em->clear();
624
625
        $query = $this->_em->createQuery('select u,a,ad from Doctrine\Tests\Models\CMS\CmsUser u join u.articles a join u.address ad');
626
        $user2 = $query->getSingleResult();
627
628
        $this->assertEquals(1, count($user2->articles));
629
        $this->assertInstanceOf(CmsAddress::class, $user2->address);
630
631
        $oldLogger = $this->_em->getConnection()->getConfiguration()->getSQLLogger();
632
        $debugStack = new DebugStack();
633
        $this->_em->getConnection()->getConfiguration()->setSQLLogger($debugStack);
634
635
        $this->_em->flush();
636
        $this->assertEquals(0, count($debugStack->queries));
637
638
        $this->_em->getConnection()->getConfiguration()->setSQLLogger($oldLogger);
639
    }
640
641
    public function testRemoveEntityByReference()
642
    {
643
        $user = new CmsUser;
644
        $user->name = 'Guilherme';
645
        $user->username = 'gblanco';
646
        $user->status = 'developer';
647
648
        //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% 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...
649
650
        $this->_em->persist($user);
651
        $this->_em->flush();
652
        $this->_em->clear();
653
654
        $userRef = $this->_em->getReference(CmsUser::class, $user->getId());
655
        $this->_em->remove($userRef);
0 ignored issues
show
Bug introduced by
It seems like $userRef defined by $this->_em->getReference...:class, $user->getId()) on line 654 can also be of type null; however, Doctrine\ORM\EntityManager::remove() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
656
        $this->_em->flush();
657
        $this->_em->clear();
658
659
        $this->assertEquals(0, $this->_em->getConnection()->fetchColumn("select count(*) from cms_users"));
660
661
        //$this->_em->getConnection()->getConfiguration()->setSQLLogger(null);
0 ignored issues
show
Unused Code Comprehensibility introduced by
77% 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...
662
    }
663
664
    public function testQueryEntityByReference()
665
    {
666
        $user = new CmsUser;
667
        $user->name = 'Guilherme';
668
        $user->username = 'gblanco';
669
        $user->status = 'developer';
670
671
        $address = new CmsAddress;
672
        $address->country = 'Germany';
673
        $address->city = 'Berlin';
674
        $address->zip = '12345';
675
676
        $user->setAddress($address);
677
678
        $this->_em->transactional(function($em) use($user) {
679
            $em->persist($user);
680
        });
681
        $this->_em->clear();
682
683
        //$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% 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...
684
685
        $userRef = $this->_em->getReference(CmsUser::class, $user->getId());
686
        $address2 = $this->_em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsAddress a where a.user = :user')
687
                ->setParameter('user', $userRef)
688
                ->getSingleResult();
689
690
        $this->assertInstanceOf(Proxy::class, $address2->getUser());
691
        $this->assertTrue($userRef === $address2->getUser());
692
        $this->assertFalse($userRef->__isInitialized__);
693
        $this->assertEquals('Germany', $address2->country);
694
        $this->assertEquals('Berlin', $address2->city);
695
        $this->assertEquals('12345', $address2->zip);
696
    }
697
698
    public function testOneToOneNullUpdate()
699
    {
700
        $user = new CmsUser();
701
        $user->username = "beberlei";
702
        $user->name = "Benjamin E.";
703
        $user->status = 'active';
704
705
        $address = new CmsAddress();
706
        $address->city = "Bonn";
707
        $address->zip = "12354";
708
        $address->country = "Germany";
709
        $address->street = "somestreet";
710
        $address->user = $user;
711
712
        $this->_em->persist($address);
713
        $this->_em->persist($user);
714
        $this->_em->flush();
715
716
        $this->assertEquals(1, $this->_em->getConnection()->fetchColumn("select 1 from cms_addresses where user_id = ".$user->id));
717
718
        $address->user = null;
719
        $this->_em->flush();
720
721
        $this->assertNotEquals(1, $this->_em->getConnection()->fetchColumn("select 1 from cms_addresses where user_id = ".$user->id));
722
    }
723
724
    /**
725
     * @group DDC-600
726
     * @group DDC-455
727
     */
728
    public function testNewAssociatedEntityDuringFlushThrowsException()
729
    {
730
        $user = new CmsUser();
731
        $user->username = "beberlei";
732
        $user->name = "Benjamin E.";
733
        $user->status = 'active';
734
735
        $address = new CmsAddress();
736
        $address->city = "Bonn";
737
        $address->zip = "12354";
738
        $address->country = "Germany";
739
        $address->street = "somestreet";
740
        $address->user = $user;
741
742
        $this->_em->persist($address);
743
744
        // flushing without persisting $user should raise an exception
745
        $this->expectException(\InvalidArgumentException::class);
746
        $this->_em->flush();
747
    }
748
749
    /**
750
     * @group DDC-600
751
     * @group DDC-455
752
     */
753
    public function testNewAssociatedEntityDuringFlushThrowsException2()
754
    {
755
        $user = new CmsUser();
756
        $user->username = "beberlei";
757
        $user->name = "Benjamin E.";
758
        $user->status = 'active';
759
760
        $address = new CmsAddress();
761
        $address->city = "Bonn";
762
        $address->zip = "12354";
763
        $address->country = "Germany";
764
        $address->street = "somestreet";
765
        $address->user = $user;
766
767
        $this->_em->persist($address);
768
        $this->_em->persist($user);
769
        $this->_em->flush();
770
771
        $u2 = new CmsUser;
772
        $u2->username = "beberlei";
773
        $u2->name = "Benjamin E.";
774
        $u2->status = 'inactive';
775
        $address->user = $u2;
776
777
        // flushing without persisting $u2 should raise an exception
778
        $this->expectException(\InvalidArgumentException::class);
779
        $this->_em->flush();
780
    }
781
782
    /**
783
     * @group DDC-600
784
     * @group DDC-455
785
     */
786
    public function testNewAssociatedEntityDuringFlushThrowsException3()
787
    {
788
        $art = new CmsArticle();
789
        $art->topic = 'topic';
790
        $art->text = 'the text';
791
792
        $com = new CmsComment();
793
        $com->topic = 'Good';
794
        $com->text = 'Really good!';
795
        $art->addComment($com);
796
797
        $this->_em->persist($art);
798
799
        // flushing without persisting $com should raise an exception
800
        $this->expectException(\InvalidArgumentException::class);
801
        $this->_em->flush();
802
    }
803
804
    public function testOneToOneOrphanRemoval()
805
    {
806
        $user = new CmsUser();
807
        $user->username = "beberlei";
808
        $user->name = "Benjamin E.";
809
        $user->status = 'active';
810
811
        $address = new CmsAddress();
812
        $address->city = "Bonn";
813
        $address->zip = "12354";
814
        $address->country = "Germany";
815
        $address->street = "somestreet";
816
        $address->user = $user;
817
        $user->address = $address;
818
819
        $this->_em->persist($address);
820
        $this->_em->persist($user);
821
        $this->_em->flush();
822
        $addressId = $address->getId();
0 ignored issues
show
Unused Code introduced by
$addressId 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...
823
824
        $user->address = null;
825
826
        $this->_em->flush();
827
828
        $this->assertEquals(0, $this->_em->getConnection()->fetchColumn("select count(*) from cms_addresses"));
829
830
        // check orphan removal through replacement
831
        $user->address = $address;
832
        $address->user = $user;
833
834
        $this->_em->flush();
835
        $this->assertEquals(1, $this->_em->getConnection()->fetchColumn("select count(*) from cms_addresses"));
836
837
        // remove $address to free up unique key id
838
        $this->_em->remove($address);
839
        $this->_em->flush();
840
841
        $newAddress = new CmsAddress();
842
        $newAddress->city = "NewBonn";
843
        $newAddress->zip = "12354";
844
        $newAddress->country = "NewGermany";
845
        $newAddress->street = "somenewstreet";
846
        $newAddress->user = $user;
847
        $user->address = $newAddress;
848
849
        $this->_em->flush();
850
        $this->assertEquals(1, $this->_em->getConnection()->fetchColumn("select count(*) from cms_addresses"));
851
    }
852
853
    public function testGetPartialReferenceToUpdateObjectWithoutLoadingIt()
854
    {
855
        $user = new CmsUser();
856
        $user->username = "beberlei";
857
        $user->name = "Benjamin E.";
858
        $user->status = 'active';
859
        $this->_em->persist($user);
860
        $this->_em->flush();
861
        $userId = $user->id;
862
        $this->_em->clear();
863
864
        $user = $this->_em->getPartialReference(CmsUser::class, $userId);
865
        $this->assertTrue($this->_em->contains($user));
866
        $this->assertNull($user->getName());
867
        $this->assertEquals($userId, $user->id);
868
869
        $user->name = 'Stephan';
870
        $this->_em->flush();
871
        $this->_em->clear();
872
873
        $this->assertEquals('Benjamin E.', $this->_em->find(get_class($user), $userId)->name);
874
    }
875
876
    public function testMergePersistsNewEntities()
877
    {
878
        $user = new CmsUser();
879
        $user->username = "beberlei";
880
        $user->name = "Benjamin E.";
881
        $user->status = 'active';
882
883
        $managedUser = $this->_em->merge($user);
884
        $this->assertEquals('beberlei', $managedUser->username);
885
        $this->assertEquals('Benjamin E.', $managedUser->name);
886
        $this->assertEquals('active', $managedUser->status);
887
888
        $this->assertTrue($user !== $managedUser);
889
        $this->assertTrue($this->_em->contains($managedUser));
890
891
        $this->_em->flush();
892
        $userId = $managedUser->id;
893
        $this->_em->clear();
894
895
        $user2 = $this->_em->find(get_class($managedUser), $userId);
896
        $this->assertInstanceOf(CmsUser::class, $user2);
897
    }
898
899
    public function testMergeNonPersistedProperties()
900
    {
901
        $user = new CmsUser();
902
        $user->username = "beberlei";
903
        $user->name = "Benjamin E.";
904
        $user->status = 'active';
905
        $user->nonPersistedProperty = 'test';
906
        $user->nonPersistedPropertyObject = new CmsPhonenumber();
907
908
        $managedUser = $this->_em->merge($user);
909
        $this->assertEquals('test', $managedUser->nonPersistedProperty);
910
        $this->assertSame($user->nonPersistedProperty, $managedUser->nonPersistedProperty);
911
        $this->assertSame($user->nonPersistedPropertyObject, $managedUser->nonPersistedPropertyObject);
912
913
        $this->assertTrue($user !== $managedUser);
914
        $this->assertTrue($this->_em->contains($managedUser));
915
916
        $this->_em->flush();
917
        $userId = $managedUser->id;
918
        $this->_em->clear();
919
920
        $user2 = $this->_em->find(get_class($managedUser), $userId);
921
        $this->assertNull($user2->nonPersistedProperty);
922
        $this->assertNull($user2->nonPersistedPropertyObject);
923
        $this->assertEquals('active', $user2->status);
924
    }
925
926 View Code Duplication
    public function testMergeThrowsExceptionIfEntityWithGeneratedIdentifierDoesNotExist()
927
    {
928
        $user = new CmsUser();
929
        $user->username = "beberlei";
930
        $user->name = "Benjamin E.";
931
        $user->status = 'active';
932
        $user->id = 42;
933
934
        $this->expectException(EntityNotFoundException::class);
935
        $this->_em->merge($user);
936
    }
937
938
    /**
939
     * @group DDC-634
940
     */
941
    public function testOneToOneMergeSetNull()
942
    {
943
        $user = new CmsUser();
944
        $user->username = "beberlei";
945
        $user->name = "Benjamin E.";
946
        $user->status = 'active';
947
948
        $ph = new CmsPhonenumber();
949
        $ph->phonenumber = "12345";
950
        $user->addPhonenumber($ph);
951
952
        $this->_em->persist($user);
953
        $this->_em->persist($ph);
954
        $this->_em->flush();
955
956
        $this->_em->clear();
957
958
        $ph->user = null;
959
        $managedPh = $this->_em->merge($ph);
0 ignored issues
show
Unused Code introduced by
$managedPh 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...
960
961
        $this->_em->flush();
962
        $this->_em->clear();
963
964
        $this->assertNull($this->_em->find(get_class($ph), $ph->phonenumber)->getUser());
965
    }
966
967
    /**
968
     * @group DDC-952
969
     */
970
    public function testManyToOneFetchModeQuery()
971
    {
972
        $user = new CmsUser();
973
        $user->username = "beberlei";
974
        $user->name = "Benjamin E.";
975
        $user->status = 'active';
976
977
        $article = new CmsArticle();
978
        $article->topic = "foo";
979
        $article->text = "bar";
980
        $article->user = $user;
981
982
        $this->_em->persist($article);
983
        $this->_em->persist($user);
984
        $this->_em->flush();
985
        $this->_em->clear();
986
987
        $qc = $this->getCurrentQueryCount();
988
        $dql = "SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a WHERE a.id = ?1";
989
        $article = $this->_em->createQuery($dql)
990
                             ->setParameter(1, $article->id)
991
                             ->setFetchMode(CmsArticle::class, 'user', ClassMetadata::FETCH_EAGER)
992
                             ->getSingleResult();
993
        $this->assertInstanceOf(Proxy::class, $article->user, "It IS a proxy, ...");
994
        $this->assertTrue($article->user->__isInitialized__, "...but its initialized!");
0 ignored issues
show
Bug introduced by
The property __isInitialized__ does not seem to exist in Doctrine\Tests\Models\CMS\CmsUser.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
995
        $this->assertEquals($qc+2, $this->getCurrentQueryCount());
996
    }
997
998
    /**
999
     * @group DDC-1278
1000
     */
1001
    public function testClearWithEntityName()
1002
    {
1003
        $user = new CmsUser;
1004
        $user->name = 'Dominik';
1005
        $user->username = 'domnikl';
1006
        $user->status = 'developer';
1007
1008
        $address = new CmsAddress();
1009
        $address->city = "Springfield";
1010
        $address->zip = "12354";
1011
        $address->country = "Germany";
1012
        $address->street = "Foo Street";
1013
        $address->user = $user;
1014
        $user->address = $address;
1015
1016
        $article1 = new CmsArticle();
1017
        $article1->topic = 'Foo';
1018
        $article1->text = 'Foo Text';
1019
1020
        $article2 = new CmsArticle();
1021
        $article2->topic = 'Bar';
1022
        $article2->text = 'Bar Text';
1023
1024
        $user->addArticle($article1);
1025
        $user->addArticle($article2);
1026
1027
        $this->_em->persist($article1);
1028
        $this->_em->persist($article2);
1029
        $this->_em->persist($address);
1030
        $this->_em->persist($user);
1031
        $this->_em->flush();
1032
1033
        $unitOfWork = $this->_em->getUnitOfWork();
1034
1035
        $this->_em->clear(CmsUser::class);
1036
1037
        $this->assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($user));
1038
        $this->assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($article1));
1039
        $this->assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($article2));
1040
        $this->assertEquals(UnitOfWork::STATE_MANAGED, $unitOfWork->getEntityState($address));
1041
1042
        $this->_em->clear();
1043
1044
        $this->assertEquals(UnitOfWork::STATE_DETACHED, $unitOfWork->getEntityState($address));
1045
    }
1046
1047
    public function testFlushManyExplicitEntities()
1048
    {
1049
        $userA = new CmsUser;
1050
        $userA->username = 'UserA';
1051
        $userA->name = 'UserA';
1052
1053
        $userB = new CmsUser;
1054
        $userB->username = 'UserB';
1055
        $userB->name = 'UserB';
1056
1057
        $userC = new CmsUser;
1058
        $userC->username = 'UserC';
1059
        $userC->name = 'UserC';
1060
1061
        $this->_em->persist($userA);
1062
        $this->_em->persist($userB);
1063
        $this->_em->persist($userC);
1064
1065
        $this->_em->flush([$userA, $userB, $userB]);
1066
1067
        $userC->name = 'changed name';
1068
1069
        $this->_em->flush([$userA, $userB]);
1070
        $this->_em->refresh($userC);
1071
1072
        $this->assertTrue($userA->id > 0, 'user a has an id');
1073
        $this->assertTrue($userB->id > 0, 'user b has an id');
1074
        $this->assertTrue($userC->id > 0, 'user c has an id');
1075
        $this->assertEquals('UserC', $userC->name, 'name has not changed because we did not flush it');
1076
    }
1077
1078
    /**
1079
     * @group DDC-720
1080
     */
1081 View Code Duplication
    public function testFlushSingleManagedEntity()
1082
    {
1083
        $user = new CmsUser;
1084
        $user->name = 'Dominik';
1085
        $user->username = 'domnikl';
1086
        $user->status = 'developer';
1087
1088
        $this->_em->persist($user);
1089
        $this->_em->flush();
1090
1091
        $user->status = 'administrator';
1092
        $this->_em->flush($user);
1093
        $this->_em->clear();
1094
1095
        $user = $this->_em->find(get_class($user), $user->id);
1096
        $this->assertEquals('administrator', $user->status);
1097
    }
1098
1099
    /**
1100
     * @group DDC-720
1101
     */
1102 View Code Duplication
    public function testFlushSingleUnmanagedEntity()
1103
    {
1104
        $user = new CmsUser;
1105
        $user->name = 'Dominik';
1106
        $user->username = 'domnikl';
1107
        $user->status = 'developer';
1108
1109
        $this->expectException(\InvalidArgumentException::class);
1110
        $this->expectExceptionMessage('Entity has to be managed or scheduled for removal for single computation');
1111
1112
        $this->_em->flush($user);
1113
    }
1114
1115
    /**
1116
     * @group DDC-720
1117
     */
1118
    public function testFlushSingleAndNewEntity()
1119
    {
1120
        $user = new CmsUser;
1121
        $user->name = 'Dominik';
1122
        $user->username = 'domnikl';
1123
        $user->status = 'developer';
1124
1125
        $this->_em->persist($user);
1126
        $this->_em->flush();
1127
1128
        $otherUser = new CmsUser;
1129
        $otherUser->name = 'Dominik2';
1130
        $otherUser->username = 'domnikl2';
1131
        $otherUser->status = 'developer';
1132
1133
        $user->status = 'administrator';
1134
1135
        $this->_em->persist($otherUser);
1136
        $this->_em->flush($user);
1137
1138
        $this->assertTrue($this->_em->contains($otherUser), "Other user is contained in EntityManager");
1139
        $this->assertTrue($otherUser->id > 0, "other user has an id");
1140
    }
1141
1142
    /**
1143
     * @group DDC-720
1144
     */
1145
    public function testFlushAndCascadePersist()
1146
    {
1147
        $user = new CmsUser;
1148
        $user->name = 'Dominik';
1149
        $user->username = 'domnikl';
1150
        $user->status = 'developer';
1151
1152
        $this->_em->persist($user);
1153
        $this->_em->flush();
1154
1155
        $address = new CmsAddress();
1156
        $address->city = "Springfield";
1157
        $address->zip = "12354";
1158
        $address->country = "Germany";
1159
        $address->street = "Foo Street";
1160
        $address->user = $user;
1161
        $user->address = $address;
1162
1163
        $this->_em->flush($user);
1164
1165
        $this->assertTrue($this->_em->contains($address), "Other user is contained in EntityManager");
1166
        $this->assertTrue($address->id > 0, "other user has an id");
1167
    }
1168
1169
    /**
1170
     * @group DDC-720
1171
     */
1172 View Code Duplication
    public function testFlushSingleAndNoCascade()
1173
    {
1174
        $user = new CmsUser;
1175
        $user->name = 'Dominik';
1176
        $user->username = 'domnikl';
1177
        $user->status = 'developer';
1178
1179
        $this->_em->persist($user);
1180
        $this->_em->flush();
1181
1182
        $article1 = new CmsArticle();
1183
        $article1->topic = 'Foo';
1184
        $article1->text = 'Foo Text';
1185
        $article1->author = $user;
0 ignored issues
show
Bug introduced by
The property author does not seem to exist in Doctrine\Tests\Models\CMS\CmsArticle.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1186
        $user->articles[] = $article1;
1187
1188
        $this->expectException(\InvalidArgumentException::class);
1189
        $this->expectExceptionMessage("A new entity was found through the relationship 'Doctrine\Tests\Models\CMS\CmsUser#articles'");
1190
1191
        $this->_em->flush($user);
1192
    }
1193
1194
    /**
1195
     * @group DDC-720
1196
     * @group DDC-1612
1197
     * @group DDC-2267
1198
     */
1199 View Code Duplication
    public function testFlushSingleNewEntityThenRemove()
1200
    {
1201
        $user = new CmsUser;
1202
        $user->name = 'Dominik';
1203
        $user->username = 'domnikl';
1204
        $user->status = 'developer';
1205
1206
        $this->_em->persist($user);
1207
        $this->_em->flush($user);
1208
1209
        $userId = $user->id;
1210
1211
        $this->_em->remove($user);
1212
        $this->_em->flush($user);
1213
        $this->_em->clear();
1214
1215
        $this->assertNull($this->_em->find(get_class($user), $userId));
1216
    }
1217
1218
    /**
1219
     * @group DDC-720
1220
     */
1221
    public function testProxyIsIgnored()
1222
    {
1223
        $user = new CmsUser;
1224
        $user->name = 'Dominik';
1225
        $user->username = 'domnikl';
1226
        $user->status = 'developer';
1227
1228
        $this->_em->persist($user);
1229
        $this->_em->flush();
1230
        $this->_em->clear();
1231
1232
        $user = $this->_em->getReference(get_class($user), $user->id);
1233
1234
        $otherUser = new CmsUser;
1235
        $otherUser->name = 'Dominik2';
1236
        $otherUser->username = 'domnikl2';
1237
        $otherUser->status = 'developer';
1238
1239
        $this->_em->persist($otherUser);
1240
        $this->_em->flush($user);
1241
1242
        $this->assertTrue($this->_em->contains($otherUser), "Other user is contained in EntityManager");
1243
        $this->assertTrue($otherUser->id > 0, "other user has an id");
1244
    }
1245
1246
    /**
1247
     * @group DDC-720
1248
     */
1249
    public function testFlushSingleSaveOnlySingle()
1250
    {
1251
        $user = new CmsUser;
1252
        $user->name = 'Dominik';
1253
        $user->username = 'domnikl';
1254
        $user->status = 'developer';
1255
        $this->_em->persist($user);
1256
1257
        $user2 = new CmsUser;
1258
        $user2->name = 'Dominik';
1259
        $user2->username = 'domnikl2';
1260
        $user2->status = 'developer';
1261
        $this->_em->persist($user2);
1262
1263
        $this->_em->flush();
1264
1265
        $user->status = 'admin';
1266
        $user2->status = 'admin';
1267
1268
        $this->_em->flush($user);
1269
        $this->_em->clear();
1270
1271
        $user2 = $this->_em->find(get_class($user2), $user2->id);
1272
        $this->assertEquals('developer', $user2->status);
1273
    }
1274
1275
    /**
1276
     * @group DDC-1585
1277
     */
1278
    public function testWrongAssociationInstance()
1279
    {
1280
        $user = new CmsUser;
1281
        $user->name = 'Dominik';
1282
        $user->username = 'domnikl';
1283
        $user->status = 'developer';
1284
        $user->address = $user;
1285
1286
        $this->expectException(ORMInvalidArgumentException::class);
1287
        $this->expectExceptionMessage(
1288
            'Expected value of type "Doctrine\Tests\Models\CMS\CmsAddress" for association field ' .
1289
            '"Doctrine\Tests\Models\CMS\CmsUser#$address", got "Doctrine\Tests\Models\CMS\CmsUser" instead.'
1290
        );
1291
1292
        $this->_em->persist($user);
1293
1294
        $this->_em->flush();
1295
    }
1296
}
1297