Passed
Pull Request — develop (#6935)
by Michael
503:01 queued 406:10
created

testFindByOrderByAssociation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 0
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Tests\ORM\Functional;
6
7
use Doctrine\Common\Collections\ArrayCollection;
8
use Doctrine\Common\Collections\Criteria;
9
use Doctrine\DBAL\Connection;
10
use Doctrine\DBAL\LockMode;
11
use Doctrine\ORM\EntityRepository;
12
use Doctrine\ORM\OptimisticLockException;
13
use Doctrine\ORM\ORMException;
14
use Doctrine\ORM\Query;
15
use Doctrine\ORM\TransactionRequiredException;
16
use Doctrine\Tests\Models\CMS\CmsAddress;
17
use Doctrine\Tests\Models\CMS\CmsEmail;
18
use Doctrine\Tests\Models\CMS\CmsUser;
19
use Doctrine\Tests\Models\DDC753\DDC753CustomRepository;
20
use Doctrine\Tests\Models\DDC753\DDC753DefaultRepository;
21
use Doctrine\Tests\Models\DDC753\DDC753EntityWithCustomRepository;
22
use Doctrine\Tests\Models\DDC753\DDC753EntityWithDefaultCustomRepository;
23
use Doctrine\Tests\Models\DDC753\DDC753InvalidRepository;
24
use Doctrine\Tests\OrmFunctionalTestCase;
25
26
/**
27
 * @author robo
28
 */
29
class EntityRepositoryTest extends OrmFunctionalTestCase
30
{
31
    protected function setUp()
32
    {
33
        $this->useModelSet('cms');
34
        parent::setUp();
35
    }
36
37
    public function loadFixture()
38
    {
39
        $user = new CmsUser;
40
        $user->name = 'Roman';
41
        $user->username = 'romanb';
42
        $user->status = 'freak';
43
        $this->em->persist($user);
44
45
        $user2 = new CmsUser;
46
        $user2->name = 'Guilherme';
47
        $user2->username = 'gblanco';
48
        $user2->status = 'dev';
49
        $this->em->persist($user2);
50
51
        $user3 = new CmsUser;
52
        $user3->name = 'Benjamin';
53
        $user3->username = 'beberlei';
54
        $user3->status = null;
55
        $this->em->persist($user3);
56
57
        $user4 = new CmsUser;
58
        $user4->name = 'Alexander';
59
        $user4->username = 'asm89';
60
        $user4->status = 'dev';
61
        $this->em->persist($user4);
62
63
        $this->em->flush();
64
65
        $user1Id = $user->getId();
66
67
        unset($user);
68
        unset($user2);
69
        unset($user3);
70
        unset($user4);
71
72
        $this->em->clear();
73
74
        return $user1Id;
75
    }
76
77
    public function loadAssociatedFixture()
78
    {
79
        $address = new CmsAddress();
80
        $address->city = "Berlin";
81
        $address->country = "Germany";
82
        $address->street = "Foostreet";
83
        $address->zip = "12345";
84
85
        $user = new CmsUser();
86
        $user->name = 'Roman';
87
        $user->username = 'romanb';
88
        $user->status = 'freak';
89
        $user->setAddress($address);
90
91
        $this->em->persist($user);
92
        $this->em->persist($address);
93
        $this->em->flush();
94
        $this->em->clear();
95
96
        return [$user->id, $address->id];
97
    }
98
99
    public function loadFixtureUserEmail()
100
    {
101
        $user1 = new CmsUser();
102
        $user2 = new CmsUser();
103
        $user3 = new CmsUser();
104
105
        $email1 = new CmsEmail();
106
        $email2 = new CmsEmail();
107
        $email3 = new CmsEmail();
108
109
        $user1->name     = 'Test 1';
110
        $user1->username = 'test1';
111
        $user1->status   = 'active';
112
113
        $user2->name     = 'Test 2';
114
        $user2->username = 'test2';
115
        $user2->status   = 'active';
116
117
        $user3->name     = 'Test 3';
118
        $user3->username = 'test3';
119
        $user3->status   = 'active';
120
121
        $email1->email   = '[email protected]';
122
        $email2->email   = '[email protected]';
123
        $email3->email   = '[email protected]';
124
125
        $user1->setEmail($email1);
126
        $user2->setEmail($email2);
127
        $user3->setEmail($email3);
128
129
        $this->em->persist($user1);
130
        $this->em->persist($user2);
131
        $this->em->persist($user3);
132
133
        $this->em->persist($email1);
134
        $this->em->persist($email2);
135
        $this->em->persist($email3);
136
137
        $this->em->flush();
138
        $this->em->clear();
139
140
        return [$user1, $user2, $user3];
141
    }
142
143
    public function buildUser($name, $username, $status, $address)
144
    {
145
        $user = new CmsUser();
146
        $user->name     = $name;
147
        $user->username = $username;
148
        $user->status   = $status;
149
        $user->setAddress($address);
150
151
        $this->em->persist($user);
152
        $this->em->flush();
153
154
        return $user;
155
    }
156
157
    public function buildAddress($country, $city, $street, $zip)
158
    {
159
        $address = new CmsAddress();
160
        $address->country = $country;
161
        $address->city    = $city;
162
        $address->street  = $street;
163
        $address->zip     = $zip;
164
165
        $this->em->persist($address);
166
        $this->em->flush();
167
168
        return $address;
169
    }
170
171
    public function testBasicFind()
172
    {
173
        $user1Id = $this->loadFixture();
174
        $repos = $this->em->getRepository(CmsUser::class);
175
176
        $user = $repos->find($user1Id);
177
        self::assertInstanceOf(CmsUser::class,$user);
178
        self::assertEquals('Roman', $user->name);
179
        self::assertEquals('freak', $user->status);
180
    }
181
182
    public function testFindByField()
183
    {
184
        $user1Id = $this->loadFixture();
0 ignored issues
show
Unused Code introduced by
The assignment to $user1Id is dead and can be removed.
Loading history...
185
        $repos = $this->em->getRepository(CmsUser::class);
186
187
        $users = $repos->findBy(['status' => 'dev']);
188
        self::assertCount(2, $users);
189
        self::assertInstanceOf(CmsUser::class,$users[0]);
190
        self::assertEquals('Guilherme', $users[0]->name);
191
        self::assertEquals('dev', $users[0]->status);
192
    }
193
194
    public function testFindByAssociationWithIntegerAsParameter()
195
    {
196
        $address1 = $this->buildAddress('Germany', 'Berlim', 'Foo st.', '123456');
197
        $user1    = $this->buildUser('Benjamin', 'beberlei', 'dev', $address1);
198
199
        $address2 = $this->buildAddress('Brazil', 'São Paulo', 'Bar st.', '654321');
200
        $user2    = $this->buildUser('Guilherme', 'guilhermeblanco', 'freak', $address2);
201
202
        $address3 = $this->buildAddress('USA', 'Nashville', 'Woo st.', '321654');
203
        $user3    = $this->buildUser('Jonathan', 'jwage', 'dev', $address3);
0 ignored issues
show
Unused Code introduced by
The assignment to $user3 is dead and can be removed.
Loading history...
204
205
        unset($address1);
206
        unset($address2);
207
        unset($address3);
208
209
        $this->em->clear();
210
211
        $repository = $this->em->getRepository(CmsAddress::class);
212
        $addresses  = $repository->findBy(['user' => [$user1->getId(), $user2->getId()]]);
213
214
        self::assertCount(2, $addresses);
215
        self::assertInstanceOf(CmsAddress::class,$addresses[0]);
216
    }
217
218
    public function testFindByAssociationWithObjectAsParameter()
219
    {
220
        $address1 = $this->buildAddress('Germany', 'Berlim', 'Foo st.', '123456');
221
        $user1    = $this->buildUser('Benjamin', 'beberlei', 'dev', $address1);
222
223
        $address2 = $this->buildAddress('Brazil', 'São Paulo', 'Bar st.', '654321');
224
        $user2    = $this->buildUser('Guilherme', 'guilhermeblanco', 'freak', $address2);
225
226
        $address3 = $this->buildAddress('USA', 'Nashville', 'Woo st.', '321654');
227
        $user3    = $this->buildUser('Jonathan', 'jwage', 'dev', $address3);
0 ignored issues
show
Unused Code introduced by
The assignment to $user3 is dead and can be removed.
Loading history...
228
229
        unset($address1);
230
        unset($address2);
231
        unset($address3);
232
233
        $this->em->clear();
234
235
        $repository = $this->em->getRepository(CmsAddress::class);
236
        $addresses  = $repository->findBy(['user' => [$user1, $user2]]);
237
238
        self::assertCount(2, $addresses);
239
        self::assertInstanceOf(CmsAddress::class,$addresses[0]);
240
    }
241
242
    public function testFindFieldByMagicCall()
243
    {
244
        $user1Id = $this->loadFixture();
0 ignored issues
show
Unused Code introduced by
The assignment to $user1Id is dead and can be removed.
Loading history...
245
        $repos = $this->em->getRepository(CmsUser::class);
246
247
        $users = $repos->findByStatus('dev');
0 ignored issues
show
Bug introduced by
The method findByStatus() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findBy()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

247
        /** @scrutinizer ignore-call */ 
248
        $users = $repos->findByStatus('dev');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
248
        self::assertCount(2, $users);
249
        self::assertInstanceOf(CmsUser::class,$users[0]);
250
        self::assertEquals('Guilherme', $users[0]->name);
251
        self::assertEquals('dev', $users[0]->status);
252
    }
253
254
    public function testFindAll()
255
    {
256
        $user1Id = $this->loadFixture();
0 ignored issues
show
Unused Code introduced by
The assignment to $user1Id is dead and can be removed.
Loading history...
257
        $repos = $this->em->getRepository(CmsUser::class);
258
259
        $users = $repos->findAll();
260
        self::assertCount(4, $users);
261
    }
262
263
    public function testCount()
264
    {
265
        $this->loadFixture();
266
        $repos = $this->em->getRepository(CmsUser::class);
267
268
        $userCount = $repos->count([]);
269
        self::assertSame(4, $userCount);
270
271
        $userCount = $repos->count(['status' => 'dev']);
272
        self::assertSame(2, $userCount);
273
274
        $userCount = $repos->count(['status' => 'nonexistent']);
275
        self::assertSame(0, $userCount);
276
    }
277
278
    public function testCountBy()
279
    {
280
        $this->loadFixture();
281
        $repos = $this->em->getRepository(CmsUser::class);
282
283
        $userCount = $repos->countByStatus('dev');
284
        self::assertSame(2, $userCount);
285
    }
286
287
    /**
288
     * @expectedException \Doctrine\ORM\ORMException
289
     */
290
    public function testExceptionIsThrownWhenCallingFindByWithoutParameter()
291
    {
292
        $this->em->getRepository(CmsUser::class)
293
                  ->findByStatus();
294
    }
295
296
    /**
297
     * @expectedException \Doctrine\ORM\ORMException
298
     */
299
    public function testExceptionIsThrownWhenUsingInvalidFieldName()
300
    {
301
        $this->em->getRepository(CmsUser::class)
302
                  ->findByThisFieldDoesNotExist('testvalue');
0 ignored issues
show
Bug introduced by
The method findByThisFieldDoesNotExist() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findBy()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

302
                  ->/** @scrutinizer ignore-call */ findByThisFieldDoesNotExist('testvalue');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
303
    }
304
305
    /**
306
     * @group locking
307
     * @group DDC-178
308
     */
309
    public function testPessimisticReadLockWithoutTransaction_ThrowsException()
310
    {
311
        $this->expectException(TransactionRequiredException::class);
312
313
        $this->em->getRepository(CmsUser::class)
314
                  ->find(1, LockMode::PESSIMISTIC_READ);
0 ignored issues
show
Unused Code introduced by
The call to Doctrine\Common\Persiste...bjectRepository::find() has too many arguments starting with Doctrine\DBAL\LockMode::PESSIMISTIC_READ. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

314
                  ->/** @scrutinizer ignore-call */ find(1, LockMode::PESSIMISTIC_READ);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
315
    }
316
317
    /**
318
     * @group locking
319
     * @group DDC-178
320
     */
321
    public function testPessimisticWriteLockWithoutTransaction_ThrowsException()
322
    {
323
        $this->expectException(TransactionRequiredException::class);
324
325
        $this->em->getRepository(CmsUser::class)
326
                  ->find(1, LockMode::PESSIMISTIC_WRITE);
0 ignored issues
show
Unused Code introduced by
The call to Doctrine\Common\Persiste...bjectRepository::find() has too many arguments starting with Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

326
                  ->/** @scrutinizer ignore-call */ find(1, LockMode::PESSIMISTIC_WRITE);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
327
    }
328
329
    /**
330
     * @group locking
331
     * @group DDC-178
332
     */
333
    public function testOptimisticLockUnversionedEntity_ThrowsException()
334
    {
335
        $this->expectException(OptimisticLockException::class);
336
337
        $this->em->getRepository(CmsUser::class)
338
                  ->find(1, LockMode::OPTIMISTIC);
0 ignored issues
show
Unused Code introduced by
The call to Doctrine\Common\Persiste...bjectRepository::find() has too many arguments starting with Doctrine\DBAL\LockMode::OPTIMISTIC. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

338
                  ->/** @scrutinizer ignore-call */ find(1, LockMode::OPTIMISTIC);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
339
    }
340
341
    /**
342
     * @group locking
343
     * @group DDC-178
344
     */
345
    public function testIdentityMappedOptimisticLockUnversionedEntity_ThrowsException()
346
    {
347
        $user = new CmsUser;
348
        $user->name = 'Roman';
349
        $user->username = 'romanb';
350
        $user->status = 'freak';
351
        $this->em->persist($user);
352
        $this->em->flush();
353
354
        $userId = $user->id;
355
356
        $this->em->find(CmsUser::class, $userId);
357
358
        $this->expectException(OptimisticLockException::class);
359
360
        $this->em->find(CmsUser::class, $userId, LockMode::OPTIMISTIC);
0 ignored issues
show
Unused Code introduced by
The call to Doctrine\Common\Persistence\ObjectManager::find() has too many arguments starting with Doctrine\DBAL\LockMode::OPTIMISTIC. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

360
        $this->em->/** @scrutinizer ignore-call */ 
361
                   find(CmsUser::class, $userId, LockMode::OPTIMISTIC);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
361
    }
362
363
    /**
364
     * @group DDC-819
365
     */
366
    public function testFindMagicCallByNullValue()
367
    {
368
        $this->loadFixture();
369
370
        $repos = $this->em->getRepository(CmsUser::class);
371
372
        $users = $repos->findByStatus(null);
373
        self::assertCount(1, $users);
374
    }
375
376
    /**
377
     * @group DDC-819
378
     */
379
    public function testInvalidMagicCall()
380
    {
381
        $this->expectException(\BadMethodCallException::class);
382
383
        $repos = $this->em->getRepository(CmsUser::class);
384
        $repos->foo();
385
    }
386
387
    /**
388
     * @group DDC-817
389
     */
390
    public function testFindByAssociationKey_ExceptionOnInverseSide()
391
    {
392
        list($userId, $addressId) = $this->loadAssociatedFixture();
393
        $repos = $this->em->getRepository(CmsUser::class);
394
395
        $this->expectException(ORMException::class);
396
        $this->expectExceptionMessage("You cannot search for the association field 'Doctrine\Tests\Models\CMS\CmsUser#address', because it is the inverse side of an association. Find methods only work on owning side associations.");
397
398
        $user = $repos->findBy(['address' => $addressId]);
0 ignored issues
show
Unused Code introduced by
The assignment to $user is dead and can be removed.
Loading history...
399
    }
400
401
    /**
402
     * @group DDC-817
403
     */
404
    public function testFindOneByAssociationKey()
405
    {
406
        list($userId, $addressId) = $this->loadAssociatedFixture();
407
        $repos = $this->em->getRepository(CmsAddress::class);
408
        $address = $repos->findOneBy(['user' => $userId]);
409
410
        self::assertInstanceOf(CmsAddress::class, $address);
411
        self::assertEquals($addressId, $address->id);
412
    }
413
414
    /**
415
     * @group DDC-1241
416
     */
417
    public function testFindOneByOrderBy()
418
    {
419
        $this->loadFixture();
420
421
        $repos = $this->em->getRepository(CmsUser::class);
422
        $userAsc = $repos->findOneBy([], ["username" => "ASC"]);
0 ignored issues
show
Unused Code introduced by
The call to Doctrine\Common\Persiste...Repository::findOneBy() has too many arguments starting with array('username' => 'ASC'). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

422
        /** @scrutinizer ignore-call */ 
423
        $userAsc = $repos->findOneBy([], ["username" => "ASC"]);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
423
        $userDesc = $repos->findOneBy([], ["username" => "DESC"]);
424
425
        self::assertNotSame($userAsc, $userDesc);
426
    }
427
428
    /**
429
     * @group DDC-817
430
     */
431
    public function testFindByAssociationKey()
432
    {
433
        list($userId, $addressId) = $this->loadAssociatedFixture();
434
        $repos = $this->em->getRepository(CmsAddress::class);
435
        $addresses = $repos->findBy(['user' => $userId]);
436
437
        self::assertContainsOnly(CmsAddress::class, $addresses);
438
        self::assertCount(1, $addresses);
439
        self::assertEquals($addressId, $addresses[0]->id);
440
    }
441
442
    /**
443
     * @group DDC-817
444
     */
445
    public function testFindAssociationByMagicCall()
446
    {
447
        list($userId, $addressId) = $this->loadAssociatedFixture();
448
        $repos = $this->em->getRepository(CmsAddress::class);
449
        $addresses = $repos->findByUser($userId);
0 ignored issues
show
Bug introduced by
The method findByUser() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findBy()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

449
        /** @scrutinizer ignore-call */ 
450
        $addresses = $repos->findByUser($userId);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
450
451
        self::assertContainsOnly(CmsAddress::class, $addresses);
452
        self::assertCount(1, $addresses);
453
        self::assertEquals($addressId, $addresses[0]->id);
454
    }
455
456
    /**
457
     * @group DDC-817
458
     */
459
    public function testFindOneAssociationByMagicCall()
460
    {
461
        list($userId, $addressId) = $this->loadAssociatedFixture();
462
        $repos = $this->em->getRepository(CmsAddress::class);
463
        $address = $repos->findOneByUser($userId);
0 ignored issues
show
Bug introduced by
The method findOneByUser() does not exist on Doctrine\Common\Persistence\ObjectRepository. Did you maybe mean findOneBy()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

463
        /** @scrutinizer ignore-call */ 
464
        $address = $repos->findOneByUser($userId);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
464
465
        self::assertInstanceOf(CmsAddress::class, $address);
466
        self::assertEquals($addressId, $address->id);
467
    }
468
469
    public function testValidNamedQueryRetrieval()
470
    {
471
        $repos = $this->em->getRepository(CmsUser::class);
472
473
        $query = $repos->createNamedQuery('all');
474
475
        self::assertInstanceOf(Query::class, $query);
476
        self::assertEquals('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u', $query->getDQL());
477
    }
478
479
    public function testInvalidNamedQueryRetrieval()
480
    {
481
        $repos = $this->em->getRepository(CmsUser::class);
482
483
        $this->expectException(\Doctrine\ORM\Mapping\MappingException::class);
484
485
        $repos->createNamedQuery('invalidNamedQuery');
486
    }
487
488
    /**
489
     * @group DDC-1087
490
     */
491
    public function testIsNullCriteriaDoesNotGenerateAParameter()
492
    {
493
        $repos = $this->em->getRepository(CmsUser::class);
494
        $users = $repos->findBy(['status' => null, 'username' => 'romanb']);
0 ignored issues
show
Unused Code introduced by
The assignment to $users is dead and can be removed.
Loading history...
495
496
        $params = $this->sqlLoggerStack->queries[$this->sqlLoggerStack->currentQuery]['params'];
497
        self::assertCount(1, $params, "Should only execute with one parameter.");
498
        self::assertEquals(['romanb'], $params);
499
    }
500
501
    public function testIsNullCriteria()
502
    {
503
        $this->loadFixture();
504
505
        $repos = $this->em->getRepository(CmsUser::class);
506
507
        $users = $repos->findBy(['status' => null]);
508
        self::assertCount(1, $users);
509
    }
510
511
    /**
512
     * @group DDC-1094
513
     */
514
    public function testFindByLimitOffset()
515
    {
516
        $this->loadFixture();
517
518
        $repos = $this->em->getRepository(CmsUser::class);
519
520
        $users1 = $repos->findBy([], null, 1, 0);
521
        $users2 = $repos->findBy([], null, 1, 1);
522
523
        self::assertCount(4, $repos->findBy([]));
524
        self::assertCount(1, $users1);
525
        self::assertCount(1, $users2);
526
        self::assertNotSame($users1[0], $users2[0]);
527
    }
528
529
    /**
530
     * @group DDC-1094
531
     */
532
    public function testFindByOrderBy()
533
    {
534
        $this->loadFixture();
535
536
        $repos = $this->em->getRepository(CmsUser::class);
537
        $usersAsc = $repos->findBy([], ["username" => "ASC"]);
538
        $usersDesc = $repos->findBy([], ["username" => "DESC"]);
539
540
        self::assertCount(4, $usersAsc, "Pre-condition: only four users in fixture");
541
        self::assertCount(4, $usersDesc, "Pre-condition: only four users in fixture");
542
        self::assertSame($usersAsc[0], $usersDesc[3]);
543
        self::assertSame($usersAsc[3], $usersDesc[0]);
544
    }
545
546
    /**
547
     * @group DDC-1376
548
     */
549
    public function testFindByOrderByAssociation()
550
    {
551
        $this->loadFixtureUserEmail();
552
553
        $repository = $this->em->getRepository(CmsUser::class);
554
        $resultAsc  = $repository->findBy([], ['email' => 'ASC']);
555
        $resultDesc = $repository->findBy([], ['email' => 'DESC']);
556
557
        self::assertCount(3, $resultAsc);
558
        self::assertCount(3, $resultDesc);
559
560
        self::assertEquals($resultAsc[0]->getEmail()->getId(), $resultDesc[2]->getEmail()->getId());
561
        self::assertEquals($resultAsc[2]->getEmail()->getId(), $resultDesc[0]->getEmail()->getId());
562
    }
563
564
    /**
565
     * @group DDC-1426
566
     */
567
    public function testFindFieldByMagicCallOrderBy()
568
    {
569
        $this->loadFixture();
570
        $repos = $this->em->getRepository(CmsUser::class);
571
572
        $usersAsc = $repos->findByStatus('dev', ['username' => "ASC"]);
573
        $usersDesc = $repos->findByStatus('dev', ['username' => "DESC"]);
574
575
        self::assertCount(2, $usersAsc);
576
        self::assertCount(2, $usersDesc);
577
578
        self::assertInstanceOf(CmsUser::class,$usersAsc[0]);
579
        self::assertEquals('Alexander', $usersAsc[0]->name);
580
        self::assertEquals('dev', $usersAsc[0]->status);
581
582
        self::assertSame($usersAsc[0], $usersDesc[1]);
583
        self::assertSame($usersAsc[1], $usersDesc[0]);
584
    }
585
586
    /**
587
     * @group DDC-1426
588
     */
589
    public function testFindFieldByMagicCallLimitOffset()
590
    {
591
        $this->loadFixture();
592
        $repos = $this->em->getRepository(CmsUser::class);
593
594
        $users1 = $repos->findByStatus('dev', [], 1, 0);
595
        $users2 = $repos->findByStatus('dev', [], 1, 1);
596
597
        self::assertCount(1, $users1);
598
        self::assertCount(1, $users2);
599
        self::assertNotSame($users1[0], $users2[0]);
600
    }
601
602
    /**
603
     * @group DDC-753
604
     */
605
    public function testDefaultRepositoryClassName()
606
    {
607
        self::assertEquals($this->em->getConfiguration()->getDefaultRepositoryClassName(), EntityRepository::class);
608
        $this->em->getConfiguration()->setDefaultRepositoryClassName(DDC753DefaultRepository::class);
609
        self::assertEquals($this->em->getConfiguration()->getDefaultRepositoryClassName(), DDC753DefaultRepository::class);
610
611
        $repos = $this->em->getRepository(DDC753EntityWithDefaultCustomRepository::class);
612
        self::assertInstanceOf(DDC753DefaultRepository::class, $repos);
613
        self::assertTrue($repos->isDefaultRepository());
614
615
616
        $repos = $this->em->getRepository(DDC753EntityWithCustomRepository::class);
617
        self::assertInstanceOf(DDC753CustomRepository::class, $repos);
618
        self::assertTrue($repos->isCustomRepository());
619
620
        self::assertEquals($this->em->getConfiguration()->getDefaultRepositoryClassName(), DDC753DefaultRepository::class);
621
        $this->em->getConfiguration()->setDefaultRepositoryClassName(EntityRepository::class);
622
        self::assertEquals($this->em->getConfiguration()->getDefaultRepositoryClassName(), EntityRepository::class);
623
    }
624
625
    /**
626
     * @group DDC-753
627
     * @expectedException Doctrine\ORM\ORMException
628
     * @expectedExceptionMessage Invalid repository class 'Doctrine\Tests\Models\DDC753\DDC753InvalidRepository'. It must be a Doctrine\Common\Persistence\ObjectRepository.
629
     */
630
    public function testSetDefaultRepositoryInvalidClassError()
631
    {
632
        self::assertEquals($this->em->getConfiguration()->getDefaultRepositoryClassName(), EntityRepository::class);
633
        $this->em->getConfiguration()->setDefaultRepositoryClassName(DDC753InvalidRepository::class);
634
    }
635
636
    /**
637
     * @group DDC-3257
638
     */
639
    public function testCanRetrieveRepositoryFromClassNameWithLeadingBackslash()
640
    {
641
        self::assertSame(
642
            $this->em->getRepository('\\' . CmsUser::class),
643
            $this->em->getRepository(CmsUser::class)
644
        );
645
    }
646
647
    /**
648
     * @group DDC-1376
649
     *
650
     * @expectedException Doctrine\ORM\ORMException
651
     * @expectedExceptionMessage You cannot search for the association field 'Doctrine\Tests\Models\CMS\CmsUser#address', because it is the inverse side of an association.
652
     */
653
    public function testInvalidOrderByAssociation()
654
    {
655
        $this->em->getRepository(CmsUser::class)
656
            ->findBy(['status' => 'test'], ['address' => 'ASC']);
657
    }
658
659
    /**
660
     * @group DDC-1500
661
     */
662
    public function testInvalidOrientation()
663
    {
664
        $this->expectException(ORMException::class);
665
        $this->expectExceptionMessage('Invalid order by orientation specified for Doctrine\Tests\Models\CMS\CmsUser#username');
666
667
        $repo = $this->em->getRepository(CmsUser::class);
668
        $repo->findBy(['status' => 'test'], ['username' => 'INVALID']);
669
    }
670
671
    /**
672
     * @group DDC-1713
673
     */
674
    public function testFindByAssociationArray()
675
    {
676
        $repo = $this->em->getRepository(CmsAddress::class);
677
        $data = $repo->findBy(['user' => [1, 2, 3]]);
0 ignored issues
show
Unused Code introduced by
The assignment to $data is dead and can be removed.
Loading history...
678
679
        $query = array_pop($this->sqlLoggerStack->queries);
680
        self::assertEquals([1,2,3], $query['params'][0]);
681
        self::assertEquals(Connection::PARAM_INT_ARRAY, $query['types'][0]);
682
    }
683
684
    /**
685
     * @group DDC-1637
686
     */
687
    public function testMatchingEmptyCriteria()
688
    {
689
        $this->loadFixture();
690
691
        $repository = $this->em->getRepository(CmsUser::class);
692
        $users = $repository->matching(new Criteria());
693
694
        self::assertCount(4, $users);
695
    }
696
697
    /**
698
     * @group DDC-1637
699
     */
700
    public function testMatchingCriteriaEqComparison()
701
    {
702
        $this->loadFixture();
703
704
        $repository = $this->em->getRepository(CmsUser::class);
705
        $users = $repository->matching(new Criteria(
706
            Criteria::expr()->eq('username', 'beberlei')
707
        ));
708
709
        self::assertCount(1, $users);
710
    }
711
712
    /**
713
     * @group DDC-1637
714
     */
715
    public function testMatchingCriteriaNeqComparison()
716
    {
717
        $this->loadFixture();
718
719
        $repository = $this->em->getRepository(CmsUser::class);
720
        $users = $repository->matching(new Criteria(
721
            Criteria::expr()->neq('username', 'beberlei')
722
        ));
723
724
        self::assertCount(3, $users);
725
    }
726
727
    /**
728
     * @group DDC-1637
729
     */
730
    public function testMatchingCriteriaInComparison()
731
    {
732
        $this->loadFixture();
733
734
        $repository = $this->em->getRepository(CmsUser::class);
735
        $users = $repository->matching(new Criteria(
736
            Criteria::expr()->in('username', ['beberlei', 'gblanco'])
737
        ));
738
739
        self::assertCount(2, $users);
740
    }
741
742
    /**
743
     * @group DDC-1637
744
     */
745
    public function testMatchingCriteriaNotInComparison()
746
    {
747
        $this->loadFixture();
748
749
        $repository = $this->em->getRepository(CmsUser::class);
750
        $users = $repository->matching(new Criteria(
751
            Criteria::expr()->notIn('username', ['beberlei', 'gblanco', 'asm89'])
752
        ));
753
754
        self::assertCount(1, $users);
755
    }
756
757
    /**
758
     * @group DDC-1637
759
     */
760
    public function testMatchingCriteriaLtComparison()
761
    {
762
        $firstUserId = $this->loadFixture();
763
764
        $repository = $this->em->getRepository(CmsUser::class);
765
        $users = $repository->matching(new Criteria(
766
            Criteria::expr()->lt('id', $firstUserId + 1)
767
        ));
768
769
        self::assertCount(1, $users);
770
    }
771
772
    /**
773
     * @group DDC-1637
774
     */
775
    public function testMatchingCriteriaLeComparison()
776
    {
777
        $firstUserId = $this->loadFixture();
778
779
        $repository = $this->em->getRepository(CmsUser::class);
780
        $users = $repository->matching(new Criteria(
781
            Criteria::expr()->lte('id', $firstUserId + 1)
782
        ));
783
784
        self::assertCount(2, $users);
785
    }
786
787
    /**
788
     * @group DDC-1637
789
     */
790
    public function testMatchingCriteriaGtComparison()
791
    {
792
        $firstUserId = $this->loadFixture();
793
794
        $repository = $this->em->getRepository(CmsUser::class);
795
        $users = $repository->matching(new Criteria(
796
            Criteria::expr()->gt('id', $firstUserId)
797
        ));
798
799
        self::assertCount(3, $users);
800
    }
801
802
    /**
803
     * @group DDC-1637
804
     */
805
    public function testMatchingCriteriaGteComparison()
806
    {
807
        $firstUserId = $this->loadFixture();
808
809
        $repository = $this->em->getRepository(CmsUser::class);
810
        $users = $repository->matching(new Criteria(
811
            Criteria::expr()->gte('id', $firstUserId)
812
        ));
813
814
        self::assertCount(4, $users);
815
    }
816
817
    /**
818
     * @group DDC-2430
819
     */
820
    public function testMatchingCriteriaAssocationByObjectInMemory()
821
    {
822
        list($userId, $addressId) = $this->loadAssociatedFixture();
823
824
        $user = $this->em->find(CmsUser::class, $userId);
825
826
        $criteria = new Criteria(
827
            Criteria::expr()->eq('user', $user)
828
        );
829
830
        $repository = $this->em->getRepository(CmsAddress::class);
831
        $addresses = $repository->matching($criteria);
832
833
        self::assertCount(1, $addresses);
834
835
        $addresses = new ArrayCollection($repository->findAll());
836
837
        self::assertCount(1, $addresses->matching($criteria));
838
    }
839
840
    /**
841
     * @group DDC-2430
842
     */
843
    public function testMatchingCriteriaAssocationInWithArray()
844
    {
845
        list($userId, $addressId) = $this->loadAssociatedFixture();
846
847
        $user = $this->em->find(CmsUser::class, $userId);
848
849
        $criteria = new Criteria(
850
            Criteria::expr()->in('user', [$user])
851
        );
852
853
        $repository = $this->em->getRepository(CmsAddress::class);
854
        $addresses = $repository->matching($criteria);
855
856
        self::assertCount(1, $addresses);
857
858
        $addresses = new ArrayCollection($repository->findAll());
859
860
        self::assertCount(1, $addresses->matching($criteria));
861
    }
862
863
    public function testMatchingCriteriaContainsComparison()
864
    {
865
        $this->loadFixture();
866
867
        $repository = $this->em->getRepository(CmsUser::class);
868
869
        $users = $repository->matching(new Criteria(Criteria::expr()->contains('name', 'Foobar')));
870
        self::assertCount(0, $users);
871
872
        $users = $repository->matching(new Criteria(Criteria::expr()->contains('name', 'Rom')));
873
        self::assertCount(1, $users);
874
875
        $users = $repository->matching(new Criteria(Criteria::expr()->contains('status', 'dev')));
876
        self::assertCount(2, $users);
877
    }
878
879
    public function testMatchingCriteriaStartsWithComparison()
880
    {
881
        $this->loadFixture();
882
883
        $repository = $this->em->getRepository(CmsUser::class);
884
885
        $users = $repository->matching(new Criteria(Criteria::expr()->startsWith('name', 'Foo')));
886
        self::assertCount(0, $users);
887
888
        $users = $repository->matching(new Criteria(Criteria::expr()->startsWith('name', 'R')));
889
        self::assertCount(1, $users);
890
891
        $users = $repository->matching(new Criteria(Criteria::expr()->startsWith('status', 'de')));
892
        self::assertCount(2, $users);
893
    }
894
895
    public function testMatchingCriteriaEndsWithComparison()
896
    {
897
        $this->loadFixture();
898
899
        $repository = $this->em->getRepository(CmsUser::class);
900
901
        $users = $repository->matching(new Criteria(Criteria::expr()->endsWith('name', 'foo')));
902
        self::assertCount(0, $users);
903
904
        $users = $repository->matching(new Criteria(Criteria::expr()->endsWith('name', 'oman')));
905
        self::assertCount(1, $users);
906
907
        $users = $repository->matching(new Criteria(Criteria::expr()->endsWith('status', 'ev')));
908
        self::assertCount(2, $users);
909
    }
910
911
    /**
912
     * @group DDC-2478
913
     */
914
    public function testMatchingCriteriaNullAssocComparison()
915
    {
916
        $fixtures       = $this->loadFixtureUserEmail();
917
        $user           = $this->em->find(get_class($fixtures[0]), $fixtures[0]->id);
918
        $repository     = $this->em->getRepository(CmsUser::class);
919
        $criteriaIsNull = Criteria::create()->where(Criteria::expr()->isNull('email'));
920
        $criteriaEqNull = Criteria::create()->where(Criteria::expr()->eq('email', null));
921
922
        $user->setEmail(null);
923
        $this->em->flush();
924
        $this->em->clear();
925
926
        $usersIsNull = $repository->matching($criteriaIsNull);
927
        $usersEqNull = $repository->matching($criteriaEqNull);
928
929
        self::assertCount(1, $usersIsNull);
930
        self::assertCount(1, $usersEqNull);
931
932
        self::assertInstanceOf(CmsUser::class, $usersIsNull[0]);
933
        self::assertInstanceOf(CmsUser::class, $usersEqNull[0]);
934
935
        self::assertNull($usersIsNull[0]->getEmail());
936
        self::assertNull($usersEqNull[0]->getEmail());
937
    }
938
939
    /**
940
     * @group DDC-2055
941
     */
942
    public function testCreateResultSetMappingBuilder()
943
    {
944
        $repository = $this->em->getRepository(CmsUser::class);
945
        $rsm = $repository->createResultSetMappingBuilder('u');
946
947
        self::assertInstanceOf(Query\ResultSetMappingBuilder::class, $rsm);
948
        self::assertEquals(['u' => CmsUser::class], $rsm->aliasMap);
949
    }
950
951
    /**
952
     * @group DDC-3045
953
     */
954
    public function testFindByFieldInjectionPrevented()
955
    {
956
        $this->expectException(ORMException::class);
957
        $this->expectExceptionMessage('Unrecognized field: ');
958
959
        $repository = $this->em->getRepository(CmsUser::class);
960
        $repository->findBy(['username = ?; DELETE FROM cms_users; SELECT 1 WHERE 1' => 'test']);
961
    }
962
963
    /**
964
     * @group DDC-3045
965
     */
966
    public function testFindOneByFieldInjectionPrevented()
967
    {
968
        $this->expectException(ORMException::class);
969
        $this->expectExceptionMessage('Unrecognized field: ');
970
971
        $repository = $this->em->getRepository(CmsUser::class);
972
        $repository->findOneBy(['username = ?; DELETE FROM cms_users; SELECT 1 WHERE 1' => 'test']);
973
    }
974
975
    /**
976
     * @group DDC-3045
977
     */
978
    public function testMatchingInjectionPrevented()
979
    {
980
        $this->expectException(ORMException::class);
981
        $this->expectExceptionMessage('Unrecognized field: ');
982
983
        $repository = $this->em->getRepository(CmsUser::class);
984
        $result     = $repository->matching(new Criteria(
985
            Criteria::expr()->eq('username = ?; DELETE FROM cms_users; SELECT 1 WHERE 1', 'beberlei')
986
        ));
987
988
        // Because repository returns a lazy collection, we call toArray to force initialization
989
        $result->toArray();
990
    }
991
992
    /**
993
     * @group DDC-3045
994
     */
995
    public function testFindInjectionPrevented()
996
    {
997
        $this->expectException(ORMException::class);
998
        $this->expectExceptionMessage('Unrecognized identifier fields: ');
999
1000
        $repository = $this->em->getRepository(CmsUser::class);
1001
        $repository->find(['username = ?; DELETE FROM cms_users; SELECT 1 WHERE 1' => 'test', 'id' => 1]);
1002
    }
1003
1004
    /**
1005
     * @group DDC-3056
1006
     */
1007
    public function testFindByNullValueInInCondition()
1008
    {
1009
        $user1 = new CmsUser();
1010
        $user2 = new CmsUser();
1011
1012
        $user1->username = 'ocramius';
1013
        $user1->name = 'Marco';
1014
        $user2->status = null;
1015
        $user2->username = 'deeky666';
1016
        $user2->name = 'Steve';
1017
        $user2->status = 'dbal maintainer';
1018
1019
        $this->em->persist($user1);
1020
        $this->em->persist($user2);
1021
        $this->em->flush();
1022
1023
        $users = $this->em->getRepository(CmsUser::class)->findBy(['status' => [null]]);
1024
1025
        self::assertCount(1, $users);
1026
        self::assertSame($user1, reset($users));
1027
    }
1028
1029
    /**
1030
     * @group DDC-3056
1031
     */
1032
    public function testFindByNullValueInMultipleInCriteriaValues()
1033
    {
1034
        $user1 = new CmsUser();
1035
        $user2 = new CmsUser();
1036
1037
        $user1->username = 'ocramius';
1038
        $user1->name = 'Marco';
1039
        $user2->status = null;
1040
        $user2->username = 'deeky666';
1041
        $user2->name = 'Steve';
1042
        $user2->status = 'dbal maintainer';
1043
1044
        $this->em->persist($user1);
1045
        $this->em->persist($user2);
1046
        $this->em->flush();
1047
1048
        $users = $this
1049
            ->em
1050
            ->getRepository(CmsUser::class)
1051
            ->findBy(['status' => ['foo', null]]);
1052
1053
        self::assertCount(1, $users);
1054
        self::assertSame($user1, reset($users));
1055
    }
1056
1057
    /**
1058
     * @group DDC-3056
1059
     */
1060
    public function testFindMultipleByNullValueInMultipleInCriteriaValues()
1061
    {
1062
        $user1 = new CmsUser();
1063
        $user2 = new CmsUser();
1064
1065
        $user1->username = 'ocramius';
1066
        $user1->name = 'Marco';
1067
        $user2->status = null;
1068
        $user2->username = 'deeky666';
1069
        $user2->name = 'Steve';
1070
        $user2->status = 'dbal maintainer';
1071
1072
        $this->em->persist($user1);
1073
        $this->em->persist($user2);
1074
        $this->em->flush();
1075
1076
        $users = $this
1077
            ->em
1078
            ->getRepository(CmsUser::class)
1079
            ->findBy(['status' => ['dbal maintainer', null]]);
1080
1081
        self::assertCount(2, $users);
1082
1083
        foreach ($users as $user) {
1084
            self::assertContains($user, [$user1, $user2]);
1085
        }
1086
    }
1087
}
1088